API: rework authentication in register model

This commit is contained in:
Alejandro Domínguez 2019-01-28 18:36:32 +01:00 committed by Julian Sparber
parent 1239698960
commit 1ce06f4245
3 changed files with 122 additions and 98 deletions

View file

@ -8,8 +8,6 @@ use crate::error::Error;
use crate::globals; use crate::globals;
use crate::util::json_q; use crate::util::json_q;
use crate::types::AuthenticationData;
use crate::types::AuthenticationKind;
use crate::types::LoginRequest; use crate::types::LoginRequest;
use crate::types::LoginResponse; use crate::types::LoginResponse;
use crate::types::RegisterRequest; use crate::types::RegisterRequest;
@ -57,7 +55,7 @@ pub fn login(bk: &Backend, user: String, password: String, server: &str) -> Resu
bk.data.lock().unwrap().server_url = Url::parse(server)?; bk.data.lock().unwrap().server_url = Url::parse(server)?;
let url = bk.url("login", vec![])?; let url = bk.url("login", vec![])?;
let attrs = LoginRequest::new(user.clone(), password); let attrs = LoginRequest::new(user.clone(), password, Some(String::from("Fractal")), None);
let attrs_json = serde_json::to_value(attrs).expect("Failed to serialize login request"); let attrs_json = serde_json::to_value(attrs).expect("Failed to serialize login request");
let data = bk.data.clone(); let data = bk.data.clone();
@ -124,10 +122,6 @@ pub fn register(bk: &Backend, user: String, password: String, server: &str) -> R
let url = bk.url("register", vec![("kind", String::from("user"))])?; let url = bk.url("register", vec![("kind", String::from("user"))])?;
let attrs = RegisterRequest { let attrs = RegisterRequest {
auth: Some(AuthenticationData {
kind: AuthenticationKind::Password,
session: None,
}),
username: Some(user), username: Some(user),
password: Some(password), password: Some(password),
..Default::default() ..Default::default()

View file

@ -8,3 +8,113 @@ pub mod room;
pub mod stickers; pub mod stickers;
pub mod sync; pub mod sync;
pub mod userinfo; pub mod userinfo;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum Medium {
#[serde(rename = "email")]
Email,
#[serde(rename = "msisdn")]
MsIsdn,
}
#[derive(Clone, Debug, Serialize)]
#[serde(tag = "type")]
pub enum UserIdentifier {
#[serde(rename = "m.id.user")]
User { user: String },
#[serde(rename = "m.id.thirdparty")]
ThirdParty { medium: Medium, address: String },
#[serde(rename = "m.id.phone")]
Phone { country: String, phone: String },
}
#[derive(Clone, Debug, Serialize)]
enum LegacyMedium {
#[serde(rename = "email")]
Email,
}
#[derive(Clone, Debug, Serialize)]
#[serde(untagged)]
enum LegacyIdentifier {
User {
user: String,
},
Email {
medium: LegacyMedium,
address: String,
},
}
#[derive(Clone, Debug, Serialize)]
pub struct Identifier {
identifier: UserIdentifier,
#[serde(flatten)]
legacy_identifier: Option<LegacyIdentifier>,
}
impl Identifier {
pub fn new(identifier: UserIdentifier) -> Self {
Self {
identifier: identifier.clone(),
legacy_identifier: match identifier {
UserIdentifier::User { user } => Some(LegacyIdentifier::User { user }),
UserIdentifier::ThirdParty { medium: _, address } => {
Some(LegacyIdentifier::Email {
medium: LegacyMedium::Email,
address,
})
}
UserIdentifier::Phone { .. } => None,
},
}
}
}
#[derive(Clone, Debug, Serialize)]
pub struct ThreePIDCredentials {
pub client_secret: String,
pub id_server: String,
pub sid: String,
}
#[derive(Clone, Debug, Serialize)]
#[serde(tag = "type")]
pub enum AuthenticationData {
#[serde(rename = "m.login.password")]
Password {
#[serde(flatten)]
identifier: Identifier,
password: String,
#[serde(skip_serializing_if = "Option::is_none")]
session: Option<String>,
},
#[serde(rename = "m.login.recaptcha")]
Recaptcha {
response: String,
#[serde(skip_serializing_if = "Option::is_none")]
session: Option<String>,
},
#[serde(rename = "m.login.token")]
Token {
token: String,
txn_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
session: Option<String>,
},
#[serde(rename = "m.login.oauth2")]
OAuth2 { uri: String },
#[serde(rename = "m.login.email.identity")]
Email {
threepid_creds: ThreePIDCredentials,
#[serde(skip_serializing_if = "Option::is_none")]
session: Option<String>,
},
#[serde(rename = "m.login.dummy")]
Dummy {
#[serde(skip_serializing_if = "Option::is_none")]
session: Option<String>,
},
}

View file

@ -1,3 +1,4 @@
use super::{AuthenticationData, Identifier, Medium, UserIdentifier};
use crate::globals; use crate::globals;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::ops::Not; use std::ops::Not;
@ -21,14 +22,6 @@ pub struct LoginResponse {
pub device_id: Option<String>, pub device_id: Option<String>,
} }
#[derive(Clone, Debug, Serialize)]
pub enum Medium {
#[serde(rename = "email")]
Email,
#[serde(rename = "msisdn")]
MsIsdn,
}
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum Auth { pub enum Auth {
@ -38,78 +31,29 @@ pub enum Auth {
Token { token: String }, Token { token: String },
} }
#[derive(Clone, Debug, Serialize)]
#[serde(tag = "type")]
pub enum UserIdentifier {
#[serde(rename = "m.id.user")]
User { user: String },
#[serde(rename = "m.id.thirdparty")]
ThirdParty { medium: Medium, address: String },
#[serde(rename = "m.id.phone")]
Phone { country: String, phone: String },
}
#[derive(Clone, Debug, Serialize)]
enum LegacyMedium {
#[serde(rename = "email")]
Email,
}
#[derive(Clone, Debug, Serialize)]
#[serde(untagged)]
enum LegacyIdentifier {
User {
user: String,
},
Email {
medium: LegacyMedium,
address: String,
},
}
#[derive(Clone, Debug, Serialize)]
pub struct Identifier {
identifier: UserIdentifier,
#[serde(flatten)]
legacy_identifier: Option<LegacyIdentifier>,
}
impl Identifier {
pub fn new(identifier: UserIdentifier) -> Self {
Self {
identifier: identifier.clone(),
legacy_identifier: match identifier {
UserIdentifier::User { user } => Some(LegacyIdentifier::User { user }),
UserIdentifier::ThirdParty { medium: _, address } => {
Some(LegacyIdentifier::Email {
medium: LegacyMedium::Email,
address,
})
}
UserIdentifier::Phone { .. } => None,
},
}
}
}
impl LoginRequest { impl LoginRequest {
pub fn new(user: String, password: String) -> Self { pub fn new(
user: String,
password: String,
initial_device_display_name: Option<String>,
device_id: Option<String>,
) -> Self {
if globals::EMAIL_RE.is_match(&user) { if globals::EMAIL_RE.is_match(&user) {
Self { Self {
auth: Auth::Password { password }, auth: Auth::Password { password },
initial_device_display_name: Some(String::from("Fractal")), initial_device_display_name,
identifier: Identifier::new(UserIdentifier::ThirdParty { identifier: Identifier::new(UserIdentifier::ThirdParty {
medium: Medium::Email, medium: Medium::Email,
address: user, address: user,
}), }),
device_id: None, device_id,
} }
} else { } else {
Self { Self {
auth: Auth::Password { password }, auth: Auth::Password { password },
initial_device_display_name: Some(String::from("Fractal")), initial_device_display_name,
identifier: Identifier::new(UserIdentifier::User { user }), identifier: Identifier::new(UserIdentifier::User { user }),
device_id: None, device_id,
} }
} }
} }
@ -139,27 +83,3 @@ pub struct RegisterResponse {
pub access_token: Option<String>, pub access_token: Option<String>,
pub device_id: Option<String>, pub device_id: Option<String>,
} }
#[derive(Clone, Debug, Serialize)]
pub struct AuthenticationData {
#[serde(rename = "type")]
pub kind: AuthenticationKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub session: Option<String>,
}
#[derive(Clone, Debug, Serialize)]
pub enum AuthenticationKind {
#[serde(rename = "m.login.password")]
Password,
#[serde(rename = "m.login.recaptcha")]
Recaptcha,
#[serde(rename = "m.login.oauth2")]
OAuth2,
#[serde(rename = "m.login.email.identity")]
Email,
#[serde(rename = "m.login.token")]
Token,
#[serde(rename = "m.login.dummy")]
Dummy,
}