backend/users/users.go
ACoolName 8ac960102a
Some checks failed
Build and Push Docker Image / Build image (push) Has been cancelled
fixed initial user
2025-04-09 03:15:38 +03:00

167 lines
4.8 KiB
Go

package users
import (
"context"
"encoding/json"
"errors"
"log"
"net/http"
"time"
"git.acooldomain.co/server-manager/backend/auth"
"git.acooldomain.co/server-manager/backend/dbhandler"
"git.acooldomain.co/server-manager/backend/factories"
"git.acooldomain.co/server-manager/backend/mail"
"git.acooldomain.co/server-manager/backend/models"
"github.com/gin-gonic/gin"
)
type UsersApi struct {
userPassAuthHandler dbhandler.UserPassAuthanticationDbHandler
tokenHandler dbhandler.InviteTokenDbHandler
mailClient mail.MailClient
config *models.GlobalConfig
}
type UserResponse struct {
Username string `json:"Username"`
Nickname string `json:"nickname"`
Email string `json:"Email"`
Permissions models.Permission `json:"Permissions"`
}
func (con UsersApi) GetUsers(ctx *gin.Context) {
users, err := con.userPassAuthHandler.ListUsers(ctx)
if err != nil {
ctx.AbortWithError(500, err)
return
}
usersResponse := make([]UserResponse, len(users))
for i, user := range users {
usersResponse[i] = UserResponse{
Username: user.Username,
Permissions: user.Permissions,
Nickname: user.Nickname,
Email: user.Email,
}
}
ctx.JSON(http.StatusOK, usersResponse)
}
func (con UsersApi) GetUser(ctx *gin.Context) {
claims, exists := ctx.Get("claims")
if !exists {
ctx.AbortWithStatus(403)
return
}
ctx.IndentedJSON(http.StatusOK, UserResponse{
Username: claims.(*auth.AuthClaims).Username,
Permissions: claims.(*auth.AuthClaims).Permissions,
})
}
type InviteUser struct {
Email string `json:"Email"`
Permissions models.Permission `json:"Permissions"`
}
func (con *UsersApi) inviteUser(ctx context.Context, email string, permissions models.Permission) error {
token, err := con.tokenHandler.SaveInviteToken(ctx, email, permissions)
if err != nil {
return err
}
err = con.mailClient.SendMail(email, "You've been invited to join", "please open this link https://games.acooldomain.co/signup?token="+token)
if err != nil {
return err
}
return nil
}
func (con UsersApi) InviteUser(ctx *gin.Context) {
var request InviteUser
json.NewDecoder(ctx.Request.Body).Decode(&request)
err := con.inviteUser(ctx, request.Email, request.Permissions)
if err != nil {
ctx.AbortWithError(500, err)
return
}
ctx.JSON(200, "OK")
}
type SetUserPermissionsRequest struct {
Permissions models.Permission `json:"Permissions"`
}
func (con UsersApi) SetUserPermissions(ctx *gin.Context) {
var request SetUserPermissionsRequest
json.NewDecoder(ctx.Request.Body).Decode(&request)
username := ctx.Param("user_id")
err := con.userPassAuthHandler.SetPermissions(ctx, username, request.Permissions)
if err != nil {
ctx.AbortWithError(500, err)
return
}
ctx.JSON(200, "OK")
}
func (con UsersApi) DeleteUser(ctx *gin.Context) {
username := ctx.Param("user_id")
err := con.userPassAuthHandler.RemoveUser(ctx, username)
if err != nil {
ctx.AbortWithError(500, err)
return
}
ctx.JSON(200, "OK")
}
func LoadGroup(group *gin.RouterGroup, config models.GlobalConfig) {
userAuthHandler, err := factories.GetUserPassAuthDbHandler(config.Authentication.UserPass)
if err != nil {
panic(err)
}
inviteHandler, err := factories.GetInviteTokenDbHandler(config.Authentication.UserPass.InviteTokenDatabase)
if err != nil {
panic(err)
}
mailClient := *mail.NewMailClient(config.Email)
connection := UsersApi{
userPassAuthHandler: userAuthHandler,
tokenHandler: inviteHandler,
mailClient: mailClient,
config: &config,
}
if config.Authentication.Type == models.UserPass && config.Authentication.UserPass.InitialUser != nil {
ctx, cancel := context.WithTimeoutCause(context.Background(), 5*time.Second, errors.New("Timeout"))
defer cancel()
count, _ := connection.userPassAuthHandler.CountUsers(ctx)
if count == 0 {
log.Printf("Trying to create user %#v\n", config.Authentication.UserPass.InitialUser)
err := connection.inviteUser(ctx, config.Authentication.UserPass.InitialUser.Email, models.Admin)
if err != nil {
log.Printf("Failed to create initial user %e\n", err)
}
}
}
group.GET("", auth.AuthorizedTo(0), auth.AuthorizationEnforcer(), connection.GetUsers)
group.GET("/@me", auth.AuthorizedTo(0), auth.AuthorizationEnforcer(), connection.GetUser)
group.POST("", auth.AuthorizedTo(models.Admin), auth.AuthorizationEnforcer(), connection.InviteUser)
group.DELETE("/:user_id", auth.AuthorizedTo(models.Admin), auth.AuthorizationEnforcer(), connection.DeleteUser)
group.PATCH("/:user_id/permissions", auth.AuthorizedTo(models.Admin), auth.AuthorizationEnforcer(), connection.SetUserPermissions)
}