// 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.
type Status = strict enum {
    /// 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.
type AuthProviderConfig = struct {
    /// 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.
    auth_provider_type string;

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

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

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

    /// OAuth client id.
    client_id string:optional;

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

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

/// 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.
closed protocol AuthenticationContextProvider {
    strict GetAuthenticationUIContext(resource struct {
        request server_end:AuthenticationUIContext;
    });
};

/// 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
closed 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.
    strict GetTokenManager(resource struct {
        user_id string;
        application_url string;
        auth_provider_configs vector<AuthProviderConfig>;
        auth_context_provider client_end:AuthenticationContextProvider;
        token_manager server_end:TokenManager;
    });
};

/// 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.
closed 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.
    strict Authorize(resource struct {
        app_config AppConfig;
        auth_ui_context client_end:<AuthenticationUIContext, optional>;
        app_scopes vector<string>;
        user_profile_id string:optional;
        auth_code string:optional;
    }) -> (struct {
        status Status;
        user_profile_info box<UserProfileInfo>;
    });

    /// 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.
    strict GetAccessToken(struct {
        app_config AppConfig;
        user_profile_id string;
        app_scopes vector<string>;
    }) -> (struct {
        status Status;
        access_token string:optional;
    });

    /// 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.
    strict GetIdToken(struct {
        app_config AppConfig;
        user_profile_id string;
        audience string:optional;
    }) -> (struct {
        status Status;
        id_token string:optional;
    });

    /// 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.
    strict DeleteAllTokens(struct {
        app_config AppConfig;
        user_profile_id string;
        force bool;
    }) -> (struct {
        status Status;
    });

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