* PUT Service - Create bucket for the user * @param {AuthInfo} authInfo - Instance of AuthInfo class with requester's info * @param {object} request - http request object * @param {object} log - Werelogs logger * @param {function} callback - callback to server * @return {undefined}
(authInfo, request, log, callback)
| 215 | * @return {undefined} |
| 216 | */ |
| 217 | function bucketPut(authInfo, request, log, callback) { |
| 218 | log.debug('processing request', { method: 'bucketPut' }); |
| 219 | |
| 220 | if (authInfo.isRequesterPublicUser()) { |
| 221 | log.debug('operation not available for public user'); |
| 222 | monitoring.promMetrics( |
| 223 | 'PUT', request.bucketName, 403, 'createBucket'); |
| 224 | return callback(errors.AccessDenied); |
| 225 | } |
| 226 | if (!aclUtils.checkGrantHeaderValidity(request.headers)) { |
| 227 | log.trace('invalid acl header'); |
| 228 | monitoring.promMetrics( |
| 229 | 'PUT', request.bucketName, 400, 'createBucket'); |
| 230 | return callback(errors.InvalidArgument); |
| 231 | } |
| 232 | const { bucketName } = request; |
| 233 | |
| 234 | |
| 235 | if (request.bucketName === 'METADATA' |
| 236 | // Note: for this to work with Vault, would need way to set |
| 237 | // canonical ID to http://acs.zenko.io/accounts/service/clueso |
| 238 | && !authInfo.isRequesterThisServiceAccount('clueso')) { |
| 239 | monitoring.promMetrics( |
| 240 | 'PUT', bucketName, 403, 'createBucket'); |
| 241 | return callback(errorInstances.AccessDenied |
| 242 | .customizeDescription('The bucket METADATA is used ' + |
| 243 | 'for internal purposes')); |
| 244 | } |
| 245 | |
| 246 | return waterfall([ |
| 247 | next => _parseXML(request, log, next), |
| 248 | (locationConstraint, next) => { |
| 249 | if (!isRequesterNonAccountUser(authInfo)) { |
| 250 | return next(null, locationConstraint); |
| 251 | } |
| 252 | |
| 253 | const authParams = auth.server.extractParams(request, log, 's3', request.query); |
| 254 | const requestConstantParams = authBucketPut( |
| 255 | authParams, bucketName, locationConstraint, request, authInfo |
| 256 | ); |
| 257 | |
| 258 | return vault.checkPolicies( |
| 259 | requestConstantParams.map(_buildConstantParams), |
| 260 | authInfo.getArn(), |
| 261 | log, |
| 262 | _handleAuthResults(locationConstraint, log, next), |
| 263 | ); |
| 264 | }, |
| 265 | (locationConstraint, next) => createBucket(authInfo, bucketName, |
| 266 | request.headers, locationConstraint, log, (err, previousBucket) => { |
| 267 | // if bucket already existed, gather any relevant cors |
| 268 | // headers |
| 269 | const corsHeaders = collectCorsHeaders( |
| 270 | request.headers.origin, request.method, previousBucket); |
| 271 | if (err) { |
| 272 | return next(err, corsHeaders); |
| 273 | } |
| 274 | pushMetric('createBucket', log, { |