objectstore_server/auth/
service.rs1use objectstore_service::backend::common::{ExpiryUpdate, SetExpiryResponse};
2use objectstore_service::id::{ObjectContext, ObjectId};
3use objectstore_service::service::{
4 CreateUploadSessionResponse, DeleteResponse, GetResponse, InsertResponse, MetadataResponse,
5};
6
7use objectstore_service::{ClientStream, StorageService};
8use objectstore_types::auth::Permission;
9use objectstore_types::metadata::Metadata;
10use objectstore_types::range::ByteRange;
11use objectstore_types::resumable::{SessionToken, UploadProgress};
12use objectstore_types::time::Timestamp;
13
14use crate::auth::AuthContext;
15use crate::endpoints::common::ApiResult;
16
17#[derive(Debug)]
43pub struct AuthAwareService {
44 service: StorageService,
45 context: AuthContext,
46 enforce: bool,
47}
48
49impl AuthAwareService {
50 pub fn new(service: StorageService, context: AuthContext, enforce: bool) -> Self {
58 Self {
59 service,
60 context,
61 enforce,
62 }
63 }
64
65 pub fn check_permission(&self, perm: Permission, context: &ObjectContext) -> ApiResult<()> {
69 if let Err(error) = self.context.assert_authorized(perm, context) {
70 sentry::with_scope(
71 |s| s.set_tag("perm", perm.to_string()),
72 || error.log(!self.enforce),
73 );
74
75 if self.enforce {
76 return Err(error.into());
77 }
78 }
79
80 Ok(())
81 }
82
83 pub async fn insert_object(
85 &self,
86 context: ObjectContext,
87 key: Option<String>,
88 metadata: Metadata,
89 stream: ClientStream,
90 access_time: Timestamp,
91 ) -> ApiResult<InsertResponse> {
92 self.check_permission(Permission::ObjectWrite, &context)?;
93 Ok(self
94 .service
95 .insert_object(context, key, metadata, stream, access_time)
96 .await?)
97 }
98
99 pub async fn get_metadata(
101 &self,
102 id: ObjectId,
103 access_time: Timestamp,
104 ) -> ApiResult<MetadataResponse> {
105 self.check_permission(Permission::ObjectRead, id.context())?;
106 Ok(self.service.get_metadata(id, access_time).await?)
107 }
108
109 pub async fn set_expiry(
111 &self,
112 id: ObjectId,
113 target: ExpiryUpdate,
114 access_time: Timestamp,
115 ) -> ApiResult<SetExpiryResponse> {
116 self.check_permission(Permission::ObjectWrite, id.context())?;
117 Ok(self.service.set_expiry(id, target, access_time).await?)
118 }
119
120 pub async fn get_object(
122 &self,
123 id: ObjectId,
124 access_time: Timestamp,
125 range: Option<ByteRange>,
126 ) -> ApiResult<GetResponse> {
127 self.check_permission(Permission::ObjectRead, id.context())?;
128 Ok(self.service.get_object(id, access_time, range).await?)
129 }
130
131 pub async fn delete_object(
133 &self,
134 id: ObjectId,
135 access_time: Timestamp,
136 ) -> ApiResult<DeleteResponse> {
137 self.check_permission(Permission::ObjectDelete, id.context())?;
138 Ok(self.service.delete_object(id, access_time).await?)
139 }
140
141 pub async fn create_upload_session(
145 &self,
146 id: ObjectId,
147 metadata: Metadata,
148 total_length: u64,
149 ) -> ApiResult<Option<CreateUploadSessionResponse>> {
150 self.check_permission(Permission::ObjectWrite, id.context())?;
151 Ok(self
152 .service
153 .create_upload_session(id, metadata, total_length)
154 .await?)
155 }
156
157 pub async fn put_chunk(
159 &self,
160 id: ObjectId,
161 token: SessionToken,
162 offset: u64,
163 content_length: u64,
164 body: ClientStream,
165 ) -> ApiResult<UploadProgress> {
166 self.check_permission(Permission::ObjectWrite, id.context())?;
167 Ok(self
168 .service
169 .put_chunk(id, token, offset, content_length, body)
170 .await?)
171 }
172
173 pub async fn upload_offset(
175 &self,
176 id: ObjectId,
177 token: SessionToken,
178 ) -> ApiResult<UploadProgress> {
179 self.check_permission(Permission::ObjectWrite, id.context())?;
181 Ok(self.service.upload_offset(id, token).await?)
182 }
183
184 pub async fn cancel_upload(&self, id: ObjectId, token: SessionToken) -> ApiResult<()> {
186 self.check_permission(Permission::ObjectWrite, id.context())?;
188 Ok(self.service.cancel_upload(id, token).await?)
189 }
190}