1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! [POST /_matrix/client/r0/register](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-register)

use ruma_api::ruma_api;
use ruma_identifiers::{DeviceId, DeviceIdBox, UserId};
use serde::{Deserialize, Serialize};

use crate::r0::uiaa::{AuthData, IncomingAuthData, UiaaResponse};

ruma_api! {
    metadata: {
        description: "Register an account on this homeserver.",
        method: POST,
        name: "register",
        path: "/_matrix/client/r0/register",
        rate_limited: true,
        authentication: None,
    }

    #[derive(Default)]
    request: {
        /// The desired password for the account.
        ///
        /// May be empty for accounts that should not be able to log in again
        /// with a password, e.g., for guest or application service accounts.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub password: Option<&'a str>,

        /// Localpart of the desired Matrix ID.
        ///
        /// If omitted, the homeserver MUST generate a Matrix ID local part.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub username: Option<&'a str>,

        /// ID of the client device.
        ///
        /// If this does not correspond to a known client device, a new device will be created.
        /// The server will auto-generate a device_id if this is not specified.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub device_id: Option<&'a DeviceId>,

        /// A display name to assign to the newly-created device.
        ///
        /// Ignored if `device_id` corresponds to a known device.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub initial_device_display_name: Option<&'a str>,

        /// Additional authentication information for the user-interactive authentication API.
        ///
        /// Note that this information is not used to define how the registered user should be
        /// authenticated, but is instead used to authenticate the register call itself.
        /// It should be left empty, or omitted, unless an earlier call returned an response
        /// with status code 401.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub auth: Option<AuthData<'a>>,

        /// Kind of account to register
        ///
        /// Defaults to `User` if omitted.
        #[ruma_api(query)]
        #[serde(default, skip_serializing_if = "ruma_serde::is_default")]
        pub kind: RegistrationKind,

        /// If `true`, an `access_token` and `device_id` should not be returned
        /// from this call, therefore preventing an automatic login.
        #[serde(default, skip_serializing_if = "ruma_serde::is_default")]
        pub inhibit_login: bool,

        /// Login `type` used by Appservices.
        ///
        /// Appservices can [bypass the registration flows][admin] entirely by providing their
        /// token in the header and setting this login `type` to `m.login.application_service`.
        ///
        /// [admin]: https://matrix.org/docs/spec/application_service/r0.1.2#server-admin-style-permissions
        #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
        pub login_type: Option<&'a LoginType>,
    }

    response: {
        /// An access token for the account.
        ///
        /// This access token can then be used to authorize other requests.
        #[serde(skip_serializing_if = "Option::is_none")]
        pub access_token: Option<String>,

        /// The fully-qualified Matrix ID that has been registered.
        pub user_id: UserId,

        /// ID of the registered device.
        ///
        /// Will be the same as the corresponding parameter in the request, if one was specified.
        pub device_id: Option<DeviceIdBox>,
    }

    error: UiaaResponse
}

impl Request<'_> {
    /// Creates a new `Request` with all parameters defaulted.
    pub fn new() -> Self {
        Default::default()
    }
}

impl Response {
    /// Creates a new `Response` with the given user ID.
    pub fn new(user_id: UserId) -> Self {
        Self { access_token: None, user_id, device_id: None }
    }
}

/// The kind of account being registered.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub enum RegistrationKind {
    /// A guest account
    ///
    /// These accounts may have limited permissions and may not be supported by all servers.
    Guest,

    /// A regular user account
    User,
}

impl Default for RegistrationKind {
    fn default() -> Self {
        Self::User
    }
}

/// The login type.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub enum LoginType {
    /// An appservice-specific login type
    #[serde(rename = "m.login.application_service")]
    ApplicationService,
}