objectstore_server/auth/
service.rs1use objectstore_service::id::{ObjectContext, ObjectId};
2use objectstore_service::multipart::{
3 AbortMultipartResponse, CompleteMultipartResponse, CompletedPart, InitiateMultipartResponse,
4 ListPartsResponse, PartNumber, UploadId, UploadPartResponse,
5};
6use objectstore_service::service::{DeleteResponse, GetResponse, InsertResponse, MetadataResponse};
7
8use objectstore_service::{ClientStream, StorageService};
9use objectstore_types::auth::Permission;
10use objectstore_types::metadata::Metadata;
11use objectstore_types::range::ByteRange;
12
13use crate::auth::AuthContext;
14use crate::endpoints::common::ApiResult;
15
16#[derive(Debug)]
38pub struct AuthAwareService {
39 service: StorageService,
40 context: AuthContext,
41 enforce: bool,
42}
43
44impl AuthAwareService {
45 pub fn new(service: StorageService, context: AuthContext, enforce: bool) -> Self {
53 Self {
54 service,
55 context,
56 enforce,
57 }
58 }
59
60 pub fn check_permission(&self, perm: Permission, context: &ObjectContext) -> ApiResult<()> {
64 if let Err(error) = self.context.assert_authorized(perm, context) {
65 sentry::with_scope(
66 |s| s.set_tag("perm", perm.to_string()),
67 || error.log(!self.enforce),
68 );
69
70 if self.enforce {
71 return Err(error.into());
72 }
73 }
74
75 Ok(())
76 }
77
78 pub async fn insert_object(
80 &self,
81 context: ObjectContext,
82 key: Option<String>,
83 metadata: Metadata,
84 stream: ClientStream,
85 ) -> ApiResult<InsertResponse> {
86 self.check_permission(Permission::ObjectWrite, &context)?;
87 Ok(self
88 .service
89 .insert_object(context, key, metadata, stream)
90 .await?)
91 }
92
93 pub async fn get_metadata(&self, id: ObjectId) -> ApiResult<MetadataResponse> {
95 self.check_permission(Permission::ObjectRead, id.context())?;
96 Ok(self.service.get_metadata(id).await?)
97 }
98
99 pub async fn get_object(
101 &self,
102 id: ObjectId,
103 range: Option<ByteRange>,
104 ) -> ApiResult<GetResponse> {
105 self.check_permission(Permission::ObjectRead, id.context())?;
106 Ok(self.service.get_object(id, range).await?)
107 }
108
109 pub async fn delete_object(&self, id: ObjectId) -> ApiResult<DeleteResponse> {
111 self.check_permission(Permission::ObjectDelete, id.context())?;
112 Ok(self.service.delete_object(id).await?)
113 }
114
115 pub async fn initiate_multipart(
119 &self,
120 id: ObjectId,
121 metadata: Metadata,
122 ) -> ApiResult<InitiateMultipartResponse> {
123 self.check_permission(Permission::ObjectWrite, id.context())?;
124 Ok(self.service.initiate_multipart(id, metadata).await?)
125 }
126
127 pub async fn upload_part(
129 &self,
130 id: ObjectId,
131 upload_id: UploadId,
132 part_number: PartNumber,
133 content_length: u64,
134 content_md5: Option<String>,
135 body: ClientStream,
136 ) -> ApiResult<UploadPartResponse> {
137 self.check_permission(Permission::ObjectWrite, id.context())?;
138 Ok(self
139 .service
140 .upload_part(
141 id,
142 upload_id,
143 part_number,
144 content_length,
145 content_md5,
146 body,
147 )
148 .await?)
149 }
150
151 pub async fn list_parts(
153 &self,
154 id: ObjectId,
155 upload_id: UploadId,
156 max_parts: Option<u32>,
157 part_number_marker: Option<PartNumber>,
158 ) -> ApiResult<ListPartsResponse> {
159 self.check_permission(Permission::ObjectWrite, id.context())?;
160 Ok(self
161 .service
162 .list_parts(id, upload_id, max_parts, part_number_marker)
163 .await?)
164 }
165
166 pub async fn abort_multipart(
168 &self,
169 id: ObjectId,
170 upload_id: UploadId,
171 ) -> ApiResult<AbortMultipartResponse> {
172 self.check_permission(Permission::ObjectWrite, id.context())?;
173 Ok(self.service.abort_multipart(id, upload_id).await?)
174 }
175
176 pub async fn complete_multipart(
178 &self,
179 id: ObjectId,
180 upload_id: UploadId,
181 parts: Vec<CompletedPart>,
182 ) -> ApiResult<CompleteMultipartResponse> {
183 self.check_permission(Permission::ObjectWrite, id.context())?;
184 Ok(self
185 .service
186 .complete_multipart(id, upload_id, parts)
187 .await?)
188 }
189}