Commit a2610b9b authored by Srihari Prabaharan's avatar Srihari Prabaharan
Browse files

Merge branch 'test/update-parameter-store' into 'trusted-aws'

Test/update parameter store

See merge request !2
parents 34a852df 17e9fc9c
Pipeline #2219 failed with stages
in 10 minutes and 38 seconds
.DS_Store
**/.DS_Store
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
......
// Copyright © Amazon Web Services
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.amazonaws.osdu.entitlements;
import java.io.*;
import java.util.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.opengroup.osdu.core.aws.entitlements.RequestKeys;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import org.opengroup.osdu.core.aws.entitlements.Authorizer;
import org.opengroup.osdu.core.aws.lambda.HttpLambdaUtil;
import org.opengroup.osdu.core.aws.lambda.HttpStatusCodes;
import org.opengroup.osdu.core.aws.lambda.LambdaLogger;
/**
* Class that handles the authorization lambda code.
* Secret key and client id should come from environment variables and should be set at time of deployment
*/
public class Authorize implements RequestStreamHandler {
private final static String SUCCESS_MSG = "Successful authorization";
HttpLambdaUtil httpLambdaUtil = new HttpLambdaUtil();
Authorizer authorizer = new Authorizer();
/**
* Method that gets called by Lambda. We parse the inputstream and write the response to the outputstream.
* Here we call out to the keystore and verify the jwt against it. Assumes that jwks will be present
*
* header example:
* {
* "typ": "JWT",
* "alg": "HS256"
* }
*
* payload example:
* {
* "sub": "c30214ba-44af-4b52-bfb9-689cbeee8733",
* "event_id": "b4476e21-b629-4e68-bb6f-a50613be68f0",
* "token_use": "access",
* "scope": "aws.cognito.signin.user.admin",
* "auth_time": 1572884830,
* "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_LBaTvpEXx",
* "exp": 1572888455,
* "iat": 1572884830,
* "jti": "e4e1449e-a990-4b8e-a55d-e095a730b6ca",
* "client_id": "test-id",
* "username": "user"
* }
* @param inputStream
* @param outputStream
* @param context
* @throws IOException
*/
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context)
throws IOException {
ObjectMapper mapper = new ObjectMapper();
Map<String, String> headers = new HashMap<>();
try{
Map<String, Object> request = mapper.readValue(inputStream, Map.class);
headers = (HashMap<String, String>) request.get(RequestKeys.HEADERS_REQUEST_KEY);
} catch (ClassCastException e){
LambdaLogger.logException("Casting exception in parsing request, headers, httpMethod.", e);
httpLambdaUtil.unauthorizedRequest(outputStream, new HashMap<>());
} catch (IOException e){
LambdaLogger.logException("IO exception in parsing request, headers, httpMethod.", e);
httpLambdaUtil.unauthorizedRequest(outputStream, new HashMap<>());
} catch (Exception e){
LambdaLogger.logException("General exception in parsing request, headers, httpMethod.", e);
httpLambdaUtil.unauthorizedRequest(outputStream, new HashMap<>());
}
if (authorizer.validateJWT(headers.get("authorization")) != null){
httpLambdaUtil.okRequest(outputStream, SUCCESS_MSG, new HashMap<>());
} else {
httpLambdaUtil.unauthorizedRequest(outputStream, new HashMap<>());
}
}
}
// Copyright © Amazon Web Services
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.amazonaws.osdu.entitlements;
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.junit.Test;
import org.mockito.Mockito;
import org.opengroup.osdu.core.aws.entitlements.Authorizer;
import org.opengroup.osdu.core.aws.lambda.HttpLambdaUtil;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class AuthorizeTest {
private static final ObjectMapper MAPPER = new ObjectMapper();
@Test
public void successfulResponse() throws IOException, InvalidJwtException {
// arrange
String request = "{\n" +
" \"body\": \"null\",\n" +
" \"headers\": {\n" +
" \"user\": \"spencer.sutton@parivedasolutions.com\",\n" +
" \"authorization\": \"Bearer test-token\",\n" +
" \"data-partition-id\": \"common\"\n" +
" },\n" +
" \"httpMethod\": \"GET\"\n" +
"}";
InputStream stream = new ByteArrayInputStream(request.getBytes(StandardCharsets.UTF_8));
Authorize authorize = new Authorize();
ByteArrayOutputStream out = new ByteArrayOutputStream();
authorize.httpLambdaUtil = Mockito.mock(HttpLambdaUtil.class);
authorize.authorizer = Mockito.mock(Authorizer.class);
Mockito.when(authorize.authorizer.validateJWT(Mockito.anyString())).thenReturn("test-user");
// act
authorize.handleRequest(stream, out, new MockLambdaContext());
// assert
Mockito.verify(authorize.httpLambdaUtil, Mockito.times(1)).okRequest(Mockito.anyObject(),
Mockito.anyString(),
Mockito.anyMap());
}
@Test
public void failureResponse() throws IOException {
// arrange
String request = "{\n" +
" \"body\": \"null\",\n" +
" \"headers\": {\n" +
" \"user\": \"spencer.sutton@parivedasolutions.com\",\n" +
" \"authorization\": \"Bearer test-token\",\n" +
" \"data-partition-id\": \"common\"\n" +
" },\n" +
" \"httpMethod\": \"GET\"\n" +
"}";
InputStream stream = new ByteArrayInputStream(request.getBytes(StandardCharsets.UTF_8));
Authorize authorize = new Authorize();
ByteArrayOutputStream out = new ByteArrayOutputStream();
authorize.httpLambdaUtil = Mockito.mock(HttpLambdaUtil.class);
authorize.authorizer = Mockito.mock(Authorizer.class);
Mockito.when(authorize.authorizer.validateJWT(Mockito.eq("test-token"))).thenReturn(null);
// act
authorize.handleRequest(stream, out, new MockLambdaContext());
// assert
Mockito.verify(authorize.httpLambdaUtil, Mockito.times(1)).unauthorizedRequest(Mockito.anyObject(),
Mockito.anyMap());
}
}
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
AWSTemplateFormatVersion: 2010-09-09
Description: >-
CloudFormation template for creating the lambda functions associated with entitlements
Parameters:
Environment:
Description: The name of the environment.
Type: String
AllowedValues:
- dev
- uat
- prod
ConstraintDescription: Environment can only be "dev/uat/prod".
Default: dev
DeploymentRegion:
Description: The AWS region to deploy the resources to.
Type: String
Default: us-east-1
ChildTemplateBasePath:
Description: >-
The base path for where child CloudFormation templates are located – can be relative or absolute, e.g.
https://s3.amazonaws.com/dev-osdu-cloudformation-scripts/Automated/
Type: String
AllowedPattern: '^https:\/\/s3.amazonaws.com\/.*\/$'
Default: https://s3.amazonaws.com/dev-os-entitlements-cloudformation-scripts/CloudFormation/Automated/
ApplicationName:
Description: >
The name of the application, should be equal to the repository name.
Type: String
MinLength: '1'
MaxLength: '64'
AllowedPattern: "^[a-zA-Z]+[0-9a-zA-Z_-]*$"
ConstraintDescription: Must start with a letter. Only numbers, letters, -, and _ accepted. Max. length 64 characters.
Default: os-entitlements
Region:
Description: The AWS region to deploy the resources to.
Type: String
Default: us-east-1
GroupsDynamoDBTableName:
Description: The name of the DynamoDB table for the groups repository; will be prefixed by the environment (e.g. Groups).
AllowedPattern: "^[a-zA-Z]+[0-9a-zA-Z_]*$"
ConstraintDescription: Must start with a letter. Only numbers, letters, and _ accepted. Max. length 64 characters.
Default: 'GroupsTest'
Type: String
MinLength: '1'
MaxLength: '64'
Resources:
GroupsDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Sub ${Environment}-${GroupsDynamoDBTableName}
AttributeDefinitions:
- AttributeName: "groupUniqueIdentifier"
AttributeType: "S"
- AttributeName: "groupEmail"
AttributeType: "S"
- AttributeName: "role"
AttributeType: "S"
- AttributeName: "memberEmailAndDataPartition"
AttributeType: "S"
KeySchema:
- AttributeName: "groupUniqueIdentifier"
KeyType: "HASH"
GlobalSecondaryIndexes:
- IndexName: "groupEmail-role-index"
KeySchema:
- AttributeName: "groupEmail"
KeyType: "HASH"
- AttributeName: "role"
KeyType: "RANGE"
Projection:
ProjectionType: "KEYS_ONLY"
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
- IndexName: "memberEmailAndDataPartition-index"
KeySchema:
- AttributeName: "memberEmailAndDataPartition"
KeyType: "HASH"
Projection:
ProjectionType: "KEYS_ONLY"
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
GroupsFunction:
Type: AWS::Lambda::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
FunctionName: dev-os-entitlements-GroupsFunction
Handler: com.amazonaws.osdu.entitlements.GetGroups::handleRequest
Runtime: java8
Role: arn:aws:iam::888733619319:role/dev-os-entitlements-GroupsFunctionRole-TWC0MVYAPYT8
Code:
S3Bucket: dev-os-entitlements-cloudformation-scripts
S3Key: groups-function-code.zip
MemorySize: 512
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
dynamoDBEndpoint: dynamodb.us-east-1.amazonaws.com
dynamoDBRegion: us-east-1
groupsTablePrefix: dev-
jwksEndpoint: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_anhVORG8D/.well-known/jwks.json
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
AWSTemplateFormatVersion: 2010-09-09
Description: >
This CloudFormation script creates the deployment pipeline for OSDU's entitlements
Parameters:
Environment:
Description: Environment Name. Defaults to 'dev'. Can only be dev/uat/prod.
Type: String
AllowedValues:
- dev
- uat
- prod
Default: dev
DeploymentRegion:
Description: The AWS region to deploy the application to. The default is us-east-1.
Type: String
Default: us-east-1
SNSNotificationEmail:
Description: The email address to send SNS notifications about the build to.
Type: String
Default: spencer.sutton@parivedasolutions.com
CodeCommitRepositoryName:
Description: The name of the Code Commit Repository that the CodePipeline source is connected to.
Type: String
Default: os-entitlements
CodeCommitBranchName:
Description: The name of the Code Commit branch that the CodePipeline source is connected to.
Type: String
Default: dev
MasterStackName:
Description: The name of the master stack that is being deployed by the CodePipeline.
Type: String
Default: os-entitlements-master-stack
MasterTemplateName:
Description: The name of the master template that is called when creating the master stack.
Type: String
Default: CloudFormation/Master/lambdas.yml
BucketTemplateName:
Description: The name of the template that creates the s3 bucket for lambda code
Type: String
Default: Cloudformation/Automated/lambda-bucket.yml
Resources:
ArtifactStoreBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
VersioningConfiguration:
Status: Enabled
CFNRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: ['sts:AssumeRole']
Effect: Allow
Principal:
Service: [cloudformation.amazonaws.com]
Version: '2012-10-17'
Path: /
Policies:
- PolicyName: !Sub CloudFormationRole-${CodeCommitRepositoryName}
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- 's3:*'
- 'ec2:*'
- 'apigateway:*'
- 'cloudwatch:*'
- 'events:*'
- 'logs:*'
- 'xray:*'
- 'lambda:*'
- 'rds:*'
- 'codepipeline:*'
- 'codecommit:*'
- 'cloudformation:*'
- 'dynamodb:*'
- 'application-autoscaling:*'
- 'autoscaling:*'
- 'states:*'
- 'iam:CreateUser'
- 'iam:UpdateUser'
- 'iam:DeleteUser'
- 'iam:CreateAccessKey'
- 'iam:UpdateAccessKey'
- 'iam:DeleteAccessKey'
- 'iam:Delete*'
- "iam:List*"
- "iam:Get*"
- "iam:CreateServiceSpecificCredential"
- "iam:DeactivateMFADevice"
- "iam:GenerateServiceLastAccessedDetails"
- "iam:UpdateOpenIDConnectProviderThumbprint"
- "iam:PutRolePolicy"
- "iam:PutUserPolicy"
- "iam:AddRoleToInstanceProfile"
- "iam:SimulateCustomPolicy"
- "iam:UploadSSHPublicKey"
- "iam:UpdateServiceSpecificCredential"
- "iam:RemoveClientIDFromOpenIDConnectProvider"
- "iam:UpdateRoleDescription"
- "iam:UpdateServerCertificate"
- "iam:CreateInstanceProfile"
- "iam:GenerateCredentialReport"
- "iam:UntagRole"
- "iam:PutRolePermissionsBoundary"
- "iam:TagRole"
- "iam:ResetServiceSpecificCredential"
- "iam:PassRole"
- "iam:EnableMFADevice"
- "iam:ResyncMFADevice"
- "iam:UpdateSAMLProvider"
- "iam:CreatePolicy"
- "iam:CreateServiceLinkedRole"
- "iam:UpdateRole"
- "iam:AddClientIDToOpenIDConnectProvider"
- "iam:SetDefaultPolicyVersion"
- "iam:UpdateAssumeRolePolicy"
- "iam:RemoveRoleFromInstanceProfile"
- "iam:CreateRole"
- "iam:AttachRolePolicy"
- "iam:CreateLoginProfile"
- "iam:DetachRolePolicy"
- "iam:AttachUserPolicy"
- "iam:DetachUserPolicy"
- "iam:SimulatePrincipalPolicy"
- "iam:CreateAccountAlias"
- "iam:ChangePassword"
- "iam:UpdateLoginProfile"
- "iam:UpdateAccessKey"
- "iam:UpdateSSHPublicKey"
- "iam:UpdateAccountPasswordPolicy"
- "iam:CreateSAMLProvider"
- "iam:CreateVirtualMFADevice"
- "iam:CreateAccessKey"
- "iam:AddUserToGroup"
- "iam:RemoveUserFromGroup"
- "iam:CreatePolicyVersion"
- "iam:UploadSigningCertificate"
- "iam:TagUser"
- "iam:CreateOpenIDConnectProvider"
- "iam:UploadServerCertificate"
- "iam:UntagUser"
- "iam:UpdateSigningCertificate"
- 'sns:*'
- 'sqs:*'
- 'secretsmanager:*'
- 'acm:*'
- 'kms:*'
- 'cloudfront:*'
- 'route53:*'
- 'route53domains:*'
- 'elasticache:*'
- 'ecr:*'
- 'codedeploy:*'
- 'elasticloadbalancing:*'
- 'ecs:*'
- 'servicediscovery:CreatePrivateDnsNamespace'
- 'servicediscovery:CreateService'
- 'servicediscovery:GetNamespace'
- 'servicediscovery:GetOperation'
- 'servicediscovery:GetService'
- 'servicediscovery:ListNamespaces'
- 'servicediscovery:ListServices'
- 'servicediscovery:UpdateService'
- 'servicediscovery:DeleteService'
Effect: Allow
Resource: '*'
PipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: ['sts:AssumeRole']
Effect: Allow
Principal:
Service: [codepipeline.amazonaws.com]
Version: '2012-10-17'
Path: /
Policies:
- PolicyName: !Sub CodePipelineAccess-${CodeCommitRepositoryName}
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- 's3:*'
- 'cloudformation:CreateStack'
- 'cloudformation:DescribeStacks'
- 'cloudformation:DeleteStack'
- 'cloudformation:UpdateStack'
- 'cloudformation:CreateChangeSet'
- 'cloudformation:ExecuteChangeSet'
- 'cloudformation:DeleteChangeSet'
- 'cloudformation:DescribeChangeSet'
- 'cloudformation:SetStackPolicy'
- 'cloudformation:ValidateTemplate'
- 'iam:PassRole'
- 'sns:Publish'
- 'lambda:ListFunctions'
- 'lambda:InvokeFunction'
- 'ec2:Describe*'
- 'ec2:Get*'
- 'ec2:Search*'
- 'ec2:*Vpc*'
- 'ec2:*Gateway'
- 'ec2:*Tags'
- 'ec2:*Subnet*'
- 'ec2:*Route*'
- 'ec2:*SecurityGroup'
- 'ec2:allocate*'
- 'ec2:release*'
Effect: Allow
Resource: '*'
- Action:
- 'codecommit:GetUploadArchiveStatus'
- 'codecommit:CancelUploadArchive'
- 'codecommit:GetBranch'
- 'codecommit:GetCommit'
- 'codecommit:GetUploadStatus'
- 'codecommit:UploadArchive'
Effect: Allow
Resource: '*'
- Effect: "Allow"
Action:
- "codebuild:*"
Resource:
- Fn::Sub: arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/*
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
Location: !Ref ArtifactStoreBucket
Type: S3
Name: !Sub '${Environment}-OSDU-OS-Entitlements-CodePipeline'
RoleArn: !GetAtt [PipelineRole, Arn]
Stages:
- Name: Source
Actions:
- Name: Source