// Copyright 2018 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.account;

using fuchsia.auth;
using fuchsia.identity.keys;
using fuchsia.sys;
using fuchsia.io;

/// A protocol to receive events when the authentication state of an account
/// changes.
///
/// AuthListeners may be registered through the `AuthTarget` protocol and this
/// registration also defines the types of authentication state changes that
/// should be sent to the listener.
///
/// All methods include an empty response to follow the "Throttle push using
/// acknowledgements" FIDL design pattern.
protocol AuthListener {
    /// A method that is called when the AccountListener is first connected.
    OnInitialize(AuthState auth_state) -> ();

    /// A method that is called when the authentication state of the account
    /// changes.
    OnAuthStateChanged(AuthState auth_state) -> ();
};

/// A protocol that is extended by other protocols defining an entity
/// (referred to as the "target") with an authentication state, such as a
/// Fuchsia account or persona.
///
/// AuthTarget defines a set of methods to monitor the current authentication
/// state of an entity and to request changes in that authentication state.
protocol AuthTarget {
    /// Returns the current `AuthState` of the target.
    ///
    /// `scenario` The scenario to produce the authentication state for.
    ///
    /// Returns: `auth_state` The target's current authentication state.
    GetAuthState(Scenario scenario) -> (AuthState auth_state) error Error;

    /// Connects a channel that will receive changes in the authentication
    /// state of the target.
    ///
    /// `listener` The client end of an `AuthListener` channel
    /// `initial_state` If true, the listener will receive the initial auth
    ///                 state in addition to any changes.
    /// `granularity` An `AuthChangeGranularity` expressing the magnitude of
    ///               change in authentication state than should lead to a
    ///               callback
    RegisterAuthListener(
        Scenario scenario,
        AuthListener listener,
        bool initial_state,
        AuthChangeGranularity granularity)
        -> () error Error;

    // TODO(fxbug.dev/562): Add methods that request in increase in the authentication
    //                 state or authentication for a particular event.
};

/// A protocol that exposes information about the personae and recovery account
/// for a Fuchsia account and provides methods to manipulate these. It also
/// exposes a writable data directory.
///
/// An Account provides access to sensitive long term identifiers and is only
/// intended only for use by a small number of trusted system components.
protocol Account {
    compose AuthTarget;

    // Note: a LocalAccountID accessor method may be added if and when the
    // first valid use case arrives.

    /// Returns a human readable name for the account. Account names are set by
    /// a human and are not guaranteed to be meaningful or unique, even among
    /// the accounts on a single device.
    GetAccountName() -> (string:MAX_NAME_SIZE name);

    /// Returns the account's lifetime.
    GetLifetime() -> (Lifetime lifetime);

    /// Returns a vector of all the personae defined for the account.
    /// NOTE: Currently all Fuchsia accounts have exactly one persona.
    GetPersonaIds() -> (vector<LocalPersonaId>:MAX_PERSONAE_PER_ACCOUNT persona_ids);

    /// Connects a channel to read properties of and access tokens for
    /// the default persona for the account.
    ///
    /// `persona` The server end of a `Persona` channel
    ///
    /// Returns: `id` The identifier for the default persona
    GetDefaultPersona(request<Persona> persona)
        -> (LocalPersonaId id) error Error;

    /// Connects a channel to read properties of and access tokens for
    /// one of the personae for the account.
    ///
    /// `id` The persona's identifier as returned by GetPersonaIds()
    /// `persona` The server end of a `Persona` channel
    GetPersona(LocalPersonaId id, request<Persona> persona) -> () error Error;

    // TODO(fxbug.dev/563): Add methods to create, delete, and manage personae.

    /// Returns the service provider account that can be used to access the
    /// Fuchsia account if more direct methods of authentication are not
    /// available, provided such an account exists.
    ///
    /// Returns: The `ServiceProviderAccount` used for recovery if one exists
    GetRecoveryAccount()
        -> (fuchsia.auth.ServiceProviderAccount? account) error Error;

    /// Sets the service provider account that can be used to access the Fuchsia
    /// account if more direct methods of authentication are not available.
    ///
    /// `account` The `ServiceProviderAccount` to use as the recovery account.
    ///           This must be an existing account that has already been
    ///           provisioned on the current device using TokenManager.
    SetRecoveryAccount(fuchsia.auth.ServiceProviderAccount account)
        -> () error Error;

    /// Returns all authentication mechanism enrollments.
    GetAuthMechanismEnrollments()
        -> (vector<AuthMechanismEnrollmentMetadata>:MAX_AUTH_MECHANISM_ENROLLMENTS enrollments)
        error Error;

    /// Create a new enrollment of the provided authentication mechanism,
    /// and add it to the account.
    ///
    /// `auth_mechanism_id` The identifier of the authentication mechanism to
    ///                     use for the enrollment.
    ///
    /// Returns: The `AuthMechanismEnrollmentId` of the created enrollment.
    // TODO(dnordstrom): Define and document how to authenticate prior to making
    // changes to the enrollment set.
    CreateAuthMechanismEnrollment(AuthMechanismId auth_mechanism_id)
        -> (AuthMechanismEnrollmentId enrollment_id) error Error;

    /// Remove an authentication mechanism enrollment for the account.
    ///
    /// `enrollment_id` The id of the enrollment to remove.
    // TODO(dnordstrom): Define and document how to authenticate prior to making
    // changes to the enrollment set.
    RemoveAuthMechanismEnrollment(AuthMechanismEnrollmentId enrollment_id) -> () error Error;

    // TODO(dnordstrom): Add support for modifications and/or replacement of
    // enrollments.

    /// Lock an account. After a successful call, all Account and Persona
    /// channels for this account will be terminated. If storage unlock is not
    /// enabled for the account, a FailedPrecondition error is returned.
    // TODO(dnordstrom): Document the side effects on underlying storage that
    // may still be in use by the client.
    Lock() -> () error Error;

    /// Connects a channel to access a data directory of the account. The directory is
    /// writable, and is initially empty for a newly created account. The
    /// directory is persisted according to the lifetime of the account and is
    /// never modified by the account system.
    ///
    /// NOTE: This method should only be called by the root session
    /// component instance. Multiple component instance clients are not yet
    /// supported.
    ///
    /// `data_directory` The server end of a `fuchsia.io.Directory` channel
    // TODO(fxbug.dev/45799): Support multiple component instance clients.
    GetDataDirectory(request<fuchsia.io.Directory> data_directory)
        -> () error Error;
};

/// A protocol that exposes basic information about a Fuchsia persona and access
/// to the authentication tokens that are visible through it.
///
/// Note a Persona purposefully does not provide access to a long term
/// identifier for the persona. This is to support components in the system that
/// work with short lived identifiers (e.g. SessionManager), but note that long
/// term identifiers can usually still be derived via the TokenManger protocol.
protocol Persona {
    compose AuthTarget;

    /// Returns the lifetime of this persona.
    GetLifetime() -> (Lifetime lifetime);

    /// Connects a channel to acquire and revoke authentication tokens for
    /// service provider (aka cloud service) accounts that are visible through
    /// this persona.
    ///
    /// `application_url` A url for the Fuchsia agent that this channel will be
    ///                   used by. Applications are only allowed to access
    ///                   tokens that they created.
    /// `token_manager` The server end of a `TokenManager` channel
    GetTokenManager(
        // TODO(fxbug.dev/560): Migrate token manager to a more appropriate form
        // of software identity. This is likely to be some verifiable
        // representation of the organization that wrote the software, such as
        // a URL domain.
        fuchsia.sys.component_url application_url,
        request<fuchsia.auth.TokenManager> token_manager)
        -> () error Error;

    /// Connects a channel to access and manage key material that is consistent
    /// across all devices with access to this persona.
    ///
    /// Persona key storage is a very limited resource. Only a small number of
    /// core components should use KeyManager, often in order to supply more
    /// scalable forms of synchronization to other applications (e.g. Ledger).
    ///
    /// `application_url` A url for the component that this channel will be
    ///                   used by. Applications are only allowed to access
    ///                   their own keys.
    /// `key_manager` The server end of a `KeyManager` channel
    GetKeyManager(
        // TODO(fxbug.dev/560): Migrate key manager to a more appropriate form
        // of software identity. This might be a set of whitelisted URLs or a
        // simple enum.
        fuchsia.sys.component_url application_url,
        request<fuchsia.identity.keys.KeyManager> key_manager)
        -> () error Error;
};
