async fn register_user(
    base_url: &str,
    registration_shared_secret: &str,
    user: &User,
) -> Result<(), Error> {
    #[derive(Debug, Deserialize)]
    struct GetRegisterResponse {
        nonce: String,
    }
    let registration_url = format!("{}/_synapse/admin/v1/register", base_url);
    debug!(
        "Registration shared secret: {}, url: {}, user: {:#?}",
        registration_shared_secret, registration_url, user
    );
    let client = reqwest::Client::new();
    let nonce = client
        .get(&registration_url)
        .auto_retry(RETRY_ATTEMPTS)
        .await?
        .json::<GetRegisterResponse>()
        .await?
        .nonce;
    // We use map_err here because Hmac::InvalidKeyLength doesn't implement the std::error::Error trait.
    let mut mac =
        HmacSha1::new_from_slice(registration_shared_secret.as_bytes()).map_err(|err| {
            anyhow!(
                "Couldn't use the provided registration shared secret to create a hmac: {}",
                err
            )
        })?;
    mac.update(
        format!(
            "{nonce}\0{username}\0{password}\0{admin}",
            nonce = nonce,
            username = user.localname,
            password = user.password,
            admin = if user.admin { "admin" } else { "notadmin" }
        )
        .as_bytes(),
    );

    #[derive(Debug, Serialize)]
    struct RegistrationPayload {
        nonce: String,
        username: String,
        displayname: String,
        password: String,
        admin: bool,
        mac: String,
    }

    let registration_payload = RegistrationPayload {
        nonce,
        username: user.localname.to_string(),
        displayname: user.localname.to_string(),
        password: user.password.to_string(),
        admin: user.admin,
        mac: HEXLOWER.encode(&mac.finalize().into_bytes()),
    };
    debug!(
        "Sending payload {:#?}",
        serde_json::to_string_pretty(&registration_payload)
    );

    #[derive(Debug, Deserialize)]
    struct ErrorResponse {
        errcode: String,
        error: String,
    }
    let client = reqwest::Client::new();
    let response = client
        .post(&registration_url)
        .json(&registration_payload)
        .auto_retry(RETRY_ATTEMPTS)
        .await?;
    match response.status() {
        StatusCode::OK => Ok(()),
        _ => {
            let body = response.json::<ErrorResponse>().await?;
            Err(anyhow!(
                "Homeserver responded with errcode: {}, error: {}",
                body.errcode,
                body.error
            ))
        }
    }
}
/// Register a user using the admin api and a registration shared secret.
/// The base_url is the Scheme and Authority of the URL to access synapse via.
/// Returns a RegistrationResponse if registration succeeded, otherwise returns an error.
Register a user using the admin api and a registration shared secret.
The base_url is the Scheme and Authority of the URL to access synapse via.
Returns a RegistrationResponse if registration succeeded, otherwise returns an error.
Register a user using the admin api and a registration shared secret . The base_url is the Scheme and Authority of the URL to access synapse via . Returns a RegistrationResponse if registration succeeded otherwise returns an error .
async fn register_user(
    base_url: &str,
    registration_shared_secret: &str,
    user: &User,
) -> Result<(), Error> {
    #[derive(Debug, Deserialize)]
    struct GetRegisterResponse {
        nonce: String,
    }
    let registration_url = format!("{}/_synapse/admin/v1/register", base_url);
    debug!(
        "Registration shared secret: {}, url: {}, user: {:#?}",
        registration_shared_secret, registration_url, user
    );
    let client = reqwest::Client::new();
    let nonce = client
        .get(&registration_url)
        .auto_retry(RETRY_ATTEMPTS)
        .await?
        .json::<GetRegisterResponse>()
        .await?
        .nonce;
    // We use map_err here because Hmac::InvalidKeyLength doesn't implement the std::error::Error trait.
    let mut mac =
        HmacSha1::new_from_slice(registration_shared_secret.as_bytes()).map_err(|err| {
            anyhow!(
                "Couldn't use the provided registration shared secret to create a hmac: {}",
                err
            )
        })?;
    mac.update(
        format!(
            "{nonce}\0{username}\0{password}\0{admin}",
            nonce = nonce,
            username = user.localname,
            password = user.password,
            admin = if user.admin { "admin" } else { "notadmin" }
        )
        .as_bytes(),
    );
    #[derive(Debug, Serialize)]
    struct RegistrationPayload {
        nonce: String,
        username: String,
        displayname: String,
        password: String,
        admin: bool,
        mac: String,
    }
    let registration_payload = RegistrationPayload {
        nonce,
        username: user.localname.to_string(),
        displayname: user.localname.to_string(),
        password: user.password.to_string(),
        admin: user.admin,
        mac: HEXLOWER.encode(&mac.finalize().into_bytes()),
    };
    debug!(
        "Sending payload {:#?}",
        serde_json::to_string_pretty(&registration_payload)
    );
    #[derive(Debug, Deserialize)]
    struct ErrorResponse {
        errcode: String,
        error: String,
    }
    let client = reqwest::Client::new();
    let response = client
        .post(&registration_url)
        .json(&registration_payload)
        .auto_retry(RETRY_ATTEMPTS)
        .await?;
    match response.status() {
        StatusCode::OK => Ok(()),
        _ => {
            let body = response.json::<ErrorResponse>().await?;
            Err(anyhow!(
                "Homeserver responded with errcode: {}, error: {}",
                body.errcode,
                body.error
            ))
        }
    }
}
async fn register_user ( base_url : & str , registration_shared_secret : & str , user : & User , ) -> Result < ( ) , Error > { # [ derive ( Debug Deserialize ) ] struct GetRegisterResponse { nonce : String , } let registration_url = format ! ( " " base_url ) ; debug ! ( " " registration_shared_secret registration_url user ) ; let client = reqwest :: Client :: new ( ) ; let nonce = client . get ( & registration_url ) . auto_retry ( RETRY_ATTEMPTS ) . await ? . json :: < GetRegisterResponse > ( ) . await ? . nonce ; // We use map_err here because Hmac::InvalidKeyLength doesn't implement the std::error::Error trait. let mut mac = HmacSha1 :: new_from_slice ( registration_shared_secret . as_bytes ( ) ) . map_err ( | err | { anyhow ! ( " " err ) } ) ? ; mac . update ( format ! ( " \0 \0 \0 " nonce nonce username user localname password user password admin if user admin { " " } else { " " } ) . as_bytes ( ) , ) ; # [ derive ( Debug Serialize ) ] struct RegistrationPayload { nonce : String , username : String , displayname : String , password : String , admin : bool , mac : String , } let registration_payload = RegistrationPayload { nonce , username : user . localname . to_string ( ) , displayname : user . localname . to_string ( ) , password : user . password . to_string ( ) , admin : user . admin , mac : HEXLOWER . encode ( & mac . finalize ( ) . into_bytes ( ) ) , } ; debug ! ( " " serde_json to_string_pretty ( registration_payload ) ) ; # [ derive ( Debug Deserialize ) ] struct ErrorResponse { errcode : String , error : String , } let client = reqwest :: Client :: new ( ) ; let response = client . post ( & registration_url ) . json ( & registration_payload ) . auto_retry ( RETRY_ATTEMPTS ) . await ? ; match response . status ( ) { StatusCode :: OK => Ok ( ( ) ) , _ => { let body = response . json :: < ErrorResponse > ( ) . await ? ; Err ( anyhow ! ( " " body errcode body error ) ) } } }
Register a user using the admin api and a registration shared secret.
Register a user using the admin api and a registration shared secret .
base_url
&str
registration_shared_secret
&str
user
&User
base_url
&str
registration_shared_secret
&str
user
&User