package app import ( "context" "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" proto "evening_detective_server/proto" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func nilIfEmpty(value string) *string { if value == "" { return nil } return &value } func (s *server) AddGame(ctx context.Context, req *proto.AddGameReq) (*proto.AddGameRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } if req.StartAt == nil { return nil, status.Errorf(codes.InvalidArgument, "startAt must not be nil") } id, err := s.gameService.AddGame( ctx, req.Name, req.Description, nilIfEmpty(req.Location), req.StartAt.AsTime(), req.ScenarioID, req.Format, ) if err != nil { return nil, gameErrorStatus(err, "не удалось создать игру") } return &proto.AddGameRsp{ ID: int32(id), }, nil } func (s *server) DeleteGame(ctx context.Context, req *proto.DeleteGameReq) (*proto.DeleteGameRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } err := s.gameService.DeleteGame( ctx, int(req.ID), ) if err != nil { return nil, gameErrorStatus(err, "не удалось удалить игру") } return &proto.DeleteGameRsp{}, nil } func (s *server) GetGame(ctx context.Context, req *proto.GetGameReq) (*proto.GetGameRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } allowed, restricted := gameReadAccess(claims, s.uiService != nil && s.uiService.Environment == "venue") if !allowed { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } if restricted { game, err := s.gameService.GetGame(ctx, int(req.ID)) if err != nil { return nil, gameErrorStatus(err, "не удалось получить игру") } return &proto.GetGameRsp{Game: mapGameSummary(game)}, nil } game, err := s.gameService.GetFullGame(ctx, int(req.ID)) if err != nil { return nil, gameErrorStatus(err, "не удалось получить игру") } return &proto.GetGameRsp{ Game: mapGame(game), }, nil } func (s *server) GetGameAnswers(ctx context.Context, req *proto.GetGameAnswersReq) (*proto.GetGameAnswersRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } gameAnswers, err := s.answerService.GetGameAnswers(ctx, int(req.GameID)) if err != nil { return nil, answerErrorStatus(err, "не удалось получить ответы игры") } return &proto.GetGameAnswersRsp{ Questions: mapQuestions(gameAnswers.Questions), Teams: mapTeamAnswers(gameAnswers.Teams), }, nil } func (s *server) GetGameResults(ctx context.Context, req *proto.GetGameResultsReq) (*proto.GetGameResultsRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } results, err := s.answerService.GetGameResults(ctx, int(req.GameID)) if err != nil { return nil, answerErrorStatus(err, "не удалось получить результаты игры") } return &proto.GetGameResultsRsp{ Questions: mapResultsQuestions(results.Questions), Teams: mapTeamResults(results.Teams), }, nil } func (s *server) GetGames(ctx context.Context, _ *proto.GetGamesReq) (*proto.GetGamesRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } allowed, restricted := gameReadAccess(claims, s.uiService != nil && s.uiService.Environment == "venue") if !allowed { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } games, err := s.gameService.GetGames(ctx) if err != nil { return nil, gameErrorStatus(err, "не удалось получить игры") } if restricted { result := make([]*proto.Game, 0, len(games)) for _, game := range games { result = append(result, mapGameSummary(game)) } return &proto.GetGamesRsp{Games: result}, nil } return &proto.GetGamesRsp{Games: mapGames(games)}, nil } func (s *server) UpdateGame(ctx context.Context, req *proto.UpdateGameReq) (*proto.UpdateGameRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } if req.StartAt == nil { return nil, status.Errorf(codes.InvalidArgument, "startAt must not be nil") } err := s.gameService.UpdateGame( ctx, int(req.ID), req.Name, req.Description, nilIfEmpty(req.Location), req.StartAt.AsTime(), req.ScenarioID, req.Format, ) if err != nil { return nil, gameErrorStatus(err, "не удалось изменить игру") } return &proto.UpdateGameRsp{}, nil } func (s *server) StartGame(ctx context.Context, req *proto.StartGameReq) (*proto.StartGameRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } err := s.gameService.StartGame(ctx, int(req.ID)) if err != nil { return nil, gameErrorStatus(err, "не удалось запустить игру") } return &proto.StartGameRsp{}, nil } func (s *server) PauseGame(ctx context.Context, req *proto.PauseGameReq) (*proto.PauseGameRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } err := s.gameService.PauseGame(ctx, int(req.ID)) if err != nil { return nil, gameErrorStatus(err, "не удалось приостановить игру") } return &proto.PauseGameRsp{}, nil } func (s *server) PlayGame(ctx context.Context, req *proto.PlayGameReq) (*proto.PlayGameRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } err := s.gameService.PlayGame(ctx, int(req.ID)) if err != nil { return nil, gameErrorStatus(err, "не удалось продолжить игру") } return &proto.PlayGameRsp{}, nil } func (s *server) FinishGame(ctx context.Context, req *proto.FinishGameReq) (*proto.FinishGameRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } err := s.gameService.FinishGame(ctx, int(req.ID)) if err != nil { return nil, gameErrorStatus(err, "не удалось завершить игру") } return &proto.FinishGameRsp{}, nil } func (s *server) ResetGame(ctx context.Context, req *proto.ResetGameReq) (*proto.ResetGameRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } err := s.gameService.ResetGame(ctx, int(req.ID)) if err != nil { return nil, gameErrorStatus(err, "не удалось сбросить игру") } return &proto.ResetGameRsp{}, nil } func gameReadAccess(claims *processor_jwt.JWTClaims, venue bool) (allowed, restricted bool) { if roles.HasRole(claims, roles.Organizer) || roles.HasRole(claims, roles.Author) { return true, false } if venue && roles.HasRole(claims, roles.Developer) { return true, true } return false, false }