From 000b8bd5962643940c6c7b21f703130f3c18deaf Mon Sep 17 00:00:00 2001 From: Will Toozs Date: Fri, 8 Dec 2023 17:05:25 +0100 Subject: [PATCH] fixup: add to structures --- lib/policyEvaluator/RequestContext.ts | 32 ++- lib/policyEvaluator/utils/conditions.ts | 302 ++++++++++++------------ 2 files changed, 177 insertions(+), 157 deletions(-) diff --git a/lib/policyEvaluator/RequestContext.ts b/lib/policyEvaluator/RequestContext.ts index 2f5996a22..47ee1b04a 100644 --- a/lib/policyEvaluator/RequestContext.ts +++ b/lib/policyEvaluator/RequestContext.ts @@ -68,7 +68,7 @@ function _buildArn( } if (specificResource) { return `arn:aws:iam::${accountId}:` + - `${generalResource}${specificResource}`; + `${generalResource}${specificResource}`; } return `arn:aws:iam::${accountId}:${generalResource}`; } @@ -76,7 +76,7 @@ function _buildArn( // arn:aws:iam:::/ if (specificResource) { return `arn:aws:ring::${requesterInfo!.accountid}:` + - `${generalResource}/${specificResource}`; + `${generalResource}/${specificResource}`; } return `arn:aws:ring::${requesterInfo!.accountid}:${generalResource}`; } @@ -85,10 +85,10 @@ function _buildArn( // (possible resource types are buckets, accounts or users) if (specificResource) { return `arn:scality:utapi::${requesterInfo!.accountid}:` + - `${generalResource}/${specificResource}`; + `${generalResource}/${specificResource}`; } return `arn:scality:utapi::${requesterInfo!.accountid}:` + - `${generalResource}/`; + `${generalResource}/`; } case 'sso': { if (specificResource) { @@ -100,10 +100,10 @@ function _buildArn( // arn:scality:metadata:::/ if (specificResource) { return `arn:scality:metadata::${requesterInfo!.accountid}:` + - `${generalResource}/${specificResource}`; + `${generalResource}/${specificResource}`; } return `arn:scality:metadata::${requesterInfo!.accountid}:` + - `${generalResource}/`; + `${generalResource}/`; } default: return undefined; @@ -703,4 +703,24 @@ export default class RequestContext { getNeedTagEval() { return this._needTagEval; } + + /** + * Get object lock retention days + * + * @returns objectLockRetentionDays - object lock retention days + */ + getObjectLockRetentionDays() { + return this._objectLockRetentionDays; + } + + /** + * Set object lock retention days + * + * @param objectLockRetentionDays - object lock retention days + * @returns itself + */ + setObjectLockRetentionDays(objectLockRetentionDays: number) { + this._objectLockRetentionDays = objectLockRetentionDays; + return this; + } } diff --git a/lib/policyEvaluator/utils/conditions.ts b/lib/policyEvaluator/utils/conditions.ts index d99533e42..88827b927 100644 --- a/lib/policyEvaluator/utils/conditions.ts +++ b/lib/policyEvaluator/utils/conditions.ts @@ -24,153 +24,153 @@ export function findConditionKey( // Possible AWS Condition keys (http://docs.aws.amazon.com/IAM/latest/ // UserGuide/reference_policies_elements.html#AvailableKeys) switch (key) { - // aws:CurrentTime – Used for date/time conditions - // (see Date Condition Operators). - case 'aws:CurrentTime': return new Date().toISOString(); - // aws:EpochTime – Used for date/time conditions - // (see Date Condition Operators). - case 'aws:EpochTime': return Date.now().toString(); - // aws:TokenIssueTime – Date/time that temporary security - // credentials were issued (see Date Condition Operators). - // Only present in requests that are signed using temporary security - // credentials. - case 'aws:TokenIssueTime': return requestContext.getTokenIssueTime(); - // aws:MultiFactorAuthPresent – Used to check whether MFA was used - // (see Boolean Condition Operators). - // Note: This key is only present if MFA was used. So, the following - // will not work: - // "Condition" : - // { "Bool" : { "aws:MultiFactorAuthPresent" : false } } - // Instead use: - // "Condition" : - // { "Null" : { "aws:MultiFactorAuthPresent" : true } } - case 'aws:MultiFactorAuthPresent': return requestContext.getMultiFactorAuthPresent(); - // aws:MultiFactorAuthAge – Used to check how many seconds since - // MFA credentials were issued. If MFA was not used, - // this key is not present - case 'aws:MultiFactorAuthAge': return requestContext.getMultiFactorAuthAge(); - // aws:principaltype states whether the principal is an account, - // user, federated, or assumed role - // Note: Docs for conditions have "PrincipalType" but simulator - // and docs for variables have lowercase - case 'aws:principaltype': return requesterInfo.principaltype; - // aws:Referer – Used to check who referred the client browser to - // the address the request is being sent to. Only supported by some - // services, such as S3. Value comes from the referer header in the - // HTTPS request made to AWS. - case 'aws:referer': return headers.referer; - // aws:SecureTransport – Used to check whether the request was sent - // using SSL (see Boolean Condition Operators). - case 'aws:SecureTransport': return requestContext.getSslEnabled() ? 'true' : 'false'; - // aws:SourceArn – Used check the source of the request, - // using the ARN of the source. N/A here. - case 'aws:SourceArn': return undefined; - // aws:SourceIp – Used to check the requester's IP address - // (see IP Address Condition Operators) - case 'aws:SourceIp': return requestContext.getRequesterIp(); - // aws:SourceVpc – Used to restrict access to a specific - // AWS Virtual Private Cloud. N/A here. - case 'aws:SourceVpc': return undefined; - // aws:SourceVpce – Used to limit access to a specific VPC endpoint - // N/A here - case 'aws:SourceVpce': return undefined; - // aws:UserAgent – Used to check the requester's client app. - // (see String Condition Operators) - case 'aws:UserAgent': return headers['user-agent']; - // aws:userid – Used to check the requester's unique user ID. - // (see String Condition Operators) - case 'aws:userid': return requesterInfo.userid; - // aws:username – Used to check the requester's friendly user name. - // (see String Condition Operators) - case 'aws:username': return requesterInfo.username; - // Possible condition keys for S3: - // s3:x-amz-acl is acl request for bucket or object put request - case 's3:x-amz-acl': return headers['x-amz-acl']; - // s3:x-amz-grant-PERMISSION (where permission can be: - // read, write, read-acp, write-acp or full-control) - // Value is the value of that header (ex. id of grantee) - case 's3:x-amz-grant-read': return headers['x-amz-grant-read']; - case 's3:x-amz-grant-write': return headers['x-amz-grant-write']; - case 's3:x-amz-grant-read-acp': return headers['x-amz-grant-read-acp']; - case 's3:x-amz-grant-write-acp': return headers['x-amz-grant-write-acp']; - case 's3:x-amz-grant-full-control': return headers['x-amz-grant-full-control']; - // s3:x-amz-copy-source is x-amz-copy-source header if applicable on - // a put object - case 's3:x-amz-copy-source': return headers['x-amz-copy-source']; - // s3:x-amz-metadata-directive is x-amz-metadata-directive header if - // applicable on a put object copy. Determines whether metadata will - // be copied from original object or replaced. Values or "COPY" or - // "REPLACE". Default is "COPY" - case 's3:x-amz-metadata-directive': return headers['metadata-directive']; - // s3:x-amz-server-side-encryption -- Used to require that object put - // use server side encryption. Value is the encryption algo such as - // "AES256" - case 's3:x-amz-server-side-encryption': return headers['x-amz-server-side-encryption']; - // s3:x-amz-storage-class -- x-amz-storage-class header value - // (STANDARD, etc.) - case 's3:x-amz-storage-class': return headers['x-amz-storage-class']; - // s3:VersionId -- version id of object - case 's3:VersionId': return query.versionId; - // s3:LocationConstraint -- Used to restrict creation of bucket - // in certain region. Only applicable for CreateBucket - case 's3:LocationConstraint': return requestContext.getLocationConstraint(); - // s3:delimiter is delimiter for listing request - case 's3:delimiter': return query.delimiter; - // s3:max-keys is max-keys for listing request - case 's3:max-keys': return query['max-keys']; - // s3:prefix is prefix for listing request - case 's3:prefix': return query.prefix; - // s3 auth v4 additional condition keys - // (See http://docs.aws.amazon.com/AmazonS3/latest/API/ - // bucket-policy-s3-sigv4-conditions.html) - // s3:signatureversion -- Either "AWS" for v2 or - // "AWS4-HMAC-SHA256" for v4 - case 's3:signatureversion': return requestContext.getSignatureVersion(); - // s3:authType -- Method of authentication: either "REST-HEADER", - // "REST-QUERY-STRING" or "POST" - case 's3:authType': return requestContext.getAuthType(); - // s3:signatureAge is the length of time, in milliseconds, - // that a signature is valid in an authenticated request. So, - // can use this to limit the age to less than 7 days - case 's3:signatureAge': return requestContext.getSignatureAge(); - // s3:x-amz-content-sha256 - Valid value is "UNSIGNED-PAYLOAD" - // so can use this in a deny policy to deny any requests that do not - // have a signed payload - case 's3:x-amz-content-sha256': return headers['x-amz-content-sha256']; - // s3:ObjLocationConstraint is the location constraint set for an - // object on a PUT request using the "x-amz-meta-scal-location-constraint" - // header - case 's3:ObjLocationConstraint': return headers['x-amz-meta-scal-location-constraint']; - case 'sts:ExternalId': return requestContext.getRequesterExternalId(); - case 'iam:PolicyArn': return requestContext.getPolicyArn(); - // s3:ExistingObjectTag - Used to check that existing object tag has - // specific tag key and value. Extraction of correct tag key is done in CloudServer. - // On first pass of policy evaluation, CloudServer information will not be included, - // so evaluation should be skipped - case 's3:ExistingObjectTag': - return requestContext.getNeedTagEval() - ? requestContext.getExistingObjTag() : undefined; - // s3:RequestObjectTag - Used to limit putting object tags to specific - // tag key and value. N/A here. - // Requires information from CloudServer - // On first pass of policy evaluation, CloudServer information will not be included, - // so evaluation should be skipped - case 's3:RequestObjectTagKey': - return requestContext.getNeedTagEval() - ? requestContext.getRequestObjTags() : undefined; - // s3:RequestObjectTagKeys - Used to limit putting object tags specific tag keys. - // Requires information from CloudServer. - // On first pass of policy evaluation, CloudServer information will not be included, - // so evaluation should be skipped - case 's3:RequestObjectTagKeys': - return requestContext.getNeedTagEval() && requestContext.getRequestObjTags() - ? getTagKeys(requestContext.getRequestObjTags()!) - : undefined; - // The maximum retention period is 100 years. - case 's3:object-lock-remaining-retention-days': - return requestContext.getObjectLockRetentionDays() || undefined; - default: - return undefined; + // aws:CurrentTime – Used for date/time conditions + // (see Date Condition Operators). + case 'aws:CurrentTime': return new Date().toISOString(); + // aws:EpochTime – Used for date/time conditions + // (see Date Condition Operators). + case 'aws:EpochTime': return Date.now().toString(); + // aws:TokenIssueTime – Date/time that temporary security + // credentials were issued (see Date Condition Operators). + // Only present in requests that are signed using temporary security + // credentials. + case 'aws:TokenIssueTime': return requestContext.getTokenIssueTime(); + // aws:MultiFactorAuthPresent – Used to check whether MFA was used + // (see Boolean Condition Operators). + // Note: This key is only present if MFA was used. So, the following + // will not work: + // "Condition" : + // { "Bool" : { "aws:MultiFactorAuthPresent" : false } } + // Instead use: + // "Condition" : + // { "Null" : { "aws:MultiFactorAuthPresent" : true } } + case 'aws:MultiFactorAuthPresent': return requestContext.getMultiFactorAuthPresent(); + // aws:MultiFactorAuthAge – Used to check how many seconds since + // MFA credentials were issued. If MFA was not used, + // this key is not present + case 'aws:MultiFactorAuthAge': return requestContext.getMultiFactorAuthAge(); + // aws:principaltype states whether the principal is an account, + // user, federated, or assumed role + // Note: Docs for conditions have "PrincipalType" but simulator + // and docs for variables have lowercase + case 'aws:principaltype': return requesterInfo.principaltype; + // aws:Referer – Used to check who referred the client browser to + // the address the request is being sent to. Only supported by some + // services, such as S3. Value comes from the referer header in the + // HTTPS request made to AWS. + case 'aws:referer': return headers.referer; + // aws:SecureTransport – Used to check whether the request was sent + // using SSL (see Boolean Condition Operators). + case 'aws:SecureTransport': return requestContext.getSslEnabled() ? 'true' : 'false'; + // aws:SourceArn – Used check the source of the request, + // using the ARN of the source. N/A here. + case 'aws:SourceArn': return undefined; + // aws:SourceIp – Used to check the requester's IP address + // (see IP Address Condition Operators) + case 'aws:SourceIp': return requestContext.getRequesterIp(); + // aws:SourceVpc – Used to restrict access to a specific + // AWS Virtual Private Cloud. N/A here. + case 'aws:SourceVpc': return undefined; + // aws:SourceVpce – Used to limit access to a specific VPC endpoint + // N/A here + case 'aws:SourceVpce': return undefined; + // aws:UserAgent – Used to check the requester's client app. + // (see String Condition Operators) + case 'aws:UserAgent': return headers['user-agent']; + // aws:userid – Used to check the requester's unique user ID. + // (see String Condition Operators) + case 'aws:userid': return requesterInfo.userid; + // aws:username – Used to check the requester's friendly user name. + // (see String Condition Operators) + case 'aws:username': return requesterInfo.username; + // Possible condition keys for S3: + // s3:x-amz-acl is acl request for bucket or object put request + case 's3:x-amz-acl': return headers['x-amz-acl']; + // s3:x-amz-grant-PERMISSION (where permission can be: + // read, write, read-acp, write-acp or full-control) + // Value is the value of that header (ex. id of grantee) + case 's3:x-amz-grant-read': return headers['x-amz-grant-read']; + case 's3:x-amz-grant-write': return headers['x-amz-grant-write']; + case 's3:x-amz-grant-read-acp': return headers['x-amz-grant-read-acp']; + case 's3:x-amz-grant-write-acp': return headers['x-amz-grant-write-acp']; + case 's3:x-amz-grant-full-control': return headers['x-amz-grant-full-control']; + // s3:x-amz-copy-source is x-amz-copy-source header if applicable on + // a put object + case 's3:x-amz-copy-source': return headers['x-amz-copy-source']; + // s3:x-amz-metadata-directive is x-amz-metadata-directive header if + // applicable on a put object copy. Determines whether metadata will + // be copied from original object or replaced. Values or "COPY" or + // "REPLACE". Default is "COPY" + case 's3:x-amz-metadata-directive': return headers['metadata-directive']; + // s3:x-amz-server-side-encryption -- Used to require that object put + // use server side encryption. Value is the encryption algo such as + // "AES256" + case 's3:x-amz-server-side-encryption': return headers['x-amz-server-side-encryption']; + // s3:x-amz-storage-class -- x-amz-storage-class header value + // (STANDARD, etc.) + case 's3:x-amz-storage-class': return headers['x-amz-storage-class']; + // s3:VersionId -- version id of object + case 's3:VersionId': return query.versionId; + // s3:LocationConstraint -- Used to restrict creation of bucket + // in certain region. Only applicable for CreateBucket + case 's3:LocationConstraint': return requestContext.getLocationConstraint(); + // s3:delimiter is delimiter for listing request + case 's3:delimiter': return query.delimiter; + // s3:max-keys is max-keys for listing request + case 's3:max-keys': return query['max-keys']; + // s3:prefix is prefix for listing request + case 's3:prefix': return query.prefix; + // s3 auth v4 additional condition keys + // (See http://docs.aws.amazon.com/AmazonS3/latest/API/ + // bucket-policy-s3-sigv4-conditions.html) + // s3:signatureversion -- Either "AWS" for v2 or + // "AWS4-HMAC-SHA256" for v4 + case 's3:signatureversion': return requestContext.getSignatureVersion(); + // s3:authType -- Method of authentication: either "REST-HEADER", + // "REST-QUERY-STRING" or "POST" + case 's3:authType': return requestContext.getAuthType(); + // s3:signatureAge is the length of time, in milliseconds, + // that a signature is valid in an authenticated request. So, + // can use this to limit the age to less than 7 days + case 's3:signatureAge': return requestContext.getSignatureAge(); + // s3:x-amz-content-sha256 - Valid value is "UNSIGNED-PAYLOAD" + // so can use this in a deny policy to deny any requests that do not + // have a signed payload + case 's3:x-amz-content-sha256': return headers['x-amz-content-sha256']; + // s3:ObjLocationConstraint is the location constraint set for an + // object on a PUT request using the "x-amz-meta-scal-location-constraint" + // header + case 's3:ObjLocationConstraint': return headers['x-amz-meta-scal-location-constraint']; + case 'sts:ExternalId': return requestContext.getRequesterExternalId(); + case 'iam:PolicyArn': return requestContext.getPolicyArn(); + // s3:ExistingObjectTag - Used to check that existing object tag has + // specific tag key and value. Extraction of correct tag key is done in CloudServer. + // On first pass of policy evaluation, CloudServer information will not be included, + // so evaluation should be skipped + case 's3:ExistingObjectTag': + return requestContext.getNeedTagEval() + ? requestContext.getExistingObjTag() : undefined; + // s3:RequestObjectTag - Used to limit putting object tags to specific + // tag key and value. N/A here. + // Requires information from CloudServer + // On first pass of policy evaluation, CloudServer information will not be included, + // so evaluation should be skipped + case 's3:RequestObjectTagKey': + return requestContext.getNeedTagEval() + ? requestContext.getRequestObjTags() : undefined; + // s3:RequestObjectTagKeys - Used to limit putting object tags specific tag keys. + // Requires information from CloudServer. + // On first pass of policy evaluation, CloudServer information will not be included, + // so evaluation should be skipped + case 's3:RequestObjectTagKeys': + return requestContext.getNeedTagEval() && requestContext.getRequestObjTags() + ? getTagKeys(requestContext.getRequestObjTags()!) + : undefined; + // The maximum retention period is 100 years. + case 's3:object-lock-remaining-retention-days': + return requestContext.getObjectLockRetentionDays() || undefined; + default: + return undefined; } } @@ -433,10 +433,10 @@ export function convertConditionOperator(operator: string): boolean { return !operatorMap.ArnLike(key, value); }, Null: function nullOperator(key: string, value: string[]) { - // Null is used to check if a condition key is present. - // The policy statement value should be either true (the key doesn't - // exist — it is null) or false (the key exists and its value is - // not null). + // Null is used to check if a condition key is present. + // The policy statement value should be either true (the key doesn't + // exist — it is null) or false (the key exists and its value is + // not null). if ((key === undefined || key === null) && value[0] === 'true' || (key !== undefined && key !== null)