@@ -16,7 +16,7 @@ const {
1616} = require ( '../components/utils' ) ;
1717const { redactSecrets } = require ( '../db/models/utils' ) ;
1818
19- const { bucketService, storageService, userService } = require ( '../services' ) ;
19+ const { bucketService, storageService, userService, bucketPermissionService } = require ( '../services' ) ;
2020
2121const SERVICE = 'BucketService' ;
2222const secretFields = [ 'accessKeyId' , 'secretAccessKey' ] ;
@@ -148,60 +148,61 @@ const controller = {
148148 * @throws The error encountered upon failure
149149 */
150150 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- }
165151
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 ,
171162 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 {
182179
183180 // 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- } ;
194181 await controller . _validateCredentials ( childBucket ) ;
195182 childBucket . userId = await userService . getCurrentUserId ( getCurrentIdentity ( req . currentUser , SYSTEM_USER ) ) ;
196183
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 ) : [ ] ;
199190
200191 // 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 ) ) ;
205206 }
206207 } ,
207208
0 commit comments