diff --git a/auth/src/robocraft/email.rs b/auth/src/robocraft/email.rs
new file mode 100644
index 0000000..4ba0ee5
--- /dev/null
+++ b/auth/src/robocraft/email.rs
@@ -0,0 +1,31 @@
+use rc_core::UserAuthenticator;
+use rocket::{post, routes, serde::json::Json, http::Status, State};
+
+#[post("/authenticate/email/game", data = "
")]
+pub async fn email_password_auth(body: Json, config: &State) -> Result, Status> {
+ log::info!("Authenticating {} user {}", body.target, body.display_name);
+ let payload = libfj::robocraft::TokenPayload {
+ public_id: body.display_name.clone(),
+ display_name: body.display_name.clone(),
+ robocraft_name: body.display_name.clone(),
+ email_address: body.email_address.clone(),
+ email_verified: true,
+ flags: Vec::new(),
+ };
+ let user_info = rc_core::persist::user::UserInfo {
+ payload,
+ extra: rc_core::persist::user::ExtraUserInfo::Email { password: body.password.clone() },
+ };
+ let response = config.robocraft.account_provider.login(user_info).await
+ .map_err(|e| {
+ log::error!("Failed to authenticate {} user {}: {}", body.target, body.display_name, e);
+ Status { code: 401 }
+ })?;
+ Ok(Json(response.response))
+}
+
+pub fn stage() -> rocket::fairing::AdHoc {
+ rocket::fairing::AdHoc::on_ignite("Robocraft Username/Password", |rocket| async {
+ rocket.mount("/", routes![email_password_auth])
+ })
+}
diff --git a/auth/src/robocraft/mod.rs b/auth/src/robocraft/mod.rs
index 8abf41d..43316f9 100644
--- a/auth/src/robocraft/mod.rs
+++ b/auth/src/robocraft/mod.rs
@@ -1,10 +1,12 @@
mod debug;
mod username;
mod steam;
+mod email;
pub fn stage() -> rocket::fairing::AdHoc {
rocket::fairing::AdHoc::on_ignite("robocraft", |rocket| async {
rocket.attach(username::stage())
+ .attach(email::stage())
.attach(steam::stage())
.attach(debug::stage())
.register("/", rocket::catchers![unauthorized])
diff --git a/auth/src/robocraft/username.rs b/auth/src/robocraft/username.rs
index 94f8ee1..354d32a 100644
--- a/auth/src/robocraft/username.rs
+++ b/auth/src/robocraft/username.rs
@@ -2,7 +2,7 @@ use rc_core::UserAuthenticator;
use rocket::{post, routes, serde::json::Json, http::Status, State};
#[post("/authenticate/robocraft/game", data = "")]
-pub async fn email_password_auth(body: Json, config: &State) -> Result, Status> {
+pub async fn user_password_auth(body: Json, config: &State) -> Result, Status> {
log::info!("Authenticating {} user {}", body.target, body.display_name);
let payload = libfj::robocraft::TokenPayload {
public_id: body.display_name.clone(),
@@ -14,7 +14,7 @@ pub async fn email_password_auth(body: Json rocket::fairing::AdHoc {
- rocket::fairing::AdHoc::on_ignite("Robocraft Email/Password", |rocket| async {
- rocket.mount("/", routes![email_password_auth])
+ rocket::fairing::AdHoc::on_ignite("Robocraft Username/Password", |rocket| async {
+ rocket.mount("/", routes![user_password_auth])
})
}
diff --git a/rc_core/src/persist/user/account_json.rs b/rc_core/src/persist/user/account_json.rs
index 9f502f8..4993439 100644
--- a/rc_core/src/persist/user/account_json.rs
+++ b/rc_core/src/persist/user/account_json.rs
@@ -33,7 +33,7 @@ impl super::UserProvider for AccountProvider {
let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256);
validation.set_required_spec_claims::<&str>(&[]);
jsonwebtoken::decode::(&token.token, &secret, &validation).map_err(|e| e.to_string())?;
- let user_info = if let Some(user_info) = self.db.user_by_public_id(token.uuid.clone()).await.map_err(|e| e.to_string())? {
+ let user_info = if let Some(user_info) = self.db.user_by_any_unique_id(token.uuid.clone()).await.map_err(|e| e.to_string())? {
user_info
} else {
return Err("User not found".to_owned());
@@ -62,14 +62,19 @@ impl super::UserAuthenticator for AccountProvider {
async fn login(&self, info: super::UserInfo) -> Result {
//let new_root = self.root.join(&info.payload.public_id);
let is_new_user;
- let mut user_info = if let Some(user_info) = self.db.user_by_public_id(info.payload.public_id.clone()).await.map_err(|e| e.to_string())? {
+ let user_opt = match &info.extra {
+ super::ExtraUserInfo::Steam { id } => self.db.user_by_steam_id(*id).await,
+ super::ExtraUserInfo::Email { .. } => self.db.user_by_email(info.payload.email_address.clone()).await,
+ super::ExtraUserInfo::Username { .. } => self.db.user_by_display_name(info.payload.display_name.clone()).await,
+ }.map_err(|e| e.to_string())?;
+ let mut user_info = if let Some(user_info) = user_opt {
is_new_user = false;
user_info
} else {
is_new_user = true;
log::info!("New user {}", info.payload.public_id);
super::setup_new_user(&info, &self.db).await.map_err(|e| e.to_string())?;
- self.db.user_by_public_id(info.payload.public_id.clone()).await.map_err(|e| e.to_string())?.unwrap()
+ self.db.user_by_display_name(info.payload.display_name.clone()).await.map_err(|e| e.to_string())?.unwrap()
};
let override_password = user_info.password.is_empty() && user_info.steam_id.is_none();
match info.extra {
@@ -83,7 +88,8 @@ impl super::UserAuthenticator for AccountProvider {
return Err("SteamID not supported for this user".to_owned());
}
},
- super::ExtraUserInfo::Standalone { password } => {
+ super::ExtraUserInfo::Email { password }
+ | super::ExtraUserInfo::Username { password } => {
use argon2::password_hash::PasswordHasher;
let argon2_algo = argon2::Argon2::default();
if override_password {
diff --git a/rc_core/src/persist/user/initial_data.rs b/rc_core/src/persist/user/initial_data.rs
index 45e1076..74c2651 100644
--- a/rc_core/src/persist/user/initial_data.rs
+++ b/rc_core/src/persist/user/initial_data.rs
@@ -32,7 +32,7 @@ pub async fn setup_new_user(user: &super::UserInfo, db: &rc_database::Database)
}
fn default_user_data(user: &super::UserInfo) -> rc_database::schema::user::ActiveModel {
- let password = if let super::ExtraUserInfo::Standalone { password } = &user.extra {
+ let password = if let super::ExtraUserInfo::Email { password } | super::ExtraUserInfo::Username { password } = &user.extra {
//password.to_owned()
use argon2::password_hash::PasswordHasher;
let argon2_algo = argon2::Argon2::default();
diff --git a/rc_core/src/persist/user/traits.rs b/rc_core/src/persist/user/traits.rs
index 0a6ff4f..28e100c 100644
--- a/rc_core/src/persist/user/traits.rs
+++ b/rc_core/src/persist/user/traits.rs
@@ -15,7 +15,10 @@ pub enum ExtraUserInfo {
Steam {
id: u64,
},
- Standalone {
+ Username {
+ password: String,
+ },
+ Email {
password: String,
}
}
diff --git a/rc_database/src/wrapper.rs b/rc_database/src/wrapper.rs
index b710e99..7f5b309 100644
--- a/rc_database/src/wrapper.rs
+++ b/rc_database/src/wrapper.rs
@@ -15,13 +15,41 @@ impl Database {
})
}
- pub async fn user_by_public_id(&self, public_id: String) -> Result