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

using fuchsia.identity.account;
using fuchsia.identity.authentication;

/// The maximum length of the pre-auth account state, in bytes.
const ACCOUNT_PRE_AUTH_STATE_MAX_SIZE uint32 = 10240;

/// Data associated with an account that is available prior to authentication,
/// such as the account name.
///
/// This data is generated and used by an AccountHandler, but is persisted as an
/// opaque blob by the AccountManager on behalf of the AccountHandler. This
/// partitioning means neither component has access to both the device-encrypted
/// disk and the account-encrypted disk.
alias AccountPreAuthState = vector<uint8>:ACCOUNT_PRE_AUTH_STATE_MAX_SIZE;


/// The control channel for an AccountHandler component.
///
/// This interface is intended only for use by the AccountManager component that
/// starts instances of AccountHandler. We define which account the handler
/// should be handling one time via this channel rather than via startup flags
/// to provide additional flexibility given the range of scenarios:
/// * The account is completely new
/// * The account is being added to the current device for the first time
/// * Account information is already present on the local disk and is readable
/// * Account information is already present on the local disk but is not yet
///   readable because the disk is not yet decrypted.
///
/// A given Account Handler progresses through the following state machine:
/// ```
///               |
///               V
///       +---------------+
///       | Uninitialized |------------+
///       +---------------+            |
///               |                    |
///               |                    | Preload
///               |                    V
///               |           +------------------+
///               |           |      Locked      |
///               |           +------------------+
///               |                    ^
///               |                    |
///               |                    |
///               |                    | LockAccount /
///               | CreateAccount      | UnlockAccount
///               |                    |
///               |                    |
///               |                    |
///               V                    |
///       +---------------+            |
///       |  Initialized  |<-----------+
///       +---------------+
///               |
///               | Terminate
///               V
///       +---------------+
///       |   Finished    |
///       +---------------+
/// ```
///
/// * `Uninitialized` - the handler has just been instantiated and contains no
///   account information.
/// * `Locked` - the handler has loaded pre-authentication data, which lets it
///   unlock the account subsequently.
/// * `Initialized` - the handler has loaded account information and is ready
///   to serve requests for the `Account` interface.  If the account is
///   persistent, then it is saved to disk.
/// * `Finished` - the handler is in the process of shutting down and will soon
///   terminate.
@discoverable
closed protocol AccountHandlerControl {
    /// Creates a completely new system account, optionally protecting the
    /// account with a single enrollment of an authentication mechanism.
    ///
    /// `id` [required] AccountId for the new account
    /// `metadata` [required] Metadata for the new account
    /// `interaction` An `Interaction` channel enabling the user to select and
    ///               enroll authentication mechanisms for the new account.
    ///
    /// Returns an `AccountPreAuthState` that the client should persist for
    /// use in future operations on the account.
    ///
    /// Fails with:
    /// - `FAILED_PRECONDITION` if the AccountHandler is not in the
    ///   `Uninitialized` state.
    /// - `INVALID_REQUEST` if policy requires authentication factors for the
    ///    new account but no `interaction` channel was supplied.
    /// - `ABORTED` if the client closes the `interaction` channel.
    strict CreateAccount(resource table {
        1: id fuchsia.identity.account.AccountId;
        2: metadata fuchsia.identity.account.AccountMetadata;
        3: interaction server_end:fuchsia.identity.authentication.Interaction;
    }) -> (struct {
        pre_auth_state AccountPreAuthState;
    }) error fuchsia.identity.account.Error;

    /// Loads the supplied pre-auth data, which allows the account to be
    /// unlocked later.
    ///
    /// This moves the AccountHandler from the `Uninitialized` state to the
    /// `Locked` state.
    ///
    /// Fails with `FAILED_PRECONDITION` if the AccountHandler is not in the
    /// `Uninitialized` state.
    strict Preload(struct {
        pre_auth_state AccountPreAuthState;
    }) -> () error fuchsia.identity.account.Error;

    /// Reach the `Initialized` state, attempting authentication and unlocking
    /// the account where necessary.
    ///
    /// `interaction` An `Interaction` channel enabling the user to complete
    ///               authentication challenges if these are necessary.
    ///
    /// On success, returns an `AccountPreAuthState` if the stored pre-
    /// authentication state should be updated as a result of the operation.
    ///
    /// Fails with
    /// - `FAILED_PRECONDITION` if the AccountHandler is not in the `Locked` or
    ///   `Initialized` state.
    /// - `ABORTED` if the client closes the `interaction` channel.
    strict UnlockAccount(resource table {
        1: interaction server_end:fuchsia.identity.authentication.Interaction;
    }) -> (struct {
        pre_auth_state AccountPreAuthState:optional;
    }) error fuchsia.identity.account.Error;

    /// Reach the `Locked` state, closing any open `Account` and `Persona`
    /// channels for the account.
    ///
    /// On success, returns an `AccountPreAuthState` if the stored pre-
    /// authentication state should be updated as a result of the operation.
    ///
    /// Fails with `FAILED_PRECONDITION` if the AccountHandler is not in the
    /// `Initialized` or `Locked` state.
    strict LockAccount() -> (struct {
        pre_auth_state AccountPreAuthState:optional;
    }) error fuchsia.identity.account.Error;

    /// Deletes all persistent information about the Fuchsia account handled by
    /// this handler, including all credentials and global identifiers.
    /// After a successful call to RemoveAccount, all other open interfaces for
    /// this account handler will be closed and any subsequent calls on the
    /// current interface will fail.
    strict RemoveAccount() -> () error fuchsia.identity.account.Error;

    /// Connects an interface to read properties of and perform operations on
    /// the account handled by this handler. The AccountHandler must be in the
    /// `Initialized` state.
    ///
    /// `account` The server end of an `Account` channel
    ///
    /// Fails with `FAILED_PRECONDITION` if the AccountHandler is not in the
    /// `Initialized` state.
    strict GetAccount(resource struct {
        account server_end:fuchsia.identity.account.Account;
    }) -> () error fuchsia.identity.account.Error;

    /// Signals that the AccountHandler should tear itself down. After the
    /// receiver responds by closing its handle, the caller may terminate the
    /// component if it hasn't already exited.
    strict Terminate();
};
