unitycatalog_server/api/
recipients.rs1use itertools::Itertools;
2
3use unitycatalog_common::models::ObjectLabel;
4use unitycatalog_common::models::recipients::v1::*;
5use unitycatalog_common::models::{ResourceIdent, ResourceName, ResourceRef};
6
7use super::{RequestContext, SecuredAction};
8use crate::Result;
9pub use crate::codegen::recipients::RecipientHandler;
10use crate::policy::{Permission, Policy, process_resources};
11use crate::store::ResourceStore;
12
13#[async_trait::async_trait]
14impl<T: ResourceStore + Policy<RequestContext>> RecipientHandler<RequestContext> for T {
15 #[tracing::instrument(skip(self, context), fields(resource_name))]
16 async fn create_recipient(
17 &self,
18 request: CreateRecipientRequest,
19 context: RequestContext,
20 ) -> Result<Recipient> {
21 tracing::Span::current().record("resource_name", &request.name);
22 self.check_required(&request, &context).await?;
23 let resource = Recipient {
24 name: request.name,
25 authentication_type: request.authentication_type,
26 comment: request.comment,
27 properties: request.properties,
28 ..Default::default()
29 };
30
31 let info = self.create(resource.into()).await?.0.try_into()?;
40 Ok(info)
41 }
42
43 #[tracing::instrument(skip(self, context), fields(resource_name))]
44 async fn delete_recipient(
45 &self,
46 request: DeleteRecipientRequest,
47 context: RequestContext,
48 ) -> Result<()> {
49 tracing::Span::current().record("resource_name", &request.name);
50 self.check_required(&request, &context).await?;
51 Ok(self.delete(&request.resource()).await?)
52 }
53
54 #[tracing::instrument(skip(self, context), fields(resource_name))]
55 async fn get_recipient(
56 &self,
57 request: GetRecipientRequest,
58 context: RequestContext,
59 ) -> Result<Recipient> {
60 tracing::Span::current().record("resource_name", &request.name);
61 self.check_required(&request, &context).await?;
62 Ok(self.get(&request.resource()).await?.0.try_into()?)
63 }
64
65 #[tracing::instrument(skip(self, context))]
66 async fn list_recipients(
67 &self,
68 request: ListRecipientsRequest,
69 context: RequestContext,
70 ) -> Result<ListRecipientsResponse> {
71 self.check_required(&request, &context).await?;
72 let (mut resources, next_page_token) = self
73 .list(
74 &ObjectLabel::Recipient,
75 None,
76 request.max_results.map(|v| v as usize),
77 request.page_token,
78 )
79 .await?;
80 process_resources(self, &context, &Permission::Read, &mut resources).await?;
81 Ok(ListRecipientsResponse {
82 recipients: resources.into_iter().map(|r| r.try_into()).try_collect()?,
83 next_page_token,
84 ..Default::default()
85 })
86 }
87
88 #[tracing::instrument(skip(self, context), fields(resource_name))]
89 async fn update_recipient(
90 &self,
91 request: UpdateRecipientRequest,
92 context: RequestContext,
93 ) -> Result<Recipient> {
94 tracing::Span::current().record("resource_name", &request.name);
95 self.check_required(&request, &context).await?;
96 let ident = request.resource();
97 let current: Recipient = self.get(&ident).await?.0.try_into()?;
98
99 let updated = Recipient {
107 name: request.new_name.unwrap_or(request.name),
108 owner: request.owner.or(current.owner),
109 comment: request.comment.or(current.comment),
110 properties: if request.properties.is_empty() {
111 current.properties
112 } else {
113 request.properties
114 },
115 ..current
117 };
118
119 Ok(self.update(&ident, updated.into()).await?.0.try_into()?)
120 }
121}
122
123impl SecuredAction for CreateRecipientRequest {
124 fn resource(&self) -> ResourceIdent {
125 ResourceIdent::recipient(ResourceName::new([self.name.as_str()]))
126 }
127
128 fn permission(&self) -> &'static Permission {
129 &Permission::Create
130 }
131}
132
133impl SecuredAction for ListRecipientsRequest {
134 fn resource(&self) -> ResourceIdent {
135 ResourceIdent::recipient(ResourceRef::Undefined)
136 }
137
138 fn permission(&self) -> &'static Permission {
139 &Permission::Read
140 }
141}
142
143impl SecuredAction for GetRecipientRequest {
144 fn resource(&self) -> ResourceIdent {
145 ResourceIdent::recipient(ResourceName::new([self.name.as_str()]))
146 }
147
148 fn permission(&self) -> &'static Permission {
149 &Permission::Read
150 }
151}
152
153impl SecuredAction for UpdateRecipientRequest {
154 fn resource(&self) -> ResourceIdent {
155 ResourceIdent::recipient(ResourceName::new([self.name.as_str()]))
156 }
157
158 fn permission(&self) -> &'static Permission {
159 &Permission::Manage
160 }
161}
162
163impl SecuredAction for DeleteRecipientRequest {
164 fn resource(&self) -> ResourceIdent {
165 ResourceIdent::recipient(ResourceName::new([self.name.as_str()]))
166 }
167
168 fn permission(&self) -> &'static Permission {
169 &Permission::Manage
170 }
171}