mirror of https://github.com/JSH32/Backpack.git
Store cached OAuth username and add to `AuthMethods`
This commit is contained in:
parent
c4d4a8245c
commit
778c85ad52
|
@ -5,11 +5,20 @@
|
|||
* Enabled authorization methods.
|
||||
*/
|
||||
export type AuthMethods = {
|
||||
discord: boolean;
|
||||
github: boolean;
|
||||
google: boolean;
|
||||
/**
|
||||
* Password authentication.
|
||||
* Cached discord tag.
|
||||
*/
|
||||
discord?: string;
|
||||
/**
|
||||
* Cached github username.
|
||||
*/
|
||||
github?: string;
|
||||
/**
|
||||
* Google username (email before the @).
|
||||
*/
|
||||
google?: string;
|
||||
/**
|
||||
* Is password authentication enabled.
|
||||
*/
|
||||
password: boolean;
|
||||
};
|
||||
|
|
|
@ -44,6 +44,7 @@ impl MigrationTrait for Migration {
|
|||
.enumeration("auth_method", ["password", "google", "github", "discord"])
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(AuthMethods::CachedUsername).text())
|
||||
.col(ColumnDef::new(AuthMethods::Value).text().not_null())
|
||||
.col(
|
||||
ColumnDef::new(AuthMethods::LastAccessed)
|
||||
|
@ -106,15 +107,17 @@ impl MigrationTrait for Migration {
|
|||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(AuthMethods::Table).to_owned())
|
||||
.await?;
|
||||
|
||||
if manager.get_database_backend() == DbBackend::Postgres {
|
||||
manager
|
||||
.drop_type(Type::drop().name(AuthMethod::Type).to_owned())
|
||||
.await?;
|
||||
}
|
||||
|
||||
manager
|
||||
.drop_table(Table::drop().table(AuthMethods::Table).to_owned())
|
||||
.await
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,6 +134,7 @@ enum AuthMethods {
|
|||
Table,
|
||||
Id,
|
||||
UserId,
|
||||
CachedUsername,
|
||||
AuthMethod,
|
||||
Value,
|
||||
LastAccessed,
|
||||
|
|
|
@ -12,6 +12,7 @@ pub struct Model {
|
|||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub user_id: String,
|
||||
pub cached_username: Option<String>,
|
||||
pub auth_method: AuthMethod,
|
||||
#[sea_orm(column_type = "Text")]
|
||||
pub value: String,
|
||||
|
|
|
@ -17,9 +17,12 @@ pub struct AuthRequest {
|
|||
/// Enabled authorization methods.
|
||||
#[derive(Serialize, ToSchema, Default)]
|
||||
pub struct AuthMethods {
|
||||
/// Password authentication.
|
||||
/// Is password authentication enabled.
|
||||
pub password: bool,
|
||||
pub google: bool,
|
||||
pub github: bool,
|
||||
pub discord: bool,
|
||||
/// Google username (email before the @).
|
||||
pub google: Option<String>,
|
||||
/// Cached github username.
|
||||
pub github: Option<String>,
|
||||
/// Cached discord tag.
|
||||
pub discord: Option<String>,
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ async fn create(
|
|||
.create_user(
|
||||
form.0.username,
|
||||
form.0.email,
|
||||
(AuthMethod::Password, form.0.password),
|
||||
(AuthMethod::Password, form.0.password, None),
|
||||
form.0.registration_key,
|
||||
)
|
||||
.await
|
||||
|
|
|
@ -49,10 +49,11 @@ impl AuthMethodService {
|
|||
let mut methods = AuthMethods::default();
|
||||
|
||||
for method in found_methods {
|
||||
// These should all be true except for password.
|
||||
match method.auth_method {
|
||||
AuthMethod::Discord => methods.discord = true,
|
||||
AuthMethod::Github => methods.github = true,
|
||||
AuthMethod::Google => methods.google = true,
|
||||
AuthMethod::Discord => methods.discord = method.cached_username,
|
||||
AuthMethod::Github => methods.github = method.cached_username,
|
||||
AuthMethod::Google => methods.google = method.cached_username,
|
||||
AuthMethod::Password => methods.password = true,
|
||||
};
|
||||
}
|
||||
|
@ -66,6 +67,7 @@ impl AuthMethodService {
|
|||
&self,
|
||||
method: AuthMethod,
|
||||
value: &str,
|
||||
new_cached_username: Option<String>,
|
||||
) -> ServiceResult<Option<users::Model>> {
|
||||
match self
|
||||
.by_condition(
|
||||
|
@ -85,6 +87,8 @@ impl AuthMethodService {
|
|||
// Update `last_accessed`.
|
||||
let mut active_method = v.into_active_model();
|
||||
active_method.last_accessed = Set(Utc::now());
|
||||
active_method.cached_username = Set(new_cached_username);
|
||||
|
||||
active_method
|
||||
.update(self.database.as_ref())
|
||||
.await
|
||||
|
@ -104,6 +108,7 @@ impl AuthMethodService {
|
|||
&self,
|
||||
user_id: &str,
|
||||
method: AuthMethod,
|
||||
cached_username: Option<String>,
|
||||
value: &str,
|
||||
) -> ServiceResult<auth_methods::Model> {
|
||||
match auth_methods::Entity::find()
|
||||
|
@ -126,7 +131,10 @@ impl AuthMethodService {
|
|||
.await
|
||||
.map_err(|e| ServiceError::DbErr(e))
|
||||
}
|
||||
None => self.create_auth_method(user_id, method, value).await,
|
||||
None => {
|
||||
self.create_auth_method(user_id, method, cached_username, value)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,6 +143,7 @@ impl AuthMethodService {
|
|||
&self,
|
||||
user_id: &str,
|
||||
method: AuthMethod,
|
||||
cached_username: Option<String>,
|
||||
value: &str,
|
||||
) -> ServiceResult<auth_methods::Model> {
|
||||
let value = match method {
|
||||
|
@ -145,6 +154,7 @@ impl AuthMethodService {
|
|||
auth_methods::ActiveModel {
|
||||
user_id: Set(user_id.to_owned()),
|
||||
auth_method: Set(method),
|
||||
cached_username: Set(cached_username),
|
||||
value: Set(value),
|
||||
..Default::default()
|
||||
}
|
||||
|
|
|
@ -229,7 +229,11 @@ impl AuthService {
|
|||
// Get a user based on auth method.
|
||||
let user = match self
|
||||
.auth_method_service
|
||||
.get_user_by_value(provider_type.clone().into(), &oauth_data.id)
|
||||
.get_user_by_value(
|
||||
provider_type.clone().into(),
|
||||
&oauth_data.id,
|
||||
Some(oauth_data.username.clone()),
|
||||
)
|
||||
.await?
|
||||
{
|
||||
// User found.
|
||||
|
@ -252,7 +256,12 @@ impl AuthService {
|
|||
{
|
||||
Ok(user) => {
|
||||
self.auth_method_service
|
||||
.create_auth_method(&user.id, provider_type.into(), &oauth_data.id)
|
||||
.create_auth_method(
|
||||
&user.id,
|
||||
provider_type.into(),
|
||||
Some(oauth_data.username),
|
||||
&oauth_data.id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
user
|
||||
|
@ -264,7 +273,11 @@ impl AuthService {
|
|||
.create_user(
|
||||
self.new_unique_username(&oauth_data.username).await?,
|
||||
oauth_data.email,
|
||||
(provider_type.into(), oauth_data.id),
|
||||
(
|
||||
provider_type.into(),
|
||||
oauth_data.id,
|
||||
Some(oauth_data.username),
|
||||
),
|
||||
None,
|
||||
)
|
||||
.await?
|
||||
|
|
|
@ -101,13 +101,13 @@ impl UserService {
|
|||
///
|
||||
/// * `username` - Users username
|
||||
/// * `email` - User email
|
||||
/// * `auth_method` - Authentication method
|
||||
/// * `auth_method` - (method, identifier, optional username)
|
||||
/// * `registration_key` - Registration key. This can always be validated later.
|
||||
pub async fn create_user(
|
||||
&self,
|
||||
username: String,
|
||||
email: String,
|
||||
auth_method: (AuthMethod, String),
|
||||
auth_method: (AuthMethod, String, Option<String>),
|
||||
registration_key: Option<String>,
|
||||
) -> ServiceResult<users::Model> {
|
||||
validate_username(&username)?;
|
||||
|
@ -187,6 +187,7 @@ impl UserService {
|
|||
auth_methods::ActiveModel {
|
||||
user_id: Set(user.id.clone()),
|
||||
auth_method: Set(auth_method.0.clone()),
|
||||
cached_username: Set(auth_method.2),
|
||||
value: Set(method_value),
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -297,7 +298,7 @@ impl UserService {
|
|||
// This is done last since it is a seperate operation and occurs last.
|
||||
if let Some(password) = &password {
|
||||
self.auth_method_service
|
||||
.create_or_set_method(&user.id, AuthMethod::Password, password)
|
||||
.create_or_set_method(&user.id, AuthMethod::Password, None, password)
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue