Files
pipu-music/services/api/internal/auth/admin_handler.go
T
mrleo1nid c34272d508
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m6s
ci / ts / ts (packages + web) (push) Successful in 2m59s
ci / api / api (push) Successful in 49s
ci / db / db (push) Successful in 1m17s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m25s
fix(auth): allow admins to change any username including their own
2026-10-21 17:33:19 +03:00

169 lines
5.0 KiB
Go

package auth
import (
"context"
"pipu/api/internal/api/gen"
)
// ListUsers реализует gen.StrictServerInterface.
func (h *Handler) ListUsers(ctx context.Context, req gen.ListUsersRequestObject) (gen.ListUsersResponseObject, error) {
p, err := principal(ctx)
if err != nil {
return nil, err
}
var (
q, cursor string
role *Role
)
if req.Params.Q != nil {
q = *req.Params.Q
}
if req.Params.Cursor != nil {
cursor = *req.Params.Cursor
}
if req.Params.Role != nil {
r := Role(*req.Params.Role)
role = &r
}
users, next, err := h.svc.ListUsers(ctx, p, q, role, cursor, req.Params.Limit)
if err != nil {
return nil, err
}
items := make([]gen.AdminUser, 0, len(users))
for _, u := range users {
items = append(items, AdminUserDTO(u))
}
return gen.ListUsers200JSONResponse{Items: items, NextCursor: optional(next)}, nil
}
// CreateUser реализует gen.StrictServerInterface.
func (h *Handler) CreateUser(ctx context.Context, req gen.CreateUserRequestObject) (gen.CreateUserResponseObject, error) {
p, err := principal(ctx)
if err != nil {
return nil, err
}
in := CreateUserInput{Username: req.Body.Username, Role: Role(req.Body.Role)}
if req.Body.ReviewsUploads != nil {
in.ReviewsUploads = *req.Body.ReviewsUploads
}
if req.Body.DisplayName != nil {
in.DisplayName = *req.Body.DisplayName
}
u, password, err := h.svc.CreateUser(ctx, p, in)
if err != nil {
return nil, err
}
return gen.CreateUser201JSONResponse{User: AdminUserDTO(u), TemporaryPassword: password}, nil
}
// UpdateUser реализует gen.StrictServerInterface.
func (h *Handler) UpdateUser(ctx context.Context, req gen.UpdateUserRequestObject) (gen.UpdateUserResponseObject, error) {
p, err := principal(ctx)
if err != nil {
return nil, err
}
patch := UserPatch{Username: req.Body.Username, DisplayName: req.Body.DisplayName, IsBlocked: req.Body.IsBlocked, ReviewsUploads: req.Body.ReviewsUploads}
if req.Body.Role != nil {
r := Role(*req.Body.Role)
patch.Role = &r
}
u, err := h.svc.UpdateUser(ctx, p, req.Id, patch)
if err != nil {
return nil, err
}
return gen.UpdateUser200JSONResponse(AdminUserDTO(u)), nil
}
// DeleteUser реализует gen.StrictServerInterface.
func (h *Handler) DeleteUser(ctx context.Context, req gen.DeleteUserRequestObject) (gen.DeleteUserResponseObject, error) {
p, err := principal(ctx)
if err != nil {
return nil, err
}
if err := h.svc.DeleteUser(ctx, p, req.Id); err != nil {
return nil, err
}
return gen.DeleteUser204Response{}, nil
}
// ResetUserPassword реализует gen.StrictServerInterface.
func (h *Handler) ResetUserPassword(ctx context.Context, req gen.ResetUserPasswordRequestObject) (gen.ResetUserPasswordResponseObject, error) {
p, err := principal(ctx)
if err != nil {
return nil, err
}
password, err := h.svc.ResetPassword(ctx, p, req.Id)
if err != nil {
return nil, err
}
return gen.ResetUserPassword200JSONResponse{TemporaryPassword: password}, nil
}
// ResetUserRecommendations реализует gen.StrictServerInterface.
func (h *Handler) ResetUserRecommendations(ctx context.Context, req gen.ResetUserRecommendationsRequestObject) (gen.ResetUserRecommendationsResponseObject, error) {
p, err := principal(ctx)
if err != nil {
return nil, err
}
if err := h.svc.ResetRecommendations(ctx, p, req.Id); err != nil {
return nil, err
}
return gen.ResetUserRecommendations204Response{}, nil
}
// ListAudit реализует gen.StrictServerInterface.
func (h *Handler) ListAudit(ctx context.Context, req gen.ListAuditRequestObject) (gen.ListAuditResponseObject, error) {
p, err := principal(ctx)
if err != nil {
return nil, err
}
cursor := ""
if req.Params.Cursor != nil {
cursor = *req.Params.Cursor
}
records, next, err := h.svc.ListAudit(ctx, p, cursor, req.Params.Limit)
if err != nil {
return nil, err
}
items := make([]gen.AuditEntry, 0, len(records))
for _, r := range records {
e := gen.AuditEntry{
Id: r.ID, Action: r.Action, TargetType: r.TargetType, TargetId: r.TargetID, CreatedAt: r.CreatedAt,
}
if r.ActorID != nil && r.ActorUsername != nil {
e.Actor = &gen.AuditActor{Id: *r.ActorID, Username: *r.ActorUsername}
}
if r.Payload != nil {
payload := r.Payload
e.Payload = &payload
}
items = append(items, e)
}
return gen.ListAudit200JSONResponse{Items: items, NextCursor: optional(next)}, nil
}
// AdminUserDTO переводит пользователя в схему AdminUser.
func AdminUserDTO(u User) gen.AdminUser {
return gen.AdminUser{
Id: u.ID,
Username: u.Username,
DisplayName: u.DisplayName,
Role: gen.Role(u.Role),
ReviewsUploads: u.ReviewsUploads,
Locale: u.Locale,
IsBlocked: u.IsBlocked,
MustChangePassword: u.MustChangePassword,
MustChangeCredentials: u.MustChangeCredentials,
CreatedAt: u.CreatedAt,
LastLoginAt: u.LastLoginAt,
}
}
func optional(s string) *string {
if s == "" {
return nil
}
return &s
}