package controllers import ( "errors" "fmt" "html" "log" "net/http" "strings" "smt/models" "smt/utils/token" "github.com/gin-gonic/gin" "golang.org/x/crypto/bcrypt" ) type RegisterInput struct { UserName string `json:"userName" binding:"required"` Password string `json:"password" binding:"required"` GroupId int `json:"groupId"` GroupName string `json:"groupName"` //RoleId int `json:"roleid"` } type LoginInput struct { UserName string `json:"userName" binding:"required"` Password string `json:"password" binding:"required"` } type DeleteInput struct { UserName string `json:"userName" binding:"required"` } type AddRoleInput struct { RoleName string `json:"roleName" binding:"required"` LdapGroup string `json:"ldapGroup"` ReadOnly bool `json:"readOnly"` Admin bool `json:"admin"` } func DeleteUser(c *gin.Context) { var input DeleteInput if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } u := models.User{} u.UserName = input.UserName //remove spaces in username u.UserName = html.EscapeString(strings.TrimSpace(u.UserName)) // Confirm user account exists testUser, _ := models.UserGetByName(u.UserName) log.Printf("DeleteUser confirming user '%s' account exists\n", u.UserName) if (models.User{} == testUser) { err := errors.New("attempt to delete non-existing username '" + u.UserName + "'") log.Printf("Delete User error : '%s'\n", err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } else { err := u.DeleteUser() if err != nil { c.JSON(http.StatusBadRequest, gin.H{"Error deleting user": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "user deletion success"}) } } func RegisterUser(c *gin.Context) { var input RegisterInput if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if len(input.UserName) == 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "no username specified"}) return } if len(input.Password) == 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "no password specified"}) return } u := models.User{} u.UserName = input.UserName u.Password = input.Password // Determine which GroupId to save // Can be specified either by GroupName or GroupId in the request if len(input.GroupName) > 0 { g, err := models.GroupGetByName(input.GroupName) if err != nil { errString := fmt.Sprintf("RegisterUser error looking up group by name : '%s'", err) log.Println(errString) c.JSON(http.StatusBadRequest, gin.H{"error": errString}) return } if g == (models.Group{}) { errString := fmt.Sprintf("RegisterUser specified group not found") log.Println(errString) c.JSON(http.StatusBadRequest, gin.H{"error": errString}) return } else { u.GroupId = g.GroupId } } else if input.GroupId > 0 { u.GroupId = input.GroupId } else { errString := fmt.Sprintf("RegisterUser no group specified, must specify either GroupId or GroupName") log.Println(errString) c.JSON(http.StatusBadRequest, gin.H{"error": errString}) return } /* // Default to regular user role if not specified if input.RoleId == 0 { log.Printf("Register no role specified, defaulting to builtin role UserRole with id 2.\n") u.RoleId = 2 } else { u.RoleId = input.RoleId } */ //remove spaces in username u.UserName = html.EscapeString(strings.TrimSpace(u.UserName)) // Check if user already exists testUser, _ := models.UserGetByName(u.UserName) log.Printf("Register checking if user '%s' already exists\n", u.UserName) if (models.User{} == testUser) { log.Printf("Register confirmed no existing username\n") } else { err := errors.New("attempt to register conflicting username '" + u.UserName + "'") log.Printf("Register error : '%s'\n", err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } //turn password into hash hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"Error hashing password": err.Error()}) return } else { //log.Printf("Register generated hashed password value '%s' from '%s'\n", string(hashedPassword), input.Password) log.Printf("Register generated hashed password value '%s'\n", string(hashedPassword)) } u.Password = string(hashedPassword) _, err = u.SaveUser() if err != nil { c.JSON(http.StatusBadRequest, gin.H{"Error saving user": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "user registration success"}) } func AddRole(c *gin.Context) { var input AddRoleInput if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // define the new role properties r := models.Role{} r.RoleName = input.RoleName r.ReadOnly = input.ReadOnly r.Admin = input.Admin r.LdapGroup = input.LdapGroup // Check if role already exists testRole, _ := models.GetRoleByName(r.RoleName) log.Printf("AddRole checking if role '%s' already exists\n", r.RoleName) if (models.Role{} == testRole) { log.Printf("AddRole confirmed no existing rolename\n") } else { errorString := fmt.Sprintf("attempt to register conflicting rolename '%s'", r.RoleName) log.Printf("Register error : '%s'\n", errorString) c.JSON(http.StatusBadRequest, gin.H{"error": errorString}) return } _, err := r.AddRole() if err != nil { c.JSON(http.StatusBadRequest, gin.H{"Error creating role": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "role creation success"}) } func Login(c *gin.Context) { var input LoginInput if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } u := models.User{} u.UserName = input.UserName u.Password = input.Password log.Printf("Login checking username '%s' and password length '%d'\n", u.UserName, len(u.Password)) token, err := models.LoginCheck(u.UserName, u.Password) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "username or password is incorrect."}) return } else { log.Printf("Login verified, returning token '%s'\n", token) } c.JSON(http.StatusOK, gin.H{"access_token": token}) } func CurrentUser(c *gin.Context) { user_id, err := token.ExtractTokenID(c) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } u, err := models.UserGetByID(user_id) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "success", "data": u}) } func GetRoles(c *gin.Context) { roles, err := models.QueryRoles() if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "success", "data": roles}) } func GetUsers(c *gin.Context) { users, err := models.UserList() if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "success", "data": users}) }