@@ -16,7 +16,7 @@ const {
16
16
} = require ( '../components/utils' ) ;
17
17
const { redactSecrets } = require ( '../db/models/utils' ) ;
18
18
19
- const { bucketService, storageService, userService } = require ( '../services' ) ;
19
+ const { bucketService, storageService, userService, bucketPermissionService } = require ( '../services' ) ;
20
20
21
21
const SERVICE = 'BucketService' ;
22
22
const secretFields = [ 'accessKeyId' , 'secretAccessKey' ] ;
@@ -148,60 +148,61 @@ const controller = {
148
148
* @throws The error encountered upon failure
149
149
*/
150
150
async createBucketChild ( req , res , next ) {
151
- try {
152
- // Get Parent bucket data
153
- const parentBucketId = addDashesToUuid ( req . params . bucketId ) ;
154
- const parentBucket = await bucketService . read ( parentBucketId ) ;
155
-
156
- // Check new child key length
157
- const childKey = joinPath ( stripDelimit ( parentBucket . key ) , stripDelimit ( req . body . subKey ) ) ;
158
- if ( childKey . length > 255 ) {
159
- throw new Problem ( 422 , {
160
- detail : 'New derived key exceeds maximum length of 255' ,
161
- instance : req . originalUrl ,
162
- key : childKey
163
- } ) ;
164
- }
165
151
166
- // Future task: give user MANAGE permission on existing sub-folder (bucket) instead (see above)
167
- // Check for existing bucket collision
168
- const bucketCollision = await bucketService . readUnique ( {
169
- bucket : parentBucket . bucket ,
170
- endpoint : parentBucket . endpoint ,
152
+ // Get Parent bucket data
153
+ const parentBucketId = addDashesToUuid ( req . params . bucketId ) ;
154
+ const parentBucket = await bucketService . read ( parentBucketId ) ;
155
+
156
+ // Check new child key length
157
+ const childKey = joinPath ( stripDelimit ( parentBucket . key ) , stripDelimit ( req . body . subKey ) ) ;
158
+ if ( childKey . length > 255 ) {
159
+ throw new Problem ( 422 , {
160
+ detail : 'New derived key exceeds maximum length of 255' ,
161
+ instance : req . originalUrl ,
171
162
key : childKey
172
- } ) . catch ( ( ) => undefined ) ;
173
-
174
- if ( bucketCollision ) {
175
- throw new Problem ( 409 , {
176
- bucketId : bucketCollision . bucketId ,
177
- detail : 'Requested bucket already exists' ,
178
- instance : req . originalUrl ,
179
- key : childKey
180
- } ) ;
181
- }
163
+ } ) ;
164
+ }
165
+
166
+ const childBucket = {
167
+ bucketName : req . body . bucketName ,
168
+ accessKeyId : parentBucket . accessKeyId ,
169
+ bucket : parentBucket . bucket ,
170
+ endpoint : parentBucket . endpoint ,
171
+ key : childKey ,
172
+ secretAccessKey : parentBucket . secretAccessKey ,
173
+ region : parentBucket . region ?? undefined ,
174
+ active : parentBucket . active
175
+ } ;
176
+
177
+ let response = undefined ;
178
+ try {
182
179
183
180
// Check for credential accessibility/validity
184
- const childBucket = {
185
- bucketName : req . body . bucketName ,
186
- accessKeyId : parentBucket . accessKeyId ,
187
- bucket : parentBucket . bucket ,
188
- endpoint : parentBucket . endpoint ,
189
- key : childKey ,
190
- secretAccessKey : parentBucket . secretAccessKey ,
191
- region : parentBucket . region ?? undefined ,
192
- active : parentBucket . active
193
- } ;
194
181
await controller . _validateCredentials ( childBucket ) ;
195
182
childBucket . userId = await userService . getCurrentUserId ( getCurrentIdentity ( req . currentUser , SYSTEM_USER ) ) ;
196
183
197
- // assign all permissions
198
- childBucket . permCodes = Object . values ( Permissions ) ;
184
+ // get all permissions that user has on parent bucket
185
+ childBucket . permCodes = childBucket . userId !== SYSTEM_USER ?
186
+ ( await bucketPermissionService . searchPermissions ( {
187
+ bucketId : parentBucket . bucketId ,
188
+ userId : childBucket . userId
189
+ } ) ) . map ( p => p . permCode ) : [ ] ;
199
190
200
191
// Create child bucket
201
- const response = await bucketService . create ( childBucket ) ;
202
- res . status ( 201 ) . json ( redactSecrets ( response , secretFields ) ) ;
203
- } catch ( e ) {
204
- next ( errorToProblem ( SERVICE , e ) ) ;
192
+ response = await bucketService . create ( childBucket ) ;
193
+ }
194
+ catch ( e ) {
195
+ // If child bucket exists..
196
+ if ( e instanceof UniqueViolationError ) {
197
+ // Grant permissions if credentials precisely match
198
+ response = await bucketService . checkGrantPermissions ( childBucket ) . catch ( permErr => {
199
+ next ( new Problem ( 403 , { detail : permErr . message , instance : req . originalUrl } ) ) ;
200
+ } ) ;
201
+ } else {
202
+ next ( errorToProblem ( SERVICE , e ) ) ;
203
+ }
204
+ } finally {
205
+ if ( response ) res . status ( 201 ) . json ( redactSecrets ( response , secretFields ) ) ;
205
206
}
206
207
} ,
207
208
0 commit comments