(clientIP, request, response, log)
| 28 | } |
| 29 | |
| 30 | function routeMetadata(clientIP, request, response, log) { |
| 31 | // Attach the apiMethod method to the request, so it can used by monitoring in the server |
| 32 | // eslint-disable-next-line no-param-reassign |
| 33 | request.apiMethod = 'routeMetadata'; |
| 34 | |
| 35 | const { bootstrap } = config.bucketd; |
| 36 | if (bootstrap.length === 0) { |
| 37 | log.debug('cloudserver is not configured with bucketd', { |
| 38 | bucketdConfig: config.bucketd, |
| 39 | }); |
| 40 | return responseJSONBody(errors.ServiceUnavailable, null, response, log); |
| 41 | } |
| 42 | log.debug('routing request', { method: 'routeMetadata' }); |
| 43 | log.addDefaultFields({ clientIP, httpMethod: request.method }); |
| 44 | _normalizeMetadataRequest(request); |
| 45 | |
| 46 | // restrict access to only routes ending in bucket, log or id |
| 47 | const { resourceType, subResource } = request; |
| 48 | if (resourceType === 'admin' |
| 49 | && !['bucket', 'log', 'id'].includes(subResource)) { |
| 50 | return responseJSONBody(errors.NotImplemented, null, response, log); |
| 51 | } |
| 52 | const ip = requestUtils.getClientIp(request, config); |
| 53 | const isSecure = requestUtils.getHttpProtocolSecurity(request, config); |
| 54 | const requestContexts = [new RequestContext(request.headers, request.query, |
| 55 | request.generalResource, request.specificResource, ip, |
| 56 | isSecure, request.resourceType, 'metadata')]; |
| 57 | return waterfall([ |
| 58 | next => auth.server.doAuth(request, log, (err, userInfo, authRes) => { |
| 59 | if (err) { |
| 60 | log.debug('authentication error', { |
| 61 | error: err, |
| 62 | method: request.method, |
| 63 | bucketName: request.bucketName, |
| 64 | objectKey: request.objectKey, |
| 65 | }); |
| 66 | return next(err); |
| 67 | } |
| 68 | // authRes is not defined for account credentials |
| 69 | if (authRes && !authRes[0].isAllowed) { |
| 70 | return next(errors.AccessDenied); |
| 71 | } |
| 72 | return next(null, userInfo); |
| 73 | }, 's3', requestContexts), |
| 74 | (userInfo, next) => { |
| 75 | if (userInfo.getCanonicalID() === constants.publicId) { |
| 76 | log.debug('unauthenticated access to API routes', { |
| 77 | method: request.method, |
| 78 | bucketName: request.bucketName, |
| 79 | objectKey: request.objectKey, |
| 80 | }); |
| 81 | return next(errors.AccessDenied); |
| 82 | } |
| 83 | const { url } = request; |
| 84 | const path = url.startsWith('/_/metadata/admin') ? |
| 85 | url.replace('/_/metadata/admin/', '/_/') : |
| 86 | url.replace('/_/metadata/', '/'); |
| 87 | // bucketd is always configured on the loopback interface in s3c |
nothing calls this directly
no test coverage detected