auth: extract community auth crate
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
use async_trait::async_trait;
|
||||
use crank_core::{
|
||||
AuthenticatedIdentity, IdentityError, IdentityProvider, IdentityProviderKind, LoginOutcome,
|
||||
};
|
||||
use crank_registry::PostgresRegistry;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::hashing::verify_password;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PasswordIdentityProvider {
|
||||
registry: PostgresRegistry,
|
||||
password_pepper: String,
|
||||
}
|
||||
|
||||
impl PasswordIdentityProvider {
|
||||
pub fn new(registry: PostgresRegistry, password_pepper: impl Into<String>) -> Self {
|
||||
Self {
|
||||
registry,
|
||||
password_pepper: password_pepper.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl IdentityProvider for PasswordIdentityProvider {
|
||||
fn id(&self) -> &str {
|
||||
"community-password"
|
||||
}
|
||||
|
||||
fn kind(&self) -> IdentityProviderKind {
|
||||
IdentityProviderKind::Password
|
||||
}
|
||||
|
||||
async fn login_password(
|
||||
&self,
|
||||
payload: crank_core::LoginPayload,
|
||||
) -> Result<LoginOutcome, IdentityError> {
|
||||
let user = self
|
||||
.registry
|
||||
.get_auth_user_by_email(&payload.email)
|
||||
.await
|
||||
.map_err(|error| IdentityError::Internal(error.to_string()))?
|
||||
.ok_or(IdentityError::BadCredentials)?;
|
||||
|
||||
if user.user.status != crank_core::UserStatus::Active {
|
||||
return Err(IdentityError::AccountDisabled);
|
||||
}
|
||||
|
||||
if !verify_password(
|
||||
&payload.password,
|
||||
&self.password_pepper,
|
||||
&user.password_hash,
|
||||
) {
|
||||
debug!(email = %payload.email, "password identity provider rejected credentials");
|
||||
return Err(IdentityError::BadCredentials);
|
||||
}
|
||||
|
||||
let current_workspace_id = self
|
||||
.registry
|
||||
.list_workspaces_for_user(&user.user.id)
|
||||
.await
|
||||
.map_err(|error| IdentityError::Internal(error.to_string()))?
|
||||
.first()
|
||||
.map(|membership| membership.workspace.id.clone());
|
||||
|
||||
Ok(LoginOutcome::Authenticated(AuthenticatedIdentity {
|
||||
user: user.user,
|
||||
memberships: vec![],
|
||||
current_workspace_id,
|
||||
}))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user