1+ //! Helper functions and constants for ZITADEL Actions v3
2+
3+ use serde:: Serialize ;
4+ use serde_json:: Value ;
5+
6+ use crate :: actions:: { ActionResponse , Claim , Metadata } ;
7+
8+ /// Common ZITADEL claim keys
9+ pub mod claims {
10+ /// Resource owner (organization) ID
11+ pub const RESOURCE_OWNER_ID : & str = "urn:zitadel:iam:user:resourceowner:id" ;
12+
13+ /// Resource owner name
14+ pub const RESOURCE_OWNER_NAME : & str = "urn:zitadel:iam:user:resourceowner:name" ;
15+
16+ /// Resource owner primary domain
17+ pub const RESOURCE_OWNER_PRIMARY_DOMAIN : & str = "urn:zitadel:iam:user:resourceowner:primary_domain" ;
18+
19+ /// Project roles
20+ pub const PROJECT_ROLES : & str = "urn:zitadel:iam:org:project:roles" ;
21+
22+ /// Project-specific roles format
23+ pub const PROJECT_ROLES_FORMAT : & str = "urn:zitadel:iam:org:project:%s:roles" ;
24+
25+ /// User metadata
26+ pub const USER_METADATA : & str = "urn:zitadel:iam:user:metadata" ;
27+
28+ /// Action log format
29+ pub const ACTION_LOG_FORMAT : & str = "urn:zitadel:iam:action:%s:log" ;
30+ }
31+
32+ impl ActionResponse {
33+ /// Add a claim to the response
34+ ///
35+ /// # Example
36+ ///
37+ /// ```
38+ /// use zitadel::actions::ActionResponse;
39+ ///
40+ /// let response = ActionResponse::default()
41+ /// .add_claim("custom_claim", "value")
42+ /// .add_claim("roles", vec!["admin", "user"]);
43+ /// ```
44+ pub fn add_claim < K , V > ( mut self , key : K , value : V ) -> Self
45+ where
46+ K : Into < String > ,
47+ V : Serialize ,
48+ {
49+ self . append_claims . push ( Claim {
50+ key : key. into ( ) ,
51+ value : serde_json:: to_value ( value) . unwrap_or ( Value :: Null ) ,
52+ } ) ;
53+ self
54+ }
55+
56+ /// Add user metadata
57+ ///
58+ /// # Example
59+ ///
60+ /// ```
61+ /// use zitadel::actions::ActionResponse;
62+ ///
63+ /// let response = ActionResponse::default()
64+ /// .add_metadata("preference", "dark_mode")
65+ /// .add_metadata("last_login", "2024-01-01");
66+ /// ```
67+ pub fn add_metadata < K , V > ( mut self , key : K , value : V ) -> Self
68+ where
69+ K : Into < String > ,
70+ V : Serialize ,
71+ {
72+ self . set_user_metadata . push ( Metadata {
73+ key : key. into ( ) ,
74+ value : serde_json:: to_value ( value) . unwrap_or ( Value :: Null ) ,
75+ } ) ;
76+ self
77+ }
78+
79+ /// Add a log entry
80+ ///
81+ /// Log entries are added to the token as an array under a special claim key.
82+ ///
83+ /// # Example
84+ ///
85+ /// ```
86+ /// use zitadel::actions::ActionResponse;
87+ ///
88+ /// let response = ActionResponse::default()
89+ /// .add_log("Custom claim added successfully")
90+ /// .add_log("User verified");
91+ /// ```
92+ pub fn add_log < S > ( mut self , message : S ) -> Self
93+ where
94+ S : Into < String > ,
95+ {
96+ self . append_log_claims . push ( message. into ( ) ) ;
97+ self
98+ }
99+
100+ /// Check if the response is empty (no modifications)
101+ pub fn is_empty ( & self ) -> bool {
102+ self . append_claims . is_empty ( )
103+ && self . set_user_metadata . is_empty ( )
104+ && self . append_log_claims . is_empty ( )
105+ }
106+
107+ /// Create a response with a single claim
108+ pub fn with_claim < K , V > ( key : K , value : V ) -> Self
109+ where
110+ K : Into < String > ,
111+ V : Serialize ,
112+ {
113+ Self :: default ( ) . add_claim ( key, value)
114+ }
115+
116+ /// Create a response with a single metadata entry
117+ pub fn with_metadata < K , V > ( key : K , value : V ) -> Self
118+ where
119+ K : Into < String > ,
120+ V : Serialize ,
121+ {
122+ Self :: default ( ) . add_metadata ( key, value)
123+ }
124+ }
125+
126+ /// Helper to create a claim
127+ pub fn claim < K , V > ( key : K , value : V ) -> Claim
128+ where
129+ K : Into < String > ,
130+ V : Serialize ,
131+ {
132+ Claim {
133+ key : key. into ( ) ,
134+ value : serde_json:: to_value ( value) . unwrap_or ( Value :: Null ) ,
135+ }
136+ }
137+
138+ /// Helper to create metadata
139+ pub fn metadata < K , V > ( key : K , value : V ) -> Metadata
140+ where
141+ K : Into < String > ,
142+ V : Serialize ,
143+ {
144+ Metadata {
145+ key : key. into ( ) ,
146+ value : serde_json:: to_value ( value) . unwrap_or ( Value :: Null ) ,
147+ }
148+ }
149+
150+ #[ cfg( test) ]
151+ mod tests {
152+ use super :: * ;
153+
154+ #[ test]
155+ fn test_response_builder ( ) {
156+ let response = ActionResponse :: default ( )
157+ . add_claim ( "test" , "value" )
158+ . add_metadata ( "key" , 123 )
159+ . add_log ( "Test log" ) ;
160+
161+ assert_eq ! ( response. append_claims. len( ) , 1 ) ;
162+ assert_eq ! ( response. set_user_metadata. len( ) , 1 ) ;
163+ assert_eq ! ( response. append_log_claims. len( ) , 1 ) ;
164+ }
165+
166+ #[ test]
167+ fn test_empty_response ( ) {
168+ let response = ActionResponse :: default ( ) ;
169+ assert ! ( response. is_empty( ) ) ;
170+
171+ let response = response. add_claim ( "test" , "value" ) ;
172+ assert ! ( !response. is_empty( ) ) ;
173+ }
174+ }
0 commit comments