From 4670c93effe337ee59b4d0bb1b14258fd76a141a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Z=C3=BCrcher?= Date: Sun, 26 Oct 2025 21:05:55 +0100 Subject: [PATCH] fix missing gin context (fixes #1) --- db_test.go | 156 +++++++++++++++------- handlers/login.go | 2 - handlers/middleware.go | 5 +- handlers/role.go | 265 +++++++++++++++++-------------------- handlers/user.go | 293 +++++++++++++++++++---------------------- models/user.go | 4 +- 6 files changed, 368 insertions(+), 357 deletions(-) diff --git a/db_test.go b/db_test.go index d6f86fd..c91f07a 100644 --- a/db_test.go +++ b/db_test.go @@ -3,8 +3,10 @@ package AccessHandler import ( "bytes" "encoding/json" + "io" "net/http" "net/http/httptest" + "os" "testing" "gitea.tecamino.com/paadi/access-handler/models" @@ -13,7 +15,15 @@ import ( "github.com/go-playground/assert/v2" ) -func TestAccesshandlerLogin(t *testing.T) { +func TestDatabase(t *testing.T) { + dbName := "user.db" + if _, err := os.Stat(dbName); err == nil { + t.Log("remove user.db to start test with empty database") + if err := os.Remove(dbName); err != nil { + t.Fatal(err) + } + } + t.Log("start access handler test") t.Log("initialize accessHandler") @@ -22,39 +32,87 @@ func TestAccesshandlerLogin(t *testing.T) { t.Fatal(err) } - t.Log("add another user") - err = accessHandler.AddNewUser("guest", "guest@gmail.com", "passwordd1", "admin") - if err != nil { - t.Log(err) + r := gin.Default() + + accessHandler.SetMiddlewareLogger(r) + + r.POST("/users/add", accessHandler.AddUser) + r.GET("/users", accessHandler.GetUser) + r.GET("/roles", accessHandler.GetRole) + r.POST("/roles/add", accessHandler.AddRole) + + type request struct { + Log string + Name string + Method string + Path string + Payload any + Cookie *http.Cookie + ignoreError bool + } + var requests []request + + requests = append(requests, + request{Log: "add another user", Name: "add user", Method: "POST", Path: "/users/add", Payload: models.User{ + + Name: "guest", + Password: "passwordd1", + Role: "admin", + Email: "guest@gmail.com", + }, ignoreError: true}, + request{Log: "Get all users", Name: "get all users", Method: "GET", Path: "/users"}, + request{Log: "Get user id 1", Name: "get user id 1", Method: "GET", Path: "/users?id=1"}, + request{Log: "Add new role", Name: "add new role", Method: "POST", Path: "/roles/add", Payload: models.Role{ + Role: "testRole", + }, ignoreError: true}, + request{Log: "Get all roles", Name: "get all roles", Method: "GET", Path: "/roles"}, + request{Log: "Get all role id 1", Name: "get role id 1", Method: "GET", Path: "/roles?id=1"}, + ) + + for _, request := range requests { + if request.Log != "" { + t.Log(request.Log) + + } + var bodyReader io.Reader + if request.Payload != nil { + jsonBytes, _ := json.Marshal(request.Payload) + bodyReader = bytes.NewBuffer(jsonBytes) + } + req, _ := http.NewRequest(request.Method, request.Path, bodyReader) + if request.Cookie != nil { + req.AddCookie(request.Cookie) // attach refresh_token cookie + } + w := httptest.NewRecorder() + + r.ServeHTTP(w, req) + + t.Log(request.Name+" response:", w.Body.String()) + if !request.ignoreError { + assert.Equal(t, http.StatusOK, w.Code) + } } - t.Log("get user id 1") - result, err := accessHandler.GetUserByKey("user_name", "admin", false) - if err != nil { - t.Fatal(err) - } - t.Log(result) + // t.Log("get user id 1") + // result, err := accessHandler.GetUserByKey("user_name", "admin", false) + // if err != nil { + // t.Fatal(err) + // } + // t.Log(result) - t.Log("get all users") - result, err = accessHandler.GetUserById(0) - if err != nil { - t.Fatal(err) - } - t.Log(result) + // t.Log("get user by key") + // result, err = accessHandler.GetUserByKey("password", "passwordd", false) + // if err != nil { + // t.Fatal(err) + // } + // t.Log(result) - t.Log("get user by key") - result, err = accessHandler.GetUserByKey("password", "passwordd", false) - if err != nil { - t.Fatal(err) - } - t.Log(result) - - t.Log("get user by key and like") - result, err = accessHandler.GetUserByKey("user_name", "a*", true) - if err != nil { - t.Fatal(err) - } - t.Log(result) + // t.Log("get user by key and like") + // result, err = accessHandler.GetUserByKey("user_name", "a*", true) + // if err != nil { + // t.Fatal(err) + // } + // t.Log(result) // var user_name string = "admin1" // if len(result) > 0 { @@ -68,34 +126,34 @@ func TestAccesshandlerLogin(t *testing.T) { // Name: user_name, // }, "user_name", result[0].Name) // } - t.Log("read user again") - result, err = accessHandler.GetUserByKey("user_name", "a*", true) - if err != nil { - t.Fatal(err) - } - t.Log(result) + // t.Log("read user again") + // result, err = accessHandler.GetUserByKey("user_name", "a*", true) + // if err != nil { + // t.Fatal(err) + // } + // t.Log(result) // t.Log("delete user id 1") // err = accessHandler.DeleteUserByKey("user_name", user_name, false) // if err != nil { // t.Fatal(err) // } - t.Log("read user again") - result, err = accessHandler.GetUserById(0) - if err != nil { - t.Fatal(err) - } - t.Log(result) + // t.Log("read user again") + // result, err = accessHandler.GetUserById(0) + // if err != nil { + // t.Fatal(err) + // } + // t.Log(result) - t.Log("read admin permissions") - result1, err := accessHandler.GetRoleByKey("role", "admin", false) - if err != nil { - t.Fatal(err) - } - t.Log(result1) + // t.Log("read admin permissions") + // result1, err := accessHandler.GetRoleByKey("role", "admin", false) + // if err != nil { + // t.Fatal(err) + // } + // t.Log(result1) } -func TestLoginHandler(t *testing.T) { +func TestLoginAndAuthorization(t *testing.T) { gin.SetMode(gin.TestMode) // Setup your AccessHandler and router diff --git a/handlers/login.go b/handlers/login.go index c38f9cc..154f38b 100644 --- a/handlers/login.go +++ b/handlers/login.go @@ -2,7 +2,6 @@ package handlers import ( "fmt" - "log" "net/http" "time" @@ -62,7 +61,6 @@ func (aH *AccessHandler) Login(c *gin.Context) { } if len(dbRecord) > 1 { - log.Println("multiple users found") aH.logger.Error("Login", "more than one record found") c.JSON(http.StatusInternalServerError, models.NewJsonMessageResponse("internal error")) return diff --git a/handlers/middleware.go b/handlers/middleware.go index 0e52159..f321432 100644 --- a/handlers/middleware.go +++ b/handlers/middleware.go @@ -1,7 +1,6 @@ package handlers import ( - "fmt" "log" "net/http" "strings" @@ -141,8 +140,7 @@ func (aH *AccessHandler) AuthorizeRole(suffix string) gin.HandlerFunc { // Validate that a role was found if len(roles) == 0 { - log.Println("not logged in") - aH.logger.Error("AuthorizeRole", "no logged in") + aH.logger.Error("AuthorizeRole", "not logged in") c.JSON(http.StatusUnauthorized, http.StatusUnauthorized) return } else if len(roles) > 1 { @@ -153,7 +151,6 @@ func (aH *AccessHandler) AuthorizeRole(suffix string) gin.HandlerFunc { // Check permissions for _, permission := range roles[0].Permissions { - fmt.Println(100, permissionPath, permission.Name) if permission.Name == permissionPath { c.Next() return diff --git a/handlers/role.go b/handlers/role.go index 179cf50..5ec9c4e 100644 --- a/handlers/role.go +++ b/handlers/role.go @@ -2,45 +2,17 @@ package handlers import ( "fmt" + "net/http" + "strconv" "gitea.tecamino.com/paadi/access-handler/models" + "github.com/gin-gonic/gin" ) -// AddRoleTable -// -// Description: -// -// Creates a new database table for storing role definitions if it does not already exist. -// -// Behavior: -// - Uses the DBHandler to add a table based on the `models.Role` struct. -// - Returns an error if table creation fails. -// -// Returns: -// - error: Any database error encountered. func (aH *AccessHandler) AddRoleTable() error { return aH.dbHandler.AddNewTable(models.Role{}) } -// AddDefaultRole -// -// Description: -// -// Ensures that a default administrative role exists in the database. -// If a role named "admin" is already present, it logs and skips creation. -// -// Behavior: -// 1. Checks for an existing "admin" role. -// 2. If not found, initializes default permissions using -// `models.Permissions.DefaultPermissions()`. -// 3. Creates a new role record with those permissions. -// -// Default Role: -// - Role: "admin" -// - Permissions: all default permissions defined in `models.Permissions`. -// -// Returns: -// - error: Any database or creation error encountered. func (aH *AccessHandler) AddDefaultRole() (err error) { role := "admin" @@ -64,134 +36,135 @@ func (aH *AccessHandler) AddDefaultRole() (err error) { return } -// AddNewRole -// -// Description: -// -// Adds a new role with a specific set of permissions to the database. -// -// Behavior: -// 1. Checks whether a role with the same name already exists. -// 2. If it does not exist, creates a new role record. -// -// Parameters: -// - role: The role name (e.g., "manager", "viewer"). -// - permissions: A `models.Permissions` struct defining allowed actions. -// -// Returns: -// - error: If the role already exists or insertion fails. -func (aH *AccessHandler) AddNewRole(role string, permissions models.Permissions) (err error) { +func (aH *AccessHandler) AddRole(c *gin.Context) { + var role models.Role + err := c.BindJSON(&role) + if err != nil { + aH.logger.Error("AddRole", err) + c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err)) + return + } + + if !role.IsValid() { + aH.logger.Error("AddRole", "user empty") + c.JSON(http.StatusBadRequest, models.NewJsonMessageResponse("user empty")) + return + } + // Check if a role with this name already exists - if err := aH.dbHandler.Exists(&models.Role{}, "role", role, false); err == nil { - // Found a role → skip creation - return fmt.Errorf("role with name %s already exists", role) + if err := aH.dbHandler.Exists(&models.Role{}, "role", role.Role, false); err == nil { + aH.logger.Error("AddRole", fmt.Sprintf("role with name %s already exists", role.Role)) + c.JSON(http.StatusBadRequest, models.NewJsonMessageResponse(fmt.Sprintf("role with name %s already exists", role.Role))) } // Insert new role with provided permissions aH.dbHandler.AddNewColum(&models.Role{ - Role: role, - Permissions: permissions, + Role: role.Role, + Permissions: role.Permissions, + }) + c.JSON(http.StatusOK, gin.H{ + "message": fmt.Sprintf("role '%s' successfully added", role.Role), }) - return } -// GetRoleById -// -// Description: -// -// Retrieves a role record from the database by its numeric ID. -// -// Parameters: -// - id: The unique ID of the role. -// -// Returns: -// - roles: A slice containing the matched role (usually length 1). -// - err: Any database error encountered. -func (aH *AccessHandler) GetRoleById(id uint) (roles []models.Role, err error) { - err = aH.dbHandler.GetById(&roles, id) - return +func (aH *AccessHandler) GetRole(c *gin.Context) { + var i int + var err error + var roles []models.Role + + role := c.Query("role") + id := c.Query("id") + + if role != "" { + err = aH.dbHandler.GetByKey(&roles, "role", role, false) + } else if id != "" { + i, err = strconv.Atoi(id) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "message": err.Error(), + }) + return + } + err = aH.dbHandler.GetById(&roles, uint(i)) + } else { + err = aH.dbHandler.GetById(&roles, 0) + + } + + if err != nil { + aH.logger.Error("GetRole", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + c.JSON(http.StatusOK, roles) } -// GetRoleByKey -// -// Description: -// -// Retrieves one or more roles based on a key/value query. -// -// Parameters: -// - key: The column name to search by (e.g., "role"). -// - value: The value to match (e.g., "admin"). -// - likeSearch: Whether to use SQL LIKE for partial matches. -// -// Returns: -// - roles: A list of matched roles. -// - err: Any database error encountered. -func (aH *AccessHandler) GetRoleByKey(key string, value any, likeSearch bool) (roles []models.Role, err error) { - err = aH.dbHandler.GetByKey(&roles, key, value, likeSearch) - return +func (aH *AccessHandler) UpdateRole(c *gin.Context) { + var role models.Role + if err := c.BindJSON(&role); err != nil { + aH.logger.Error("UpdateRole", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + err := aH.dbHandler.UpdateValuesById(&role, role.Id) + if err != nil { + aH.logger.Error("UpdateRole", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + c.JSON(http.StatusOK, models.NewJsonMessageResponse("successfully updated role '"+role.Role+"'")) } -// UpdateRoleById -// -// Description: -// -// Updates a role record identified by its numeric ID. -// -// Parameters: -// - id: The ID of the role to update. -// - role: A struct containing updated role data. -// -// Returns: -// - error: Any database error encountered. -func (aH *AccessHandler) UpdateRoleById(id uint, role models.Role) error { - return aH.dbHandler.UpdateValuesById(&role, id) -} +func (aH *AccessHandler) DeleteRole(c *gin.Context) { + queryRole := c.Query("role") + if queryRole == "" || queryRole == "null" || queryRole == "undefined" { + aH.logger.Error("DeleteRole", "id query missing or wrong value: "+queryRole) + c.JSON(http.StatusInternalServerError, nil) + return + } -// UpdateRoleByKey -// -// Description: -// -// Updates a role record using a column key/value lookup. -// -// Parameters: -// - role: The updated role data. -// - key: The column name to search by. -// - value: The value to match against the key column. -// -// Returns: -// - error: Any database error encountered. -func (aH *AccessHandler) UpdateRoleByKey(role models.Role, key string, value any) error { - return aH.dbHandler.UpdateValuesByKey(&role, key, value) -} + var request struct { + Roles []string `json:"roles"` + } -// DeleteRoleById -// -// Description: -// -// Deletes a role record from the database by its numeric ID. -// -// Parameters: -// - id: The ID of the role to delete. -// -// Returns: -// - error: Any database error encountered during deletion. -func (aH *AccessHandler) DeleteRoleById(id uint) (err error) { - return aH.dbHandler.DeleteById(&models.Role{}, id) -} + err := c.BindJSON(&request) + if err != nil { + aH.logger.Error("DeleteRole", err) + c.JSON(http.StatusBadRequest, nil) + return + } -// DeleteRoleByKey -// -// Description: -// -// Deletes one or more roles from the database matching a given key/value pair. -// -// Parameters: -// - key: The column name used for filtering (e.g., "role"). -// - value: The matching value (e.g., "admin"). -// - likeSearch: If true, performs a LIKE (partial) match. -// -// Returns: -// - error: Any database error encountered. -func (aH *AccessHandler) DeleteRoleByKey(key string, value any, likeSearch bool) (err error) { - return aH.dbHandler.DeleteByKey(&models.Role{}, key, value, likeSearch) + if len(request.Roles) == 0 { + aH.logger.Error("DeleteRole", "no ids given to be deleted") + c.JSON(http.StatusBadRequest, models.NewJsonMessageResponse("no roles given to be deleted")) + return + } + + var ownRole string + + for _, role := range request.Roles { + if queryRole == role { + ownRole = role + continue + } + err = aH.dbHandler.DeleteByKey(&models.Role{}, "role", role, false) + if err != nil { + aH.logger.Error("DeleteRole", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + } + + if ownRole != "" { + aH.logger.Error("DeleteRole", "can not delete logged in role id: "+ownRole) + c.JSON(http.StatusBadRequest, gin.H{ + "message": "can not delete logged in role id: " + ownRole, + "role": ownRole, + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "role(s) deleted", + }) } diff --git a/handlers/user.go b/handlers/user.go index cffc487..d30c678 100644 --- a/handlers/user.go +++ b/handlers/user.go @@ -1,48 +1,20 @@ package handlers import ( + "errors" "fmt" + "net/http" + "strconv" "gitea.tecamino.com/paadi/access-handler/internal/utils" "gitea.tecamino.com/paadi/access-handler/models" + "github.com/gin-gonic/gin" ) -// AddUserTable -// -// Description: -// -// Creates a new database table for storing user records if it does not already exist. -// -// Behavior: -// - Uses the DBHandler to add a table based on the `models.User` struct. -// - Returns any error encountered during table creation. -// -// Returns: -// - error: Any database error that occurs while creating the table. func (aH *AccessHandler) AddUserTable() error { return aH.dbHandler.AddNewTable(models.User{}) } -// AddDefaultUser -// -// Description: -// -// Ensures a default administrative user exists in the database. -// If a user with the predefined email already exists, the function logs -// a debug message and exits without making changes. -// -// Behavior: -// 1. Checks if the default user (admin) already exists by email. -// 2. If not found, creates default Quasar UI settings and adds the user. -// -// Default User: -// - Name: "admin" -// - Role: "admin" -// - Email: "zuercher@tecamino.ch" -// - Password: (empty or hashed later) -// -// Returns: -// - error: Any database or creation error encountered. func (aH *AccessHandler) AddDefaultUser() (err error) { name := "admin" role := "admin" @@ -71,148 +43,161 @@ func (aH *AccessHandler) AddDefaultUser() (err error) { return } -// AddNewUser -// -// Description: -// -// Adds a new user record to the database with a hashed password. -// -// Behavior: -// 1. Verifies that the email does not already exist. -// 2. Hashes the password using utils.HashPassword(). -// 3. Inserts the new user record into the database. -// -// Parameters: -// - userName: The user's display name. -// - email: The user's unique email address. -// - password: The user's raw password (will be hashed). -// - role: The role assigned to the user. -// -// Returns: -// - error: If the user already exists or if hashing/insertion fails. -func (aH *AccessHandler) AddNewUser(userName, email, password, role string) (err error) { +func (aH *AccessHandler) AddUser(c *gin.Context) { + var user models.User + err := c.BindJSON(&user) + if err != nil { + aH.logger.Error("AddUser", err) + c.JSON(http.StatusInternalServerError, models.NewJsonErrorResponse(err)) + return + } + + if !user.IsValid() { + aH.logger.Error("AddUser", "user empty") + c.JSON(http.StatusBadRequest, models.NewJsonMessageResponse("user empty")) + return + } + // Check if a user with this email already exists - if err := aH.dbHandler.Exists(&models.User{}, "email", email, false); err == nil { + if err := aH.dbHandler.Exists(&models.User{}, "email", user.Email, false); err == nil { // Found a user → skip create - aH.logger.Error("AddNewUser", "user with email "+email+" already exists") - return fmt.Errorf("user with email %s already exists", email) + aH.logger.Error("AddUser", "user with email "+user.Email+" already exists") + c.JSON(http.StatusBadRequest, models.NewJsonMessageResponse(fmt.Sprintf("user with email %s already exists", user.Email))) + return + } + + if !utils.IsValidEmail(user.Email) { + aH.logger.Error("AddUser", "not valid email address") + c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(errors.New("not valid email address"))) + return } // Hash the provided password before saving - hash, err := utils.HashPassword(password) + hash, err := utils.HashPassword(user.Password) if err != nil { - return err + aH.logger.Error("AddUser", err) + c.JSON(http.StatusInternalServerError, nil) + return } - aH.logger.Debug("AddNewUser", "add new user "+userName+" with role "+role) + aH.logger.Debug("AddUser", "add default quasar user setting ") + user.Settings.DefaultQuasarSettings() + + aH.logger.Debug("AddUser", "add new user "+user.Name+" with role "+user.Role) // Insert the new user record aH.dbHandler.AddNewColum(&models.User{ - Name: userName, - Role: role, - Email: email, + Name: user.Name, + Role: user.Role, + Email: user.Email, Password: hash, + Settings: user.Settings, + }) + + c.JSON(http.StatusOK, gin.H{ + "message": fmt.Sprintf("user '%s' successfully added", user.Name), }) - return } -// GetUserById -// -// Description: -// -// Retrieves user(s) from the database by their unique ID. -// -// Parameters: -// - id: The numeric user ID. -// -// Returns: -// - users: A slice containing the matched user (usually length 1). -// - err: Any database error encountered. -func (aH *AccessHandler) GetUserById(id uint) (users []models.User, err error) { - err = aH.dbHandler.GetById(&users, id) - return +func (aH *AccessHandler) GetUser(c *gin.Context) { + var i int + var err error + + id := c.Query("id") + if id == "undefined" || id == "null" || id == "" { + i = 0 + } else { + i, err = strconv.Atoi(id) + if err != nil { + aH.logger.Error("GetUser", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + } + + var users []models.User + err = aH.dbHandler.GetById(&users, uint(i)) + if err != nil { + aH.logger.Error("GetUser", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + c.JSON(http.StatusOK, users) } -// GetUserByKey -// -// Description: -// -// Queries users based on a given column key and value. -// -// Parameters: -// - key: The column name to search by (e.g., "email"). -// - value: The value to match. -// - likeSearch: If true, performs a LIKE (partial) search. -// -// Returns: -// - users: A list of users that match the search criteria. -// - err: Any database error encountered. -func (aH *AccessHandler) GetUserByKey(key string, value any, likeSearch bool) (users []models.User, err error) { - err = aH.dbHandler.GetByKey(&users, key, value, likeSearch) - return +func (aH *AccessHandler) UpdateUser(c *gin.Context) { + var user models.User + if err := c.BindJSON(&user); err != nil { + aH.logger.Error("UpdateUser", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + err := aH.dbHandler.UpdateValuesById(&user, user.Id) + if err != nil { + aH.logger.Error("UpdateUser", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + c.JSON(http.StatusOK, models.NewJsonMessageResponse("successfully updated user '"+user.Email+"'")) } -// UpdateUserById -// -// Description: -// -// Updates an existing user record identified by its numeric ID. -// -// Parameters: -// - id: The user ID to update. -// - user: A struct containing updated field values. -// -// Returns: -// - error: Any error encountered during the update. -func (aH *AccessHandler) UpdateUserById(id uint, user models.User) error { - return aH.dbHandler.UpdateValuesById(&user, id) -} +func (aH *AccessHandler) DeleteUser(c *gin.Context) { + queryId := c.Query("id") -// UpdateUserByKey -// -// Description: -// -// Updates a user record based on a specified column key and value. -// -// Parameters: -// - user: The updated user data. -// - key: The column name used for lookup. -// - value: The value to match against the key column. -// -// Returns: -// - error: Any error encountered during the update. -func (aH *AccessHandler) UpdateUserByKey(user models.User, key string, value any) error { - return aH.dbHandler.UpdateValuesByKey(&user, key, value) -} + if queryId == "" || queryId == "null" || queryId == "undefined" { + aH.logger.Error("DeleteUser", "id query missing or wrong value: "+queryId) + c.JSON(http.StatusBadRequest, gin.H{ + "message": "id query missing or wrong value: " + queryId, + }) + return + } -// DeleteUserById -// -// Description: -// -// Deletes a user from the database using their numeric ID. -// -// Parameters: -// - id: The ID of the user to delete. -// -// Returns: -// - error: Any database error encountered during deletion. -func (aH *AccessHandler) DeleteUserById(id uint) (err error) { - return aH.dbHandler.DeleteById(&models.User{}, id) -} + var request struct { + Ids []int `json:"ids"` + } -// DeleteUserByKey -// -// Description: -// -// Deletes users matching a specific key/value pair from the database. -// -// Parameters: -// - key: The column name to search by. -// - value: The value to match. -// - likeSearch: Whether to use a partial match (LIKE). -// -// Returns: -// - error: Any database error encountered during deletion. -func (aH *AccessHandler) DeleteUserByKey(key string, value any, likeSearch bool) (err error) { - return aH.dbHandler.DeleteByKey(&models.User{}, key, value, likeSearch) + err := c.BindJSON(&request) + if err != nil { + aH.logger.Error("DeleteUser", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + + if len(request.Ids) == 0 { + aH.logger.Error("DeleteUser", "no ids given to be deleted") + c.JSON(http.StatusBadRequest, gin.H{ + "message": "no ids given to be deleted", + }) + return + } + + var ownId string + removeIds := make([]uint, len(request.Ids)) + for i, id := range request.Ids { + if queryId == fmt.Sprint(id) { + ownId = queryId + continue + } + removeIds[i] = uint(id) + } + + if ownId != "" { + aH.logger.Error("DeleteUser", "can not delete logged in member id: "+queryId) + c.JSON(http.StatusBadRequest, gin.H{ + "message": "can not delete logged in member id: " + queryId, + "id": queryId, + }) + return + } + + err = aH.dbHandler.DeleteById(&models.User{}, removeIds...) + if err != nil { + aH.logger.Error("DeleteUser", err) + c.JSON(http.StatusInternalServerError, nil) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "member(s) deleted", + }) } diff --git a/models/user.go b/models/user.go index b11db66..3539e9f 100644 --- a/models/user.go +++ b/models/user.go @@ -4,9 +4,9 @@ type User struct { Id uint `gorm:"primaryKey" json:"id"` Name string `gorm:"column:user_name" json:"user"` Email string `gorm:"column:email" json:"email"` - Role string `gorm:"column:role" json:"role"` + Role string `gorm:"column:role" json:"role,omitempty"` Password string `gorm:"column:password" json:"password"` - Settings Settings `gorm:"type:json" json:"settings"` + Settings Settings `gorm:"type:json" json:"settings,omitempty"` } func (u *User) IsValid() bool {