package db import "time" func (d *DB) GetImcUserByUsername(username string) (*ImcUser, error) { var user ImcUser if err := d.Preload("Domains.Domain").Where("username = ?", username).First(&user).Error; err != nil { return nil, err } return &user, nil } func (d *DB) GetImcUserByID(id uint) (*ImcUser, error) { var user ImcUser if err := d.Preload("Domains.Domain").First(&user, id).Error; err != nil { return nil, err } return &user, nil } func (d *DB) CreateImcUser(username, passwordHash, role string) (*ImcUser, error) { user := ImcUser{ Username: username, PasswordHash: passwordHash, Role: role, } if err := d.Create(&user).Error; err != nil { return nil, err } return &user, nil } func (d *DB) UpdateImcUserPassword(id uint, passwordHash string) error { return d.Model(&ImcUser{}).Where("id = ?", id).Update("password_hash", passwordHash).Error } func (d *DB) DeleteImcUser(id uint) error { return d.Delete(&ImcUser{}, id).Error } func (d *DB) EnsureAdminUser(username, passwordHash string) error { var user ImcUser err := d.Where("username = ? AND role = ?", username, "admin").First(&user).Error if err == nil { return d.Model(&ImcUser{}).Where("id = ?", user.ID).Update("password_hash", passwordHash).Error } _, err = d.CreateImcUser(username, passwordHash, "admin") return err } func (d *DB) GetUserAccessibleDomains(userID uint, isAdmin bool) ([]Domain, error) { if isAdmin { var domains []Domain if err := d.Find(&domains).Error; err != nil { return nil, err } return domains, nil } var domains []Domain err := d.Table("imc_users2domains"). Select("virtual_domains.*"). Joins("JOIN virtual_domains ON virtual_domains.id = imc_users2domains.domain_id"). Where("imc_users2domains.user_id = ?", userID). Find(&domains).Error if err != nil { return nil, err } if domains == nil { domains = []Domain{} } return domains, nil } func (d *DB) CanAccessDomain(userID uint, domainName string, isAdmin bool) (bool, error) { if isAdmin { return true, nil } var count int64 err := d.Table("imc_users2domains"). Select("COUNT(*)"). Joins("JOIN virtual_domains ON virtual_domains.id = imc_users2domains.domain_id"). Where("imc_users2domains.user_id = ? AND virtual_domains.name = ?", userID, domainName). Count(&count).Error if err != nil { return false, err } return count > 0, nil } func (d *DB) AddUserToDomain(userID, domainID uint) error { ud := ImcUserDomain{ UserID: userID, DomainID: domainID, } return d.Create(&ud).Error } func (d *DB) RemoveUserFromDomain(userID, domainID uint) error { return d.Where("user_id = ? AND domain_id = ?", userID, domainID).Delete(&ImcUserDomain{}).Error } func (d *DB) GetUsersForDomain(domainID uint) ([]ImcUser, error) { var users []ImcUser err := d.Table("imc_users2domains"). Select("imc_users.*"). Joins("JOIN imc_users ON imc_users.id = imc_users2domains.user_id"). Where("imc_users2domains.domain_id = ?", domainID). Find(&users).Error if err != nil { return nil, err } if users == nil { users = []ImcUser{} } return users, nil } func (d *DB) IsUserInDomain(userID, domainID uint) (bool, error) { var count int64 err := d.Model(&ImcUserDomain{}).Where("user_id = ? AND domain_id = ?", userID, domainID).Count(&count).Error return count > 0, err } func (d *DB) CreatePasswordResetToken(userID uint, token string, expiresAt time.Time) error { resetToken := PasswordResetToken{ UserID: userID, Token: token, ExpiresAt: expiresAt, } return d.Create(&resetToken).Error } func (d *DB) GetValidPasswordResetToken(token string) (*PasswordResetToken, error) { var resetToken PasswordResetToken err := d.Where("token = ? AND used = false AND expires_at > ?", token, time.Now()).First(&resetToken).Error if err != nil { return nil, err } return &resetToken, nil } func (d *DB) MarkResetTokenUsed(token string) error { return d.Model(&PasswordResetToken{}).Where("token = ?", token).Update("used", true).Error }