diff options
Diffstat (limited to 'dom/credentialmanagement/identity/IdentityCredential.h')
-rw-r--r-- | dom/credentialmanagement/identity/IdentityCredential.h | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/dom/credentialmanagement/identity/IdentityCredential.h b/dom/credentialmanagement/identity/IdentityCredential.h new file mode 100644 index 0000000000..598a8bf99c --- /dev/null +++ b/dom/credentialmanagement/identity/IdentityCredential.h @@ -0,0 +1,314 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_IdentityCredential_h +#define mozilla_dom_IdentityCredential_h + +#include "mozilla/dom/CanonicalBrowsingContext.h" +#include "mozilla/dom/Credential.h" +#include "mozilla/dom/IPCIdentityCredential.h" +#include "mozilla/MozPromise.h" + +namespace mozilla::dom { + +// This is the primary starting point for FedCM in the platform. +// This class is the implementation of the IdentityCredential object +// that is the value returned from the navigator.credentials.get call +// with an "identity" argument. It also includes static functions that +// perform operations that are used in constructing the credential. +class IdentityCredential final : public Credential { + public: + // These are promise types, all used to support the async implementation of + // this API. All are of the form MozPromise<RefPtr<T>, nsresult>. + // Tuples are included to shuffle additional values along, so that the + // intermediate state is entirely in the promise chain and we don't have to + // capture an early step's result into a callback for a subsequent promise. + typedef MozPromise<RefPtr<IdentityCredential>, nsresult, true> + GetIdentityCredentialPromise; + typedef MozPromise<IPCIdentityCredential, nsresult, true> + GetIPCIdentityCredentialPromise; + typedef MozPromise<IdentityProviderConfig, nsresult, true> + GetIdentityProviderConfigPromise; + typedef MozPromise<bool, nsresult, true> ValidationPromise; + typedef MozPromise<IdentityProviderAPIConfig, nsresult, true> + GetManifestPromise; + typedef std::tuple<IdentityProviderConfig, IdentityProviderAPIConfig> + IdentityProviderConfigWithManifest; + typedef MozPromise<IdentityProviderConfigWithManifest, nsresult, true> + GetIdentityProviderConfigWithManifestPromise; + typedef MozPromise< + std::tuple<IdentityProviderAPIConfig, IdentityProviderAccountList>, + nsresult, true> + GetAccountListPromise; + typedef MozPromise<std::tuple<IdentityProviderToken, IdentityProviderAccount>, + nsresult, true> + GetTokenPromise; + typedef MozPromise< + std::tuple<IdentityProviderAPIConfig, IdentityProviderAccount>, nsresult, + true> + GetAccountPromise; + typedef MozPromise<IdentityProviderClientMetadata, nsresult, true> + GetMetadataPromise; + + // This needs to be constructed in the context of a window + explicit IdentityCredential(nsPIDOMWindowInner* aParent); + + protected: + ~IdentityCredential() override; + + public: + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override; + + // This builds a value from an IPC-friendly version. This type is returned + // to the caller of navigator.credentials.get, however we get an IPC friendly + // version back from the main process to the content process. + // This is a deep copy of the token, ID, and type. + void CopyValuesFrom(const IPCIdentityCredential& aOther); + + // This is the inverse of CopyValuesFrom. Included for completeness. + IPCIdentityCredential MakeIPCIdentityCredential(); + + // Getter and setter for the token member of this class + void GetToken(nsAString& aToken) const; + void SetToken(const nsAString& aToken); + + // This function allows a relying party to send one last credentialed request + // to the IDP when logging out. This only works if the current account state + // in the IdentityCredentialStorageService allows logouts and clears that bit + // when a request is sent. + // + // Arguments: + // aGlobal: the global of the window calling this function + // aLogoutRequest: all of the logout requests to try to send. + // This is pairs of the IDP's logout url and the account + // ID for that IDP. + // Return value: + // a promise resolving to undefined + // Side effects: + // Will send a network request to each IDP that have a state allowing + // logouts and disables that bit. + static already_AddRefed<Promise> LogoutRPs( + GlobalObject& aGlobal, + const Sequence<IdentityCredentialLogoutRPsRequest>& aLogoutRequests, + ErrorResult& aRv); + + // This is the main static function called when a credential needs to be + // fetched from the IDP. Called in the content process. + // This is mostly a passthrough to `DiscoverFromExternalSourceInMainProcess`. + static RefPtr<GetIdentityCredentialPromise> DiscoverFromExternalSource( + nsPIDOMWindowInner* aParent, const CredentialRequestOptions& aOptions, + bool aSameOriginWithAncestors); + + // Start the FedCM flow. This will start the timeout timer, fire initial + // network requests, prompt the user, and call into CreateCredential. + // + // Arguments: + // aPrincipal: the caller of navigator.credentials.get()'s principal + // aBrowsingContext: the BC of the caller of navigator.credentials.get() + // aOptions: argument passed to navigator.credentials.get() + // Return value: + // a promise resolving to an IPC credential with type "identity", id + // constructed to identify it, and token corresponding to the token + // fetched in FetchToken. This promise may reject with nsresult errors. + // Side effects: + // Will send network requests to the IDP. The details of which are in the + // other static methods here. + static RefPtr<GetIPCIdentityCredentialPromise> + DiscoverFromExternalSourceInMainProcess( + nsIPrincipal* aPrincipal, CanonicalBrowsingContext* aBrowsingContext, + const IdentityCredentialRequestOptions& aOptions); + + // Create an IPC credential that can be passed back to the content process. + // This calls a lot of helpers to do the logic of going from a single provider + // to a bearer token for an account at that provider. + // + // Arguments: + // aPrincipal: the caller of navigator.credentials.get()'s principal + // aBrowsingContext: the BC of the caller of navigator.credentials.get() + // aProvider: the provider to validate the root manifest of + // aManifest: the internal manifest of the identity provider + // Return value: + // a promise resolving to an IPC credential with type "identity", id + // constructed to identify it, and token corresponding to the token + // fetched in FetchToken. This promise may reject with nsresult errors. + // Side effects: + // Will send network requests to the IDP. The details of which are in the + // other static methods here. + static RefPtr<GetIPCIdentityCredentialPromise> CreateCredential( + nsIPrincipal* aPrincipal, BrowsingContext* aBrowsingContext, + const IdentityProviderConfig& aProvider, + const IdentityProviderAPIConfig& aManifest); + + // Performs a Fetch for the root manifest of the provided identity provider + // and validates it as correct. The returned promise resolves with a bool + // that is true if everything is valid. + // + // Arguments: + // aPrincipal: the caller of navigator.credentials.get()'s principal + // aProvider: the provider to validate the root manifest of + // Return value: + // promise that resolves to a bool that indicates success. Will reject + // when there are network or other errors. + // Side effects: + // Network request to the IDP's well-known from inside a NullPrincipal + // sandbox + // + static RefPtr<ValidationPromise> CheckRootManifest( + nsIPrincipal* aPrincipal, const IdentityProviderConfig& aProvider); + + // Performs a Fetch for the internal manifest of the provided identity + // provider. The returned promise resolves with the manifest retrieved. + // + // Arguments: + // aPrincipal: the caller of navigator.credentials.get()'s principal + // aProvider: the provider to fetch the root manifest + // Return value: + // promise that resolves to the internal manifest. Will reject + // when there are network or other errors. + // Side effects: + // Network request to the URL in aProvider as the manifest from inside a + // NullPrincipal sandbox + // + static RefPtr<GetManifestPromise> FetchInternalManifest( + nsIPrincipal* aPrincipal, const IdentityProviderConfig& aProvider); + + // Performs a Fetch for the account list from the provided identity + // provider. The returned promise resolves with the manifest and the fetched + // account list in a tuple of objects. We put the argument manifest in the + // tuple to facilitate clean promise chaining. + // + // Arguments: + // aPrincipal: the caller of navigator.credentials.get()'s principal + // aProvider: the provider to get account lists from + // aManifest: the provider's internal manifest + // Return value: + // promise that resolves to a Tuple of the passed manifest and the fetched + // account list. Will reject when there are network or other errors. + // Side effects: + // Network request to the provider supplied account endpoint with + // credentials but without any indication of aPrincipal. + // + static RefPtr<GetAccountListPromise> FetchAccountList( + nsIPrincipal* aPrincipal, const IdentityProviderConfig& aProvider, + const IdentityProviderAPIConfig& aManifest); + + // Performs a Fetch for a bearer token to the provided identity + // provider for a given account. The returned promise resolves with the + // account argument and the fetched token in a tuple of objects. + // We put the argument account in the + // tuple to facilitate clean promise chaining. + // + // Arguments: + // aPrincipal: the caller of navigator.credentials.get()'s principal + // aProvider: the provider to get account lists from + // aManifest: the provider's internal manifest + // aAccount: the account to request + // Return value: + // promise that resolves to a Tuple of the passed account and the fetched + // token. Will reject when there are network or other errors. + // Side effects: + // Network request to the provider supplied token endpoint with + // credentials and including information about the requesting principal. + // + static RefPtr<GetTokenPromise> FetchToken( + nsIPrincipal* aPrincipal, const IdentityProviderConfig& aProvider, + const IdentityProviderAPIConfig& aManifest, + const IdentityProviderAccount& aAccount); + + // Performs a Fetch for links to legal info about the identity provider. + // The returned promise resolves with the information in an object. + // + // Arguments: + // aPrincipal: the caller of navigator.credentials.get()'s principal + // aProvider: the identity provider to get information from + // aManfiest: the identity provider's manifest + // Return value: + // promise that resolves with an object containing legal information for + // aProvider + // Side effects: + // Network request to the provider supplied token endpoint with + // credentials and including information about the requesting principal. + // + static RefPtr<GetMetadataPromise> FetchMetadata( + nsIPrincipal* aPrincipal, const IdentityProviderConfig& aProvider, + const IdentityProviderAPIConfig& aManifest); + + // Show the user a dialog to select what identity provider they would like + // to try to log in with. + // + // Arguments: + // aBrowsingContext: the BC of the caller of navigator.credentials.get() + // aProviders: the providers to let the user select from + // aManifests: the manifests + // Return value: + // a promise resolving to an identity provider that the user took action + // to select. This promise may reject with nsresult errors. + // Side effects: + // Will show a dialog to the user. + static RefPtr<GetIdentityProviderConfigWithManifestPromise> + PromptUserToSelectProvider( + BrowsingContext* aBrowsingContext, + const Sequence<IdentityProviderConfig>& aProviders, + const Sequence<GetManifestPromise::ResolveOrRejectValue>& aManifests); + + // Show the user a dialog to select what account they would like + // to try to log in with. + // + // Arguments: + // aBrowsingContext: the BC of the caller of navigator.credentials.get() + // aAccounts: the accounts to let the user select from + // aProvider: the provider that was chosen + // aManifest: the identity provider that was chosen's manifest + // Return value: + // a promise resolving to an account that the user took action + // to select (and aManifest). This promise may reject with nsresult errors. + // Side effects: + // Will show a dialog to the user. + static RefPtr<GetAccountPromise> PromptUserToSelectAccount( + BrowsingContext* aBrowsingContext, + const IdentityProviderAccountList& aAccounts, + const IdentityProviderConfig& aProvider, + const IdentityProviderAPIConfig& aManifest); + + // Show the user a dialog to select what account they would like + // to try to log in with. + // + // Arguments: + // aBrowsingContext: the BC of the caller of navigator.credentials.get() + // aAccount: the accounts the user chose + // aManifest: the identity provider that was chosen's manifest + // aProvider: the identity provider that was chosen + // Return value: + // a promise resolving to an account that the user agreed to use (and + // aManifest). This promise may reject with nsresult errors. This includes + // if the user denied the terms and privacy policy + // Side effects: + // Will show a dialog to the user. Will send a network request to the + // identity provider. Modifies the IdentityCredentialStorageService state + // for this account. + static RefPtr<GetAccountPromise> PromptUserWithPolicy( + BrowsingContext* aBrowsingContext, nsIPrincipal* aPrincipal, + const IdentityProviderAccount& aAccount, + const IdentityProviderAPIConfig& aManifest, + const IdentityProviderConfig& aProvider); + + // Close all dialogs associated with IdentityCredential generation on the + // provided browsing context + // + // Arguments: + // aBrowsingContext: the BC of the caller of navigator.credentials.get() + // Side effects: + // Will close a dialog shown to the user. + static void CloseUserInterface(BrowsingContext* aBrowsingContext); + + private: + nsAutoString mToken; +}; + +} // namespace mozilla::dom + +#endif // mozilla_dom_IdentityCredential_h |