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#[cfg(feature = "bin")]
20mod storage_proxy_backend;
21
22pub use location_policy::LocalStoragePolicy;
23
24pub trait ProvidesLocalStoragePolicy {
31 fn local_storage_policy(&self) -> &LocalStoragePolicy;
32}
33
34pub trait ProvidesManagedStorageRoot {
43 fn managed_storage_root(&self) -> Option<&str>;
44}
45
46#[derive(Clone)]
47pub struct ServerHandler<Cx> {
48 handler: Arc<ServerHandlerInner<Cx>>,
49}
50
51impl<Cx: Send + Sync + 'static> ServerHandler<Cx> {
52 pub fn try_new_tokio(
53 policy: Arc<dyn Policy<Cx>>,
54 store: Arc<dyn ResourceStore>,
55 ) -> Result<Self> {
56 Self::try_new_tokio_with_coordinator(
57 policy,
58 store,
59 Arc::new(InMemoryCommitCoordinator::default()),
60 )
61 }
62
63 pub fn try_new_tokio_with_coordinator(
68 policy: Arc<dyn Policy<Cx>>,
69 store: Arc<dyn ResourceStore>,
70 commit_coordinator: Arc<dyn CommitCoordinator>,
71 ) -> Result<Self> {
72 let handler = Arc::new(
73 ServerHandlerInner::new(policy.clone(), store.clone())
74 .with_commit_coordinator(commit_coordinator),
75 );
76 Ok(Self { handler })
77 }
78}
79
80impl<Cx: Send + Sync + 'static> ServerHandler<Cx> {
81 pub fn with_local_storage_policy(mut self, policy: impl Into<Arc<LocalStoragePolicy>>) -> Self {
87 let prev = &self.handler;
91 let inner = ServerHandlerInner {
92 policy: prev.policy.clone(),
93 store: prev.store.clone(),
94 commit_coordinator: prev.commit_coordinator.clone(),
95 local_storage_policy: policy.into(),
96 managed_storage_root: prev.managed_storage_root.clone(),
97 };
98 self.handler = Arc::new(inner);
99 self
100 }
101
102 pub fn with_managed_storage_root(mut self, root: Option<impl Into<Arc<str>>>) -> Self {
108 let prev = &self.handler;
109 let inner = ServerHandlerInner {
110 policy: prev.policy.clone(),
111 store: prev.store.clone(),
112 commit_coordinator: prev.commit_coordinator.clone(),
113 local_storage_policy: prev.local_storage_policy.clone(),
114 managed_storage_root: root.map(Into::into),
115 };
116 self.handler = Arc::new(inner);
117 self
118 }
119}
120
121#[derive(Clone)]
122pub struct ServerHandlerInner<Cx> {
123 policy: Arc<dyn Policy<Cx>>,
124 store: Arc<dyn ResourceStore>,
125 commit_coordinator: Arc<dyn CommitCoordinator>,
127 local_storage_policy: Arc<LocalStoragePolicy>,
130 managed_storage_root: Option<Arc<str>>,
134}
135
136impl<Cx: Send + Sync + 'static> ServerHandlerInner<Cx> {
137 pub fn new(policy: Arc<dyn Policy<Cx>>, store: Arc<dyn ResourceStore>) -> Self {
138 Self {
139 policy,
140 store,
141 commit_coordinator: Arc::new(InMemoryCommitCoordinator::default()),
142 local_storage_policy: Arc::new(LocalStoragePolicy::deny_all()),
144 managed_storage_root: None,
146 }
147 }
148
149 pub fn with_local_storage_policy(mut self, policy: impl Into<Arc<LocalStoragePolicy>>) -> Self {
153 self.local_storage_policy = policy.into();
154 self
155 }
156
157 pub fn with_managed_storage_root(mut self, root: Option<impl Into<Arc<str>>>) -> Self {
161 self.managed_storage_root = root.map(Into::into);
162 self
163 }
164
165 pub fn with_commit_coordinator(mut self, coordinator: Arc<dyn CommitCoordinator>) -> Self {
168 self.commit_coordinator = coordinator;
169 self
170 }
171}
172
173impl<Cx: Send + Sync + 'static> ProvidesPolicy<Cx> for ServerHandlerInner<Cx> {
174 fn policy(&self) -> &Arc<dyn Policy<Cx>> {
175 &self.policy
176 }
177}
178
179impl<Cx: Send + Sync + 'static> ProvidesPolicy<Cx> for ServerHandler<Cx> {
180 fn policy(&self) -> &Arc<dyn Policy<Cx>> {
181 &self.handler.policy
182 }
183}
184
185#[async_trait::async_trait]
186impl<Cx: Send + Sync + 'static> Policy<Cx> for ServerHandlerInner<Cx> {
187 async fn authorize(
188 &self,
189 resource: &ResourceIdent,
190 permission: &Permission,
191 context: &Cx,
192 ) -> Result<Decision> {
193 self.policy().authorize(resource, permission, context).await
194 }
195
196 async fn authorize_many(
197 &self,
198 resources: &[ResourceIdent],
199 permission: &Permission,
200 context: &Cx,
201 ) -> Result<Vec<Decision>> {
202 self.policy()
203 .authorize_many(resources, permission, context)
204 .await
205 }
206}
207
208#[async_trait::async_trait]
209impl<Cx: Send + Sync + 'static> Policy<Cx> for ServerHandler<Cx> {
210 async fn authorize(
211 &self,
212 resource: &ResourceIdent,
213 permission: &Permission,
214 context: &Cx,
215 ) -> Result<Decision> {
216 self.handler
217 .policy
218 .authorize(resource, permission, context)
219 .await
220 }
221
222 async fn authorize_many(
223 &self,
224 resources: &[ResourceIdent],
225 permission: &Permission,
226 context: &Cx,
227 ) -> Result<Vec<Decision>> {
228 self.handler
229 .policy
230 .authorize_many(resources, permission, context)
231 .await
232 }
233}
234
235impl<Cx: Send + Sync + 'static> ProvidesResourceStore for ServerHandlerInner<Cx> {
236 fn store(&self) -> &dyn ResourceStore {
237 self.store.as_ref()
238 }
239}
240
241impl<Cx: Send + Sync + 'static> ProvidesResourceStore for ServerHandler<Cx> {
242 fn store(&self) -> &dyn ResourceStore {
243 self.handler.store.as_ref()
244 }
245}
246
247impl<Cx: Send + Sync + 'static> ProvidesCommitCoordinator for ServerHandlerInner<Cx> {
248 fn commit_coordinator(&self) -> &dyn CommitCoordinator {
249 self.commit_coordinator.as_ref()
250 }
251}
252
253impl<Cx: Send + Sync + 'static> ProvidesCommitCoordinator for ServerHandler<Cx> {
254 fn commit_coordinator(&self) -> &dyn CommitCoordinator {
255 self.handler.commit_coordinator.as_ref()
256 }
257}
258
259impl<Cx: Send + Sync + 'static> ProvidesLocalStoragePolicy for ServerHandlerInner<Cx> {
260 fn local_storage_policy(&self) -> &LocalStoragePolicy {
261 self.local_storage_policy.as_ref()
262 }
263}
264
265impl<Cx: Send + Sync + 'static> ProvidesLocalStoragePolicy for ServerHandler<Cx> {
266 fn local_storage_policy(&self) -> &LocalStoragePolicy {
267 self.handler.local_storage_policy.as_ref()
268 }
269}
270
271impl<Cx: Send + Sync + 'static> ProvidesManagedStorageRoot for ServerHandlerInner<Cx> {
272 fn managed_storage_root(&self) -> Option<&str> {
273 self.managed_storage_root.as_deref()
274 }
275}
276
277impl<Cx: Send + Sync + 'static> ProvidesManagedStorageRoot for ServerHandler<Cx> {
278 fn managed_storage_root(&self) -> Option<&str> {
279 self.handler.managed_storage_root.as_deref()
280 }
281}