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 }