unitycatalog_server/services/
mod.rs1use std::sync::Arc;
2
3use crate::Result;
4use crate::policy::{Decision, Permission, Policy, ProvidesPolicy};
5use crate::store::{ProvidesResourceStore, ResourceStore};
6use unitycatalog_common::models::ResourceIdent;
7use unitycatalog_delta_api::coordinator::{
8 CommitCoordinator, InMemoryCommitCoordinator, ProvidesCommitCoordinator,
9};
10
11pub mod credential_vending;
12mod delta_backend;
13pub mod location;
14pub mod location_policy;
15pub(crate) mod object_store;
16
17pub use location_policy::LocalStoragePolicy;
18
19pub trait ProvidesLocalStoragePolicy {
26 fn local_storage_policy(&self) -> &LocalStoragePolicy;
27}
28
29pub trait ProvidesManagedStorageRoot {
38 fn managed_storage_root(&self) -> Option<&str>;
39}
40
41#[derive(Clone)]
42pub struct ServerHandler<Cx> {
43 handler: Arc<ServerHandlerInner<Cx>>,
44}
45
46impl<Cx: Send + Sync + 'static> ServerHandler<Cx> {
47 pub fn try_new_tokio(
48 policy: Arc<dyn Policy<Cx>>,
49 store: Arc<dyn ResourceStore>,
50 ) -> Result<Self> {
51 Self::try_new_tokio_with_coordinator(
52 policy,
53 store,
54 Arc::new(InMemoryCommitCoordinator::default()),
55 )
56 }
57
58 pub fn try_new_tokio_with_coordinator(
63 policy: Arc<dyn Policy<Cx>>,
64 store: Arc<dyn ResourceStore>,
65 commit_coordinator: Arc<dyn CommitCoordinator>,
66 ) -> Result<Self> {
67 let handler = Arc::new(
68 ServerHandlerInner::new(policy.clone(), store.clone())
69 .with_commit_coordinator(commit_coordinator),
70 );
71 Ok(Self { handler })
72 }
73}
74
75impl<Cx: Send + Sync + 'static> ServerHandler<Cx> {
76 pub fn with_local_storage_policy(mut self, policy: impl Into<Arc<LocalStoragePolicy>>) -> Self {
82 let prev = &self.handler;
86 let inner = ServerHandlerInner {
87 policy: prev.policy.clone(),
88 store: prev.store.clone(),
89 commit_coordinator: prev.commit_coordinator.clone(),
90 local_storage_policy: policy.into(),
91 managed_storage_root: prev.managed_storage_root.clone(),
92 };
93 self.handler = Arc::new(inner);
94 self
95 }
96
97 pub fn with_managed_storage_root(mut self, root: Option<impl Into<Arc<str>>>) -> Self {
103 let prev = &self.handler;
104 let inner = ServerHandlerInner {
105 policy: prev.policy.clone(),
106 store: prev.store.clone(),
107 commit_coordinator: prev.commit_coordinator.clone(),
108 local_storage_policy: prev.local_storage_policy.clone(),
109 managed_storage_root: root.map(Into::into),
110 };
111 self.handler = Arc::new(inner);
112 self
113 }
114}
115
116#[derive(Clone)]
117pub struct ServerHandlerInner<Cx> {
118 policy: Arc<dyn Policy<Cx>>,
119 store: Arc<dyn ResourceStore>,
120 commit_coordinator: Arc<dyn CommitCoordinator>,
122 local_storage_policy: Arc<LocalStoragePolicy>,
125 managed_storage_root: Option<Arc<str>>,
129}
130
131impl<Cx: Send + Sync + 'static> ServerHandlerInner<Cx> {
132 pub fn new(policy: Arc<dyn Policy<Cx>>, store: Arc<dyn ResourceStore>) -> Self {
133 Self {
134 policy,
135 store,
136 commit_coordinator: Arc::new(InMemoryCommitCoordinator::default()),
137 local_storage_policy: Arc::new(LocalStoragePolicy::deny_all()),
139 managed_storage_root: None,
141 }
142 }
143
144 pub fn with_local_storage_policy(mut self, policy: impl Into<Arc<LocalStoragePolicy>>) -> Self {
148 self.local_storage_policy = policy.into();
149 self
150 }
151
152 pub fn with_managed_storage_root(mut self, root: Option<impl Into<Arc<str>>>) -> Self {
156 self.managed_storage_root = root.map(Into::into);
157 self
158 }
159
160 pub fn with_commit_coordinator(mut self, coordinator: Arc<dyn CommitCoordinator>) -> Self {
163 self.commit_coordinator = coordinator;
164 self
165 }
166}
167
168impl<Cx: Send + Sync + 'static> ProvidesPolicy<Cx> for ServerHandlerInner<Cx> {
169 fn policy(&self) -> &Arc<dyn Policy<Cx>> {
170 &self.policy
171 }
172}
173
174impl<Cx: Send + Sync + 'static> ProvidesPolicy<Cx> for ServerHandler<Cx> {
175 fn policy(&self) -> &Arc<dyn Policy<Cx>> {
176 &self.handler.policy
177 }
178}
179
180#[async_trait::async_trait]
181impl<Cx: Send + Sync + 'static> Policy<Cx> for ServerHandlerInner<Cx> {
182 async fn authorize(
183 &self,
184 resource: &ResourceIdent,
185 permission: &Permission,
186 context: &Cx,
187 ) -> Result<Decision> {
188 self.policy().authorize(resource, permission, context).await
189 }
190
191 async fn authorize_many(
192 &self,
193 resources: &[ResourceIdent],
194 permission: &Permission,
195 context: &Cx,
196 ) -> Result<Vec<Decision>> {
197 self.policy()
198 .authorize_many(resources, permission, context)
199 .await
200 }
201}
202
203#[async_trait::async_trait]
204impl<Cx: Send + Sync + 'static> Policy<Cx> for ServerHandler<Cx> {
205 async fn authorize(
206 &self,
207 resource: &ResourceIdent,
208 permission: &Permission,
209 context: &Cx,
210 ) -> Result<Decision> {
211 self.handler
212 .policy
213 .authorize(resource, permission, context)
214 .await
215 }
216
217 async fn authorize_many(
218 &self,
219 resources: &[ResourceIdent],
220 permission: &Permission,
221 context: &Cx,
222 ) -> Result<Vec<Decision>> {
223 self.handler
224 .policy
225 .authorize_many(resources, permission, context)
226 .await
227 }
228}
229
230impl<Cx: Send + Sync + 'static> ProvidesResourceStore for ServerHandlerInner<Cx> {
231 fn store(&self) -> &dyn ResourceStore {
232 self.store.as_ref()
233 }
234}
235
236impl<Cx: Send + Sync + 'static> ProvidesResourceStore for ServerHandler<Cx> {
237 fn store(&self) -> &dyn ResourceStore {
238 self.handler.store.as_ref()
239 }
240}
241
242impl<Cx: Send + Sync + 'static> ProvidesCommitCoordinator for ServerHandlerInner<Cx> {
243 fn commit_coordinator(&self) -> &dyn CommitCoordinator {
244 self.commit_coordinator.as_ref()
245 }
246}
247
248impl<Cx: Send + Sync + 'static> ProvidesCommitCoordinator for ServerHandler<Cx> {
249 fn commit_coordinator(&self) -> &dyn CommitCoordinator {
250 self.handler.commit_coordinator.as_ref()
251 }
252}
253
254impl<Cx: Send + Sync + 'static> ProvidesLocalStoragePolicy for ServerHandlerInner<Cx> {
255 fn local_storage_policy(&self) -> &LocalStoragePolicy {
256 self.local_storage_policy.as_ref()
257 }
258}
259
260impl<Cx: Send + Sync + 'static> ProvidesLocalStoragePolicy for ServerHandler<Cx> {
261 fn local_storage_policy(&self) -> &LocalStoragePolicy {
262 self.handler.local_storage_policy.as_ref()
263 }
264}
265
266impl<Cx: Send + Sync + 'static> ProvidesManagedStorageRoot for ServerHandlerInner<Cx> {
267 fn managed_storage_root(&self) -> Option<&str> {
268 self.managed_storage_root.as_deref()
269 }
270}
271
272impl<Cx: Send + Sync + 'static> ProvidesManagedStorageRoot for ServerHandler<Cx> {
273 fn managed_storage_root(&self) -> Option<&str> {
274 self.handler.managed_storage_root.as_deref()
275 }
276}