package apis import ( "clortho/lib/db" "clortho/lib/users" "github.com/gin-gonic/gin" "net/http" "strconv" ) type userRequest struct { Username string `json:"username" binding:"required"` DisplayName string `json:"displayName"` Admin bool `json:"admin"` } type userUpdateRequest struct { DisplayName string `json:"displayName"` Admin bool `json:"admin"` } func InitUsersEndpoints(r *gin.RouterGroup) { group := r.Group("/users") group.Use(LoggedInMiddleware()) group.GET("/", getUsers) group.GET("/me", getMe) group.GET("/:userId", getUser) group.POST("/", AdminMiddleware(), createUser) group.PUT("/:userId", AdminMiddleware(), updateUser) group.DELETE("/:userId", AdminMiddleware(), deleteUser) } func getUsers(c *gin.Context) { userList := users.GetUsers() c.JSON(http.StatusOK, &userList) } func getUser(c *gin.Context) { // Get the user ID from the URL parameter userID, err := strconv.ParseUint(c.Param("userId"), 10, 32) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } // Get the user user, err := users.GetUserByID(uint(userID)) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) return } c.JSON(http.StatusOK, user) } func createUser(c *gin.Context) { var req userRequest if err := c.BindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Create the user user, err := users.CreateUser(req.Username) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // Update the user's display name and admin status if req.DisplayName != "" || req.Admin { displayName := req.DisplayName if displayName == "" && user.DisplayName != nil { displayName = *user.DisplayName } user, err = users.UpdateUser(user.ID, displayName, req.Admin) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } } c.JSON(http.StatusCreated, user) } func updateUser(c *gin.Context) { // Get the user ID from the URL parameter userID, err := strconv.ParseUint(c.Param("userId"), 10, 32) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } var req userUpdateRequest if err := c.BindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Get the current user to preserve existing values if not provided currentUser, err := users.GetUserByID(uint(userID)) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) return } // Use existing display name if not provided displayName := req.DisplayName if displayName == "" && currentUser.DisplayName != nil { displayName = *currentUser.DisplayName } // Update the user user, err := users.UpdateUser(uint(userID), displayName, req.Admin) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, user) } func deleteUser(c *gin.Context) { // Get the user ID from the URL parameter userID, err := strconv.ParseUint(c.Param("userId"), 10, 32) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } // Get the current session sessionInterface, _ := c.Get("session") session := sessionInterface.(*db.UserSession) // Prevent users from deleting themselves if session.User.ID == uint(userID) { c.JSON(http.StatusBadRequest, gin.H{"error": "Cannot delete your own account"}) return } // Delete the user err = users.DeleteUser(uint(userID)) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "User deleted successfully"}) }