// 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);

    /// 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);
};
