/*
  Сервис предоставляет возможность авторизации
*/
syntax = "proto3";

import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/timestamp.proto";

package keyapis.identity.v1;

option java_package = "ru.keyapis.identity.v1";
option java_outer_classname = "KeyapisIdentityV1Proto";
option java_multiple_files = false;
option java_string_check_utf8 = true;
option go_package = "/keyapis_identity_v1";
option cc_enable_arenas = true;
option csharp_namespace = "Keyapis.Identity.V1";
option objc_class_prefix = "KEYAPISIDENTITYV1";
option php_namespace = "Keyapis\\Identity\\V1";
option ruby_package = "Keyapis::Identity::V1";
option optimize_for = LITE_RUNTIME;

// Сервис авторизации пользователей
service AuthorizationService {
  // Метод авторизации по ОТП-коду.
  // Не требует авторизации
  rpc PostAuthorizationLogin(PostAuthorizationLoginRequest) returns (PostAuthorizationLoginResponse) {
    option (google.api.http) = {
      post: "/identity/api/v1/authorization/login",
      body: "*"
    };
  }
  // Метод запроса ОТП-кода.
  // Не требует авторизации
  rpc PostAuthorizationSendCode(PostAuthorizationSendCodeRequest) returns (PostAuthorizationSendCodeResponse) {
    option (google.api.http) = {
      post: "/identity/api/v1/authorization/send_code",
      body: "*"
    };
  }
  // Метод авторизации по паролю.
  // Не требует авторизации
  rpc PostAuthorizationLoginByPassword(PostAuthorizationLoginByPasswordRequest) returns (PostAuthorizationLoginByPasswordResponse) {
    option (google.api.http) = {
      post: "/identity/api/v1/authorization/login_by_password",
      body: "*"
    };
  }
}

// Информация о токене пользователя
message UserToken {
// Токен
  string access_token = 1 [(google.api.field_behavior) = REQUIRED];
  // Окончание действия токена
  google.protobuf.Timestamp expired_at = 2 [(google.api.field_behavior) = REQUIRED];
}

// Капча
message Captcha {
  // Идентификатор капчи
  string id = 1 [(google.api.field_behavior) = REQUIRED];
  // Ссылка на капчу
  string url = 2 [(google.api.field_behavior) = REQUIRED];
}

// Ответ на капчу
message CaptchaAnswer {
  // Идентификатор капчи
  string id = 1 [(google.api.field_behavior) = REQUIRED];
  // Ответ на капчу
  string code = 2 [(google.api.field_behavior) = REQUIRED];

  // Ошибка ответа на капчу
  message Error {
    // Некорректный ответ на капчу
    message WrongAnswer {}
    // Причина ошибки
    oneof reason {
      // Некорректный ответ на капчу
      WrongAnswer wrong_answer = 1;
    }
    // Капча
    Captcha captcha = 2;
  }
}

// Информация о вводе ОТП-кода
message OtpCode {
  // Идентификатор ОТП-кода
  string code_id = 1 [(google.api.field_behavior) = REQUIRED];
  // Время в секундах, оставшееся до возможности отправки следующего кода
  int32 timeout = 2 [(google.api.field_behavior) = REQUIRED];

  // Ошибка ответа на капчу
  message Error {
    // Код истек
    message LifeTimeExpired {}
    // Попыток больше нет
    message NoAttempts {}
    // Адрес для отправки кода не найден
    message AddressNotFound {}
    // Неправильный ОТП-код
    message InvalidCode {}

    // Причина ошибки
    oneof reason {
      // Код истек
      LifeTimeExpired life_time_expired = 1;
      // Попыток больше нет
      NoAttempts no_attempts = 2;
      // Адрес для отправки кода не найден.
      // В текущей реализации, эту ошибку невозможно получить
      AddressNotFound address_not_found = 3;
      // Неправильный ОТП-код
      InvalidCode invalid_code = 4;
    }
  }
}

// Ошибки из ССО
message SsoError {
  // Пользователь временно заблокирован
  message UserIsTemporaryBlocked {}
  // Пользователь не найден
  message UserNotFound {}
  // Неверный пароль
  message WrongCredentials {
    // Капча
    Captcha captcha = 1 [(google.api.field_behavior) = OPTIONAL];
  }
  // Пользователь заблокирован
  message UserIsBlocked {}
  // Превышен интервал отправки ОТП-кодов
  message IntervalExceeded {}

  // Причина ошибки
  oneof reason {
    // Пользователь временно заблокирован
    UserIsTemporaryBlocked user_is_temporary_blocked = 1;
    // Пользователь не найден
    UserNotFound user_not_found = 2;
    // Неверный пароль
    WrongCredentials wrong_credentials = 3;
    // Пользователь заблокирован
    UserIsBlocked user_is_blocked = 4;
    // Превышен интервал отправки ОТП-кодов
    IntervalExceeded interval_exceeded = 5;
  }
}

// Ошибки сервисов ключа
message KeyError {

  // Ошибка создания пользователя
  message UserCreation {}

  // Причина ошибки
  oneof reason {
    // Ошибка создания пользователя
    UserCreation user_creation = 1;
  }
}

// Запрос на отправку ОТП-кода
message PostAuthorizationSendCodeRequest {

  // Вариант входного параметра
  oneof otp_text {
    // Номер телефона
    string phone_number = 1;
  }

  // Ответ на капчу
  CaptchaAnswer captcha_answer = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Ответ на запрос на отправку ОТП-кода
message PostAuthorizationSendCodeResponse {

  // Ошибка запроса на отправку ОТП-кода
  message Error {
    // Причина ошибки
    oneof reason {
      // Ошибка ответа с капчей
      CaptchaAnswer.Error captcha_answer = 1;
      // Ошибка из ССО
      SsoError sso = 2;
    }
  }

  // Тип результата
  oneof type {
    // Информация об ОТП-коде
    OtpCode data = 1;
    // Ошибка
    Error error = 2;
  }
}

// Запрос на авторизацию по ОТП-коду
message PostAuthorizationLoginRequest {
  // Идентификатор ОТП-кода
  string code_id = 1 [(google.api.field_behavior) = REQUIRED];
  // Значение ОТП-кода
  string code = 2 [(google.api.field_behavior) = REQUIRED];
}

// Ответ на запрос об авторизации пользователя
message PostAuthorizationLoginResponse {
  // Ошибка запроса авторизации пользователя
  message Error {
    // Причина ошибки
    oneof reason {
      // Ошибка отп-кода
      OtpCode.Error otp_code = 1;
      // Ошибка из ССО
      SsoError sso = 2;
      // Ошибка из сервисов ключа
      KeyError key = 3;
    }
  }

  // Тип результата
  oneof type {
    // Токен пользователя
    UserToken data = 1;
    // Ошибка
    Error error = 2;
  }
}

// Запрос на авторизацию по паролю
message PostAuthorizationLoginByPasswordRequest {
  // Вариант авторизации
  oneof type {
    // Номер телефона
    string phone_number = 1;
    // Электронная почта
    string email = 2;
    // Логин
    string login = 3;
  }

  // Пароль
  string password = 4 [(google.api.field_behavior) = REQUIRED];
  // Ответ на капчу
  CaptchaAnswer captcha_answer = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Ответ на запрос об авторизации по паролю пользователя
message PostAuthorizationLoginByPasswordResponse {
  // Ошибка запроса авторизации пользователя
  message Error {
    // Причина ошибки
    oneof reason {
      // Ошибка капчи
      CaptchaAnswer.Error captcha_answer = 1;
      // Ошибка из ССО
      SsoError sso = 2;
      // Ошибка из сервисов ключа
      KeyError key = 3;
    }
  }

  // Тип результата
  oneof type {
    // Токен пользователя
    UserToken data = 1;
    // Ошибка
    Error error = 2;
  }
}
