diff --git a/internal/app/answers.go b/internal/app/answers.go index bf32b85..f7b94a4 100644 --- a/internal/app/answers.go +++ b/internal/app/answers.go @@ -3,7 +3,6 @@ package app import ( "context" - "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" proto "evening_detective_server/proto" @@ -45,7 +44,10 @@ func (s *server) SubmitTeamAnswers(ctx context.Context, req *proto.SubmitTeamAns } func (s *server) SetTeamAnswerScore(ctx context.Context, req *proto.SetTeamAnswerScoreReq) (*proto.SetTeamAnswerScoreRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } diff --git a/internal/app/auth.go b/internal/app/auth.go new file mode 100644 index 0000000..7fb0932 --- /dev/null +++ b/internal/app/auth.go @@ -0,0 +1,18 @@ +package app + +import ( + "context" + + "evening_detective_server/internal/modules/processor_jwt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func claimsFromContext(ctx context.Context) (*processor_jwt.JWTClaims, error) { + claims, ok := processor_jwt.ClaimsFromContext(ctx) + if !ok { + return nil, status.Error(codes.Unauthenticated, "требуется авторизация") + } + return claims, nil +} diff --git a/internal/app/file_service_test.go b/internal/app/file_service_test.go index be10de2..29724ee 100644 --- a/internal/app/file_service_test.go +++ b/internal/app/file_service_test.go @@ -67,7 +67,7 @@ func newTestFileServer(storage *fakeStorage, maxSize int) *server { } func ctxWithClaims(roles ...string) context.Context { - return context.WithValue(context.Background(), "claims", &processor_jwt.JWTClaims{UserID: 1, Roles: roles}) + return processor_jwt.ContextWithClaims(context.Background(), &processor_jwt.JWTClaims{UserID: 1, Roles: roles}) } func pdfData(n int) []byte { diff --git a/internal/app/files.go b/internal/app/files.go index 4af0108..c85f31a 100644 --- a/internal/app/files.go +++ b/internal/app/files.go @@ -5,7 +5,6 @@ import ( "errors" "evening_detective_server/internal/modules/file_storage" - "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" "evening_detective_server/internal/services/file_service" proto "evening_detective_server/proto" @@ -19,7 +18,10 @@ import ( func (s *server) UploadFile(ctx context.Context, req *proto.UploadFileReq) (*proto.UploadFileRsp, error) { // Файлы (в т.ч. улики) загружают авторы сценариев в редакторе. - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } diff --git a/internal/app/game_reviews.go b/internal/app/game_reviews.go index 33eabaf..d309bbe 100644 --- a/internal/app/game_reviews.go +++ b/internal/app/game_reviews.go @@ -3,7 +3,6 @@ package app import ( "context" - "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" "evening_detective_server/internal/repos/game_reviews_repo" "evening_detective_server/proto" @@ -49,7 +48,10 @@ func (s *server) GetScenarioReviews(ctx context.Context, req *proto.GetScenarioR } func (s *server) GetGameReviewsForModeration(ctx context.Context, req *proto.GetGameReviewsReq) (*proto.GetGameReviewsRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Admin) { return nil, status.Error(codes.PermissionDenied, "permission denied") } @@ -61,7 +63,10 @@ func (s *server) GetGameReviewsForModeration(ctx context.Context, req *proto.Get } func (s *server) GetReviewsForModeration(ctx context.Context, req *proto.GetReviewsForModerationReq) (*proto.GetGameReviewsRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Admin) { return nil, status.Error(codes.PermissionDenied, "permission denied") } @@ -73,7 +78,10 @@ func (s *server) GetReviewsForModeration(ctx context.Context, req *proto.GetRevi } func (s *server) ModerateGameReview(ctx context.Context, req *proto.ModerateGameReviewReq) (*proto.ModerateGameReviewRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Admin) { return nil, status.Error(codes.PermissionDenied, "permission denied") } diff --git a/internal/app/games.go b/internal/app/games.go index 1a1fa77..13da7e0 100644 --- a/internal/app/games.go +++ b/internal/app/games.go @@ -3,7 +3,6 @@ package app import ( "context" - "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" proto "evening_detective_server/proto" @@ -19,7 +18,10 @@ func nilIfEmpty(value string) *string { } func (s *server) AddGame(ctx context.Context, req *proto.AddGameReq) (*proto.AddGameRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -49,7 +51,10 @@ func (s *server) AddGame(ctx context.Context, req *proto.AddGameReq) (*proto.Add } func (s *server) DeleteGame(ctx context.Context, req *proto.DeleteGameReq) (*proto.DeleteGameRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -68,7 +73,10 @@ func (s *server) DeleteGame(ctx context.Context, req *proto.DeleteGameReq) (*pro } func (s *server) GetGame(ctx context.Context, req *proto.GetGameReq) (*proto.GetGameRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -86,7 +94,10 @@ func (s *server) GetGame(ctx context.Context, req *proto.GetGameReq) (*proto.Get } func (s *server) GetGameAnswers(ctx context.Context, req *proto.GetGameAnswersReq) (*proto.GetGameAnswersRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -105,7 +116,10 @@ func (s *server) GetGameAnswers(ctx context.Context, req *proto.GetGameAnswersRe } func (s *server) GetGameResults(ctx context.Context, req *proto.GetGameResultsReq) (*proto.GetGameResultsRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -124,7 +138,10 @@ func (s *server) GetGameResults(ctx context.Context, req *proto.GetGameResultsRe } func (s *server) GetGames(ctx context.Context, req *proto.GetGamesReq) (*proto.GetGamesRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -142,7 +159,10 @@ func (s *server) GetGames(ctx context.Context, req *proto.GetGamesReq) (*proto.G } func (s *server) UpdateGame(ctx context.Context, req *proto.UpdateGameReq) (*proto.UpdateGameRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -171,7 +191,10 @@ func (s *server) UpdateGame(ctx context.Context, req *proto.UpdateGameReq) (*pro } func (s *server) StartGame(ctx context.Context, req *proto.StartGameReq) (*proto.StartGameRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -187,7 +210,10 @@ func (s *server) StartGame(ctx context.Context, req *proto.StartGameReq) (*proto } func (s *server) PauseGame(ctx context.Context, req *proto.PauseGameReq) (*proto.PauseGameRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -203,7 +229,10 @@ func (s *server) PauseGame(ctx context.Context, req *proto.PauseGameReq) (*proto } func (s *server) PlayGame(ctx context.Context, req *proto.PlayGameReq) (*proto.PlayGameRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -219,7 +248,10 @@ func (s *server) PlayGame(ctx context.Context, req *proto.PlayGameReq) (*proto.P } func (s *server) FinishGame(ctx context.Context, req *proto.FinishGameReq) (*proto.FinishGameRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -235,7 +267,10 @@ func (s *server) FinishGame(ctx context.Context, req *proto.FinishGameReq) (*pro } func (s *server) ResetGame(ctx context.Context, req *proto.ResetGameReq) (*proto.ResetGameRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } diff --git a/internal/app/scenario_archive.go b/internal/app/scenario_archive.go index 75c79f4..17e82ca 100644 --- a/internal/app/scenario_archive.go +++ b/internal/app/scenario_archive.go @@ -6,7 +6,6 @@ import ( "fmt" "strings" - "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" "evening_detective_server/internal/modules/scenario_archive" "evening_detective_server/internal/modules/string_tools" @@ -22,7 +21,10 @@ import ( ) func (s *server) DownloadScenarioArchive(ctx context.Context, req *proto.DownloadScenarioArchiveReq) (*httpbody.HttpBody, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -62,7 +64,10 @@ func (s *server) DownloadScenarioArchive(ctx context.Context, req *proto.Downloa } func (s *server) UploadScenarioArchive(ctx context.Context, req *httpbody.HttpBody) (*proto.UploadScenarioArchiveRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } diff --git a/internal/app/scenario_story.go b/internal/app/scenario_story.go index 2c39fd0..e573c72 100644 --- a/internal/app/scenario_story.go +++ b/internal/app/scenario_story.go @@ -3,7 +3,6 @@ package app import ( "context" - "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" proto "evening_detective_server/proto" @@ -12,7 +11,10 @@ import ( ) func (s *server) AddScenarioPlace(ctx context.Context, req *proto.AddScenarioPlaceReq) (*proto.AddScenarioPlaceRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -34,7 +36,10 @@ func (s *server) AddScenarioPlace(ctx context.Context, req *proto.AddScenarioPla } func (s *server) UpdateScenarioPlace(ctx context.Context, req *proto.UpdateScenarioPlaceReq) (*proto.UpdateScenarioPlaceRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -57,7 +62,10 @@ func (s *server) UpdateScenarioPlace(ctx context.Context, req *proto.UpdateScena } func (s *server) DeleteScenarioPlace(ctx context.Context, req *proto.DeleteScenarioPlaceReq) (*proto.DeleteScenarioPlaceRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -79,7 +87,10 @@ func (s *server) DeleteScenarioPlace(ctx context.Context, req *proto.DeleteScena } func (s *server) AddScenarioQuestion(ctx context.Context, req *proto.AddScenarioQuestionReq) (*proto.AddScenarioQuestionRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -101,7 +112,10 @@ func (s *server) AddScenarioQuestion(ctx context.Context, req *proto.AddScenario } func (s *server) UpdateScenarioQuestion(ctx context.Context, req *proto.UpdateScenarioQuestionReq) (*proto.UpdateScenarioQuestionRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -124,7 +138,10 @@ func (s *server) UpdateScenarioQuestion(ctx context.Context, req *proto.UpdateSc } func (s *server) DeleteScenarioQuestion(ctx context.Context, req *proto.DeleteScenarioQuestionReq) (*proto.DeleteScenarioQuestionRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -146,7 +163,10 @@ func (s *server) DeleteScenarioQuestion(ctx context.Context, req *proto.DeleteSc } func (s *server) UpdateScenarioBackground(ctx context.Context, req *proto.UpdateScenarioBackgroundReq) (*proto.UpdateScenarioBackgroundRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -168,7 +188,10 @@ func (s *server) UpdateScenarioBackground(ctx context.Context, req *proto.Update } func (s *server) UpdateScenarioIntro(ctx context.Context, req *proto.UpdateScenarioIntroReq) (*proto.UpdateScenarioIntroRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -190,7 +213,10 @@ func (s *server) UpdateScenarioIntro(ctx context.Context, req *proto.UpdateScena } func (s *server) UpdateScenarioConclusion(ctx context.Context, req *proto.UpdateScenarioConclusionReq) (*proto.UpdateScenarioConclusionRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } diff --git a/internal/app/scenarios.go b/internal/app/scenarios.go index a35409e..330fe1c 100644 --- a/internal/app/scenarios.go +++ b/internal/app/scenarios.go @@ -3,7 +3,6 @@ package app import ( "context" - "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" "evening_detective_server/internal/services/scenarios_service" proto "evening_detective_server/proto" @@ -13,7 +12,10 @@ import ( ) func (s *server) AddScenario(ctx context.Context, req *proto.AddScenarioReq) (*proto.AddScenarioRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -30,7 +32,10 @@ func (s *server) AddScenario(ctx context.Context, req *proto.AddScenarioReq) (*p } func (s *server) GetMyScenarios(ctx context.Context, req *proto.GetMyScenariosReq) (*proto.GetMyScenariosRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -64,7 +69,10 @@ func (s *server) GetScenariosCatalog(ctx context.Context, req *proto.GetScenario } func (s *server) GetFullScenario(ctx context.Context, req *proto.GetScenarioReq) (*proto.GetScenarioRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -110,7 +118,10 @@ func (s *server) addScenarioRatings(ctx context.Context, scenarios []*scenarios_ } func (s *server) UpdateScenario(ctx context.Context, req *proto.UpdateScenarioReq) (*proto.UpdateScenarioRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -134,7 +145,10 @@ func (s *server) UpdateScenario(ctx context.Context, req *proto.UpdateScenarioRe } func (s *server) PublicScenario(ctx context.Context, req *proto.PublicScenarioReq) (*proto.PublicScenarioRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -156,7 +170,10 @@ func (s *server) PublicScenario(ctx context.Context, req *proto.PublicScenarioRe } func (s *server) DraftScenario(ctx context.Context, req *proto.DraftScenarioReq) (*proto.DraftScenarioRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } // Снять с публикации опубликованный сценарий может только админ: // исключительное право отчуждено Оператору в момент публикации // (п. 7.2 Пользовательского соглашения, ст. 1234, 1269 ГК РФ). @@ -181,7 +198,10 @@ func (s *server) DraftScenario(ctx context.Context, req *proto.DraftScenarioReq) } func (s *server) DeleteScenario(ctx context.Context, req *proto.DeleteScenarioReq) (*proto.DeleteScenarioRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } diff --git a/internal/app/screens.go b/internal/app/screens.go index d002718..63be67a 100644 --- a/internal/app/screens.go +++ b/internal/app/screens.go @@ -143,7 +143,7 @@ func (s *server) SetScreenSound(ctx context.Context, req *proto.SetScreenSoundRe } func canManageScreens(ctx context.Context) bool { - claims, ok := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, ok := processor_jwt.ClaimsFromContext(ctx) if !ok || claims == nil { return false } diff --git a/internal/app/team_qr.go b/internal/app/team_qr.go index 537feea..d1dbed7 100644 --- a/internal/app/team_qr.go +++ b/internal/app/team_qr.go @@ -19,7 +19,7 @@ import ( ) func (s *server) DownloadTeamQR(ctx context.Context, req *proto.GetGameReq) (*httpbody.HttpBody, error) { - claims, ok := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, ok := processor_jwt.ClaimsFromContext(ctx) if !ok || claims == nil { return nil, status.Error(codes.Unauthenticated, "необходима авторизация") } diff --git a/internal/app/teams.go b/internal/app/teams.go index b314ad7..ae68b89 100644 --- a/internal/app/teams.go +++ b/internal/app/teams.go @@ -3,7 +3,6 @@ package app import ( "context" - "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" proto "evening_detective_server/proto" @@ -12,7 +11,10 @@ import ( ) func (s *server) AddTeam(ctx context.Context, req *proto.AddTeamReq) (*proto.AddTeamRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -37,7 +39,10 @@ func (s *server) AddTeam(ctx context.Context, req *proto.AddTeamReq) (*proto.Add } func (s *server) UpdateTeam(ctx context.Context, req *proto.UpdateTeamReq) (*proto.UpdateTeamRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -57,7 +62,10 @@ func (s *server) UpdateTeam(ctx context.Context, req *proto.UpdateTeamReq) (*pro } func (s *server) DeleteTeam(ctx context.Context, req *proto.DeleteTeamReq) (*proto.DeleteTeamRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -76,7 +84,10 @@ func (s *server) DeleteTeam(ctx context.Context, req *proto.DeleteTeamReq) (*pro } func (s *server) GiveTeamApplications(ctx context.Context, req *proto.GiveTeamApplicationsReq) (*proto.GiveTeamApplicationsRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + 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") } @@ -136,7 +147,10 @@ func (s *server) AddTeamAction(ctx context.Context, req *proto.AddTeamActionReq) } func (s *server) DeleteLastTeamAction(ctx context.Context, req *proto.DeleteLastTeamActionReq) (*proto.DeleteLastTeamActionRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } diff --git a/internal/app/tickets.go b/internal/app/tickets.go index 3173602..0b4bbf4 100644 --- a/internal/app/tickets.go +++ b/internal/app/tickets.go @@ -44,7 +44,7 @@ func (s *server) GetTicket(ctx context.Context, req *proto.GetTicketReq) (*proto } func (s *server) AcceptTicket(ctx context.Context, req *proto.AcceptTicketReq) (*proto.AcceptTicketRsp, error) { - claims, ok := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, ok := processor_jwt.ClaimsFromContext(ctx) if !ok || claims == nil || (!roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author)) { return nil, status.Error(codes.PermissionDenied, "permission denied") } @@ -69,7 +69,7 @@ func (s *server) AcceptTicket(ctx context.Context, req *proto.AcceptTicketReq) ( } func (s *server) IssueGameTickets(ctx context.Context, req *proto.IssueGameTicketsReq) (*proto.IssueGameTicketsRsp, error) { - claims, ok := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, ok := processor_jwt.ClaimsFromContext(ctx) if !ok || claims == nil { return nil, status.Error(codes.Unauthenticated, "необходима авторизация") } diff --git a/internal/app/users.go b/internal/app/users.go index e8f7692..b1c2c76 100644 --- a/internal/app/users.go +++ b/internal/app/users.go @@ -37,7 +37,7 @@ func (s *server) Signup(ctx context.Context, req *proto.SignupReq) (*proto.Signu } func (s *server) DeleteAccount(ctx context.Context, req *proto.DeleteAccountReq) (*proto.DeleteAccountRsp, error) { - claims, ok := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, ok := processor_jwt.ClaimsFromContext(ctx) if !ok { return nil, status.Errorf(codes.Unauthenticated, "claims is not provided") } @@ -152,7 +152,10 @@ func (s *server) Refresh(ctx context.Context, req *proto.RefreshReq) (*proto.Ref } func (s *server) GetUsers(ctx context.Context, req *proto.GetUsersReq) (*proto.GetUsersRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Admin) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -186,7 +189,10 @@ func (s *server) GetUserById(ctx context.Context, req *proto.GetUserByIdReq) (*p } func (s *server) GetMe(ctx context.Context, req *proto.GetMeReq) (*proto.GetMeRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } user, err := s.usersService.GetUserByID(ctx, claims.UserID) if err != nil { return &proto.GetMeRsp{ @@ -200,7 +206,10 @@ func (s *server) GetMe(ctx context.Context, req *proto.GetMeReq) (*proto.GetMeRs } func (s *server) AddUserRole(ctx context.Context, req *proto.AddUserRoleReq) (*proto.AddUserRoleRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Admin) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -213,7 +222,10 @@ func (s *server) AddUserRole(ctx context.Context, req *proto.AddUserRoleReq) (*p } func (s *server) DeleteUserRole(ctx context.Context, req *proto.DeleteUserRoleReq) (*proto.DeleteUserRoleRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } if !roles.HasRole(claims, roles.Admin) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } @@ -226,7 +238,10 @@ func (s *server) DeleteUserRole(ctx context.Context, req *proto.DeleteUserRoleRe } func (s *server) GetPermissions(ctx context.Context, req *proto.GetPermissionsReq) (*proto.GetPermissionsRsp, error) { - claims := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, claimsErr := claimsFromContext(ctx) + if claimsErr != nil { + return nil, claimsErr + } permissions := s.uiService.GetPermissions(claims.Roles) return &proto.GetPermissionsRsp{ Permissions: permissions, @@ -234,7 +249,7 @@ func (s *server) GetPermissions(ctx context.Context, req *proto.GetPermissionsRe } func (s *server) ChangeUserPassword(ctx context.Context, req *proto.ChangeUserPasswordReq) (*proto.ChangeUserPasswordRsp, error) { - claims, ok := ctx.Value("claims").(*processor_jwt.JWTClaims) + claims, ok := processor_jwt.ClaimsFromContext(ctx) if !ok || claims == nil { return nil, status.Error(codes.Unauthenticated, "Требуется авторизация") } diff --git a/internal/modules/processor_jwt/context.go b/internal/modules/processor_jwt/context.go new file mode 100644 index 0000000..f588e0e --- /dev/null +++ b/internal/modules/processor_jwt/context.go @@ -0,0 +1,16 @@ +package processor_jwt + +import "context" + +type claimsContextKey struct{} + +// ContextWithClaims stores authenticated claims in ctx. +func ContextWithClaims(ctx context.Context, claims *JWTClaims) context.Context { + return context.WithValue(ctx, claimsContextKey{}, claims) +} + +// ClaimsFromContext returns authenticated claims stored in ctx. +func ClaimsFromContext(ctx context.Context) (*JWTClaims, bool) { + claims, ok := ctx.Value(claimsContextKey{}).(*JWTClaims) + return claims, ok && claims != nil +} diff --git a/internal/modules/processor_jwt/interceptor.go b/internal/modules/processor_jwt/interceptor.go index 0e1cfd7..7d048c1 100644 --- a/internal/modules/processor_jwt/interceptor.go +++ b/internal/modules/processor_jwt/interceptor.go @@ -39,7 +39,7 @@ func NewAuthorizationInterceptor( return nil, status.Errorf(codes.Unauthenticated, "invalid token") } - ctx = context.WithValue(ctx, "claims", claims) + ctx = ContextWithClaims(ctx, claims) return handler(ctx, req) } }