| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/webid/federated_identity_permission_context.h" |
| |
| #include "base/memory/scoped_refptr.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/signin/identity_manager_factory.h" |
| #include "chrome/browser/webid/federated_identity_account_keyed_permission_context.h" |
| #include "chrome/browser/webid/federated_identity_identity_provider_registration_context.h" |
| #include "chrome/browser/webid/federated_identity_identity_provider_signin_status_context.h" |
| #include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h" |
| #include "content/public/browser/browser_context.h" |
| #include "content/public/browser/webid/identity_request_account.h" |
| #include "google_apis/gaia/gaia_urls.h" |
| #include "third_party/blink/public/common/webid/login_status_account.h" |
| #include "third_party/blink/public/common/webid/login_status_options.h" |
| #include "third_party/blink/public/mojom/webid/federated_auth_request.mojom.h" |
| #include "url/origin.h" |
| |
| FederatedIdentityPermissionContext::FederatedIdentityPermissionContext( |
| content::BrowserContext* browser_context) |
| : sharing_context_( |
| new FederatedIdentityAccountKeyedPermissionContext(browser_context)), |
| idp_signin_context_( |
| new FederatedIdentityIdentityProviderSigninStatusContext( |
| browser_context)), |
| idp_registration_context_( |
| new FederatedIdentityIdentityProviderRegistrationContext( |
| browser_context)) { |
| if (!browser_context->IsOffTheRecord()) { |
| Profile* profile = Profile::FromBrowserContext(browser_context); |
| signin::IdentityManager* mgr = |
| IdentityManagerFactory::GetForProfile(profile); |
| if (mgr) { |
| obs_.Observe(mgr); |
| } |
| } |
| } |
| |
| FederatedIdentityPermissionContext::~FederatedIdentityPermissionContext() = |
| default; |
| |
| void FederatedIdentityPermissionContext::Shutdown() { |
| obs_.Reset(); |
| FlushScheduledSaveSettingsCalls(); |
| KeyedService::Shutdown(); |
| } |
| |
| void FederatedIdentityPermissionContext::AddIdpSigninStatusObserver( |
| IdpSigninStatusObserver* observer) { |
| if (idp_signin_status_observer_list_.HasObserver(observer)) { |
| return; |
| } |
| |
| idp_signin_status_observer_list_.AddObserver(observer); |
| } |
| |
| void FederatedIdentityPermissionContext::RemoveIdpSigninStatusObserver( |
| IdpSigninStatusObserver* observer) { |
| idp_signin_status_observer_list_.RemoveObserver(observer); |
| } |
| |
| bool FederatedIdentityPermissionContext::HasSharingPermission( |
| const url::Origin& relying_party_requester, |
| const url::Origin& relying_party_embedder, |
| const url::Origin& identity_provider) { |
| return sharing_context_->HasPermission( |
| relying_party_requester, relying_party_embedder, identity_provider); |
| } |
| |
| std::optional<base::Time> |
| FederatedIdentityPermissionContext::GetLastUsedTimestamp( |
| const url::Origin& relying_party_requester, |
| const url::Origin& relying_party_embedder, |
| const url::Origin& identity_provider, |
| const std::string& account_id) { |
| return sharing_context_->GetLastUsedTimestamp(relying_party_requester, |
| relying_party_embedder, |
| identity_provider, account_id); |
| } |
| |
| bool FederatedIdentityPermissionContext::HasSharingPermission( |
| const url::Origin& relying_party_requester) { |
| return sharing_context_->HasPermission(relying_party_requester); |
| } |
| |
| bool FederatedIdentityPermissionContext::HasSharingPermission( |
| const net::SchemefulSite& relying_party_embedder, |
| const net::SchemefulSite& identity_provider) { |
| return sharing_context_->HasPermission(relying_party_embedder, |
| identity_provider); |
| } |
| |
| void FederatedIdentityPermissionContext::MarkStorageAccessEligible( |
| const net::SchemefulSite& relying_party_embedder, |
| const net::SchemefulSite& identity_provider, |
| base::OnceClosure callback) { |
| sharing_context_->MarkStorageAccessEligible( |
| relying_party_embedder, identity_provider, std::move(callback)); |
| } |
| |
| void FederatedIdentityPermissionContext::OnSetRequiresUserMediation( |
| const url::Origin& relying_party, |
| base::OnceClosure callback) { |
| sharing_context_->OnSetRequiresUserMediation(relying_party, |
| std::move(callback)); |
| } |
| |
| void FederatedIdentityPermissionContext::GrantSharingPermission( |
| const url::Origin& relying_party_requester, |
| const url::Origin& relying_party_embedder, |
| const url::Origin& identity_provider, |
| const std::string& account_id) { |
| sharing_context_->GrantPermission(relying_party_requester, |
| relying_party_embedder, identity_provider, |
| account_id); |
| } |
| |
| void FederatedIdentityPermissionContext::RevokeSharingPermission( |
| const url::Origin& relying_party_requester, |
| const url::Origin& relying_party_embedder, |
| const url::Origin& identity_provider, |
| const std::string& account_id) { |
| sharing_context_->RevokePermission(relying_party_requester, |
| relying_party_embedder, identity_provider, |
| account_id, base::DoNothing()); |
| } |
| |
| void FederatedIdentityPermissionContext::RefreshExistingSharingPermission( |
| const url::Origin& relying_party_requester, |
| const url::Origin& relying_party_embedder, |
| const url::Origin& identity_provider, |
| const std::string& account_id) { |
| sharing_context_->RefreshExistingPermission(relying_party_requester, |
| relying_party_embedder, |
| identity_provider, account_id); |
| } |
| |
| ContentSettingsForOneType FederatedIdentityPermissionContext:: |
| GetSharingPermissionGrantsAsContentSettings() { |
| return sharing_context_->GetSharingPermissionGrantsAsContentSettings(); |
| } |
| |
| void FederatedIdentityPermissionContext::GetAllDataKeys( |
| base::OnceCallback<void(std::vector<DataKey>)> callback) { |
| sharing_context_->GetAllDataKeys(std::move(callback)); |
| } |
| |
| void FederatedIdentityPermissionContext::RemoveFederatedIdentityDataByDataKey( |
| const DataKey& data_key, |
| base::OnceClosure callback) { |
| sharing_context_->RemoveFederatedIdentityDataByDataKey(data_key, |
| std::move(callback)); |
| } |
| |
| std::optional<bool> FederatedIdentityPermissionContext::GetIdpSigninStatus( |
| const url::Origin& idp_origin) { |
| return idp_signin_context_->GetSigninStatus(idp_origin); |
| } |
| |
| base::Value::List FederatedIdentityPermissionContext::GetAccounts( |
| const url::Origin& identity_provider) { |
| return idp_signin_context_->GetAccounts(identity_provider); |
| } |
| |
| void FederatedIdentityPermissionContext::SetIdpSigninStatus( |
| const url::Origin& idp_origin, |
| bool idp_signin_status, |
| base::optional_ref<const blink::common::webid::LoginStatusOptions> |
| options) { |
| std::optional<bool> old_idp_signin_status = GetIdpSigninStatus(idp_origin); |
| // We always notify if idp_signin_status is true because the list of logged |
| // in accounts may have changed. |
| if (!idp_signin_status && (idp_signin_status == old_idp_signin_status)) { |
| return; |
| } |
| |
| idp_signin_context_->SetSigninStatus(idp_origin, idp_signin_status, options); |
| |
| for (IdpSigninStatusObserver& observer : idp_signin_status_observer_list_) { |
| observer.OnIdpSigninStatusReceived(idp_origin, idp_signin_status); |
| } |
| } |
| |
| std::vector<GURL> FederatedIdentityPermissionContext::GetRegisteredIdPs() { |
| return idp_registration_context_->GetRegisteredIdPs(); |
| } |
| |
| void FederatedIdentityPermissionContext::RegisterIdP(const GURL& origin) { |
| idp_registration_context_->RegisterIdP(origin); |
| } |
| |
| void FederatedIdentityPermissionContext::UnregisterIdP(const GURL& origin) { |
| idp_registration_context_->UnregisterIdP(origin); |
| } |
| |
| void FederatedIdentityPermissionContext::FlushScheduledSaveSettingsCalls() { |
| sharing_context_->FlushScheduledSaveSettingsCalls(); |
| idp_signin_context_->FlushScheduledSaveSettingsCalls(); |
| idp_registration_context_->FlushScheduledSaveSettingsCalls(); |
| } |
| |
| void FederatedIdentityPermissionContext::OnAccountsInCookieUpdated( |
| const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, |
| const GoogleServiceAuthError& error) { |
| bool logged_in = |
| !accounts_in_cookie_jar_info.GetValidSignedInAccounts().empty(); |
| GURL gaia_url = GaiaUrls::GetInstance()->gaia_url(); |
| url::Origin origin = url::Origin::Create(gaia_url); |
| SetIdpSigninStatus(origin, logged_in, std::nullopt); |
| } |