diff --git a/cloudformation/iam.yml b/cloudformation/iam.yml index fbeb9e3a..4d33f98a 100644 --- a/cloudformation/iam.yml +++ b/cloudformation/iam.yml @@ -1,6 +1,7 @@ AWSTemplateFormatVersion: "2010-09-09" Description: Stack IAM Roles Transform: AWS::Serverless-2016-10-31 + Parameters: RunEnvironment: Type: String @@ -14,8 +15,9 @@ Parameters: Type: String SqsQueueArn: Type: String + Resources: - ApiLambdaIAMRole: + SqsLambdaIAMRole: Type: AWS::IAM::Role Properties: ManagedPolicyArns: @@ -30,7 +32,8 @@ Resources: Service: - lambda.amazonaws.com Policies: - - PolicyDocument: + - PolicyName: ses-membership + PolicyDocument: Version: "2012-10-17" Statement: - Action: @@ -40,20 +43,85 @@ Resources: Resource: "*" Condition: StringEquals: - ses:FromAddress: !Sub "membership@${SesEmailDomain}" + ses:FromAddress: + Fn::Sub: "membership@${SesEmailDomain}" ForAllValues:StringLike: ses:Recipients: - "*@illinois.edu" - PolicyName: ses-membership - - PolicyDocument: + + - PolicyName: lambda-logs + PolicyDocument: + Version: "2012-10-17" + Statement: + - Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Effect: Allow + Resource: + - Fn::Sub: arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${LambdaFunctionName}:* + + - PolicyName: lambda-db-secrets + PolicyDocument: + Version: "2012-10-17" + Statement: + - Action: + - secretsmanager:GetSecretValue + Effect: Allow + Resource: + - Fn::Sub: arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:infra-core-api-config* + + - PolicyName: lambda-dynamo + PolicyDocument: + Version: "2012-10-17" + Statement: + - Sid: DynamoDBTableAccess + Effect: Allow + Action: + - dynamodb:BatchGetItem + - dynamodb:BatchWriteItem + - dynamodb:ConditionCheckItem + - dynamodb:PutItem + - dynamodb:DescribeTable + - dynamodb:DeleteItem + - dynamodb:GetItem + - dynamodb:Scan + - dynamodb:Query + - dynamodb:UpdateItem + Resource: + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-cache + + - Sid: DynamoDBDescribeLimitsAccess + Effect: Allow + Action: + - dynamodb:DescribeLimits + Resource: "*" + + ApiLambdaIAMRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Policies: + - PolicyName: lambda-sqs + PolicyDocument: Version: "2012-10-17" Statement: - Action: - sqs:SendMessage Effect: Allow - Resource: !Ref SqsQueueArn - PolicyName: lambda-sqs - - PolicyDocument: + Resource: + - Fn::Sub: "${SqsQueueArn}" + + - PolicyName: lambda-logs + PolicyDocument: Version: "2012-10-17" Statement: - Action: @@ -63,55 +131,71 @@ Resources: Effect: Allow Resource: - Fn::Sub: arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${LambdaFunctionName}:* - - Effect: Allow - Action: - - ec2:CreateNetworkInterface - - ec2:DescribeNetworkInterfaces - - ec2:DeleteNetworkInterface - - ec2:DescribeSubnets - - ec2:DeleteNetworkInterface - - ec2:AssignPrivateIpAddresses - - ec2:UnassignPrivateIpAddresses - Resource: "*" - PolicyName: lambda - - PolicyDocument: - Version: 2012-10-17 + + - PolicyName: lambda-db-secrets + PolicyDocument: + Version: "2012-10-17" Statement: - Action: - secretsmanager:GetSecretValue Effect: Allow Resource: - - !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:infra-core-api-config* - PolicyName: lambda-db-secrets - - PolicyDocument: - Version: 2012-10-17 + - Fn::Sub: arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:infra-core-api-config* + + - PolicyName: lambda-dynamo + PolicyDocument: + Version: "2012-10-17" Statement: - - Action: - - dynamodb:* + - Sid: DynamoDBIndexAccess Effect: Allow + Action: + - dynamodb:Query + Resource: + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links/index/* + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events/index/* + + - Sid: DynamoDBStreamAccess + Effect: Allow + Action: + - dynamodb:GetShardIterator + - dynamodb:DescribeStream + - dynamodb:GetRecords + - dynamodb:ListStreams + Resource: + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links/stream/* + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events/stream/* + + - Sid: DynamoDBTableAccess + Effect: Allow + Action: + - dynamodb:BatchGetItem + - dynamodb:BatchWriteItem + - dynamodb:ConditionCheckItem + - dynamodb:PutItem + - dynamodb:DescribeTable + - dynamodb:DeleteItem + - dynamodb:GetItem + - dynamodb:Scan + - dynamodb:Query + - dynamodb:UpdateItem Resource: - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events/* - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-cache - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-cache/* - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-purchase-history/* - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-purchase-history - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-tickets - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-tickets/* - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-ticketing-metadata/* - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-ticketing-metadata - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-metadata/* - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-metadata - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-userroles - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-userroles/* - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-grouproles - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-grouproles/* - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links/* - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-membership-provisioning - - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-membership-provisioning/* + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-events + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-cache + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-purchase-history + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-tickets + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-events-ticketing-metadata + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-merchstore-metadata + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-userroles + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-iam-grouproles + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-stripe-links + - Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/infra-core-api-membership-provisioning + + - Sid: DynamoDBDescribeLimitsAccess + Effect: Allow + Action: + - dynamodb:DescribeLimits + Resource: "*" - PolicyName: lambda-dynamo Outputs: MainFunctionRoleArn: Description: Main API IAM role ARN @@ -119,3 +203,10 @@ Outputs: Fn::GetAtt: - ApiLambdaIAMRole - Arn + + SqsFunctionRoleArn: + Description: Sqs IAM role ARN + Value: + Fn::GetAtt: + - SqsLambdaIAMRole + - Arn diff --git a/cloudformation/main.yml b/cloudformation/main.yml index cd7eface..d39d9333 100644 --- a/cloudformation/main.yml +++ b/cloudformation/main.yml @@ -216,7 +216,8 @@ Resources: FunctionName: !Sub ${ApplicationPrefix}-sqs-lambda Handler: index.handler MemorySize: 512 - Role: !GetAtt AppSecurityRoles.Outputs.MainFunctionRoleArn + Role: + Fn::GetAtt: AppSecurityRoles.Outputs.SqsFunctionRoleArn Timeout: !Ref SqsLambdaTimeout LoggingConfig: LogGroup: !Sub /aws/lambda/${ApplicationPrefix}-lambda diff --git a/src/ui/pages/events/ViewEvents.page.tsx b/src/ui/pages/events/ViewEvents.page.tsx index a44ef44e..003ac354 100644 --- a/src/ui/pages/events/ViewEvents.page.tsx +++ b/src/ui/pages/events/ViewEvents.page.tsx @@ -1,4 +1,15 @@ -import { Text, Button, Table, Modal, Group, Transition, ButtonGroup, Title } from '@mantine/core'; +import { + Text, + Button, + Table, + Modal, + Group, + Transition, + ButtonGroup, + Title, + Badge, + Anchor, +} from '@mantine/core'; import { useDisclosure } from '@mantine/hooks'; import { notifications } from '@mantine/notifications'; import { IconPlus, IconTrash } from '@tabler/icons-react'; @@ -65,13 +76,21 @@ export const ViewEventsPage: React.FC = () => { style={{ ...styles, display: shouldShow ? 'table-row' : 'none' }} key={`${event.id}-tr`} > -