role permission system

main
alex 2023-06-17 23:14:38 +02:00
parent 4612764b0b
commit 6b73e8ee57
7 changed files with 243 additions and 13 deletions

View File

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"janex/admin-dashboard-backend/modules/config" "janex/admin-dashboard-backend/modules/config"
"janex/admin-dashboard-backend/modules/structs" "janex/admin-dashboard-backend/modules/structs"
"log" "janex/admin-dashboard-backend/modules/utils"
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
@ -23,7 +23,7 @@ func InitDatabase() {
&gorm.Config{}) &gorm.Config{})
if err != nil { if err != nil {
log.Fatal(err) panic(err)
} }
DB = db DB = db
@ -33,24 +33,134 @@ func InitDatabase() {
db.AutoMigrate(&structs.GroupTasks{}) db.AutoMigrate(&structs.GroupTasks{})
db.AutoMigrate(&structs.GroupTaskSteps{}) db.AutoMigrate(&structs.GroupTaskSteps{})
db.AutoMigrate(&structs.Scanner{}) db.AutoMigrate(&structs.Scanner{})
db.AutoMigrate(&structs.Role{})
db.AutoMigrate(&structs.RolePermission{})
//createUser() createDefaultRole()
//adminRoleId := createDefaultRole()
//createUser(adminRoleId)
} }
func createUser() { func createUser(roleId string) {
pw := []byte("haha") pw := []byte("haha")
hashedPassword, err := bcrypt.GenerateFromPassword(pw, bcrypt.DefaultCost) hashedPassword, err := bcrypt.GenerateFromPassword(pw, bcrypt.DefaultCost)
if err != nil { if err != nil {
log.Fatal(err) panic(err)
} }
DB.Create(&structs.User{ DB.Create(&structs.User{
Id: uuid.New().String(), Id: uuid.New().String(),
RoleId: roleId,
Username: "Alex", Username: "Alex",
Email: "alex@roese.dev", Email: "alex@roese.dev",
Password: string(hashedPassword), Password: string(hashedPassword),
CreatedAt: time.Now(), CreatedAt: time.Now(),
}) })
} }
func createDefaultRole() (roleId string) {
// create admin role if not already existing
role := structs.Role{
Id: uuid.New().String(),
DisplayName: "Admin",
Description: "Management board",
CreatedAt: time.Now(),
}
var foundRole structs.Role
DB.First(&foundRole, "display_name = ?", role.DisplayName)
if foundRole.Id == "" {
result := DB.Create(&role)
if result.Error != nil {
panic(result.Error)
}
foundRole.Id = role.Id
}
// looking for role permissions
var foundRolePermissions []structs.RolePermission
DB.Where("role_id = ?", foundRole.Id).Find(&foundRolePermissions)
systemPermissions := utils.GetSystemPermissions()
if len(foundRolePermissions) > 0 {
// add new permissions if not already present
var newPermissions []string
for _, systemPermission := range systemPermissions {
if !hasPermission(foundRolePermissions, systemPermission) {
newPermissions = append(newPermissions, systemPermission)
}
}
if len(newPermissions) > 0 {
var newRolePermissions []structs.RolePermission
for _, newPermission := range newPermissions {
newRolePermissions = append(newRolePermissions, structs.RolePermission{
RoleId: foundRole.Id,
PermissionId: newPermission,
})
}
DB.Create(newRolePermissions)
}
// deleting permissions that are no longer supported
var outdatedPermissions []structs.RolePermission
for _, foundRolePermission := range foundRolePermissions {
if isPermissionOutdated(systemPermissions, foundRolePermission.PermissionId) {
outdatedPermissions = append(outdatedPermissions, foundRolePermission)
}
}
if len(outdatedPermissions) > 0 {
for _, outdatedPermission := range outdatedPermissions {
DB.Where("role_id = ?", outdatedPermission.RoleId).
Where("permission_id = ?", outdatedPermission.PermissionId).
Delete(&outdatedPermission)
}
}
} else { // admin role has no permissions - grant all permissions
var newRolePermissions []structs.RolePermission
for _, systemPermission := range systemPermissions {
newRolePermissions = append(newRolePermissions, structs.RolePermission{
RoleId: foundRole.Id,
PermissionId: systemPermission,
})
}
DB.Create(newRolePermissions)
}
return foundRole.Id
}
func hasPermission(rolePermissions []structs.RolePermission, permission string) bool {
for _, rolePermission := range rolePermissions {
if rolePermission.PermissionId == permission {
return true
}
}
return false
}
func isPermissionOutdated(systemPermissions []string, permission string) bool {
for _, systemPermission := range systemPermissions {
if systemPermission == permission {
return false
}
}
return true
}

24
modules/structs/roles.go Normal file
View File

@ -0,0 +1,24 @@
package structs
import (
"time"
)
type Role struct {
Id string
DisplayName string
Description string
UpdatedAt time.Time
CreatedAt time.Time
}
// Permissions assigned to the role
type RolePermission struct {
RoleId string
PermissionId string
}
type RolePermissions struct {
RoleId string
Permissions []string
}

View File

@ -90,10 +90,17 @@ type InitUserSocketConnection struct {
GroupTasksSteps []GroupTaskSteps GroupTasksSteps []GroupTaskSteps
AllUsers []AllUsers AllUsers []AllUsers
Scanners []Scanner Scanners []Scanner
AllRoles []Role
AdminArea InitUserSocketConnectionAdminArea
}
type InitUserSocketConnectionAdminArea struct {
RolesPermissions []RolePermissions `json:"RolesPermissions,omitempty"`
} }
type AllUsers struct { type AllUsers struct {
Id string Id string
RoleId string
Avatar string Avatar string
Username string Username string
ConnectionStatus uint8 ConnectionStatus uint8
@ -102,9 +109,11 @@ type AllUsers struct {
type UserData struct { type UserData struct {
Id string Id string
RoleId string
Username string Username string
Email string Email string
Sessions []UserSessionSocket Sessions []UserSessionSocket
Permissions []string
} }
type UserSessionSocket struct { type UserSessionSocket struct {

View File

@ -6,6 +6,7 @@ import (
type User struct { type User struct {
Id string Id string
RoleId string
Avatar string Avatar string
Username string Username string
Email string Email string

View File

@ -72,3 +72,27 @@ var (
"ScannerName": "required,min=" + minScannerName + ",max=" + maxScannerName, "ScannerName": "required,min=" + minScannerName + ",max=" + maxScannerName,
} }
) )
const (
_groupTasks = "group_tasks."
PermissionGroupTasksHistory = _groupTasks + "history"
_adminArea = "admin_area."
_adminAreaRoles = _adminArea + "roles."
PermissionAdminAreaAddRole = _adminAreaRoles + "add_role"
PermissionAdminAreaUpdateRole = _adminAreaRoles + "update_role"
PermissionAdminAreaDeleteRole = _adminAreaRoles + "delete_role"
PermissionAdminAreaAddUserToRole = _adminAreaRoles + "add_user_to_role"
PermissionAdminAreaLogs = _adminArea + "logs"
)
func GetSystemPermissions() []string {
return []string{
PermissionGroupTasksHistory,
PermissionAdminAreaAddRole,
PermissionAdminAreaUpdateRole,
PermissionAdminAreaDeleteRole,
PermissionAdminAreaAddUserToRole,
PermissionAdminAreaLogs,
}
}

View File

@ -149,6 +149,7 @@ func GetAllUsers() []structs.AllUsers {
for _, user := range users { for _, user := range users {
allUsers = append(allUsers, structs.AllUsers{ allUsers = append(allUsers, structs.AllUsers{
Id: user.Id, Id: user.Id,
RoleId: user.RoleId,
Avatar: user.Avatar, Avatar: user.Avatar,
Username: user.Username, Username: user.Username,
ConnectionStatus: isUserGenerallyConnected(user.Id), ConnectionStatus: isUserGenerallyConnected(user.Id),
@ -299,3 +300,58 @@ func isUsernameLengthValid(username string) bool {
l := len(username) l := len(username)
return l > utils.MinUsername && l < utils.MaxUsername return l > utils.MinUsername && l < utils.MaxUsername
} }
func GetAllRoles() []structs.Role {
var roles []structs.Role
database.DB.Find(&roles)
return roles
}
func GetPermissionsByRoleId(roleId string) []string {
var rolePermissions []structs.RolePermission
database.DB.Where("role_id = ?", roleId).Find(&rolePermissions)
var permissions []string
for _, rolePermission := range rolePermissions {
permissions = append(permissions, rolePermission.PermissionId)
}
return permissions
}
// Retrieve all roles with a list of all permissions for each role
func GetAdminAreaRolesPermissions() []structs.RolePermissions {
roles := GetAllRoles()
var rolesPermissions []structs.RolePermission
database.DB.Find(&rolesPermissions)
log.Debug().Msgf("rolePermissions: %v", rolesPermissions)
var rolePermissions []structs.RolePermissions
for _, role := range roles {
var permissions []string
for _, rolePermission := range rolesPermissions {
if rolePermission.RoleId == role.Id {
permissions = append(permissions, rolePermission.PermissionId)
}
}
log.Debug().Msgf("permissions %v", permissions)
rolePermissions = append(rolePermissions, structs.RolePermissions{
RoleId: role.Id,
Permissions: permissions,
})
}
log.Debug().Msgf("role permissions: %v", rolePermissions)
return rolePermissions
}

View File

@ -65,15 +65,21 @@ func RunHub() {
Body: structs.InitUserSocketConnection{ Body: structs.InitUserSocketConnection{
User: structs.UserData{ User: structs.UserData{
Id: user.Id, Id: user.Id,
RoleId: user.RoleId,
Username: user.Username, Username: user.Username,
Email: user.Email, Email: user.Email,
Sessions: socketclients.GetUserSessions(userId), Sessions: socketclients.GetUserSessions(userId),
Permissions: socketclients.GetPermissionsByRoleId(user.RoleId),
}, },
CategoryGroups: cache.GetCategoryGroupsSorted(), CategoryGroups: cache.GetCategoryGroupsSorted(),
GroupTasks: grouptasks.GetAllGroupTasks(), GroupTasks: grouptasks.GetAllGroupTasks(),
GroupTasksSteps: grouptasks.GetAllGroupTasksSteps(), GroupTasksSteps: grouptasks.GetAllGroupTasksSteps(),
AllUsers: socketclients.GetAllUsers(), AllUsers: socketclients.GetAllUsers(),
Scanners: socketclients.GetAllScanners(), Scanners: socketclients.GetAllScanners(),
AllRoles: socketclients.GetAllRoles(),
AdminArea: structs.InitUserSocketConnectionAdminArea{
RolesPermissions: socketclients.GetAdminAreaRolesPermissions(),
},
}, },
}) })