diff --git a/cmd/main.go b/cmd/main.go index 7537909..7cca195 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -66,7 +66,7 @@ func main() { groupSvc := group.NewService(groupRepo, userRepo, cacheRepo, &conf.Group, logger.Named("groupSvc")) selectionRepo := selection.NewRepository(db) - selectionSvc := selection.NewService(selectionRepo, cacheRepo, &conf.Selection, logger.Named("selectionSvc")) + selectionSvc := selection.NewService(selectionRepo, groupRepo, cacheRepo, &conf.Selection, logger.Named("selectionSvc")) countRepo := count.NewRepository(db) countSvc := count.NewService(countRepo, logger.Named("countSvc")) diff --git a/internal/group/group.service.go b/internal/group/group.service.go index 8245603..1eaa595 100644 --- a/internal/group/group.service.go +++ b/internal/group/group.service.go @@ -189,6 +189,11 @@ func (s *serviceImpl) DeleteMember(_ context.Context, in *proto.DeleteMemberGrou return nil, err } + if group.IsConfirmed { + s.log.Named("DeleteMember").Error("Group is confirmed", zap.String("user_id", in.UserId)) + return nil, status.Error(codes.PermissionDenied, "Group is confirmed, so you cannot delete member") + } + if in.LeaderId != group.LeaderID.String() { s.log.Named("DeleteMember").Error("Requested leader_id is not leader of this group", zap.String("leader_id", in.LeaderId)) return nil, status.Error(codes.PermissionDenied, "requested leader_id is not leader of this group") @@ -263,6 +268,11 @@ func (s *serviceImpl) Leave(_ context.Context, in *proto.LeaveGroupRequest) (*pr return nil, err } + if group.IsConfirmed { + s.log.Named("Leave").Error("Group is confirmed", zap.String("user_id", in.UserId)) + return nil, status.Error(codes.PermissionDenied, "Group is confirmed, so you cannot leave") + } + if in.UserId == group.LeaderID.String() { s.log.Named("Leave").Error("User is the leader of the group", zap.String("user_id", in.UserId)) return nil, status.Error(codes.PermissionDenied, "You are the group leader, so you cannot leave") @@ -328,6 +338,17 @@ func (s *serviceImpl) Leave(_ context.Context, in *proto.LeaveGroupRequest) (*pr } func (s *serviceImpl) Join(_ context.Context, in *proto.JoinGroupRequest) (*proto.JoinGroupResponse, error) { + group, err := s.findByUserId(in.UserId) + if err != nil { + s.log.Named("Join").Error("findByUserId group: ", zap.Error(err)) + return nil, err + } + + if group.IsConfirmed { + s.log.Named("Join").Error("Group is confirmed", zap.String("user_id", in.UserId)) + return nil, status.Error(codes.PermissionDenied, "Group is confirmed, so you cannot leave to join other groups") + } + joiningGroup := &model.Group{} if err := s.repo.FindByToken(in.Token, joiningGroup); err != nil { s.log.Named("Join").Error("FindByToken joiningGroup TX: ", zap.Error(err)) diff --git a/internal/selection/selection.service.go b/internal/selection/selection.service.go index 58c2098..6822433 100644 --- a/internal/selection/selection.service.go +++ b/internal/selection/selection.service.go @@ -7,6 +7,7 @@ import ( "github.com/google/uuid" "github.com/isd-sgcu/rpkm67-backend/config" "github.com/isd-sgcu/rpkm67-backend/internal/cache" + "github.com/isd-sgcu/rpkm67-backend/internal/group" proto "github.com/isd-sgcu/rpkm67-go-proto/rpkm67/backend/selection/v1" "github.com/isd-sgcu/rpkm67-model/model" "go.uber.org/zap" @@ -20,22 +21,34 @@ type Service interface { type serviceImpl struct { proto.UnimplementedSelectionServiceServer - repo Repository - cache cache.Repository - conf *config.SelectionConfig - log *zap.Logger + repo Repository + groupRepo group.Repository + cache cache.Repository + conf *config.SelectionConfig + log *zap.Logger } -func NewService(repo Repository, cache cache.Repository, conf *config.SelectionConfig, log *zap.Logger) Service { +func NewService(repo Repository, groupRepo group.Repository, cache cache.Repository, conf *config.SelectionConfig, log *zap.Logger) Service { return &serviceImpl{ - repo: repo, - cache: cache, - conf: conf, - log: log, + repo: repo, + groupRepo: groupRepo, + cache: cache, + conf: conf, + log: log, } } func (s *serviceImpl) Create(ctx context.Context, in *proto.CreateSelectionRequest) (*proto.CreateSelectionResponse, error) { + isConfirmed, err := s.isGroupConfirmed(in.GroupId) + if err != nil { + s.log.Named("Create").Error(fmt.Sprintf("isGroupConfirmed: group_id=%s", in.GroupId), zap.Error(err)) + return nil, status.Error(codes.Internal, err.Error()) + } + if isConfirmed { + s.log.Named("Create").Error(fmt.Sprintf("Failed to create selection: group_id=%s", in.GroupId), zap.Error(err)) + return nil, status.Error(codes.InvalidArgument, "Group is confirmed, cannot create selection") + } + groupUUID, err := uuid.Parse(in.GroupId) if err != nil { s.log.Named("Create").Error(fmt.Sprintf("Parse group id: %s", in.GroupId), zap.Error(err)) @@ -130,7 +143,17 @@ func (s *serviceImpl) FindByGroupId(ctx context.Context, in *proto.FindByGroupId } func (s *serviceImpl) Delete(ctx context.Context, in *proto.DeleteSelectionRequest) (*proto.DeleteSelectionResponse, error) { - err := s.repo.Delete(in.GroupId, in.BaanId) + isConfirmed, err := s.isGroupConfirmed(in.GroupId) + if err != nil { + s.log.Named("Create").Error(fmt.Sprintf("isGroupConfirmed: group_id=%s", in.GroupId), zap.Error(err)) + return nil, status.Error(codes.Internal, err.Error()) + } + if isConfirmed { + s.log.Named("Create").Error(fmt.Sprintf("Failed to create selection: group_id=%s", in.GroupId), zap.Error(err)) + return nil, status.Error(codes.InvalidArgument, "Group is confirmed, cannot delete selection") + } + + err = s.repo.Delete(in.GroupId, in.BaanId) if err != nil { s.log.Named("Delete").Error(fmt.Sprintf("Delete: group_id=%s, baan_id=%s", in.GroupId, in.BaanId), zap.Error(err)) return nil, status.Error(codes.Internal, err.Error()) @@ -184,9 +207,19 @@ func (s *serviceImpl) CountByBaanId(ctx context.Context, in *proto.CountByBaanId } func (s *serviceImpl) Update(ctx context.Context, in *proto.UpdateSelectionRequest) (*proto.UpdateSelectionResponse, error) { + isConfirmed, err := s.isGroupConfirmed(in.GroupId) + if err != nil { + s.log.Named("Create").Error(fmt.Sprintf("isGroupConfirmed: group_id=%s", in.GroupId), zap.Error(err)) + return nil, status.Error(codes.Internal, err.Error()) + } + if isConfirmed { + s.log.Named("Create").Error(fmt.Sprintf("Failed to create selection: group_id=%s", in.GroupId), zap.Error(err)) + return nil, status.Error(codes.InvalidArgument, "Group is confirmed, cannot update selection") + } + oldSelections := &[]model.Selection{} - err := s.repo.FindByGroupId(in.GroupId, oldSelections) + err = s.repo.FindByGroupId(in.GroupId, oldSelections) if err != nil { s.log.Named("Update").Error(fmt.Sprintf("FindByGroupId: group_id=%s", in.GroupId), zap.Error(err)) return nil, status.Error(codes.Internal, err.Error()) @@ -254,3 +287,13 @@ func (s *serviceImpl) Update(ctx context.Context, in *proto.UpdateSelectionReque return &res, nil } + +func (s *serviceImpl) isGroupConfirmed(groupID string) (bool, error) { + group := &model.Group{} + if err := s.groupRepo.FindOne(groupID, group); err != nil { + s.log.Named("isGroupConfirmed").Error(fmt.Sprintf("FindOne: group_id=%s", groupID), zap.Error(err)) + return false, err + } + + return group.IsConfirmed, nil +}