update role
parent
5bc47a5789
commit
866bba7f07
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue