blob: ed3cb950eacee2693ef0cf65464c03a5cb9a3976 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/identity_utils.h"
#include <string>
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/prefs/pref_service.h"
#include "third_party/icu/source/i18n/unicode/regex.h"
namespace identity {
bool IsUsernameAllowedByPattern(base::StringPiece username,
base::StringPiece pattern) {
if (pattern.empty())
return true;
// Patterns like "*@foo.com" are not accepted by our regex engine (since they
// are not valid regular expressions - they should instead be ".*@foo.com").
// For convenience, detect these patterns and insert a "." character at the
// front.
base::string16 utf16_pattern = base::UTF8ToUTF16(pattern);
if (utf16_pattern[0] == L'*')
utf16_pattern.insert(utf16_pattern.begin(), L'.');
// See if the username matches the policy-provided pattern.
UErrorCode status = U_ZERO_ERROR;
const icu::UnicodeString icu_pattern(FALSE, utf16_pattern.data(),
utf16_pattern.length());
icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status);
if (!U_SUCCESS(status)) {
LOG(ERROR) << "Invalid login regex: " << utf16_pattern
<< ", status: " << status;
// If an invalid pattern is provided, then prohibit *all* logins (better to
// break signin than to quietly allow users to sign in).
return false;
}
// The default encoding is UTF-8 in Chromium's ICU.
icu::UnicodeString icu_input(username.data());
matcher.reset(icu_input);
status = U_ZERO_ERROR;
UBool match = matcher.matches(status);
DCHECK(U_SUCCESS(status));
return !!match; // !! == convert from UBool to bool.
}
bool LegacyIsUsernameAllowedByPatternFromPrefs(
PrefService* prefs,
const std::string& username,
const std::string& pattern_pref_name) {
// TODO(crbug.com/908121): We need to deal for now with the fact that most
// unit tests don't register a local state with the browser process, in which
// case all usernames are considered 'allowed'.
if (!prefs)
return true;
return IsUsernameAllowedByPattern(username,
prefs->GetString(pattern_pref_name));
}
} // namespace identity