package repository import ( "context" "omega-server/local/model" "github.com/google/uuid" "gorm.io/gorm" ) // MembershipRepository handles database operations for users, roles, and permissions. type MembershipRepository struct { *BaseRepository[model.User, model.MembershipFilter] db *gorm.DB } // NewMembershipRepository creates a new MembershipRepository. func NewMembershipRepository(db *gorm.DB) *MembershipRepository { return &MembershipRepository{ BaseRepository: NewBaseRepository[model.User, model.MembershipFilter](db, model.User{}), db: db, } } // FindUserByEmail finds a user by their email. // It preloads the user's role and the role's permissions. func (r *MembershipRepository) FindUserByEmail(ctx context.Context, email string) (*model.User, error) { var user model.User db := r.db.WithContext(ctx) err := db.Preload("Roles.Permissions").Where("email = ?", email).First(&user).Error if err != nil { return nil, err } return &user, nil } // FindUserByIDWithPermissions finds a user by their ID and preloads Role and Permissions. func (r *MembershipRepository) FindUserByIDWithPermissions(ctx context.Context, userID string) (*model.User, error) { var user model.User db := r.db.WithContext(ctx) err := db.Preload("Roles.Permissions").First(&user, "id = ?", userID).Error if err != nil { return nil, err } return &user, nil } // CreateUser creates a new user. func (r *MembershipRepository) CreateUser(ctx context.Context, user *model.User) error { db := r.db.WithContext(ctx) return db.Create(user).Error } // FindRoleByName finds a role by its name. func (r *MembershipRepository) FindRoleByName(ctx context.Context, name string) (*model.Role, error) { var role model.Role db := r.db.WithContext(ctx) err := db.Where("name = ?", name).First(&role).Error if err != nil { return nil, err } return &role, nil } // CreateRole creates a new role. func (r *MembershipRepository) CreateRole(ctx context.Context, role *model.Role) error { db := r.db.WithContext(ctx) return db.Create(role).Error } // FindPermissionByName finds a permission by its name. func (r *MembershipRepository) FindPermissionByName(ctx context.Context, name string) (*model.Permission, error) { var permission model.Permission db := r.db.WithContext(ctx) err := db.Where("name = ?", name).First(&permission).Error if err != nil { return nil, err } return &permission, nil } // CreatePermission creates a new permission. func (r *MembershipRepository) CreatePermission(ctx context.Context, permission *model.Permission) error { db := r.db.WithContext(ctx) return db.Create(permission).Error } // AssignPermissionsToRole assigns a set of permissions to a role. func (r *MembershipRepository) AssignPermissionsToRole(ctx context.Context, role *model.Role, permissions []model.Permission) error { db := r.db.WithContext(ctx) return db.Model(role).Association("Permissions").Replace(permissions) } // GetUserPermissions retrieves all permissions for a given user ID. func (r *MembershipRepository) GetUserPermissions(ctx context.Context, userID uuid.UUID) ([]string, error) { var user model.User db := r.db.WithContext(ctx) if err := db.Preload("Roles.Permissions").First(&user, "id = ?", userID).Error; err != nil { return nil, err } permissionSet := make(map[string]bool) for _, role := range user.Roles { for _, permission := range role.Permissions { permissionSet[permission.Name] = true } } permissions := make([]string, 0, len(permissionSet)) for permission := range permissionSet { permissions = append(permissions, permission) } return permissions, nil } // ListUsers retrieves all users. func (r *MembershipRepository) ListUsers(ctx context.Context) ([]*model.User, error) { var users []*model.User db := r.db.WithContext(ctx) err := db.Preload("Roles").Find(&users).Error return users, err } // DeleteUser deletes a user. func (r *MembershipRepository) DeleteUser(ctx context.Context, userID uuid.UUID) error { db := r.db.WithContext(ctx) return db.Delete(&model.User{}, "id = ?", userID).Error } // FindUserByID finds a user by their ID. func (r *MembershipRepository) FindUserByID(ctx context.Context, userID uuid.UUID) (*model.User, error) { var user model.User db := r.db.WithContext(ctx) err := db.Preload("Roles").First(&user, "id = ?", userID).Error if err != nil { return nil, err } return &user, nil } // UpdateUser updates a user's details in the database. func (r *MembershipRepository) UpdateUser(ctx context.Context, user *model.User) error { db := r.db.WithContext(ctx) return db.Save(user).Error } // FindRoleByID finds a role by its ID. func (r *MembershipRepository) FindRoleByID(ctx context.Context, roleID uuid.UUID) (*model.Role, error) { var role model.Role db := r.db.WithContext(ctx) err := db.First(&role, "id = ?", roleID).Error if err != nil { return nil, err } return &role, nil } // ListUsersWithFilter retrieves users based on the membership filter. func (r *MembershipRepository) ListUsersWithFilter(ctx context.Context, filter *model.MembershipFilter) (*[]model.User, error) { return r.BaseRepository.GetAll(ctx, filter) } // ListRoles retrieves all roles. func (r *MembershipRepository) ListRoles(ctx context.Context) ([]*model.Role, error) { var roles []*model.Role db := r.db.WithContext(ctx) err := db.Find(&roles).Error return roles, err }