mirror of
https://github.com/Jackzmc/storage.git
synced 2025-05-05 21:03:20 +00:00
Implement login_user for sso
This commit is contained in:
parent
e5a9ef1b58
commit
fe17ca5633
2 changed files with 35 additions and 13 deletions
|
@ -1,4 +1,5 @@
|
||||||
use std::hash::{DefaultHasher, Hash, Hasher};
|
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||||
|
use std::net::IpAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use rocket::futures::TryStreamExt;
|
use rocket::futures::TryStreamExt;
|
||||||
|
@ -10,7 +11,7 @@ use sqlx::{query, query_as, Pool, QueryBuilder};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::config::AppConfig;
|
use crate::config::AppConfig;
|
||||||
use crate::consts::ENCRYPTION_ROUNDS;
|
use crate::consts::ENCRYPTION_ROUNDS;
|
||||||
use crate::{SessionData, DB};
|
use crate::{LoginSessionData, SessionData, DB};
|
||||||
use crate::models::user::{UserAuthError, UserModel};
|
use crate::models::user::{UserAuthError, UserModel};
|
||||||
|
|
||||||
pub struct UserManager {
|
pub struct UserManager {
|
||||||
|
@ -80,17 +81,17 @@ impl UserManager {
|
||||||
.map_err(|e| anyhow!(e))
|
.map_err(|e| anyhow!(e))
|
||||||
}
|
}
|
||||||
/// Returns user's id
|
/// Returns user's id
|
||||||
pub async fn create_normal_user(&self, user: CreateUserOptions, plain_password: String) -> Result<String, anyhow::Error> {
|
pub async fn create_normal_user(&self, user: CreateUserOptions, plain_password: String) -> Result<UserModel, anyhow::Error> {
|
||||||
let password = bcrypt::hash(plain_password, ENCRYPTION_ROUNDS)
|
let password = bcrypt::hash(plain_password, ENCRYPTION_ROUNDS)
|
||||||
.map_err(|e| anyhow!(e))?;
|
.map_err(|e| anyhow!(e))?;
|
||||||
let id = Self::generate_id(None);
|
let id = Self::generate_id(None);
|
||||||
self.create_user(id, user, Some(password)).await
|
self.create_user(id, user, Some(password)).await
|
||||||
}
|
}
|
||||||
/// Returns user's id
|
/// Returns user's id
|
||||||
pub async fn create_sso_user(&self, user: CreateUserOptions, id: String) -> Result<String, anyhow::Error> {
|
pub async fn create_sso_user(&self, user: CreateUserOptions, id: String) -> Result<UserModel, anyhow::Error> {
|
||||||
self.create_user(id, user, None).await
|
self.create_user(id, user, None).await
|
||||||
}
|
}
|
||||||
async fn create_user(&self, id: String, user: CreateUserOptions, encrypted_password: Option<String>) -> Result<String, anyhow::Error> {
|
async fn create_user(&self, id: String, user: CreateUserOptions, encrypted_password: Option<String>) -> Result<UserModel, anyhow::Error> {
|
||||||
query!(
|
query!(
|
||||||
"INSERT INTO storage.users (id, name, password, email, username) VALUES ($1, $2, $3, $4, $5)",
|
"INSERT INTO storage.users (id, name, password, email, username) VALUES ($1, $2, $3, $4, $5)",
|
||||||
id,
|
id,
|
||||||
|
@ -101,6 +102,22 @@ impl UserManager {
|
||||||
)
|
)
|
||||||
.execute(&self.pool)
|
.execute(&self.pool)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(id)
|
Ok(UserModel {
|
||||||
|
id,
|
||||||
|
username: user.username,
|
||||||
|
email: user.email,
|
||||||
|
created_at: Default::default(),
|
||||||
|
name: user.name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn login_user(&self, user: UserModel, ip_address: IpAddr, sessions: Session<'_, SessionData>) {
|
||||||
|
sessions.set(SessionData {
|
||||||
|
csrf_token: None,
|
||||||
|
login: Some(LoginSessionData {
|
||||||
|
user,
|
||||||
|
ip_address
|
||||||
|
}),
|
||||||
|
}).await.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -101,7 +101,7 @@ async fn callback_handler(sso: &State<SSOState>, ip: IpAddr, code: String, state
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/auth/sso/cb?<code>&<state>")]
|
#[get("/auth/sso/cb?<code>&<state>")]
|
||||||
pub async fn callback(config: &State<AppConfig>, users: &State<UsersState>, ip: IpAddr, sso: &State<SSOState>, code: String, state: String) -> Result<HackyRedirectBecauseRocketBug, (Status, Template)> {
|
pub async fn callback(sessions: Session<'_, SessionData>, config: &State<AppConfig>, users: &State<UsersState>, ip: IpAddr, sso: &State<SSOState>, code: String, state: String) -> Result<HackyRedirectBecauseRocketBug, (Status, Template)> {
|
||||||
let (userinfo, provider_id, return_to) = callback_handler(sso, ip, code, state).await
|
let (userinfo, provider_id, return_to) = callback_handler(sso, ip, code, state).await
|
||||||
.map_err(|e| (Status::InternalServerError, Template::render("errors/500", context! {
|
.map_err(|e| (Status::InternalServerError, Template::render("errors/500", context! {
|
||||||
error: e.to_string()
|
error: e.to_string()
|
||||||
|
@ -120,7 +120,7 @@ pub async fn callback(config: &State<AppConfig>, users: &State<UsersState>, ip:
|
||||||
error: "Provider did not provide an username"
|
error: "Provider did not provide an username"
|
||||||
})))?.to_string();
|
})))?.to_string();
|
||||||
let search_options = vec![FindUserOption::Id(uid.clone()), FindUserOption::Email(email.clone()), FindUserOption::Username(username.clone())];
|
let search_options = vec![FindUserOption::Id(uid.clone()), FindUserOption::Email(email.clone()), FindUserOption::Username(username.clone())];
|
||||||
let user = users.fetch_user(&search_options).await.map_err(|e|(Status::InternalServerError, Template::render("errors/500", context! {
|
let mut user = users.fetch_user(&search_options).await.map_err(|e|(Status::InternalServerError, Template::render("errors/500", context! {
|
||||||
error: format!("Failed to find user: {}", e)
|
error: format!("Failed to find user: {}", e)
|
||||||
})))?;
|
})))?;
|
||||||
debug!("existing user = {:?}", user);
|
debug!("existing user = {:?}", user);
|
||||||
|
@ -130,13 +130,18 @@ pub async fn callback(config: &State<AppConfig>, users: &State<UsersState>, ip:
|
||||||
error: "No account found linked to oidc provider and account creation has been disabled"
|
error: "No account found linked to oidc provider and account creation has been disabled"
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
let id = users.create_sso_user(CreateUserOptions {
|
user = {
|
||||||
email,
|
let u = users.create_sso_user(CreateUserOptions {
|
||||||
username,
|
email,
|
||||||
name: userinfo.name().unwrap().get(None).map(|s| s.to_string()),
|
username,
|
||||||
}, uid).await.expect("later i fix");
|
name: userinfo.name().unwrap().get(None).map(|s| s.to_string()),
|
||||||
debug!("new user = {}", id);
|
}, uid).await.expect("later i fix");
|
||||||
|
debug!("new user = {}", u.id);
|
||||||
|
Some(u)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
let user = user.unwrap();
|
||||||
|
users.login_user(user, ip, sessions).await;
|
||||||
debug!("user={:?}\nemail={:?}\nname={:?}", userinfo.subject(), userinfo.email(), userinfo.name());
|
debug!("user={:?}\nemail={:?}\nname={:?}", userinfo.subject(), userinfo.email(), userinfo.name());
|
||||||
// TODO: login user to session, prob through UserManager/users
|
// TODO: login user to session, prob through UserManager/users
|
||||||
let return_to = return_to.unwrap_or("/".to_string());
|
let return_to = return_to.unwrap_or("/".to_string());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue