add membership

This commit is contained in:
Fran Jurmanović
2025-06-26 00:51:54 +02:00
parent 69733e4940
commit 74df36cd0d
24 changed files with 863 additions and 83 deletions

View File

@@ -27,9 +27,9 @@ func NewConfigController(as *service.ConfigService, routeGroups *common.RouteGro
apiService: as2,
}
routeGroups.Config.Put("/:file", ac.updateConfig)
routeGroups.Config.Get("/:file", ac.getConfig)
routeGroups.Config.Get("/", ac.getConfigs)
routeGroups.Config.Put("/:file", ac.UpdateConfig)
routeGroups.Config.Get("/:file", ac.GetConfig)
routeGroups.Config.Get("/", ac.GetConfigs)
return ac
}
@@ -44,7 +44,7 @@ func NewConfigController(as *service.ConfigService, routeGroups *common.RouteGro
// @Tags Config
// @Success 200 {array} string
// @Router /v1/server/{id}/config/{file} [put]
func (ac *ConfigController) updateConfig(c *fiber.Ctx) error {
func (ac *ConfigController) UpdateConfig(c *fiber.Ctx) error {
restart := c.QueryBool("restart")
serverID, _ := c.ParamsInt("id")
c.Locals("serverId", serverID)
@@ -79,7 +79,7 @@ func (ac *ConfigController) updateConfig(c *fiber.Ctx) error {
// @Tags Config
// @Success 200 {array} string
// @Router /v1/server/{id}/config/{file} [get]
func (ac *ConfigController) getConfig(c *fiber.Ctx) error {
func (ac *ConfigController) GetConfig(c *fiber.Ctx) error {
Model, err := ac.service.GetConfig(c)
if err != nil {
logging.Error(err.Error())
@@ -96,7 +96,7 @@ func (ac *ConfigController) getConfig(c *fiber.Ctx) error {
// @Tags Config
// @Success 200 {array} string
// @Router /v1/server/{id}/config [get]
func (ac *ConfigController) getConfigs(c *fiber.Ctx) error {
func (ac *ConfigController) GetConfigs(c *fiber.Ctx) error {
Model, err := ac.service.GetConfigs(c)
if err != nil {
logging.Error(err.Error())

View File

@@ -1,6 +1,7 @@
package controller
import (
"acc-server-manager/local/middleware"
"acc-server-manager/local/service"
"acc-server-manager/local/utl/logging"
@@ -15,6 +16,10 @@ import (
func InitializeControllers(c *dig.Container) {
service.InitializeServices(c)
if err := c.Provide(middleware.NewAuthMiddleware); err != nil {
logging.Panic("unable to initialize auth middleware")
}
err := c.Invoke(NewApiController)
if err != nil {
logging.Panic("unable to initialize api controller")
@@ -39,4 +44,9 @@ func InitializeControllers(c *dig.Container) {
if err != nil {
logging.Panic("unable to initialize stateHistory controller")
}
err = c.Invoke(NewMembershipController)
if err != nil {
logging.Panic("unable to initialize membership controller")
}
}

View File

@@ -23,11 +23,11 @@ func NewLookupController(as *service.LookupService, routeGroups *common.RouteGro
ac := &LookupController{
service: as,
}
routeGroups.Lookup.Get("/tracks", ac.getTracks)
routeGroups.Lookup.Get("/car-models", ac.getCarModels)
routeGroups.Lookup.Get("/driver-categories", ac.getDriverCategories)
routeGroups.Lookup.Get("/cup-categories", ac.getCupCategories)
routeGroups.Lookup.Get("/session-types", ac.getSessionTypes)
routeGroups.Lookup.Get("/tracks", ac.GetTracks)
routeGroups.Lookup.Get("/car-models", ac.GetCarModels)
routeGroups.Lookup.Get("/driver-categories", ac.GetDriverCategories)
routeGroups.Lookup.Get("/cup-categories", ac.GetCupCategories)
routeGroups.Lookup.Get("/session-types", ac.GetSessionTypes)
return ac
}
@@ -39,7 +39,7 @@ func NewLookupController(as *service.LookupService, routeGroups *common.RouteGro
// @Tags Lookup
// @Success 200 {array} string
// @Router /v1/lookup/tracks [get]
func (ac *LookupController) getTracks(c *fiber.Ctx) error {
func (ac *LookupController) GetTracks(c *fiber.Ctx) error {
result, err := ac.service.GetTracks(c)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -56,7 +56,7 @@ func (ac *LookupController) getTracks(c *fiber.Ctx) error {
// @Tags Lookup
// @Success 200 {array} string
// @Router /v1/lookup/car-models [get]
func (ac *LookupController) getCarModels(c *fiber.Ctx) error {
func (ac *LookupController) GetCarModels(c *fiber.Ctx) error {
result, err := ac.service.GetCarModels(c)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -73,7 +73,7 @@ func (ac *LookupController) getCarModels(c *fiber.Ctx) error {
// @Tags Lookup
// @Success 200 {array} string
// @Router /v1/lookup/driver-categories [get]
func (ac *LookupController) getDriverCategories(c *fiber.Ctx) error {
func (ac *LookupController) GetDriverCategories(c *fiber.Ctx) error {
result, err := ac.service.GetDriverCategories(c)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -90,7 +90,7 @@ func (ac *LookupController) getDriverCategories(c *fiber.Ctx) error {
// @Tags Lookup
// @Success 200 {array} string
// @Router /v1/lookup/cup-categories [get]
func (ac *LookupController) getCupCategories(c *fiber.Ctx) error {
func (ac *LookupController) GetCupCategories(c *fiber.Ctx) error {
result, err := ac.service.GetCupCategories(c)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -107,7 +107,7 @@ func (ac *LookupController) getCupCategories(c *fiber.Ctx) error {
// @Tags Lookup
// @Success 200 {array} string
// @Router /v1/lookup/session-types [get]
func (ac *LookupController) getSessionTypes(c *fiber.Ctx) error {
func (ac *LookupController) GetSessionTypes(c *fiber.Ctx) error {
result, err := ac.service.GetSessionTypes(c)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{

View File

@@ -0,0 +1,142 @@
package controller
import (
"acc-server-manager/local/middleware"
"acc-server-manager/local/model"
"acc-server-manager/local/service"
"acc-server-manager/local/utl/common"
"acc-server-manager/local/utl/jwt"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
)
// MembershipController handles API requests for membership.
type MembershipController struct {
service *service.MembershipService
auth *middleware.AuthMiddleware
}
// NewMembershipController creates a new MembershipController.
func NewMembershipController(service *service.MembershipService, auth *middleware.AuthMiddleware, routeGroups *common.RouteGroups) *MembershipController {
mc := &MembershipController{
service: service,
auth: auth,
}
routeGroups.Auth.Post("/login", mc.Login)
usersGroup := routeGroups.Api.Group("/users", mc.auth.Authenticate)
usersGroup.Post("/", mc.auth.HasPermission(model.MembershipCreate), mc.CreateUser)
usersGroup.Get("/", mc.auth.HasPermission(model.MembershipView), mc.ListUsers)
usersGroup.Get("/:id", mc.auth.HasPermission(model.MembershipView), mc.GetUser)
usersGroup.Put("/:id", mc.auth.HasPermission(model.MembershipEdit), mc.UpdateUser)
routeGroups.Api.Get("/me", mc.auth.Authenticate, mc.GetMe)
return mc
}
// Login handles user login.
func (c *MembershipController) Login(ctx *fiber.Ctx) error {
type request struct {
Username string `json:"username"`
Password string `json:"password"`
}
var req request
if err := ctx.BodyParser(&req); err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request"})
}
token, err := c.service.Login(ctx.UserContext(), req.Username, req.Password)
if err != nil {
return ctx.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": err.Error()})
}
return ctx.JSON(fiber.Map{"token": token})
}
// CreateUser creates a new user.
func (mc *MembershipController) CreateUser(c *fiber.Ctx) error {
type request struct {
Username string `json:"username"`
Password string `json:"password"`
Role string `json:"role"`
}
var req request
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request"})
}
user, err := mc.service.CreateUser(c.UserContext(), req.Username, req.Password, req.Role)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(user)
}
// ListUsers lists all users.
func (mc *MembershipController) ListUsers(c *fiber.Ctx) error {
users, err := mc.service.ListUsers(c.UserContext())
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(users)
}
// GetUser gets a single user by ID.
func (mc *MembershipController) GetUser(c *fiber.Ctx) error {
id, err := uuid.Parse(c.Params("id"))
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid user ID"})
}
user, err := mc.service.GetUser(c.UserContext(), id)
if err != nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
}
return c.JSON(user)
}
// GetMe returns the currently authenticated user's details.
func (mc *MembershipController) GetMe(c *fiber.Ctx) error {
claims, ok := c.Locals("user").(*jwt.Claims)
if !ok || claims == nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Unauthorized"})
}
user, err := mc.service.GetUserWithPermissions(c.UserContext(), claims.UserID)
if err != nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
}
// Sanitize the user object to not expose password
user.Password = ""
return c.JSON(user)
}
// UpdateUser updates a user.
func (mc *MembershipController) UpdateUser(c *fiber.Ctx) error {
id, err := uuid.Parse(c.Params("id"))
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid user ID"})
}
var req service.UpdateUserRequest
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request"})
}
user, err := mc.service.UpdateUser(c.UserContext(), id, req)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(user)
}

View File

@@ -1,6 +1,7 @@
package controller
import (
"acc-server-manager/local/middleware"
"acc-server-manager/local/model"
"acc-server-manager/local/service"
"acc-server-manager/local/utl/common"
@@ -12,34 +13,26 @@ type ServerController struct {
service *service.ServerService
}
// NewServerController
// Initializes ServerController.
//
// Args:
// *services.ServerService: Server service
// *Fiber.RouterGroup: Fiber Router Group
// Returns:
// *ServerController: Controller for "Server" interactions
func NewServerController(as *service.ServerService, routeGroups *common.RouteGroups,) *ServerController {
// NewServerController initializes ServerController.
func NewServerController(ss *service.ServerService, routeGroups *common.RouteGroups, auth *middleware.AuthMiddleware) *ServerController {
ac := &ServerController{
service: as,
service: ss,
}
routeGroups.Server.Get("/", ac.getAll)
routeGroups.Server.Get("/:id", ac.getById)
routeGroups.Server.Post("/", ac.createServer)
serverRoutes := routeGroups.Server
serverRoutes.Use(auth.Authenticate)
serverRoutes.Get("/", auth.HasPermission(model.ServerView), ac.GetAll)
serverRoutes.Get("/:id", auth.HasPermission(model.ServerView), ac.GetById)
serverRoutes.Post("/", auth.HasPermission(model.ServerCreate), ac.CreateServer)
serverRoutes.Put("/:id", auth.HasPermission(model.ServerUpdate), ac.UpdateServer)
serverRoutes.Delete("/:id", auth.HasPermission(model.ServerDelete), ac.DeleteServer)
return ac
}
// getAll returns Servers
//
// @Summary Return Servers
// @Description Return Servers
// @Tags Server
// @Success 200 {array} string
// @Router /v1/server [get]
func (ac *ServerController) getAll(c *fiber.Ctx) error {
var filter model.ServerFilter
// GetAll returns Servers
func (ac *ServerController) GetAll(c *fiber.Ctx) error {
var filter model.ServerFilter
if err := common.ParseQueryFilter(c, &filter); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": err.Error(),
@@ -52,14 +45,8 @@ func (ac *ServerController) getAll(c *fiber.Ctx) error {
return c.JSON(ServerModel)
}
// getById returns Servers
//
// @Summary Return Servers
// @Description Return Servers
// @Tags Server
// @Success 200 {array} string
// @Router /v1/server [get]
func (ac *ServerController) getById(c *fiber.Ctx) error {
// GetById returns a single server by its ID
func (ac *ServerController) GetById(c *fiber.Ctx) error {
serverID, _ := c.ParamsInt("id")
ServerModel, err := ac.service.GetById(c, serverID)
if err != nil {
@@ -68,14 +55,8 @@ func (ac *ServerController) getById(c *fiber.Ctx) error {
return c.JSON(ServerModel)
}
// createServer creates a new server
//
// @Summary Create a new server
// @Description Create a new server
// @Tags Server
// @Success 200 {array} string
// @Router /v1/server [post]
func (ac *ServerController) createServer(c *fiber.Ctx) error {
// CreateServer creates a new server
func (ac *ServerController) CreateServer(c *fiber.Ctx) error {
server := new(model.Server)
if err := c.BodyParser(server); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
@@ -89,4 +70,37 @@ func (ac *ServerController) createServer(c *fiber.Ctx) error {
})
}
return c.JSON(server)
}
// UpdateServer updates an existing server
func (ac *ServerController) UpdateServer(c *fiber.Ctx) error {
serverID, _ := c.ParamsInt("id")
server := new(model.Server)
if err := c.BodyParser(server); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": err.Error(),
})
}
server.ID = uint(serverID)
if err := ac.service.UpdateServer(c, server); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": err.Error(),
})
}
return c.JSON(server)
}
// DeleteServer deletes a server
func (ac *ServerController) DeleteServer(c *fiber.Ctx) error {
serverID, err := c.ParamsInt("id")
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid server ID"})
}
if err := ac.service.DeleteServer(c, serverID); err != nil {
return c.Status(500).SendString(err.Error())
}
return c.SendStatus(204)
}

View File

@@ -25,20 +25,20 @@ func NewStateHistoryController(as *service.StateHistoryService, routeGroups *com
service: as,
}
routeGroups.StateHistory.Get("/", ac.getAll)
routeGroups.StateHistory.Get("/statistics", ac.getStatistics)
routeGroups.StateHistory.Get("/", ac.GetAll)
routeGroups.StateHistory.Get("/statistics", ac.GetStatistics)
return ac
}
// getAll returns StateHistorys
// GetAll returns StateHistorys
//
// @Summary Return StateHistorys
// @Description Return StateHistorys
// @Tags StateHistory
// @Success 200 {array} string
// @Router /v1/state-history [get]
func (ac *StateHistoryController) getAll(c *fiber.Ctx) error {
func (ac *StateHistoryController) GetAll(c *fiber.Ctx) error {
var filter model.StateHistoryFilter
if err := common.ParseQueryFilter(c, &filter); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
@@ -63,7 +63,7 @@ func (ac *StateHistoryController) getAll(c *fiber.Ctx) error {
// @Tags StateHistory
// @Success 200 {array} string
// @Router /v1/state-history/statistics [get]
func (ac *StateHistoryController) getStatistics(c *fiber.Ctx) error {
func (ac *StateHistoryController) GetStatistics(c *fiber.Ctx) error {
var filter model.StateHistoryFilter
if err := common.ParseQueryFilter(c, &filter); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{