1- use anyhow:: Error ;
1+ use std:: fmt:: { Debug , Display } ;
2+
23use async_trait:: async_trait;
4+ use http:: StatusCode ;
35use permit_client_rs:: {
46 apis:: {
57 resource_instances_api:: { create_resource_instance, delete_resource_instance} ,
68 role_assignments_api:: { assign_role, unassign_role} ,
79 users_api:: { create_user, delete_user, get_user} ,
10+ Error as PermitClientError ,
811 } ,
912 models:: {
1013 ResourceInstanceCreate , RoleAssignmentCreate , RoleAssignmentRemove , UserCreate , UserRead ,
@@ -17,6 +20,7 @@ use permit_pdp_client_rs::{
1720 } ,
1821 data_updater_api:: trigger_policy_data_update_data_updater_trigger_post,
1922 policy_updater_api:: trigger_policy_update_policy_updater_trigger_post,
23+ Error as PermitPDPClientError ,
2024 } ,
2125 models:: { AuthorizationQuery , Resource , User , UserPermissionsQuery , UserPermissionsResult } ,
2226} ;
@@ -143,7 +147,7 @@ impl PermissionsDal for Client {
143147 }
144148
145149 async fn create_project ( & self , user_id : & str , project_id : & str ) -> Result < ( ) , Error > {
146- create_resource_instance (
150+ if let Err ( e ) = create_resource_instance (
147151 & self . api ,
148152 & self . proj_id ,
149153 & self . env_id ,
@@ -154,7 +158,18 @@ impl PermissionsDal for Client {
154158 attributes : None ,
155159 } ,
156160 )
157- . await ?;
161+ . await
162+ {
163+ // Early return all errors except 409's (project already exists)
164+ let e: Error = e. into ( ) ;
165+ if let Error :: ResponseError ( ref re) = e {
166+ if re. status != StatusCode :: CONFLICT {
167+ return Err ( e) ;
168+ }
169+ } else {
170+ return Err ( e) ;
171+ }
172+ }
158173
159174 self . assign_resource_role ( user_id, format ! ( "Project:{project_id}" ) , "admin" )
160175 . await ?;
@@ -492,7 +507,7 @@ impl Client {
492507 }
493508}
494509
495- // #[cfg(feature = "admin")]
510+ /// Higher level management methods. Use with care.
496511mod admin {
497512 use permit_client_rs:: {
498513 apis:: environments_api:: copy_environment,
@@ -505,7 +520,8 @@ mod admin {
505520 use super :: * ;
506521
507522 impl Client {
508- /// Copy and overwrite the policies of one env to another existing one
523+ /// Copy and overwrite a permit env's policies to another env.
524+ /// Requires a project level API key.
509525 pub async fn copy_environment ( & self , target_env : & str ) -> Result < ( ) , Error > {
510526 copy_environment (
511527 & self . api ,
@@ -543,3 +559,59 @@ mod admin {
543559 }
544560 }
545561}
562+
563+ /// Dumbed down and unified version of the client's errors to get rid of the genereic <T>
564+ #[ derive( thiserror:: Error , Debug ) ]
565+ pub enum Error {
566+ #[ error( "reqwest error: {0}" ) ]
567+ Reqwest ( reqwest:: Error ) ,
568+ #[ error( "serde error: {0}" ) ]
569+ Serde ( serde_json:: Error ) ,
570+ #[ error( "io error: {0}" ) ]
571+ Io ( std:: io:: Error ) ,
572+ #[ error( "response error: {0}" ) ]
573+ ResponseError ( ResponseContent ) ,
574+ }
575+ #[ derive( Debug ) ]
576+ pub struct ResponseContent {
577+ pub status : reqwest:: StatusCode ,
578+ pub content : String ,
579+ pub entity : String ,
580+ }
581+ impl Display for ResponseContent {
582+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
583+ write ! (
584+ f,
585+ "status: {}, content: {}, entity: {}" ,
586+ self . status, self . content, self . entity
587+ )
588+ }
589+ }
590+ impl < T : Debug > From < PermitClientError < T > > for Error {
591+ fn from ( value : PermitClientError < T > ) -> Self {
592+ match value {
593+ PermitClientError :: Reqwest ( e) => Self :: Reqwest ( e) ,
594+ PermitClientError :: Serde ( e) => Self :: Serde ( e) ,
595+ PermitClientError :: Io ( e) => Self :: Io ( e) ,
596+ PermitClientError :: ResponseError ( e) => Self :: ResponseError ( ResponseContent {
597+ status : e. status ,
598+ content : e. content ,
599+ entity : format ! ( "{:?}" , e. entity) ,
600+ } ) ,
601+ }
602+ }
603+ }
604+ impl < T : Debug > From < PermitPDPClientError < T > > for Error {
605+ fn from ( value : PermitPDPClientError < T > ) -> Self {
606+ match value {
607+ PermitPDPClientError :: Reqwest ( e) => Self :: Reqwest ( e) ,
608+ PermitPDPClientError :: Serde ( e) => Self :: Serde ( e) ,
609+ PermitPDPClientError :: Io ( e) => Self :: Io ( e) ,
610+ PermitPDPClientError :: ResponseError ( e) => Self :: ResponseError ( ResponseContent {
611+ status : e. status ,
612+ content : e. content ,
613+ entity : format ! ( "{:?}" , e. entity) ,
614+ } ) ,
615+ }
616+ }
617+ }
0 commit comments