204 lines
4.2 KiB
Go
204 lines
4.2 KiB
Go
package rest
|
|
|
|
import (
|
|
"context"
|
|
testerv1 "git.sch9.ru/new_gate/ms-tester/contracts/tester/v1"
|
|
"git.sch9.ru/new_gate/ms-tester/internal/models"
|
|
"git.sch9.ru/new_gate/ms-tester/internal/users"
|
|
"git.sch9.ru/new_gate/ms-tester/pkg"
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
type Handlers struct {
|
|
usersUC users.UseCase
|
|
}
|
|
|
|
func NewHandlers(usersUC users.UseCase) *Handlers {
|
|
return &Handlers{
|
|
usersUC: usersUC,
|
|
}
|
|
}
|
|
|
|
const (
|
|
sessionKey = "session"
|
|
)
|
|
|
|
func sessionFromCtx(ctx context.Context) (*models.Session, error) {
|
|
const op = "sessionFromCtx"
|
|
|
|
session, ok := ctx.Value(sessionKey).(*models.Session)
|
|
if !ok {
|
|
return nil, pkg.Wrap(pkg.ErrUnauthenticated, nil, op, "")
|
|
}
|
|
|
|
return session, nil
|
|
}
|
|
|
|
func (h *Handlers) CreateUser(c *fiber.Ctx) error {
|
|
ctx := c.Context()
|
|
|
|
session, err := sessionFromCtx(ctx)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
switch session.Role {
|
|
case models.RoleAdmin, models.RoleTeacher:
|
|
var req = &testerv1.CreateUserRequest{}
|
|
err := c.BodyParser(req)
|
|
if err != nil {
|
|
return c.SendStatus(fiber.StatusBadRequest)
|
|
}
|
|
|
|
id, err := h.usersUC.CreateUser(ctx,
|
|
&models.UserCreation{
|
|
Username: req.Username,
|
|
Password: req.Password,
|
|
Role: models.RoleStudent,
|
|
},
|
|
)
|
|
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.JSON(testerv1.CreateUserResponse{Id: id})
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|
|
|
|
func (h *Handlers) GetUser(c *fiber.Ctx, id int32) error {
|
|
ctx := c.Context()
|
|
|
|
session, err := sessionFromCtx(ctx)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
switch session.Role {
|
|
case models.RoleAdmin, models.RoleTeacher, models.RoleStudent:
|
|
user, err := h.usersUC.ReadUserById(c.Context(), id)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.JSON(testerv1.GetUserResponse{
|
|
User: UserDTO(*user),
|
|
})
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|
|
|
|
func (h *Handlers) UpdateUser(c *fiber.Ctx, id int32) error {
|
|
ctx := c.Context()
|
|
|
|
session, err := sessionFromCtx(ctx)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
switch session.Role {
|
|
case models.RoleAdmin:
|
|
var req = &testerv1.UpdateUserRequest{}
|
|
err := c.BodyParser(req)
|
|
if err != nil {
|
|
return c.SendStatus(fiber.StatusBadRequest)
|
|
}
|
|
|
|
err = h.usersUC.UpdateUser(c.Context(), id, &models.UserUpdate{
|
|
Username: req.Username,
|
|
Role: RoleDTO(req.Role),
|
|
})
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.SendStatus(fiber.StatusOK)
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|
|
|
|
func (h *Handlers) DeleteUser(c *fiber.Ctx, id int32) error {
|
|
ctx := c.Context()
|
|
|
|
session, err := sessionFromCtx(ctx)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
switch session.Role {
|
|
case models.RoleAdmin:
|
|
ctx := c.Context()
|
|
|
|
err := h.usersUC.DeleteUser(ctx, id)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.SendStatus(fiber.StatusOK)
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|
|
|
|
func (h *Handlers) ListUsers(c *fiber.Ctx, params testerv1.ListUsersParams) error {
|
|
ctx := c.Context()
|
|
|
|
session, err := sessionFromCtx(ctx)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
switch session.Role {
|
|
case models.RoleAdmin, models.RoleTeacher:
|
|
usersList, err := h.usersUC.ListUsers(c.Context(), models.UsersListFilters{
|
|
PageSize: params.PageSize,
|
|
Page: params.Page,
|
|
})
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
resp := testerv1.ListUsersResponse{
|
|
Users: make([]testerv1.User, len(usersList.Users)),
|
|
Pagination: PaginationDTO(usersList.Pagination),
|
|
}
|
|
|
|
for i, user := range usersList.Users {
|
|
resp.Users[i] = UserDTO(*user)
|
|
}
|
|
|
|
return c.JSON(resp)
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|
|
|
|
func RoleDTO(i *int32) *models.Role {
|
|
if i == nil {
|
|
return nil
|
|
}
|
|
ii := models.Role(*i)
|
|
return &ii
|
|
}
|
|
|
|
func PaginationDTO(p models.Pagination) testerv1.Pagination {
|
|
return testerv1.Pagination{
|
|
Page: p.Page,
|
|
Total: p.Total,
|
|
}
|
|
}
|
|
|
|
// UserDTO sanitizes password
|
|
func UserDTO(u models.User) testerv1.User {
|
|
return testerv1.User{
|
|
Id: u.Id,
|
|
Username: u.Username,
|
|
Role: int32(u.Role),
|
|
CreatedAt: u.CreatedAt,
|
|
ModifiedAt: u.UpdatedAt,
|
|
}
|
|
}
|