package database import ( "GoMembership/internal/constants" "GoMembership/internal/models" "GoMembership/pkg/logger" "crypto/rand" "encoding/base64" "time" "github.com/alexedwards/argon2id" "gorm.io/driver/sqlite" "gorm.io/gorm" ) var DB *gorm.DB func Open(dbPath string, adminMail string) error { db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{}) if err != nil { return err } if err := db.AutoMigrate( &models.User{}, &models.SubscriptionModel{}, &models.Membership{}, &models.Consent{}, &models.Verification{}, &models.Licence{}, &models.Category{}, &models.BankAccount{}); err != nil { logger.Error.Fatalf("Couldn't create database: %v", err) return err } DB = db logger.Info.Print("Opened DB") var categoriesCount int64 db.Model(&models.Category{}).Count(&categoriesCount) if categoriesCount == 0 { categories := createLicenceCategories() for _, model := range categories { result := db.Create(&model) if result.Error != nil { return result.Error } } } var subscriptionsCount int64 db.Model(&models.SubscriptionModel{}).Count(&subscriptionsCount) if subscriptionsCount == 0 { subscriptionModels := createSubscriptionModels() for _, model := range subscriptionModels { result := db.Create(&model) if result.Error != nil { return result.Error } } } var userCount int64 db.Model(&models.User{}).Count(&userCount) if userCount == 0 { var createdModel models.SubscriptionModel if err := db.First(&createdModel).Error; err != nil { return err } admin, err := createAdmin(adminMail, createdModel.ID) if err != nil { return err } result := db.Session(&gorm.Session{FullSaveAssociations: true}).Create(&admin) if result.Error != nil { return result.Error } } return nil } func createSubscriptionModels() []models.SubscriptionModel { return []models.SubscriptionModel{ { Name: "Keins", Details: "Dieses Modell ist für Vereinsmitglieder, die keinen Wunsch haben, an dem Carhsharing teilzunehmen.", HourlyRate: 999, MonthlyFee: 0, }, } } func createLicenceCategories() []models.Category { return []models.Category{ {Name: "AM"}, {Name: "A1"}, {Name: "A2"}, {Name: "A"}, {Name: "B"}, {Name: "C1"}, {Name: "C"}, {Name: "D1"}, {Name: "D"}, {Name: "BE"}, {Name: "C1E"}, {Name: "CE"}, {Name: "D1E"}, {Name: "DE"}, {Name: "T"}, {Name: "L"}, } } // TODO: Landing page to create an admin func createAdmin(userMail string, subscriptionModelID uint) (*models.User, error) { passwordBytes := make([]byte, 12) _, err := rand.Read(passwordBytes) if err != nil { return nil, err } // Encode into a URL-safe base64 string password := base64.URLEncoding.EncodeToString(passwordBytes)[:12] hash, err := argon2id.CreateHash(password, argon2id.DefaultParams) if err != nil { return nil, err } logger.Error.Print("==============================================================") logger.Error.Printf("Admin Email: %v", userMail) logger.Error.Printf("Admin Password: %v", password) logger.Error.Print("==============================================================") return &models.User{ FirstName: "ad", LastName: "min", DateOfBirth: time.Now().AddDate(-20, 0, 0), Password: hash, Address: "Downhill 4", ZipCode: "99999", City: "TechTown", Phone: "0123455678", Email: userMail, Status: constants.ActiveStatus, RoleID: constants.Roles.Admin, Membership: models.Membership{ Status: constants.DisabledStatus, StartDate: time.Now(), SubscriptionModelID: subscriptionModelID, }, BankAccount: models.BankAccount{}, Licence: &models.Licence{ Status: constants.UnverifiedStatus, }, }, nil //"DE49700500000008447644", //fake } func Close() error { logger.Info.Print("Closing DB") db, err := DB.DB() if err != nil { return err } return db.Close() }