role permission system
parent
4612764b0b
commit
6b73e8ee57
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
|
@ -101,10 +108,12 @@ type AllUsers struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserData struct {
|
type UserData struct {
|
||||||
Id string
|
Id string
|
||||||
Username string
|
RoleId string
|
||||||
Email string
|
Username string
|
||||||
Sessions []UserSessionSocket
|
Email string
|
||||||
|
Sessions []UserSessionSocket
|
||||||
|
Permissions []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserSessionSocket struct {
|
type UserSessionSocket struct {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -64,16 +64,22 @@ func RunHub() {
|
||||||
Cmd: utils.SentCmdInitUserSocketConnection,
|
Cmd: utils.SentCmdInitUserSocketConnection,
|
||||||
Body: structs.InitUserSocketConnection{
|
Body: structs.InitUserSocketConnection{
|
||||||
User: structs.UserData{
|
User: structs.UserData{
|
||||||
Id: user.Id,
|
Id: user.Id,
|
||||||
Username: user.Username,
|
RoleId: user.RoleId,
|
||||||
Email: user.Email,
|
Username: user.Username,
|
||||||
Sessions: socketclients.GetUserSessions(userId),
|
Email: user.Email,
|
||||||
|
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(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue