Skip to main content

sa_token_core/stp_interface/
storage.rs

1// Author: 金书记 | Author: Jin Shuji
2//
3//! Storage-Backed Default Data Source | 基于存储的默认数据源
4//!
5//! ## 为什么需要这个薄包装
6//!
7//! 修复 B2-2 后 `GrantRepo` 已不认识 `StpInterface`,本类型看似只是它的转发层。
8//! 但它承担了一个关键的设计职责:让「框架默认行为」也表达为一个 `StpInterface`,
9//! 于是 [`crate::service::AuthzService`] 的读路径面对的永远是**一个** trait 对象,
10//! 不需要在十几个读方法里各写一遍 `if let Some(iface) = ... else { repo }` 分支。
11//!
12//! ## Why this thin wrapper exists
13//!
14//! After the B2-2 fix, `GrantRepo` no longer knows about `StpInterface`, so this
15//! type looks like a mere forwarder. Its real job is to express the *default*
16//! behaviour as a `StpInterface` too, letting `AuthzService` always talk to a
17//! single trait object instead of repeating an `Option` branch across a dozen
18//! read methods.
19
20use std::sync::Arc;
21
22use async_trait::async_trait;
23
24use crate::error::SaTokenResult;
25use crate::repository::GrantRepo;
26use crate::stp_interface::StpInterface;
27
28/// 基于 storage 的默认 `StpInterface` 实现 | Default storage-backed `StpInterface`
29pub struct StorageStpInterface {
30    grant_repo: Arc<GrantRepo>,
31}
32
33impl std::fmt::Debug for StorageStpInterface {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        f.debug_struct("StorageStpInterface").finish()
36    }
37}
38
39impl StorageStpInterface {
40    /// 由授权仓储构造 | Build from the grant repository
41    pub fn new(grant_repo: Arc<GrantRepo>) -> Self {
42        Self { grant_repo }
43    }
44
45    /// 底层仓储引用 | Underlying repository reference
46    pub fn grant_repo(&self) -> &Arc<GrantRepo> {
47        &self.grant_repo
48    }
49}
50
51#[async_trait]
52impl StpInterface for StorageStpInterface {
53    async fn get_permission_list(
54        &self,
55        login_id: &str,
56        login_type: &str,
57    ) -> SaTokenResult<Vec<String>> {
58        self.grant_repo.get_permissions(login_type, login_id).await
59    }
60
61    async fn get_role_list(&self, login_id: &str, login_type: &str) -> SaTokenResult<Vec<String>> {
62        self.grant_repo.get_roles(login_type, login_id).await
63    }
64
65    /// 读写同源,故接受框架写入 | Reads and writes share storage, so writes are accepted
66    fn is_writable(&self) -> bool {
67        true
68    }
69}