generated from VLADIMIR/template
add change password
This commit is contained in:
+28
-7
@@ -186,6 +186,20 @@ service EveningDetectiveServer {
|
||||
};
|
||||
}
|
||||
|
||||
// Только администратор; сеансы пользователя сохраняются.
|
||||
// Ошибки: 401, 403, 400, 404, 500.
|
||||
rpc ChangeUserPassword(ChangeUserPasswordReq) returns (ChangeUserPasswordRsp) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/users/{id}/password"
|
||||
body: "*"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
tags : "Пользователи";
|
||||
summary : "Изменить чужой пароль (только администратор)";
|
||||
description: "Пароль вводится вручную: минимум 12 символов, максимум 72 байта. Сеансы сохраняются. Ошибки: 401 — нет авторизации, 403 — нет прав, 400 — неверные данные или собственный ID, 404 — пользователь не найден, 500 — ошибка сохранения.";
|
||||
};
|
||||
}
|
||||
|
||||
rpc AddUserRole(AddUserRoleReq) returns (AddUserRoleRsp) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/users/{id}/role/add"
|
||||
@@ -423,11 +437,11 @@ service EveningDetectiveServer {
|
||||
// Видео загружается через UploadFile (MP4/WebM). Пустая conclusion удаляет закрывашку.
|
||||
rpc UpdateScenarioConclusion(UpdateScenarioConclusionReq) returns (UpdateScenarioConclusionRsp) {
|
||||
option (google.api.http) = {
|
||||
put: "/api/scenarios/{id}/conclusion"
|
||||
put : "/api/scenarios/{id}/conclusion"
|
||||
body: "*"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
tags: "Сценарии";
|
||||
tags : "Сценарии";
|
||||
summary: "Обновить закрывашку сценария (игрокам не передаётся)";
|
||||
};
|
||||
}
|
||||
@@ -826,6 +840,13 @@ message GetMeRsp {
|
||||
User user = 2;
|
||||
}
|
||||
|
||||
message ChangeUserPasswordReq {
|
||||
int32 id = 1;
|
||||
string new_password = 2;
|
||||
}
|
||||
|
||||
message ChangeUserPasswordRsp {}
|
||||
|
||||
message AddUserRoleReq {
|
||||
int32 id = 1;
|
||||
string role = 2;
|
||||
@@ -922,7 +943,7 @@ message Story {
|
||||
}
|
||||
|
||||
message Conclusion {
|
||||
string text = 1;
|
||||
string text = 1;
|
||||
string video = 2;
|
||||
}
|
||||
|
||||
@@ -1062,7 +1083,7 @@ message DeleteScenarioPlaceRsp {
|
||||
}
|
||||
|
||||
message UpdateScenarioConclusionReq {
|
||||
int32 id = 1;
|
||||
int32 id = 1;
|
||||
Conclusion conclusion = 2;
|
||||
}
|
||||
|
||||
@@ -1309,9 +1330,9 @@ message GetTeamStoryReq {
|
||||
}
|
||||
|
||||
message GetTeamStoryRsp {
|
||||
string error = 1;
|
||||
Story story = 2;
|
||||
Game game = 3;
|
||||
string error = 1;
|
||||
Story story = 2;
|
||||
Game game = 3;
|
||||
repeated TeamAction actions = 4;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -2056,6 +2056,47 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/users/{id}/password": {
|
||||
"post": {
|
||||
"summary": "Изменить чужой пароль (только администратор)",
|
||||
"description": "Пароль вводится вручную: минимум 12 символов, максимум 72 байта. Сеансы сохраняются. Ошибки: 401 — нет авторизации, 403 — нет прав, 400 — неверные данные или собственный ID, 404 — пользователь не найден, 500 — ошибка сохранения.",
|
||||
"operationId": "EveningDetectiveServer_ChangeUserPassword",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/evening_detective_serverChangeUserPasswordRsp"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/EveningDetectiveServerChangeUserPasswordBody"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Пользователи"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/users/{id}/role/add": {
|
||||
"post": {
|
||||
"summary": "Добавить пользователю роль",
|
||||
@@ -2173,6 +2214,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"EveningDetectiveServerChangeUserPasswordBody": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"newPassword": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"EveningDetectiveServerDeleteUserRoleBody": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -2495,6 +2544,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"evening_detective_serverChangeUserPasswordRsp": {
|
||||
"type": "object"
|
||||
},
|
||||
"evening_detective_serverConclusion": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"evening_detective_server/internal/modules/processor_jwt"
|
||||
"evening_detective_server/internal/repos"
|
||||
"evening_detective_server/internal/repos/users_repo"
|
||||
"evening_detective_server/internal/services/users_service"
|
||||
"evening_detective_server/proto"
|
||||
"fmt"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/grpc/test/bufconn"
|
||||
"net"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestChangeUserPasswordAccess(t *testing.T) {
|
||||
s := &server{}
|
||||
for _, tc := range []struct {
|
||||
ctx context.Context
|
||||
want codes.Code
|
||||
}{
|
||||
{context.Background(), codes.Unauthenticated},
|
||||
{ctxWithClaims(), codes.PermissionDenied},
|
||||
{ctxWithClaims("user"), codes.PermissionDenied},
|
||||
{ctxWithClaims("author"), codes.PermissionDenied},
|
||||
{ctxWithClaims("organizer"), codes.PermissionDenied},
|
||||
} {
|
||||
_, err := s.ChangeUserPassword(tc.ctx, &proto.ChangeUserPasswordReq{Id: 2, NewPassword: "123456789012"})
|
||||
if status.Code(err) != tc.want {
|
||||
t.Errorf("code = %v, want %v", status.Code(err), tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Embed the real repository so unexpected calls fail rather than silently pass.
|
||||
type passwordRepo struct {
|
||||
*users_repo.UsersRepo
|
||||
role string
|
||||
saveErr error
|
||||
hash string
|
||||
}
|
||||
|
||||
func (r *passwordRepo) GetUserByID(_ context.Context, id int) (*repos.User, error) {
|
||||
if id == 1 {
|
||||
return &repos.User{ID: 1, Roles: []string{r.role}}, nil
|
||||
}
|
||||
if id == 2 {
|
||||
return &repos.User{ID: 2, Email: "target@example.org"}, nil
|
||||
}
|
||||
return nil, users_repo.ErrUserNotFound
|
||||
}
|
||||
func (r *passwordRepo) UpdateUserPassword(_ context.Context, email, hash string) error {
|
||||
if r.saveErr != nil {
|
||||
return r.saveErr
|
||||
}
|
||||
r.hash = hash
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestChangeUserPasswordTransports(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
jwt := processor_jwt.NewProcessor("test-secret")
|
||||
repo := &passwordRepo{role: "admin"}
|
||||
svc := users_service.NewUsersService(repo, nil, nil, nil, nil, "")
|
||||
listener := bufconn.Listen(1024 * 1024)
|
||||
defer listener.Close()
|
||||
gs := grpc.NewServer(grpc.UnaryInterceptor(processor_jwt.NewAuthorizationInterceptor(nil, jwt)))
|
||||
proto.RegisterEveningDetectiveServerServer(gs, &server{usersService: svc})
|
||||
go gs.Serve(listener)
|
||||
defer gs.Stop()
|
||||
conn, err := grpc.NewClient("passthrough:///test", grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { return listener.Dial() }))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
mux := runtime.NewServeMux()
|
||||
if err := proto.RegisterEveningDetectiveServerHandler(ctx, mux, conn); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
client := proto.NewEveningDetectiveServerClient(conn)
|
||||
for _, tc := range []struct {
|
||||
name, tokenRole, dbRole string
|
||||
id int32
|
||||
password string
|
||||
saveErr error
|
||||
code codes.Code
|
||||
httpCode int
|
||||
}{
|
||||
{"anonymous", "", "admin", 2, "123456789012", nil, codes.Unauthenticated, 401},
|
||||
{"user", "user", "admin", 2, "123456789012", nil, codes.PermissionDenied, 403},
|
||||
{"removed admin", "admin", "user", 2, "123456789012", nil, codes.PermissionDenied, 403},
|
||||
{"invalid", "admin", "admin", 2, "short", nil, codes.InvalidArgument, 400},
|
||||
{"missing", "admin", "admin", 3, "123456789012", nil, codes.NotFound, 404},
|
||||
{"save failure", "admin", "admin", 2, "123456789012", errors.New("private database detail"), codes.Internal, 500},
|
||||
{"deleted during save", "admin", "admin", 2, "123456789012", users_repo.ErrUserNotFound, codes.NotFound, 404},
|
||||
{"success", "admin", "admin", 2, "123456789012", nil, codes.OK, 200},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
repo.role, repo.saveErr, repo.hash = tc.dbRole, tc.saveErr, ""
|
||||
token := ""
|
||||
rpcCtx := ctx
|
||||
if tc.tokenRole != "" {
|
||||
token, err = jwt.GenerateAccessToken(1, "admin@example.org", []string{tc.tokenRole})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rpcCtx = metadata.NewOutgoingContext(ctx, metadata.Pairs("authorization", "Bearer "+token))
|
||||
}
|
||||
_, err := client.ChangeUserPassword(rpcCtx, &proto.ChangeUserPasswordReq{Id: tc.id, NewPassword: tc.password})
|
||||
if status.Code(err) != tc.code {
|
||||
t.Fatalf("gRPC = %v, want %v", err, tc.code)
|
||||
}
|
||||
req := httptest.NewRequest("POST", fmt.Sprintf("/api/users/%d/password", tc.id), strings.NewReader(fmt.Sprintf(`{"new_password":%q}`, tc.password)))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
if token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
}
|
||||
rsp := httptest.NewRecorder()
|
||||
mux.ServeHTTP(rsp, req)
|
||||
if rsp.Code != tc.httpCode {
|
||||
t.Fatalf("HTTP = %d: %s", rsp.Code, rsp.Body.String())
|
||||
}
|
||||
if strings.Contains(rsp.Body.String(), tc.password) || strings.Contains(rsp.Body.String(), "private database detail") {
|
||||
t.Fatal("sensitive response")
|
||||
}
|
||||
if tc.code == codes.OK {
|
||||
if bcrypt.CompareHashAndPassword([]byte(repo.hash), []byte(tc.password)) != nil {
|
||||
t.Fatal("password not saved")
|
||||
}
|
||||
if _, err := jwt.GetClaims(token); err != nil {
|
||||
t.Fatal("existing token rejected")
|
||||
}
|
||||
} else if repo.hash != "" {
|
||||
t.Fatal("unauthorized or failed write")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"evening_detective_server/internal/modules/scenario_archive"
|
||||
"evening_detective_server/internal/modules/string_tools"
|
||||
"evening_detective_server/internal/repos/scenarios_repo"
|
||||
"evening_detective_server/internal/repos/users_repo"
|
||||
"evening_detective_server/internal/services/file_service"
|
||||
"evening_detective_server/internal/services/game_service"
|
||||
"evening_detective_server/internal/services/scenarios_service"
|
||||
@@ -1226,3 +1227,25 @@ func (s *server) SetTeamAnswerScore(ctx context.Context, req *proto.SetTeamAnswe
|
||||
|
||||
return &proto.SetTeamAnswerScoreRsp{}, nil
|
||||
}
|
||||
|
||||
func (s *server) ChangeUserPassword(ctx context.Context, req *proto.ChangeUserPasswordReq) (*proto.ChangeUserPasswordRsp, error) {
|
||||
claims, ok := ctx.Value("claims").(*processor_jwt.JWTClaims)
|
||||
if !ok || claims == nil {
|
||||
return nil, status.Error(codes.Unauthenticated, "Требуется авторизация")
|
||||
}
|
||||
if !roles.HasRole(claims, roles.Admin) {
|
||||
return nil, status.Error(codes.PermissionDenied, "Недостаточно прав")
|
||||
}
|
||||
err := s.usersService.ChangeUserPassword(ctx, claims.UserID, int(req.GetId()), req.GetNewPassword())
|
||||
switch {
|
||||
case errors.Is(err, users_service.ErrPasswordChangeForbidden):
|
||||
return nil, status.Error(codes.PermissionDenied, err.Error())
|
||||
case errors.Is(err, users_service.ErrInvalidPasswordChange):
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
case errors.Is(err, users_repo.ErrUserNotFound):
|
||||
return nil, status.Error(codes.NotFound, err.Error())
|
||||
case err != nil:
|
||||
return nil, status.Error(codes.Internal, "Не удалось изменить пароль")
|
||||
}
|
||||
return &proto.ChangeUserPasswordRsp{}, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package users_service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"evening_detective_server/internal/repos"
|
||||
"evening_detective_server/internal/repos/users_repo"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func TestChangeUserPassword(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name, role, password string
|
||||
actor, target int
|
||||
want error
|
||||
}{
|
||||
{"success", "admin", " новый пароль ", 1, 2, nil},
|
||||
{"other admin", "admin", "123456789012", 1, 3, nil},
|
||||
{"removed role", "user", "123456789012", 1, 2, ErrPasswordChangeForbidden},
|
||||
{"missing actor", "admin", "123456789012", 4, 2, ErrPasswordChangeForbidden},
|
||||
{"self", "admin", "123456789012", 1, 1, ErrInvalidPasswordChange},
|
||||
{"bad id", "admin", "123456789012", 1, -1, ErrInvalidPasswordChange},
|
||||
{"missing target", "admin", "123456789012", 1, 4, users_repo.ErrUserNotFound},
|
||||
{"empty", "admin", "", 1, 2, ErrInvalidPasswordChange},
|
||||
{"short unicode", "admin", "яяббввггдде", 1, 2, ErrInvalidPasswordChange},
|
||||
{"too many bytes", "admin", strings.Repeat("я", 37), 1, 2, ErrInvalidPasswordChange},
|
||||
{"72 bytes", "admin", strings.Repeat("я", 36), 1, 2, nil},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
r := newFakeRepo()
|
||||
old, err := bcrypt.GenerateFromPassword([]byte("old password"), bcrypt.MinCost)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for id, role := range []string{tc.role, "user", "admin"} {
|
||||
u := &repos.User{ID: id + 1, Email: role + string(rune('0'+id)), Roles: []string{role}, PasswordHash: string(old)}
|
||||
r.byID[u.ID] = u
|
||||
r.users[u.Email] = u
|
||||
}
|
||||
// Nil JWT, token repository and mail sender ensure this operation does not use them.
|
||||
s := &UsersService{usersRepo: r}
|
||||
err = s.ChangeUserPassword(context.Background(), tc.actor, tc.target, tc.password)
|
||||
if !errors.Is(err, tc.want) {
|
||||
t.Fatalf("error = %v, want %v", err, tc.want)
|
||||
}
|
||||
for id, u := range r.byID {
|
||||
if tc.want == nil && id == tc.target {
|
||||
if bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(tc.password)) != nil {
|
||||
t.Fatal("new password rejected")
|
||||
}
|
||||
if bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte("old password")) == nil {
|
||||
t.Fatal("old password accepted")
|
||||
}
|
||||
} else if u.PasswordHash != string(old) {
|
||||
t.Fatal("unrelated or rejected update")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
@@ -372,3 +373,34 @@ func (s *UsersService) DeleteUserRole(
|
||||
}
|
||||
return s.usersRepo.DeleteUserRole(ctx, userId, role)
|
||||
}
|
||||
|
||||
var (
|
||||
ErrPasswordChangeForbidden = errors.New("Изменять чужой пароль может только администратор")
|
||||
ErrInvalidPasswordChange = errors.New("Укажите чужой положительный ID и пароль от 12 символов до 72 байт")
|
||||
)
|
||||
|
||||
// ChangeUserPassword сохраняет только хеш; действующие сеансы не изменяются.
|
||||
func (s *UsersService) ChangeUserPassword(ctx context.Context, actorID, userID int, password string) error {
|
||||
actor, err := s.usersRepo.GetUserByID(ctx, actorID)
|
||||
if errors.Is(err, users_repo.ErrUserNotFound) {
|
||||
return ErrPasswordChangeForbidden
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !slices.Contains(actor.Roles, roles.Admin) {
|
||||
return ErrPasswordChangeForbidden
|
||||
}
|
||||
if userID <= 0 || userID == actorID || !utf8.ValidString(password) || utf8.RuneCountInString(password) < 12 || len(password) > 72 {
|
||||
return ErrInvalidPasswordChange
|
||||
}
|
||||
user, err := s.usersRepo.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.usersRepo.UpdateUserPassword(ctx, user.Email, string(hash))
|
||||
}
|
||||
|
||||
+689
-591
File diff suppressed because it is too large
Load Diff
@@ -365,6 +365,51 @@ func local_request_EveningDetectiveServer_GetMe_0(ctx context.Context, marshaler
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func request_EveningDetectiveServer_ChangeUserPassword_0(ctx context.Context, marshaler runtime.Marshaler, client EveningDetectiveServerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq ChangeUserPasswordReq
|
||||
metadata runtime.ServerMetadata
|
||||
err error
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if req.Body != nil {
|
||||
_, _ = io.Copy(io.Discard, req.Body)
|
||||
}
|
||||
val, ok := pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
protoReq.Id, err = runtime.Int32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
msg, err := client.ChangeUserPassword(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func local_request_EveningDetectiveServer_ChangeUserPassword_0(ctx context.Context, marshaler runtime.Marshaler, server EveningDetectiveServerServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq ChangeUserPasswordReq
|
||||
metadata runtime.ServerMetadata
|
||||
err error
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
val, ok := pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
protoReq.Id, err = runtime.Int32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
msg, err := server.ChangeUserPassword(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func request_EveningDetectiveServer_AddUserRole_0(ctx context.Context, marshaler runtime.Marshaler, client EveningDetectiveServerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq AddUserRoleReq
|
||||
@@ -2617,6 +2662,26 @@ func RegisterEveningDetectiveServerHandlerServer(ctx context.Context, mux *runti
|
||||
}
|
||||
forward_EveningDetectiveServer_GetMe_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_EveningDetectiveServer_ChangeUserPassword_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/crabs.evening_detective_server.EveningDetectiveServer/ChangeUserPassword", runtime.WithHTTPPathPattern("/api/users/{id}/password"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_EveningDetectiveServer_ChangeUserPassword_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_EveningDetectiveServer_ChangeUserPassword_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_EveningDetectiveServer_AddUserRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -3838,6 +3903,23 @@ func RegisterEveningDetectiveServerHandlerClient(ctx context.Context, mux *runti
|
||||
}
|
||||
forward_EveningDetectiveServer_GetMe_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_EveningDetectiveServer_ChangeUserPassword_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/crabs.evening_detective_server.EveningDetectiveServer/ChangeUserPassword", runtime.WithHTTPPathPattern("/api/users/{id}/password"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_EveningDetectiveServer_ChangeUserPassword_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_EveningDetectiveServer_ChangeUserPassword_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_EveningDetectiveServer_AddUserRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -4671,6 +4753,7 @@ var (
|
||||
pattern_EveningDetectiveServer_GetUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "users"}, ""))
|
||||
pattern_EveningDetectiveServer_GetUserById_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "users", "id"}, ""))
|
||||
pattern_EveningDetectiveServer_GetMe_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "users", "me"}, ""))
|
||||
pattern_EveningDetectiveServer_ChangeUserPassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"api", "users", "id", "password"}, ""))
|
||||
pattern_EveningDetectiveServer_AddUserRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"api", "users", "id", "role", "add"}, ""))
|
||||
pattern_EveningDetectiveServer_DeleteUserRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"api", "users", "id", "role", "delete"}, ""))
|
||||
pattern_EveningDetectiveServer_GetPermissions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "ui", "permissions"}, ""))
|
||||
@@ -4735,6 +4818,7 @@ var (
|
||||
forward_EveningDetectiveServer_GetUsers_0 = runtime.ForwardResponseMessage
|
||||
forward_EveningDetectiveServer_GetUserById_0 = runtime.ForwardResponseMessage
|
||||
forward_EveningDetectiveServer_GetMe_0 = runtime.ForwardResponseMessage
|
||||
forward_EveningDetectiveServer_ChangeUserPassword_0 = runtime.ForwardResponseMessage
|
||||
forward_EveningDetectiveServer_AddUserRole_0 = runtime.ForwardResponseMessage
|
||||
forward_EveningDetectiveServer_DeleteUserRole_0 = runtime.ForwardResponseMessage
|
||||
forward_EveningDetectiveServer_GetPermissions_0 = runtime.ForwardResponseMessage
|
||||
|
||||
@@ -33,6 +33,7 @@ const (
|
||||
EveningDetectiveServer_GetUsers_FullMethodName = "/crabs.evening_detective_server.EveningDetectiveServer/GetUsers"
|
||||
EveningDetectiveServer_GetUserById_FullMethodName = "/crabs.evening_detective_server.EveningDetectiveServer/GetUserById"
|
||||
EveningDetectiveServer_GetMe_FullMethodName = "/crabs.evening_detective_server.EveningDetectiveServer/GetMe"
|
||||
EveningDetectiveServer_ChangeUserPassword_FullMethodName = "/crabs.evening_detective_server.EveningDetectiveServer/ChangeUserPassword"
|
||||
EveningDetectiveServer_AddUserRole_FullMethodName = "/crabs.evening_detective_server.EveningDetectiveServer/AddUserRole"
|
||||
EveningDetectiveServer_DeleteUserRole_FullMethodName = "/crabs.evening_detective_server.EveningDetectiveServer/DeleteUserRole"
|
||||
EveningDetectiveServer_GetPermissions_FullMethodName = "/crabs.evening_detective_server.EveningDetectiveServer/GetPermissions"
|
||||
@@ -100,6 +101,9 @@ type EveningDetectiveServerClient interface {
|
||||
GetUsers(ctx context.Context, in *GetUsersReq, opts ...grpc.CallOption) (*GetUsersRsp, error)
|
||||
GetUserById(ctx context.Context, in *GetUserByIdReq, opts ...grpc.CallOption) (*GetUserByIdRsp, error)
|
||||
GetMe(ctx context.Context, in *GetMeReq, opts ...grpc.CallOption) (*GetMeRsp, error)
|
||||
// Только администратор; сеансы пользователя сохраняются.
|
||||
// Ошибки: 401, 403, 400, 404, 500.
|
||||
ChangeUserPassword(ctx context.Context, in *ChangeUserPasswordReq, opts ...grpc.CallOption) (*ChangeUserPasswordRsp, error)
|
||||
AddUserRole(ctx context.Context, in *AddUserRoleReq, opts ...grpc.CallOption) (*AddUserRoleRsp, error)
|
||||
DeleteUserRole(ctx context.Context, in *DeleteUserRoleReq, opts ...grpc.CallOption) (*DeleteUserRoleRsp, error)
|
||||
GetPermissions(ctx context.Context, in *GetPermissionsReq, opts ...grpc.CallOption) (*GetPermissionsRsp, error)
|
||||
@@ -290,6 +294,16 @@ func (c *eveningDetectiveServerClient) GetMe(ctx context.Context, in *GetMeReq,
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *eveningDetectiveServerClient) ChangeUserPassword(ctx context.Context, in *ChangeUserPasswordReq, opts ...grpc.CallOption) (*ChangeUserPasswordRsp, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ChangeUserPasswordRsp)
|
||||
err := c.cc.Invoke(ctx, EveningDetectiveServer_ChangeUserPassword_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *eveningDetectiveServerClient) AddUserRole(ctx context.Context, in *AddUserRoleReq, opts ...grpc.CallOption) (*AddUserRoleRsp, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AddUserRoleRsp)
|
||||
@@ -787,6 +801,9 @@ type EveningDetectiveServerServer interface {
|
||||
GetUsers(context.Context, *GetUsersReq) (*GetUsersRsp, error)
|
||||
GetUserById(context.Context, *GetUserByIdReq) (*GetUserByIdRsp, error)
|
||||
GetMe(context.Context, *GetMeReq) (*GetMeRsp, error)
|
||||
// Только администратор; сеансы пользователя сохраняются.
|
||||
// Ошибки: 401, 403, 400, 404, 500.
|
||||
ChangeUserPassword(context.Context, *ChangeUserPasswordReq) (*ChangeUserPasswordRsp, error)
|
||||
AddUserRole(context.Context, *AddUserRoleReq) (*AddUserRoleRsp, error)
|
||||
DeleteUserRole(context.Context, *DeleteUserRoleReq) (*DeleteUserRoleRsp, error)
|
||||
GetPermissions(context.Context, *GetPermissionsReq) (*GetPermissionsRsp, error)
|
||||
@@ -886,6 +903,9 @@ func (UnimplementedEveningDetectiveServerServer) GetUserById(context.Context, *G
|
||||
func (UnimplementedEveningDetectiveServerServer) GetMe(context.Context, *GetMeReq) (*GetMeRsp, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetMe not implemented")
|
||||
}
|
||||
func (UnimplementedEveningDetectiveServerServer) ChangeUserPassword(context.Context, *ChangeUserPasswordReq) (*ChangeUserPasswordRsp, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ChangeUserPassword not implemented")
|
||||
}
|
||||
func (UnimplementedEveningDetectiveServerServer) AddUserRole(context.Context, *AddUserRoleReq) (*AddUserRoleRsp, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method AddUserRole not implemented")
|
||||
}
|
||||
@@ -1286,6 +1306,24 @@ func _EveningDetectiveServer_GetMe_Handler(srv interface{}, ctx context.Context,
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _EveningDetectiveServer_ChangeUserPassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ChangeUserPasswordReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(EveningDetectiveServerServer).ChangeUserPassword(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: EveningDetectiveServer_ChangeUserPassword_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(EveningDetectiveServerServer).ChangeUserPassword(ctx, req.(*ChangeUserPasswordReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _EveningDetectiveServer_AddUserRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AddUserRoleReq)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -2209,6 +2247,10 @@ var EveningDetectiveServer_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GetMe",
|
||||
Handler: _EveningDetectiveServer_GetMe_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ChangeUserPassword",
|
||||
Handler: _EveningDetectiveServer_ChangeUserPassword_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddUserRole",
|
||||
Handler: _EveningDetectiveServer_AddUserRole_Handler,
|
||||
|
||||
Reference in New Issue
Block a user