| // 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. |
| |
| #ifndef CHROME_BROWSER_ASH_PRINTING_OAUTH2_AUTHORIZATION_ZONES_MANAGER_H_ |
| #define CHROME_BROWSER_ASH_PRINTING_OAUTH2_AUTHORIZATION_ZONES_MANAGER_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/callback.h" |
| #include "chrome/browser/ash/printing/oauth2/status_code.h" |
| #include "components/keyed_service/core/keyed_service.h" |
| #include "components/sync/model/model_type_store.h" |
| #include "components/sync/model/model_type_sync_bridge.h" |
| |
| class GURL; |
| class Profile; |
| |
| namespace chromeos { |
| class Uri; |
| } // namespace chromeos |
| |
| namespace syncer { |
| class ModelTypeChangeProcessor; |
| } // namespace syncer |
| |
| namespace ash::printing::oauth2 { |
| |
| class AuthorizationZone; |
| class ClientIdsDatabase; |
| |
| // This class is responsible for managing OAuth2 sessions required to get access |
| // to some printers. In the API provided by the class, printers are referred to |
| // as IPP Endpoints. IPP Endpoints that require OAuth2 token report the |
| // following IPP attributes in the response for Get-Printer-Attributes request: |
| // * oauth-authorization-server-uri - the URL of the Authorization Server; |
| // * oauth-authorization-scope - optional, if missing use an empty string. |
| // These two values correspond to the parameters `auth_server` and `scope` in |
| // the API below. |
| // |
| // How to use: |
| // * SaveAuthorizationServerAsTrusted() - this must be called once for each |
| // Authorization Server to mark it as trusted. The list of trusted |
| // Authorization Servers is saved in user's profile. All API calls for any |
| // Authorization Server not included in the trusted list will fail with the |
| // error StatusCode::kUntrustedAuthorizationServer. |
| // * InitAuthorization() - the callback returns a URL that must be opened in an |
| // internet browser to allow a user to go through an authorization procedure. |
| // * FinishAuthorization() - this method finalizes the authorization procedure |
| // started by InitAuthorization(). The authorization procedure in the |
| // internet browser is completed when the browser receives a response with |
| // the HTTP 302 status code. The value of the "Location" attribute from the |
| // HTTP header must be passed to this method to finalize the process and |
| // open an OAuth2 session with the Authorization Server. |
| // * GetEndpointAccessToken() - the callback returns an endpoint access token |
| // for given IPP Endpoint. You can call this method as the first one and |
| // then fallback to InitAuthorization()/FinishAuthorization() when it |
| // returns the status StatusCode::kAuthorizationNeeded. This method can |
| // be called repeatedly and will return the same token for the same |
| // parameters until the method MarkEndpointAccessTokenAsExpired() is called. |
| // * MarkEndpointAccessTokenAsExpired() - call this method to mark the |
| // endpoint access token as expired. Then the following call to |
| // GetEndpointAccessToken() will try to obtain a new endpoint access token |
| // or returns StatusCode::kAuthorizationNeeded when a new authorization |
| // procedure is needed (i.e. a new call to InitAuthorization() and |
| // FinishAuthorization() is required). |
| // |
| // Results and errors are returned by StatusCallback passed as the last |
| // parameter. See chrome/browser/ash/printing/oauth2/status_code.h for more |
| // details. |
| class AuthorizationZonesManager : public KeyedService { |
| public: |
| using CreateAuthZoneCallback = |
| base::RepeatingCallback<std::unique_ptr<AuthorizationZone>( |
| const GURL& url, |
| ClientIdsDatabase* client_ids_database)>; |
| |
| // `profile` must not be nullptr. |
| static std::unique_ptr<AuthorizationZonesManager> Create(Profile* profile); |
| static std::unique_ptr<AuthorizationZonesManager> CreateForTesting( |
| Profile* profile, |
| CreateAuthZoneCallback auth_zone_creator, |
| std::unique_ptr<ClientIdsDatabase> client_ids_database, |
| std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor, |
| syncer::OnceModelTypeStoreFactory store_factory); |
| |
| ~AuthorizationZonesManager() override; |
| virtual syncer::ModelTypeSyncBridge* GetModelTypeSyncBridge() = 0; |
| |
| // Marks `auth_server` as trusted. |
| virtual StatusCode SaveAuthorizationServerAsTrusted( |
| const GURL& auth_server) = 0; |
| |
| // Starts authorization process. If successful, the `callback` is called |
| // with StatusCode::kOK and with an authorization URL that must be opened in |
| // an internet browser to enable the user to complete the authorization |
| // process. Before calling this method the caller should make sure that |
| // creating a new session is necessary by calling the method |
| // GetEndpointAccessToken() first. |
| virtual void InitAuthorization(const GURL& auth_server, |
| const std::string& scope, |
| StatusCallback callback) = 0; |
| |
| // Finalizes authorization process. As an parameter this method takes an URL |
| // that the internet browser was redirected to at the end of the authorization |
| // procedure completed by the user. The return code StatusCode::kOK means |
| // that a new OAuth2 session was created and the caller can now use the method |
| // GetEndpointAccessToken() to get an endpoint access token. |
| virtual void FinishAuthorization(const GURL& auth_server, |
| const GURL& redirect_url, |
| StatusCallback callback) = 0; |
| |
| // Obtains an endpoint access token to use with the given IPP Endpoint. If |
| // succeeded `callback` returns StatusCode::kOK and endpoint access token as |
| // `data`. StatusCode::kAuthorizationNeeded means that the caller must call |
| // methods InitAuthorization() and FinishAuthorization() first to open OAuth2 |
| // session. The parameter `scope` is used only when an endpoint access token |
| // for the given IPP endpoint does not exists yet (the parameter has no |
| // effects when the endpoint access token already exists). |
| virtual void GetEndpointAccessToken(const GURL& auth_server, |
| const chromeos::Uri& ipp_endpoint, |
| const std::string& scope, |
| StatusCallback callback) = 0; |
| |
| // This method marks the `endpoint_access_token` issued for `ipp_endpoint` as |
| // expired. The next call to GetEndpointAccessToken() will start internally a |
| // procedure to obtain a new endpoint access token. This method should be |
| // called when the IPP Endpoint rejects a request with `endpoint_access_token` |
| // by sending back a response with the HTTP 401 status code. If the HTTP |
| // header of that response contains "error" attribute, you should check if it |
| // equals "invalid_token" before calling this method. See RFC 6750 for more |
| // details. |
| virtual void MarkEndpointAccessTokenAsExpired( |
| const GURL& auth_server, |
| const chromeos::Uri& ipp_endpoint, |
| const std::string& endpoint_access_token) = 0; |
| |
| protected: |
| AuthorizationZonesManager(); |
| }; |
| |
| } // namespace ash::printing::oauth2 |
| |
| #endif // CHROME_BROWSER_ASH_PRINTING_OAUTH2_AUTHORIZATION_ZONES_MANAGER_H_ |