Skip to content

Commit

Permalink
impl kick operation
Browse files Browse the repository at this point in the history
  • Loading branch information
yuizho committed May 14, 2022
1 parent c8b4a00 commit 2bb7885
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 14 deletions.
50 changes: 50 additions & 0 deletions room/appsync/room-api/resolvers/Mutation.kick.req.vtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#if($util.isNullOrEmpty($ctx.args.room_id))
$util.error("null or empty", "room_id")
#end
#if($ctx.args.room_id.length() > 30)
$util.error("unexpected length (too long)", "room_id")
#end
#if(!$util.matches("^[0-9a-zA-Z]+$", $ctx.args.room_id))
$util.error("unexpected pattern", "room_id")
#end

#if($util.isNullOrEmpty($ctx.args.user_id))
$util.error("null or empty", "user_id")
#end
#if($ctx.args.user_id.length() > 30)
$util.error("unexpected length (too long)", "user_id")
#end
#if(!$util.matches("^[0-9a-zA-Z]+$", $ctx.args.user_id))
$util.error("unexpected pattern", "user_id")
#end

#if($util.isNullOrEmpty($ctx.args.kicked_user_id))
$util.error("null or empty", "kicked_user_id")
#end
#if($ctx.args.kicked_user_id.length() > 30)
$util.error("unexpected length (too long)", "kicked_user_id")
#end
#if(!$util.matches("^[0-9a-zA-Z]+$", $ctx.args.kicked_user_id))
$util.error("unexpected pattern", "kicked_user_id")
#end

{
"version" : "2017-02-28",
"operation" : "PutItem",
"key" : {
"event_id": $util.dynamodb.toDynamoDBJson($util.autoUlid()),
},
"attributeValues" : {
"room_id": $util.dynamodb.toDynamoDBJson($ctx.args.room_id),
"user_id": $util.dynamodb.toDynamoDBJson($ctx.args.user_id),
"op_type": $util.dynamodb.toDynamoDBJson("KICK"),
"operated_at": $util.dynamodb.toDynamoDBJson($util.time.nowISO8601()),
"kicked_user_id": $util.dynamodb.toDynamoDBJson($ctx.args.kicked_user_id),
},
"condition": {
"expression": "attribute_not_exists(#event_id)",
"expressionNames": {
"#event_id": "event_id",
},
},
}
3 changes: 3 additions & 0 deletions room/appsync/room-api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
@aws_api_key
refreshTable(room_id: String!, user_id: String!): Operation @aws_api_key
heartbeat(room_id: String!, user_id: String!): Operation @aws_api_key
kick(room_id: String!, user_id: String!, kicked_user_id: String!): Operation
@aws_api_key
updatePoker(
room_id: String!
user_id: String!
Expand Down Expand Up @@ -42,6 +44,7 @@ enum OperationType {
PICK
REFRESH_TABLE
HEARTBEAT
KICK
}

type Room @aws_api_key @aws_iam {
Expand Down
33 changes: 20 additions & 13 deletions room/lambda/room-rmu/model/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ const (
Pick = OpType("PICK")
RefreshTable = OpType("REFRESH_TABLE")
Heartbeat = OpType("HEARTBEAT")
Kick = OpType("KICK")
)

func NewOpType(s string) (OpType, error) {
opType := OpType(s)
switch opType {
case OpenRoom, Join, Leave, Pick, RefreshTable, Heartbeat:
case OpenRoom, Join, Leave, Pick, RefreshTable, Heartbeat, Kick:
return opType, nil
default:
return "", fmt.Errorf("unexpected op_type string: %s", s)
Expand All @@ -34,12 +35,13 @@ func (opType OpType) String() string {
}

type Operation struct {
EventId string `dynamodbav:"event_id" json:"event_id"`
RoomId string `dynamodbav:"room_id" json:"room_id"`
OpType OpType `dynamodbav:"op_type" json:"op_type"`
UserId string `dynamodbav:"user_id" json:"user_id"`
OperatedAt string `dynamodbav:"operated_at" json:"operated_at"`
PickedCard string `dynamodbav:"picked_card" json:"picked_card"`
EventId string `dynamodbav:"event_id" json:"event_id"`
RoomId string `dynamodbav:"room_id" json:"room_id"`
OpType OpType `dynamodbav:"op_type" json:"op_type"`
UserId string `dynamodbav:"user_id" json:"user_id"`
OperatedAt string `dynamodbav:"operated_at" json:"operated_at"`
PickedCard string `dynamodbav:"picked_card" json:"picked_card"`
KickedUserId string `dynamodbav:"kicked_user_id" json:"kicked_user_id"`
}

func NewOperation(attrs map[string]events.DynamoDBAttributeValue) (*Operation, error) {
Expand Down Expand Up @@ -81,6 +83,10 @@ func NewOperation(attrs map[string]events.DynamoDBAttributeValue) (*Operation, e
return nil, errors.New("invalid operated_at")
}

if m, _ := regexp.MatchString(`^[0-9a-zA-Z\-]+$`, attrs["kicked_user_id"].String()); !m {
return nil, errors.New("invalid kicked_user_id")
}

pickedCard := ""
if !attrs["picked_card"].IsNull() {
if m, _ := regexp.MatchString(`^[0-9a-zA-Z]*$`, attrs["picked_card"].String()); !m {
Expand All @@ -90,11 +96,12 @@ func NewOperation(attrs map[string]events.DynamoDBAttributeValue) (*Operation, e
}

return &Operation{
EventId: attrs["event_id"].String(),
RoomId: attrs["room_id"].String(),
OpType: opType,
UserId: attrs["user_id"].String(),
OperatedAt: attrs["operated_at"].String(),
PickedCard: pickedCard,
EventId: attrs["event_id"].String(),
RoomId: attrs["room_id"].String(),
OpType: opType,
UserId: attrs["user_id"].String(),
OperatedAt: attrs["operated_at"].String(),
PickedCard: pickedCard,
KickedUserId: attrs["kicked_user_id"].String(),
}, nil
}
2 changes: 1 addition & 1 deletion room/lambda/room-rmu/model/room_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func createStatus(opType OpType) (Status, error) {
switch opType {
case OpenRoom, Join, RefreshTable:
return NewStatus("CHOOSING")
case Leave:
case Leave, Kick:
return NewStatus("LEAVED")
case Pick:
return NewStatus("CHOSEN")
Expand Down
28 changes: 28 additions & 0 deletions room/lambda/room-rmu/service/room_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func (service *RoomService) SaveRoom(context context.Context, attrs map[string]e
return service.refreshPokerTable(context, operation)
case model.Heartbeat:
return service.updateOperatedAt(context, operation)
case model.Kick:
return service.kickUser(context, operation)
default:
return fmt.Errorf("unreachable error")
}
Expand Down Expand Up @@ -148,6 +150,32 @@ func (service *RoomService) updateOperatedAt(context context.Context, operation
return service.repository.UpdateActiveUserOperatedAt(context, operation.RoomId, operation.UserId, operation.OperatedAt)
}

func (service *RoomService) kickUser(context context.Context, operation *model.Operation) error {
rooms, err := service.repository.FindActiveUsers(context, operation.RoomId)
if err != nil {
return err
}

if !isProperUser(rooms, operation.UserId) {
return fmt.Errorf("passed user id is not active: %s", operation.UserId)
}

reqId, err := util.GetAWSRequestId(context)
if err != nil {
return err
}

logger.Infof("%s Room to kick %s by %s", reqId, operation.KickedUserId, operation.UserId)

return service.updateUserState(context, &model.Operation{
EventId: operation.EventId,
RoomId: operation.RoomId,
OpType: model.OpType("LEAVE"),
UserId: operation.KickedUserId,
OperatedAt: operation.OperatedAt,
})
}

func isProperUser(rooms *[]model.Room, userId string) bool {
for _, room := range *rooms {
if room.UserId == userId {
Expand Down
8 changes: 8 additions & 0 deletions room/lib/room-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ export class RoomStack extends Stack {
),
responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultItem(),
});
operationDataSource.createResolver({
typeName: "Mutation",
fieldName: "kick",
requestMappingTemplate: appsync.MappingTemplate.fromFile(
"appsync/room-api/resolvers/Mutation.kick.req.vtl"
),
responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultItem(),
});
const roomDataSource = roomAPI.addDynamoDbDataSource("room", roomTable);
const PokerDataSource = roomAPI.addNoneDataSource("poker");
// Define resolvers
Expand Down

0 comments on commit 2bb7885

Please sign in to comment.