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

using fuchsia.ui.views;

// This file defines an auth provider service that can be used by Garnet's
// Token Manager service to mint oauth tokens for clients such as Framework,
// Ledger, gmail or chat module.

/// Specifies the success/failure status from auth provider.
enum AuthProviderStatus {
    OK = 0;
    BAD_REQUEST = 1;
    BAD_RESPONSE = 2;
    OAUTH_SERVER_ERROR = 3;
    USER_CANCELLED = 4;
    REAUTH_REQUIRED = 5;
    NETWORK_ERROR = 6;
    UNSUPPORTED_PROVIDER = 7;
    INTERNAL_ERROR = 8;
    UNKNOWN_ERROR = 9;
};

/// The type of token returned.
enum TokenType {
    ACCESS_TOKEN = 0;
    ID_TOKEN = 1;
};

/// OAuth token response populated after parsing JSON object that contains
/// short-lived access token or id token returned by the auth provider.
struct AuthToken {
    /// Type of token.
    TokenType token_type;

    /// Contains access token or a JWT identity token.
    string token;

    /// The remaining lifetime of the token in seconds.
    uint64 expires_in;
};

/// Stores attributes related to a firebase auth token for a given firebase api
/// key.
///
/// These tokens are minted by Firebase Auth server and are meant to be used for
/// authorizing users into Firebase services such as DB and storage.
struct FirebaseToken {
    /// Use this as the auth token in firebase database and storage requests.
    string id_token;

    /// Use this to uniquely identify users.
    string? local_id;

    /// Use this to uniquely identify user's email address provided by the
    /// Auth Provider Firebase server.
    string? email;

    /// The remaining lifetime of the token in seconds.
    uint64 expires_in;
};

/// Challenge response returned by the auth provider during remote attestation
/// based authentication.
struct AuthChallenge {
    /// The value of nonce to be used for the next token refresh request
    string challenge;

    /// The lifetime of `challenge` in seconds.
    uint64 expires_in;
};

/// Stores Elliptic Curve public key parameters of the credential key.
struct CredentialECKey {
    /// Supported elliptic curve value used in JWT attestation. Refer to Section
    /// 6.2.1.1 of RFC7518 for the canonical list of supported elliptic curves.
    /// For example:(P-256,P-384,P-521)
    string curve;

    /// Value of x of the generated EC key
    string key_x_val;

    /// Value of y of the generated EC key
    string key_y_val;

    /// Base64 encoded SHA256 hash of the EC public key
    string fingerprint_sha_256;
};

/// Contains parameters required by the auth provider component to build
/// attestation JWTs.
struct AttestationJWTParams {
    /// Contains the ephemeral Elliptic curve credential public key which will be
    /// bound to the newly generated refresh token grant.
    CredentialECKey credential_eckey;

    /// The full chain of certificates from the device attestation certificate
    /// to the root certificate that was registered on the OAuth client id.
    /// Each string should be base64-encoded DER PKIX certificate value.
    vector<string> certificate_chain;

    /// OAuth authorization code bound to the given user and device
    string auth_code;
};

/// Contains parameters required by the auth provider to build assertion JWTs.
struct AssertionJWTParams {
    /// Contains Elliptic curve credential public key which is bound to existing
    /// refresh token.
    CredentialECKey credential_eckey;

    /// An optional challenge that could be used for the next token refresh request
    string? challenge;
};

/// User attributes returned to callers on authorizing a new user at any auth
/// provider. These attributes are generated by calling the auth provider's
/// user profile apis.
struct UserProfileInfo {
    /// User identifier returned by the backend identity provider server to
    /// identify the user after successful authorization. Some identity providers
    /// send verified email address as the identifier, and some send an opaque
    /// string as the user identifier.
    string id;

    /// The name that is displayed on the base shell while logging in. Display
    /// name is fetched from user profile attributes as configured by the user at
    /// the given identity provider.
    string? display_name;

    /// User's profile url that is used by the base shell while logging in.
    /// Profile url is fetched from user profile attributes as configured by the
    /// user at the given identity provider.
    string? url;

    /// User's profile image url that is used by the base shell while logging in.
    /// Profile image url is fetched from user profile attributes as configured by
    /// the user at the given identity provider.
    string? image_url;
};

/// This interface is implemented by base shell. It is used to notify the
/// base shell that a view for login needs to be started / stopped.
protocol AuthenticationUIContext {
    /// Requests base shell to display `view_holder_token` for authentication.
    /// Another call to StartOverlay() will not be made until StopOverlay()
    /// has been called.
    StartOverlay(fuchsia.ui.views.ViewHolderToken view_holder_token);

    /// Requests base shell to stop displaying the auth view.
    StopOverlay();
};

/// OAuth identity service that provisions new users and provides authorization
/// tokens for the currently enrolled users. Some common Auth Providers are
/// Google, Facebook, Spotify and Twitter.
[Discoverable]
protocol AuthProvider {
    /// Authenticates and authorizes a user against an auth provider backend system
    /// using the OAuth protocol and returns the persistent credential such as
    /// Google's refresh token or Facebook's access token for this user. These
    /// persistent credentials are long lived and their expiration time is set by
    /// the identity provider, for example Google's refresh tokens are valid until
    /// the user changes their password or revokes access explicitly, whereas
    /// Facebook access tokens are valid for up to 60 days or until the user
    /// revokes access.
    ///
    /// During OAuth handshake, user needs to explicitly consent to the permissions
    /// as configured at the server. The consent is presented in a web_view using
    /// an `auth_ui_context` overlay provided by the base_shell.
    ///
    /// An optional `user_profile_id` is provided for simplifying reauthorization
    /// flow.
    GetPersistentCredential(AuthenticationUIContext? auth_ui_context,
                            string? user_profile_id)
        -> (AuthProviderStatus status, string? credential,
            UserProfileInfo? user_profile_info);

    /// Exchanges a persistent user `credential` for a short lived app specific
    /// OAuth access token for the specified `client_id` and `scopes`. The
    /// `credential` is a long lived OAuth token as generated by the external
    /// identity provider in the above GetPersistentCredential() call. If no
    /// client_id is specified a default will be used.
    ///
    /// Access tokens are used by applications to make API requests against
    /// services offered by the Auth Provider.
    ///
    /// Returns an `auth_token` response containing an access token, if successful.
    /// Otherwise, an error status is returned.
    GetAppAccessToken(string credential, string? client_id,
                      vector<string> scopes)
        -> (AuthProviderStatus status, AuthToken? auth_token);

    /// Exchanges a persistent user `credential` for an OAuth Identity token for
    /// the specified `audience`. The audience is the intended recipient of the
    /// id_token. The `credential` is a long lived OAuth token as generated by the
    /// external identity provider in the above GetPersistentCredential() call.
    ///
    /// OAuth Id tokens are JSON Web Tokens (JWT) that contains digitally signed
    /// identity information about the user for the intended recipient.
    ///
    /// Returns an `auth_token` response containing an id token, if successful.
    /// Otherwise, an error status is returned.
    GetAppIdToken(string credential, string? audience)
        -> (AuthProviderStatus status, AuthToken? auth_token);

    /// Gets a firebase auth token for the user identified by `id_token` and the
    /// requested |firebase_api key|. The `id_token` is a JWT Identity token
    /// returned from GetAppIdToken() call above.
    ///
    /// Returns a `firebase_token` from the server if successful. Otherwise, an
    /// error status is returned.
    GetAppFirebaseToken(string id_token, string firebase_api_key)
        -> (AuthProviderStatus status, FirebaseToken? firebase_token);

    /// Revokes user's grants at the Auth Provider by revoking a credential. The
    /// `credential` is either a long lived OAuth token as returned by the
    /// GetPersistentCredential() call or an app specific access token as returned
    /// by the GetAppAccessToken() call.
    RevokeAppOrPersistentCredential(string credential)
        -> (AuthProviderStatus status);

    /// Authenticates and authorizes a user against a remote attestation based
    /// auth provider backend system that mints bound persistent credentials.
    ///
    /// This method is capable of performing user authorization directly on the
    /// device or use the OAuth authorization code generated out-of-band on a
    /// secondary device that is sent over a secure channel to the target device.
    /// In the latter case, auth_code generated out-of-band is passed as an
    /// argument in the attestation `jwt_params`. Where as in the former case,
    /// user needs to explicitly consent to the permissions on the target device
    /// and the auth_code is returned to the device directly. The consent is
    /// presented in a web_view using an `auth_ui_context` overlay provided by the
    /// base_shell. An optional `user_profile_id` is provided for simplifying
    /// reauthorization flow.
    ///
    /// The authorization code is exchanged to a bound refresh token using an
    /// attestation JWT constructed from `jwt_params` and is signed by the
    /// `attestation_signer` component passed in the request.
    ///
    /// If the operation is successful, a long-lived `credential` that is bound to
    /// the originating device is returned along with an optional `auth_token`
    /// containing short-lived access token and an optional `nonce` that is used on
    /// next token exchange request. An optional `user_profile_info` containing
    /// user profile attributes is also returned if successful. Otherwise, an error
    /// status is returned.
    GetPersistentCredentialFromAttestationJWT(
        AttestationSigner attestation_signer, AttestationJWTParams jwt_params,
        AuthenticationUIContext? auth_ui_context,
        string? user_profile_id)
        -> (AuthProviderStatus status, string? credential, AuthToken? auth_token,
            AuthChallenge? auth_challenge, UserProfileInfo? user_profile_info);

    /// Exchanges a bound persistent user `credential` for a short lived app
    /// specific OAuth access token using the specified assertion JWT. The
    /// assertion JWT is constructed from `jwt_params` and is signed by the
    /// `attestation_signer` component passed in the request.
    ///
    /// Access tokens are used by applications to make API requests against
    /// services offered by the Auth Provider.
    ///
    /// Returns an `auth_token` response containing an access token and an optional
    /// `updated_credential` and `auth_challenge` to be used on next token refresh
    /// request, if successful. Otherwise, an error status is returned.
    GetAppAccessTokenFromAssertionJWT(AttestationSigner attestation_signer,
                                      AssertionJWTParams jwt_params, string credential,
                                      vector<string> scopes)
        -> (AuthProviderStatus status, string? updated_credential,
            AuthToken? auth_token, AuthChallenge? auth_challenge);

    // TODO(ukode): Add methods for bound IDToken and FirebaseToken.
};
