// 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 uint32 MAX_SERVICE_PROVIDER_COUNT = 128;

/// The maximum number of Accounts that can be authorized within a service
/// provider for a single instance of TokenManager.
const uint32 MAX_ACCOUNT_COUNT = 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.
using 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() -> (
        vector<ServiceProvider>:MAX_SERVICE_PROVIDER_COUNT service_providers
        ) 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(ServiceProvider service_provider)
        -> (vector<AccountId>:MAX_ACCOUNT_COUNT account_ids) 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(ServiceProvider service_provider,
               vector<Scope>:MAX_SCOPE_COUNT scopes)
        -> (AccountId account_id) 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(ServiceProvider service_provider,
                       AccountId account_id,
                       vector<Scope>:MAX_SCOPE_COUNT scopes) -> () 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(ServiceProvider service_provider,
                        AccountId account_id,
                        ClientId? client_id,
                        vector<Scope>:MAX_SCOPE_COUNT scopes)
        -> (OauthAccessToken access_token) 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(ServiceProvider service_provider, AccountId account_id)
        -> (OpenIdUserInfo user_info) 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(ServiceProvider service_provider,
                   AccountId account_id,
                   Audience? audience)
        -> (OpenIdToken id_token) 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(ServiceProvider service_provider,
                  AccountId account_id,
                  bool force)
        -> () error Error;
};
