// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.auth;

// Specifies the success/failure status of TokenManager calls.
enum Status {
    // The command completed successfully
    OK = 0;
    // The command referred to a missing, misconfigured, or failed auth provider.
    // Retrying is not recommended.
    AUTH_PROVIDER_SERVICE_UNAVAILABLE = 1;
    // The auth server was reachable but responded with an error. These errors
    // are typically caused by a configuration problem or a revoked token and so
    // should not be retried.
    AUTH_PROVIDER_SERVER_ERROR = 2;
    // An internal error occurred. This usually indicates a bug within the Token
    // Manager itself. Retry is optional.
    INTERNAL_ERROR = 3;
    // An invalid or non-functional AuthContextProvider was provided. Retrying is
    // unlikely to correct this error.
    INVALID_AUTH_CONTEXT = 4;
    // The request was malformed in some way, such as using an empty string for
    // the user_profile_id. The request should not be retried.
    INVALID_REQUEST = 5;
    // The requested user profile could not be found in the database. The request
    // should not be retried.
    USER_NOT_FOUND = 6;
    // A local error occurred such as disk I/O or memory allocation. Retry, after
    // a delay, is recommended.
    IO_ERROR = 7;
    // Some other problem occurred that cannot be classified using one of the more
    // specific statuses. Retry is optional.
    UNKNOWN_ERROR = 8;
    // The auth server requires that the user reauthenticate. The client should
    // call the Authorize method.
    REAUTH_REQUIRED = 9;
    // The user cancelled the flow. User consent is required before any retry.
    USER_CANCELLED = 10;
    // A network error occurred while communicating with the auth server. Retry,
    // after a delay, is recommended.
    NETWORK_ERROR = 11;
};

// Stores configuration parameters required to connect to available
// |AuthProvider|s. It is used by TokenManager to instantiate all auth providers
// during startup.
struct AuthProviderConfig {
    // Type of OAuth Identity provider. An identity provider authenticates and
    // authorizes users for accessing their services. They also provide unique
    // identifiers for users to interact with the system and may provide
    // information about the user that is known to the provider.
    //
    // Sample auth provider types include:
    //     Dev : An identity provider that's used for development and testing.
    //     Google: Uses Google as the identity provider. Authorization from Google
    //             requires a working network connection and a web view.
    //     Spotify: Uses Spotify as an identity provider.
    string auth_provider_type;

    // Url of the Fuchsia component implementing the AuthProvider.
    string url;

    // Optional parameters specified during AuthProvider startup.
    vector<string>? params;
};

// Stores OAuth configuration details for a given client application. These
// details are used in the OAuth authorization step.
struct AppConfig {
    // An OAuth identity provider matching a configuration set in
    // AuthProviderConfig.auth_provider_type.
    string auth_provider_type;

    // OAuth client id.
    string? client_id;

    // OAuth client secret.
    // This field is optional and will only be used on calls to Authorize.
    string? client_secret;

    // OAuth application's redirect uri.
    // This field is optional and will only be used on calls to Authorize.
    string? redirect_uri;
};

// Implemented by a privileged system component with the ability to display UI
// to the end user.
//
// This is provided during the initialization of TokenManager service and is
// used for any subsequent authorize calls. The UI contexts created by this
// interface are used to display OAuth login and permission screens to the end
// user.
protocol AuthenticationContextProvider {
    GetAuthenticationUIContext(request<AuthenticationUIContext> request);
};

// This interface provides a discoverable mechanism to create TokenManager
// instances for each user, and to supply auth provider configuration
// information using the structs defined in |auth_provider.fidl|.
[Discoverable]
protocol TokenManagerFactory {
    // Creates an OAuth TokenManager instance scoped for the component specified
    // by |application_url|, the Fuchsia user specified by |user_id|, and the list
    // of auth providers specified in |auth_provider_configs|.
    //
    // |auth_context_provider| is used to generate AuthenticationUIContexts during
    // TokenManager methods that require UI, unless the caller of those methods
    // supplies an alternative AuthenticationUIContext.
    GetTokenManager(string user_id, string application_url,
                    vector<AuthProviderConfig> auth_provider_configs,
                    AuthenticationContextProvider auth_context_provider,
                    request<TokenManager> token_manager);
};

// This interface manages OAuth tokens at the Fuchsia system level for different
// auth identity providers.
//
// If user authorization is required for minting tokens, TokenManager uses the
// |auth_context_provider's| UI context for displaying OAuth UI to the end user.
//
// After initialization, TokenManager handles are typically handed out by
// Framework to components like Ledger and Agents. These components fetch
// OAuth tokens from any configured auth provider, and use the
// |auth_context_provider| initialized above for new authorizations.
protocol TokenManager {
    // The first step of OAuth is to get authorization from the user. For Fuchsia
    // components, this is accomplished by displaying OAuth permissions in a view
    // provided by the caller. This view will use |auth_ui_context| if supplied,
    // or the |auth_context_provider| supplied at TokenManager creation if not.
    // The component's OAuth configuration is provided in |app_config| and
    // |app_scopes|. An optional |user_profile_id| that uniquely identifies an
    // account for a given auth provider may be provided to identify an existing
    // account during a re-auth flow.
    //
    // IoT ID authorization includes a mode where the user authorizes on a second
    // device and that device acquires an auth code from the auth provider.
    // In this mode, the auth code may be supplied in |auth_code| and no local
    // user interface will be displayed.
    //
    // After the user has successfully authorized, Token manager receives and
    // securely stores a persistent credential, such as an OAuth refresh token,
    // for the intended scopes. TokenManager later uses this credential for
    // minting short lived tokens.
    //
    // If the operation is successful, an OK status is returned along with user
    // profile information in |user_profile_info| such as the user's email,
    // image_url, profile_url, and first and last names as configured on the auth
    // provider backend system.
    Authorize(AppConfig app_config, AuthenticationUIContext? auth_ui_context,
              vector<string> app_scopes, string? user_profile_id, string? auth_code)
        -> (Status status, UserProfileInfo? user_profile_info);

    // Returns a downscoped access token from an auth provider for the given user
    // |user_profile_id| and |scopes| to a Fuchsia component. The component's
    // OAuth configuration is provided in |app_config| and the |user_profile_id|
    // is the unique user identifier returned by the Authorize() call.
    //
    // In the interests of performance, Token Manager does not place the supplied
    // scopes in a canonical order during caching. To benefit from caching of
    // tokens, clients must request the same scopes in the same order across
    // calls.
    //
    // The access token is returned from cache if possible, otherwise the auth
    // provider is used to exchange the persistent credential for a new access
    // token.
    GetAccessToken(AppConfig app_config, string user_profile_id,
                   vector<string> app_scopes) -> (Status status, string? access_token);

    // Returns a JWT identity token from an auth provider to a Fuchsia component
    // intended for the given |audience|. The component's OAuth configuration is
    // supplied in |app_config|, the intended recipient of the id_token is
    // supplied in |audience|, and |user_profile_id| is a unique account
    // identifier returned by the Authorize() or ListProfileIds() calls.
    //
    // |user_profile_id| is the unique user identifier returned by the
    // Authorize() call.
    //
    // The identity token is returned from cache if possible, otherwise the auth
    // provider is used to exchange the persistant credential for a new identity
    // token.
    GetIdToken(AppConfig app_config, string user_profile_id, string? audience)
        -> (Status status, string? id_token);

    // Returns a Firebase token from an auth provider for the given account and
    // Fuchsia component, and Firebase client. The component's OAuth configuration
    // is supplied in |app_config|, the Firebase client is supplied in
    // |firebase_api_key|, and |user_profile_id| is a unique account identifier
    // returned by the Authorize() or ListProfileIds() calls.
    //
    // This api invokes firebase auth's VerifyAssertion endpoint that takes an
    // OAuth IdToken as the fuchsia.ui.input. Audience is the intended recipient
    // of the firebase id token.
    //
    // The Firebase auth token is returned from cache if possible, otherwise it is
    // refreshed from the auth provider.
    GetFirebaseToken(AppConfig app_config, string user_profile_id,
                     string audience, string firebase_api_key)
        -> (Status status, FirebaseToken? firebase_token);

    // Deletes and revokes all long lived and short lived tokens generated for
    // an account and on behalf of a Fuchsia component. The component's OAuth
    // configuration is provided in |app_config| and |user_profile_id|
    // is a unique account identifier returned by the Authorize() or
    // ListProfileIds() calls.
    //
    // Deletion of tokens involves three steps:
    //   1. Revoking credentials remotely at the auth provider.
    //   2. Deleting short lived tokens from the in-memory cache.
    //   3. Deleting persistent credentials stored locally on disk.
    //
    // If |force| is false then a failure at step 1 will terminate the method,
    // ensuring client and server state remain consistent. If |force| is true
    // then steps 2&3 will be performed and the method will return OK even if
    // step 1 fails, ensuring the local credentials are wiped in all
    // circumstances.
    DeleteAllTokens(AppConfig app_config, string user_profile_id, bool force)
        -> (Status status);

    // Returns a vector of all currently authorized user_profile_ids for a
    // component's OAuth configuration provided in |app_config|.
    ListProfileIds(AppConfig app_config)
        -> (Status status, vector<string> user_profile_ids);
};
