update role

main
alex 2023-06-20 16:55:58 +02:00
parent 5bc47a5789
commit 866bba7f07
5 changed files with 176 additions and 35 deletions

View File

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/rs/zerolog/log"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/gorm" "gorm.io/gorm"
@ -36,12 +37,12 @@ func InitDatabase() {
db.AutoMigrate(&structs.Role{}) db.AutoMigrate(&structs.Role{})
db.AutoMigrate(&structs.RolePermission{}) db.AutoMigrate(&structs.RolePermission{})
createDefaultRole() //createUser()
//adminRoleId := createDefaultRole()
//createUser(adminRoleId)
} }
func createUser(roleId string) { func createUser() {
adminRoleId := createDefaultRole()
pw := []byte("haha") pw := []byte("haha")
hashedPassword, err := bcrypt.GenerateFromPassword(pw, bcrypt.DefaultCost) hashedPassword, err := bcrypt.GenerateFromPassword(pw, bcrypt.DefaultCost)
@ -52,7 +53,7 @@ func createUser(roleId string) {
DB.Create(&structs.User{ DB.Create(&structs.User{
Id: uuid.New().String(), Id: uuid.New().String(),
RoleId: roleId, RoleId: adminRoleId,
Username: "Alex", Username: "Alex",
Email: "alex@roese.dev", Email: "alex@roese.dev",
Password: string(hashedPassword), Password: string(hashedPassword),
@ -63,15 +64,17 @@ func createUser(roleId string) {
func createDefaultRole() (roleId string) { func createDefaultRole() (roleId string) {
// create admin role if not already existing // create admin role if not already existing
role := structs.Role{ role := structs.Role{
Id: uuid.New().String(), Id: uuid.New().String(),
DisplayName: "Admin", Master: true,
Description: "Management board", DisplayName: "Admin",
CreatedAt: time.Now(), Description: "Management board",
CreatedAt: time.Now(),
SortingOrder: 0,
} }
var foundRole structs.Role var foundRole structs.Role
DB.First(&foundRole, "display_name = ?", role.DisplayName) DB.First(&foundRole, "master = ?", true)
if foundRole.Id == "" { if foundRole.Id == "" {
result := DB.Create(&role) result := DB.Create(&role)
@ -164,3 +167,14 @@ func isPermissionOutdated(systemPermissions []string, permission string) bool {
return true return true
} }
func GetRoleSortingOrder() int {
var lastSortingOrder int
if err := DB.Model(&structs.Role{}).Select("MAX(sorting_order)").Scan(&lastSortingOrder).Error; err != nil {
log.Error().Msgf("Error getting role sorting order %v", err.Error())
return 0
}
return lastSortingOrder + 1
}

View File

@ -5,11 +5,13 @@ import (
) )
type Role struct { type Role struct {
Id string Id string
DisplayName string Master bool `gorm:"type:bool"` // this reflects the role that has all rights
Description string DisplayName string
UpdatedAt time.Time Description string
CreatedAt time.Time SortingOrder int
UpdatedAt time.Time
CreatedAt time.Time
} }
// Permissions assigned to the role // Permissions assigned to the role

View File

@ -1,16 +1,19 @@
package utils package utils
const ( const (
minUsername = "2" minUsername = "2"
maxUsername = "20" maxUsername = "20"
MinUsername = 2 MinUsername = 2
MaxUsername = 20 MaxUsername = 20
minPassword = "6" minPassword = "6"
MinPassword = 6 MinPassword = 6
maxPassword = "64" maxPassword = "64"
MaxPassword = 64 MaxPassword = 64
minScannerName = "3" minScannerName = "3"
maxScannerName = "16" maxScannerName = "16"
MinRoleDisplayName = 3
MaxRoleDisplayName = 30
MaxRoleDescription = 80
LenHeaderXAuthorization = 36 LenHeaderXAuthorization = 36
lenHeaderXAuthorization = "36" lenHeaderXAuthorization = "36"
@ -45,6 +48,7 @@ const (
SentCmdTaskUnlocked = 17 SentCmdTaskUnlocked = 17
SentCmdUserProfileUpdated = 18 SentCmdUserProfileUpdated = 18
SentCmdAdminAreaNewRoleCreated = 19 SentCmdAdminAreaNewRoleCreated = 19
SentCmdAdminAreaRoleUpdated = 20
) )
// commands received from web clients // commands received from web clients
@ -56,6 +60,7 @@ const (
ReceivedCmdTaskLocking = 5 ReceivedCmdTaskLocking = 5
ReceivedCmdUpdateUserProfile = 6 ReceivedCmdUpdateUserProfile = 6
ReceivedCmdAdminAreaCreateNewRole = 7 ReceivedCmdAdminAreaCreateNewRole = 7
ReceivedCmdAdminAreaUpdateRole = 8
) )
const ( const (

View File

@ -201,7 +201,7 @@ func UpdateUserProfile(conn *websocket.Conn, changes map[string]interface{}) {
if changes["username"] != nil { if changes["username"] != nil {
username := changes["username"].(string) username := changes["username"].(string)
if isUsernameLengthValid(username) { // only affected if username was manipulated as min and max is provided in web ui if isValueLenValid(username, utils.MinUsername, utils.MaxUsername) { // only affected if username was manipulated as min and max is provided in web ui
if isUsernameAvailable(username) { if isUsernameAvailable(username) {
user.Username = username user.Username = username
updates["Username"] = username updates["Username"] = username
@ -296,15 +296,15 @@ func UpdateUserProfile(conn *websocket.Conn, changes map[string]interface{}) {
} }
} }
func isUsernameLengthValid(username string) bool { func isValueLenValid(value string, min int, max int) bool {
l := len(username) l := len(value)
return l > utils.MinUsername && l < utils.MaxUsername return l > min && l < max
} }
func GetAllRoles() []structs.Role { func GetAllRoles() []structs.Role {
var roles []structs.Role var roles []structs.Role
database.DB.Find(&roles) database.DB.Order("sorting_order").Find(&roles)
return roles return roles
} }
@ -355,3 +355,119 @@ func GetAdminAreaRolesPermissions() []structs.RolePermissions {
return rolePermissions return rolePermissions
} }
func isRoleDisplayNameAvailable(roleDisplayName string) bool {
var role structs.Role
database.DB.Select("display_name").Where("display_name = ?", roleDisplayName).Find(&role)
return role.DisplayName == ""
}
func AdminAreaUpdateRole(sessionId string, body map[string]interface{}) {
log.Debug().Msgf("update role %v", body)
if body["RoleId"] == nil {
log.Error().Msgf("No role id specified in update role %v", body)
return
}
roleId := body["RoleId"].(string)
changes := body["Changes"].(map[string]interface{})
if changes["AddedPermissions"] != nil {
log.Debug().Msgf("addedPermissions %v", len(changes["AddedPermissions"].([]interface{})))
}
// user has nothing changed
if changes["DisplayName"] == nil &&
changes["Description"] == nil &&
changes["AddedPermissions"] == nil &&
changes["RemovedPermissions"] == nil {
log.Error().Msgf("User has not specified anything to update the role %v", body)
return
}
updatedRole := structs.Role{
Id: roleId,
}
var changesResult = make(map[string]uint8)
var updates = make(map[string]interface{})
if changes["DisplayName"] != nil && isValueLenValid(changes["DisplayName"].(string), utils.MinRoleDisplayName, utils.MaxRoleDisplayName) {
if isRoleDisplayNameAvailable(changes["DisplayName"].(string)) {
updatedRole.DisplayName = changes["DisplayName"].(string)
updates["DisplayName"] = changes["DisplayName"].(string)
} else {
changesResult["DisplayName"] = 1
}
}
if changes["Description"] != nil {
updatedRole.Description = changes["Description"].(string)
updates["Description"] = changes["Description"].(string)
}
if changes["AddedPermissions"] != nil {
addedPermissions := changes["AddedPermissions"].([]interface{})
updates["AddedPermissions"] = addedPermissions
var dbAddedPermissions []structs.RolePermission
for _, addedPermission := range addedPermissions {
dbAddedPermissions = append(dbAddedPermissions, structs.RolePermission{
RoleId: roleId,
PermissionId: addedPermission.(string),
})
}
database.DB.Create(dbAddedPermissions)
log.Debug().Msgf("dbAddedPermissions: %v", dbAddedPermissions)
}
if changes["RemovedPermissions"] != nil {
removedPermissions := changes["RemovedPermissions"].([]interface{})
updates["RemovedPermissions"] = removedPermissions
for _, removedPermission := range removedPermissions {
database.DB.Where("role_id = ?", roleId).Where("permission_id = ?", removedPermission.(string)).Delete(&structs.RolePermission{})
log.Debug().Msgf("dbRemovedPermissions: %v", removedPermission)
}
}
database.DB.Model(&structs.Role{}).Where("id = ?", roleId).Updates(&updatedRole)
log.Debug().Msgf("updated role: %v", updatedRole)
// TODO: check permissions
SendMessageOnlyToSessionId(sessionId, structs.SendSocketMessage{
Cmd: utils.SentCmdAdminAreaRoleUpdated,
Body: struct {
RoleId string
Changes map[string]interface{}
Result map[string]uint8
}{
RoleId: roleId,
Changes: updates,
Result: changesResult,
},
})
BroadcastMessageExceptUserSessionId(sessionId, structs.SendSocketMessage{
Cmd: utils.SentCmdAdminAreaRoleUpdated,
Body: struct {
RoleId string
Changes map[string]interface{}
}{
RoleId: roleId,
Changes: updates,
},
})
}

View File

@ -201,19 +201,23 @@ func RunHub() {
// TODO: check permissions // TODO: check permissions
role := structs.Role{ role := structs.Role{
Id: uuid.New().String(), Id: uuid.New().String(),
DisplayName: "New Role " + time.Now().String(), DisplayName: "New Role " + uuid.New().String(),
Description: "Role description", Description: "Role description",
CreatedAt: time.Now(), CreatedAt: time.Now(),
SortingOrder: database.GetRoleSortingOrder(),
} }
//database.DB.Create(&role) database.DB.Create(&role)
socketclients.BroadcastMessage(structs.SendSocketMessage{ socketclients.BroadcastMessage(structs.SendSocketMessage{
Cmd: utils.SentCmdAdminAreaNewRoleCreated, Cmd: utils.SentCmdAdminAreaNewRoleCreated,
Body: role, Body: role,
}) })
break break
case utils.ReceivedCmdAdminAreaUpdateRole:
socketclients.AdminAreaUpdateRole(data.Conn.Locals("sessionId").(string), receivedMessage.Body)
break
default: default:
log.Error().Msgf("Received unknown message: %v", receivedMessage) log.Error().Msgf("Received unknown message: %v", receivedMessage)
break break