admin-dashboard-backend/modules/database/database.go

194 lines
4.6 KiB
Go

package database
import (
"fmt"
"janex/admin-dashboard-backend/modules/cache"
"janex/admin-dashboard-backend/modules/config"
"janex/admin-dashboard-backend/modules/structs"
"time"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
"golang.org/x/crypto/bcrypt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var DB *gorm.DB
func InitDatabase() {
cfg := config.Cfg.MariaDB
db, err := gorm.Open(mysql.Open(
fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", cfg.Username, cfg.Password, cfg.Hostname, cfg.Port, cfg.DatabaseName)),
&gorm.Config{})
if err != nil {
panic(err)
}
DB = db
db.AutoMigrate(&structs.User{})
db.AutoMigrate(&structs.UserSession{})
db.AutoMigrate(&structs.GroupTasks{})
db.AutoMigrate(&structs.GroupTaskSteps{})
db.AutoMigrate(&structs.Scanner{})
db.AutoMigrate(&structs.Role{})
db.AutoMigrate(&structs.RolePermission{})
masterRoleId := handleMasterRolePermissions()
//handleMasterRolePermissions()
createDefaultAdminUser(masterRoleId)
}
func createDefaultAdminUser(masterRoleId string) {
var userCount int64
DB.Model(&structs.User{}).Count(&userCount)
if userCount > 0 {
return
}
log.Info().Msg("No users found. Master account was created:")
pw := []byte("adminadmin")
hashedPassword, err := bcrypt.GenerateFromPassword(pw, bcrypt.DefaultCost)
if err != nil {
panic(err)
}
user := structs.User{
Id: uuid.New().String(),
RoleId: masterRoleId,
Username: "admin",
Email: "admin@roese.dev",
Password: string(hashedPassword),
CreatedAt: time.Now(),
}
DB.Create(&user)
log.Info().Msgf("Username: %s", user.Username)
log.Info().Msgf("Password: %s", string(pw))
}
func handleMasterRolePermissions() (roleId string) {
// create admin role if not already existing
role := structs.Role{
Id: uuid.New().String(),
Master: true,
DisplayName: "Admin",
Description: "Management board",
CreatedAt: time.Now(),
SortingOrder: 0,
}
var foundRole structs.Role
DB.First(&foundRole, "master = ?", true)
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 := cache.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 {
// delete old permissions for all roles
DB.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
}
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
}