Skip to content
Clone
main
82 lines 2.7 KB Rust
use crate::errors::{AuthError, AuthResult};
use crate::services::AuthService;
use crate::session::{Session, SessionKey, SessionStore};
impl AuthService {
/// 把 KenApi 会话键(session cookie 的值)解析成内部 RPC 使用的主体。
pub async fn resolve_internal_session(
&self,
credential: &str,
request_id: &str,
) -> AuthResult<proto::internal::v1::SessionPrincipal> {
let key =
SessionKey::try_from(credential.to_owned()).map_err(|_| AuthError::Unauthenticated)?;
let Some((state, _ttl)) = self.sessions.load(&key).await? else {
return Err(AuthError::Unauthenticated);
};
// Session 内部是 Rc<RefCell<...>>(非 Send):先同步取完字段再 await。
let (user_id, security_version, auth_session_id) = {
let session = Session::from_state(state);
(
session.uid().ok_or(AuthError::Unauthenticated)?,
session
.security_version()?
.ok_or(AuthError::Unauthenticated)?,
session.session_id().ok_or(AuthError::Unauthenticated)?,
)
};
let (user, mfa_verified) = self
.accounts
.check_session(
user_id,
security_version,
&auth_session_id,
Some(request_id),
)
.await?;
Ok(principal_of(
&user,
security_version,
auth_session_id,
mfa_verified,
))
}
/// 信封身份的权威复核:用户仍有效且安全版本一致。
pub async fn attest_internal_identity(
&self,
user_id: i64,
security_version: i64,
_request_id: &str,
) -> AuthResult<proto::internal::v1::SessionPrincipal> {
if user_id <= 0 || security_version <= 0 {
return Err(AuthError::Unauthenticated);
}
let user = self.accounts.user(user_id).await?;
if user.security_version != security_version as i32 {
return Err(AuthError::Unauthenticated);
}
Ok(principal_of(
&user,
user.security_version,
String::new(),
false,
))
}
}
fn principal_of(
user: &crate::models::users::users::Model,
security_version: i32,
session_id: String,
mfa_verified: bool,
) -> proto::internal::v1::SessionPrincipal {
proto::internal::v1::SessionPrincipal {
user_id: user.id,
session_id,
security_version: i64::from(security_version),
scopes: vec!["event".to_string()],
mfa_verified,
expires_at_unix_ms: 0,
}
}