Skip to main content

zlayer_types/api/
permissions.rs

1//! Permission grant/revoke/list API DTOs.
2
3use serde::{Deserialize, Serialize};
4use utoipa::{IntoParams, ToSchema};
5
6use crate::storage::{PermissionLevel, SubjectKind};
7
8/// Query parameters for `GET /api/v1/permissions`.
9#[derive(Debug, Deserialize, IntoParams)]
10pub struct ListPermissionsQuery {
11    /// Filter by user id.
12    #[serde(default)]
13    pub user: Option<String>,
14    /// Filter by group id.
15    #[serde(default)]
16    pub group: Option<String>,
17}
18
19/// Query parameters for `GET /api/v1/permissions/by-resource`.
20#[derive(Debug, Deserialize, IntoParams)]
21pub struct ListByResourceQuery {
22    /// Resource kind (e.g. `"environment"`).
23    pub kind: String,
24    /// Specific resource id. Omit for wildcard grants only.
25    #[serde(default)]
26    pub id: Option<String>,
27}
28
29/// Body for `POST /api/v1/permissions`.
30#[derive(Debug, Serialize, Deserialize, ToSchema)]
31pub struct GrantPermissionRequest {
32    /// Whether the subject is a user or a group.
33    pub subject_kind: SubjectKind,
34    /// The user or group id.
35    pub subject_id: String,
36    /// The kind of resource (e.g. `"deployment"`, `"project"`, `"secret"`).
37    pub resource_kind: String,
38    /// A specific resource id, or omit for a wildcard (all resources of that kind).
39    #[serde(default)]
40    pub resource_id: Option<String>,
41    /// The access level to grant.
42    pub level: PermissionLevel,
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn test_grant_permission_request_deserialize() {
51        let json = r#"{
52            "subject_kind": "user",
53            "subject_id": "u-1",
54            "resource_kind": "deployment",
55            "resource_id": "d-1",
56            "level": "write"
57        }"#;
58        let req: GrantPermissionRequest = serde_json::from_str(json).unwrap();
59        assert_eq!(req.subject_kind, SubjectKind::User);
60        assert_eq!(req.subject_id, "u-1");
61        assert_eq!(req.resource_kind, "deployment");
62        assert_eq!(req.resource_id.as_deref(), Some("d-1"));
63        assert_eq!(req.level, PermissionLevel::Write);
64    }
65
66    #[test]
67    fn test_grant_permission_request_wildcard() {
68        let json = r#"{
69            "subject_kind": "group",
70            "subject_id": "g-1",
71            "resource_kind": "project",
72            "level": "read"
73        }"#;
74        let req: GrantPermissionRequest = serde_json::from_str(json).unwrap();
75        assert_eq!(req.subject_kind, SubjectKind::Group);
76        assert!(req.resource_id.is_none());
77        assert_eq!(req.level, PermissionLevel::Read);
78    }
79
80    #[test]
81    fn test_list_permissions_query_user() {
82        let q: ListPermissionsQuery = serde_json::from_str(r#"{"user": "u-1"}"#).unwrap();
83        assert_eq!(q.user.as_deref(), Some("u-1"));
84        assert!(q.group.is_none());
85    }
86
87    #[test]
88    fn test_list_permissions_query_group() {
89        let q: ListPermissionsQuery = serde_json::from_str(r#"{"group": "g-1"}"#).unwrap();
90        assert!(q.user.is_none());
91        assert_eq!(q.group.as_deref(), Some("g-1"));
92    }
93}