Files
crank/crates/crank-community-auth/src/password_provider.rs
T
bsodfather 0e8f1ca03a
CI / Rust Checks (push) Failing after 4m28s
CI / UI Checks (push) Has been skipped
CI / Frontend E2E (push) Has been skipped
CI / Community Image Smoke (push) Has been skipped
CI / Deploy (push) Has been skipped
наблюдаемость: завершить базовый контур Community
Добавить структурированные журналы, метрики, трассировку и безопасный канал критических ошибок. Усилить границы рантайма, тесты, проверку зависимостей и сценарии развёртывания.
2026-07-31 01:01:14 +03:00

78 lines
2.1 KiB
Rust

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!(
name: "auth.password.rejected",
identity_provider = "password",
"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,
}))
}
}