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

// 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_owner| for authentication. Another
    // call to StartOverlay() will not be made until StopOverlay() has been
    // called.
    //
    // This method is deprecated in favor of the eventpair-based one below.
    // TODO(SCN-1018): Remove this.
    StartOverlay(fuchsia.ui.viewsv1token.ViewOwner view_owner);

    [Transitional]
    StartOverlay2(handle<eventpair> view_owner_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.
};
