// Copyright 2019 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.identity.tokens;

/// The maximum number of service providers for which `AuthProvider` components
/// can be simultaneously installed.
const MAX_SERVICE_PROVIDER_COUNT uint32 = 128;

/// The maximum number of Accounts that can be authorized within a service
/// provider for a single instance of TokenManager.
const MAX_ACCOUNT_COUNT uint32 = 128;

/// The primary domain name of the service provider used to authorize accounts.
/// Only one `AuthProvider` component can be installed for each service provider
/// at a time.
alias ServiceProvider = string:256;

/// `TokenManager` maintains a set of credentials for accounts with service
/// providers (such as Google) and provides access to standard tokens based on
/// these credentials (such as OAuth2 access tokens and OpenID Connect ID
/// tokens). This provides a "single sign-on" experience for these services on
/// Fuchsia, where multiple components can use a service without requiring that
/// the user signs in multiple times.
protocol TokenManager {
    /// Returns the list of service providers that are available through this
    /// `TokenManager`.
    ///
    /// - `service_providers` a vector of available service providers.
    ListServiceProviders() -> (struct {
        service_providers vector<ServiceProvider>:MAX_SERVICE_PROVIDER_COUNT;
    }) error Error;

    /// Returns the list of currently authorized accounts for a particular
    /// service provider.
    ///
    /// + `service_provider` the service provider to query.
    /// - `account_ids` a vector of authorized accounts for `service_provider`.
    ListAccounts(struct {
        service_provider ServiceProvider;
    }) -> (struct {
        account_ids vector<AccountId>:MAX_ACCOUNT_COUNT;
    }) error Error;

    /// Acquires credentials for a new account from a service provider.
    ///
    /// This process typically requires the user to interactively authenticate
    /// with the service provider and authorize the requested access.
    ///
    /// Once `AddAccount` has succeeded, tokens for the account may be acquired
    /// using the other `TokenManager` methods.
    ///
    /// + `service_provider` The `ServiceProvider` used to authorize the new
    ///                      account.
    /// + `scopes` A list of OAuth scope strings that the caller wishes to
    ///            subsequently use in `GetOauthAccessToken`. The AuthProvider
    ///            component chooses if and how to combine these with any
    ///            default or threshold scopes.
    /// - `account_id`  A unique identifier within this service provider for the
    ///                 newly authorized account.
    /// * error `ABORTED` The user cancelled or failed an interactive flow.
    /// * error `SERVICE_PROVIDER_DENIED` The service provider refused to grant
    ///         the requested token.
    AddAccount(struct {
        service_provider ServiceProvider;
        scopes vector<Scope>:MAX_SCOPE_COUNT;
    }) -> (struct {
        account_id AccountId;
    }) error Error;

    /// Refreshes credentials or changes credential scopes for an account that
    /// was previously authorized.
    ///
    /// This process may require the user to interactively authenticate with the
    /// service provider and authorize the requested access.
    ///
    /// + `service_provider` The `ServiceProvider` used to reauthorize the
    ///                      account.
    /// + `account_id`  An `AccountId` that has previously been authorized for
    ///                 this `ServiceProvider`.
    /// + `scopes` A list of OAuth scope strings that the caller wishes to
    ///            subsequently use in `GetOauthAccessToken`. The AuthProvider
    ///            component chooses if and how to combine these with any
    ///            default or threshold scopes.
    /// * error `ABORTED` The user cancelled or failed an interactive flow.
    /// * error `SERVICE_PROVIDER_DENIED` The service provider refused to grant
    ///         the requested token.
    ReauthorizeAccount(struct {
        service_provider ServiceProvider;
        account_id AccountId;
        scopes vector<Scope>:MAX_SCOPE_COUNT;
    }) -> (struct {}) error Error;

    /// Returns an OAuth 2.0 access token for the specified account.
    ///
    /// The access token may optionally be sidescoped (i.e. issued to a
    /// different `client_id` than the default `client_id` used during
    /// authorization) and may contain a smaller set of scopes than those
    /// acquired during authorization.
    ///
    /// 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. 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.
    ///
    /// + `service_provider` The `ServiceProvider` from which the token should
    ///                      be requested.
    /// + `account_id` An `AccountId` that has previously been authorized for
    ///                this `ServiceProvider`.
    /// + `client_id` The `ClientId` that the token will be used by. If ommitted
    ///               (and if supported by the auth provider component) a
    ///               default `client_id` is used.
    /// + `scopes` A list of OAuth scopes that should be included in the token,
    ///            as defined by the service provider's API documention.
    /// - `access_token` An `OauthAccessToken`.
    /// * error `ABORTED` The user rejected an interactive permission request.
    /// * error `SERVICE_PROVIDER_DENIED` The service provider refused to grant
    ///         the requested token.
    /// * error `SERVICE_PROVIDER_REAUTHORIZE` The service provider requires
    ///         that the user reauthenticate before supplying the requested
    ///         token. The client should call the `ReauthorizeAccount` method
    ///         before retrying the request.
    GetOauthAccessToken(struct {
        service_provider ServiceProvider;
        account_id AccountId;
        client_id ClientId:optional;
        scopes vector<Scope>:MAX_SCOPE_COUNT;
    }) -> (struct {
        access_token OauthAccessToken;
    }) error Error;

    /// Returns user information for the specified account as defined by
    /// OpenID Connect.
    ///
    /// + `service_provider` The `ServiceProvider` from which the token should
    ///                      be requested.
    /// + `account_id` An `AccountId` that has previously been authorized for
    ///                this `ServiceProvider`.
    /// - `user_info` An `OpenIdUserInfo` containing account information.
    /// * error `ABORTED` The user rejected an interactive permission request.
    /// * error `SERVICE_PROVIDER_REAUTHORIZE` The service provider requires
    ///         that the user reauthenticate before supplying the user info.
    /// * error `UNSUPPORTED_OPERATION` The auth provider does not support
    ///         OpenID Connect.
    GetOpenIdUserInfo(struct {
        service_provider ServiceProvider;
        account_id AccountId;
    }) -> (struct {
        user_info OpenIdUserInfo;
    }) error Error;

    /// Returns an OpenID Connect ID token for the specified account.
    ///
    /// 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.
    ///
    /// + `service_provider` The `ServiceProvider` from which the token should
    ///                      be requested.
    /// + `account_id` An `AccountId` that has previously been authorized for
    ///                this `ServiceProvider`.
    /// + `audience` The `Audience` that the ID token will be used by. If
    ///              ommitted (and if supported by the auth provider component)
    ///              a default `audience` is used.
    /// - `id_token` An `OpenIdToken`.
    /// * error `ABORTED` The user rejected an interactive permission request.
    /// * error `SERVICE_PROVIDER_DENIED` The service provider refused to grant
    ///         the requested token.
    /// * error `SERVICE_PROVIDER_REAUTHORIZE` The service provider requires
    ///         that the user reauthenticate before supplying the user info.
    /// * error `UNSUPPORTED_OPERATION` The auth provider does not support
    ///         OpenID Connect.
    GetOpenIdToken(struct {
        service_provider ServiceProvider;
        account_id AccountId;
        audience Audience:optional;
    }) -> (struct {
        id_token OpenIdToken;
    }) error Error;

    /// Deletes and revokes all long lived and short lived tokens generated for
    /// an account.
    ///
    /// Deletion of tokens involves three steps:
    ///
    ///   1. Revoking credentials remotely at the service 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 terminates the method,
    /// ensuring client and server state remain consistent. If `force` is true
    /// then steps 2&3 are performed and the method returns success even if
    /// step 1 fails, ensuring the local credentials are wiped in all
    /// circumstances.
    ///
    /// + `service_provider` The `ServiceProvider` from which the token should
    ///                      be requested.
    /// + `account_id` An `AccountId` that has previously been authorized for
    ///                this `ServiceProvider`.
    /// + `force` Whether to force local deletion even when the remote
    ///           revocation cannot be completed.
    DeleteAccount(struct {
        service_provider ServiceProvider;
        account_id AccountId;
        force bool;
    }) -> (struct {}) error Error;
};
