@@ -14,6 +14,7 @@ const http_utils = require('../../util/http_utils');
1414const signature_utils = require ( '../../util/signature_utils' ) ;
1515const config = require ( '../../../config' ) ;
1616const s3_utils = require ( './s3_utils' ) ;
17+ const { _create_detailed_message_for_access_in_s3 } = require ( '../iam/iam_utils' ) ; // authorize_request for IAM policy
1718
1819const S3_MAX_BODY_LEN = 4 * 1024 * 1024 ;
1920
@@ -330,7 +331,7 @@ async function authorize_request_policy(req) {
330331 throw new S3Error ( S3Error . AccessDenied ) ;
331332}
332333
333- // TODO - move the function and throw message error with details
334+ // TODO - move the function
334335async function authorize_request_iam_policy ( req ) {
335336 const auth_token = req . object_sdk . get_auth_token ( ) ;
336337 const is_anonymous = ! ( auth_token && auth_token . access_key ) ;
@@ -340,11 +341,12 @@ async function authorize_request_iam_policy(req) {
340341 const is_iam_user = account . owner !== undefined ;
341342 if ( ! is_iam_user ) return ; // IAM policy is only on IAM users (account root user is authorized here)
342343
343- const resource_arn = _get_arn_from_req_path ( req ) ;
344+ const resource_arn = _get_arn_from_req_path ( req ) || '*' ; // special case for list all buckets in an account
344345 const method = _get_method_from_req ( req ) ;
345346 const iam_policies = account . iam_user_policies || [ ] ;
346347 if ( iam_policies . length === 0 && req . object_sdk . nsfs_config_root ) return ; // We do not have IAM policies in NC yet
347348
349+ const requesting_account = req . object_sdk . requesting_account ;
348350 // parallel policy check
349351 const promises = [ ] ;
350352 for ( const iam_policy of iam_policies ) {
@@ -358,14 +360,20 @@ async function authorize_request_iam_policy(req) {
358360 const permission_result = await Promise . all ( promises ) ;
359361 let has_allow_permission = false ;
360362 for ( const permission of permission_result ) {
361- if ( permission === "DENY" ) throw new S3Error ( S3Error . AccessDenied ) ;
363+ if ( permission === "DENY" ) _throw_iam_access_denied_error_for_s3_operation ( requesting_account , method , resource_arn ) ;
362364 if ( permission === "ALLOW" ) {
363365 has_allow_permission = true ;
364366 }
365367 }
366368 if ( has_allow_permission ) return ;
367369 dbg . log1 ( 'authorize_request_iam_policy: user have inline policies but none of them matched the method' ) ;
368- throw new S3Error ( S3Error . AccessDenied ) ;
370+ _throw_iam_access_denied_error_for_s3_operation ( requesting_account , method , resource_arn ) ;
371+ }
372+
373+ function _throw_iam_access_denied_error_for_s3_operation ( requesting_account , method , resource_arn ) {
374+ const message_with_details = _create_detailed_message_for_access_in_s3 ( requesting_account , method , resource_arn ) ;
375+ const { code, http_code } = S3Error . AccessDenied ;
376+ throw new S3Error ( { code, message : message_with_details , http_code} ) ;
369377}
370378
371379async function authorize_anonymous_access ( s3_policy , method , arn_path , req , public_access_block ) {
@@ -398,6 +406,7 @@ function _get_method_from_req(req) {
398406}
399407
400408function _get_arn_from_req_path ( req ) {
409+ if ( ! req . params . bucket ) return ;
401410 const bucket = req . params . bucket ;
402411 const key = req . params . key ;
403412 let arn_path = `arn:aws:s3:::${ bucket } ` ;
0 commit comments