Skip to main content

openlark_security/models/
mod.rs

1//! 共享数据模型
2//!
3//! 提供所有安全服务共享的数据模型和类型定义。
4
5use serde::{Deserialize, Serialize};
6
7/// 安全服务配置
8#[derive(Debug, Clone)]
9pub struct SecurityConfig {
10    /// 应用ID
11    pub app_id: String,
12    /// 应用密钥
13    pub app_secret: String,
14    /// 基础URL
15    pub base_url: String,
16}
17
18impl SecurityConfig {
19    /// 创建新的安全配置实例
20    pub fn new(app_id: impl Into<String>, app_secret: impl Into<String>) -> Self {
21        Self {
22            app_id: app_id.into(),
23            app_secret: app_secret.into(),
24            base_url: "https://open.feishu.cn".to_string(),
25        }
26    }
27
28    /// 设置基础URL
29    pub fn with_base_url(mut self, base_url: &str) -> Self {
30        self.base_url = base_url.to_string();
31        self
32    }
33
34    /// 获取应用访问令牌
35    ///
36    /// 使用 openlark-auth 的 AuthTokenProvider 获取真实的 app_access_token
37    pub async fn get_app_access_token(&self) -> crate::SecurityResult<String> {
38        use openlark_auth::AuthTokenProvider;
39        use openlark_core::{
40            auth::{TokenProvider, TokenRequest},
41            config::Config,
42        };
43
44        // 从 SecurityConfig 创建 Config
45        let config = Config::builder()
46            .app_id(&self.app_id)
47            .app_secret(&self.app_secret)
48            .base_url(&self.base_url)
49            .build();
50
51        // 使用 AuthTokenProvider 获取 token
52        let token_provider = AuthTokenProvider::new(config);
53        let token: String = token_provider
54            .get_token(TokenRequest::app())
55            .await
56            .map_err(|e: openlark_core::CoreError| {
57                openlark_core::error::authentication_error(e.to_string())
58            })?;
59
60        Ok(token)
61    }
62}
63
64impl Default for SecurityConfig {
65    fn default() -> Self {
66        Self {
67            app_id: "".to_string(),
68            app_secret: "".to_string(),
69            base_url: "https://open.feishu.cn".to_string(),
70        }
71    }
72}
73
74/// 分页请求基础结构
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct PageRequest {
77    /// 页面大小,默认 20,最大 100
78    pub page_size: Option<i32>,
79    /// 分页标记,第一页不传,后续页面传入上一页返回的 page_token
80    pub page_token: Option<String>,
81}
82
83impl Default for PageRequest {
84    fn default() -> Self {
85        Self {
86            page_size: Some(20),
87            page_token: None,
88        }
89    }
90}
91
92/// 分页响应基础结构
93#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct PageResponse<T> {
95    /// 是否有更多数据
96    pub has_more: bool,
97    /// 分页标记,用于获取下一页数据
98    pub page_token: Option<String>,
99    /// 数据列表
100    pub data: Vec<T>,
101}
102
103/// API 响应基础结构
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct ApiResponse<T> {
106    /// 响应码
107    pub code: i32,
108    /// 响应消息
109    pub msg: String,
110    /// 响应数据
111    pub data: Option<T>,
112}
113
114/// 时间戳类型
115pub type Timestamp = i64;
116
117/// 通用状态枚举
118#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
119#[serde(rename_all = "lowercase")]
120pub enum Status {
121    /// 激活
122    Active,
123    /// 禁用
124    Disabled,
125    /// 待处理
126    Pending,
127    /// 已删除
128    Deleted,
129    /// 已过期
130    Expired,
131}
132
133// 子模块
134pub mod acs;
135pub mod common;
136
137// 重新导出 ACS 相关模型
138// acs 模块显式导出
139pub use acs::{
140    AccessRecord, AccessResult, DeviceBindRuleRequest, DeviceInfo, DeviceStatus, DeviceType,
141    FaceImageInfo, HostInfo, PermissionRuleInfo, PermissionRuleRequest, UserInfo, UserListResponse,
142    UserRequest, VerificationMethod, VisitorInfo, VisitorRequest, VisitorStatus,
143};
144
145// Security & Compliance 相关模型
146pub mod security_and_compliance;
147// security_and_compliance 模块显式导出
148pub use security_and_compliance::{
149    ApplyStatus, ComplianceCheckResult, ComplianceResult, ComplianceRuleType, ComplianceStatus,
150    DeviceApplyRecord, DeviceApplyRecordApproveRequest, DeviceComplianceRule, DeviceRecord,
151    DeviceRecordRequest, DeviceRecordStatus, DeviceRecordUpdateRequest, OpenApiLog,
152    OpenApiLogQueryRequest,
153};
154
155// 重新导出通用模型
156// common 模块显式导出
157pub use common::{
158    BatchOperationError, BatchOperationRequest, BatchOperationResponse, DeviceBase, ExtensionMap,
159    FileUploadResponse, GeoLocation, KeyValue, OperationResponse, PermissionBase, QueryCondition,
160    SortCondition, SortDirection, TimeRange, UserBase,
161};
162
163#[cfg(test)]
164mod tests {
165
166    use serde_json;
167
168    #[test]
169    fn test_serialization_roundtrip() {
170        // 基础序列化测试
171        let json = r#"{"test": "value"}"#;
172        assert!(serde_json::from_str::<serde_json::Value>(json).is_ok());
173    }
174
175    #[test]
176    fn test_deserialization_from_json() {
177        // 基础反序列化测试
178        let json = r#"{"field": "data"}"#;
179        let value: serde_json::Value = serde_json::from_str(json).expect("JSON 反序列化失败");
180        assert_eq!(value["field"], "data");
181    }
182}