300 lines
8.4 KiB
Go
300 lines
8.4 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
// UserRepository interface {
|
|
// Register(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error)
|
|
// GetUserById(ctx context.Context, tx *gorm.DB, userId string) (entities.M_User, error)
|
|
// GetUserByEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, error)
|
|
// CheckEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, bool, error)
|
|
// Update(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error)
|
|
// Delete(ctx context.Context, tx *gorm.DB, userId string) error
|
|
// SwitchRole(ctx context.Context, tx *gorm.DB, userId string, roleId string) (entities.M_User, error)
|
|
// }
|
|
|
|
type RoleRepository interface {
|
|
CreateRole(ctx context.Context, tx *gorm.DB, role entities.M_Role) (entities.M_Role, error)
|
|
GetRoleByID(ctx context.Context, tx *gorm.DB, id string) (entities.M_Role, error)
|
|
UpdateRole(ctx context.Context, tx *gorm.DB, role entities.M_Role) (entities.M_Role, error)
|
|
DeleteRole(ctx context.Context, tx *gorm.DB, id string) error
|
|
AssignPermissionsToRole(ctx context.Context, tx *gorm.DB, roleId string, permissions []string) error
|
|
RemovePermissionsFromRole(ctx context.Context, tx *gorm.DB, roleId string, permissions []string) error
|
|
AssignRoleToUser(ctx context.Context, tx *gorm.DB, userId string, roleId string) error
|
|
RemoveRoleFromUser(ctx context.Context, tx *gorm.DB, userId string, roleId string) error
|
|
GetRolesByUserID(ctx context.Context, tx *gorm.DB, userId string) ([]entities.M_Role, error)
|
|
CheckRoleName(ctx context.Context, tx *gorm.DB, name string) (entities.M_Role, bool, error)
|
|
AssignMenusToRole(ctx context.Context, tx *gorm.DB, roleId string, menus []string) error
|
|
RemoveMenusFromRole(ctx context.Context, tx *gorm.DB, roleId string, menus []string) error
|
|
GetAll(ctx context.Context, tx *gorm.DB) ([]entities.M_Role, error)
|
|
}
|
|
|
|
type roleRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// GetAll implements RoleRepository.
|
|
func (r *roleRepository) GetAll(ctx context.Context, tx *gorm.DB) ([]entities.M_Role, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
var roles []entities.M_Role
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Client").
|
|
Preload("Permissions").
|
|
Preload("Menus").
|
|
Find(&roles).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return roles, nil
|
|
}
|
|
|
|
// AssignMenusToRole implements RoleRepository.
|
|
func (r *roleRepository) AssignMenusToRole(ctx context.Context, tx *gorm.DB, roleId string, menus []string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
roleUUID, err := uuid.Parse(roleId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var roleMenus []entities.M_Role_Menu
|
|
for _, menuId := range menus {
|
|
menuUUID, err := uuid.Parse(menuId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
roleMenus = append(roleMenus, entities.M_Role_Menu{
|
|
RoleID: roleUUID,
|
|
MenuID: menuUUID,
|
|
})
|
|
}
|
|
|
|
// Use Create with OnConflict to avoid duplicate entries
|
|
if err := tx.WithContext(ctx).Clauses(
|
|
clause.OnConflict{DoNothing: true},
|
|
).Create(&roleMenus).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RemoveMenusFromRole implements RoleRepository.
|
|
func (r *roleRepository) RemoveMenusFromRole(ctx context.Context, tx *gorm.DB, roleId string, menus []string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
roleUUID, err := uuid.Parse(roleId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
menuUUIDs := make([]uuid.UUID, 0, len(menus))
|
|
for _, menuId := range menus {
|
|
menuUUID, err := uuid.Parse(menuId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
menuUUIDs = append(menuUUIDs, menuUUID)
|
|
}
|
|
|
|
if err := tx.WithContext(ctx).
|
|
Where("role_id = ? AND menu_id IN ?", roleUUID, menuUUIDs).
|
|
Delete(&entities.M_Role_Menu{}).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CheckRoleName implements RoleRepository.
|
|
func (r *roleRepository) CheckRoleName(ctx context.Context, tx *gorm.DB, name string) (entities.M_Role, bool, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
var role entities.M_Role
|
|
if err := tx.WithContext(ctx).Where("name = ?", name).First(&role).Error; err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
return entities.M_Role{}, false, nil
|
|
}
|
|
return entities.M_Role{}, false, err
|
|
}
|
|
return role, true, nil
|
|
}
|
|
|
|
// AssignPermissionsToRole implements RoleRepository.
|
|
func (r *roleRepository) AssignPermissionsToRole(ctx context.Context, tx *gorm.DB, roleId string, permissions []string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
if err := tx.WithContext(ctx).Model(&entities.M_Role{}).Where("id = ?", roleId).Update("permissions", gorm.Expr("array_cat(permissions, ?)", permissions)).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *roleRepository) AssignRoleToUser(ctx context.Context, tx *gorm.DB, userId string, roleId string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
userUUID, err := uuid.Parse(userId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
roleUUID, err := uuid.Parse(roleId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var count int64
|
|
if err := tx.WithContext(ctx).
|
|
Model(&entities.M_User_Role{}).
|
|
Where("user_id = ? AND role_id = ?", userUUID, roleUUID).
|
|
Count(&count).Error; err != nil {
|
|
return err
|
|
}
|
|
if count > 0 {
|
|
return nil
|
|
}
|
|
userRole := entities.M_User_Role{
|
|
UserID: userUUID,
|
|
RoleID: roleUUID,
|
|
}
|
|
// Insert ke tabel user_roles, bukan update ke M_User
|
|
if err := tx.WithContext(ctx).Create(&userRole).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CreateRole implements RoleRepository.
|
|
func (r *roleRepository) CreateRole(ctx context.Context, tx *gorm.DB, role entities.M_Role) (entities.M_Role, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
if err := tx.WithContext(ctx).Create(&role).Error; err != nil {
|
|
return entities.M_Role{}, err
|
|
}
|
|
|
|
return role, nil
|
|
}
|
|
|
|
// DeleteRole implements RoleRepository.
|
|
func (r *roleRepository) DeleteRole(ctx context.Context, tx *gorm.DB, id string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
if err := tx.WithContext(ctx).Where("id = ?", id).Delete(&entities.M_Role{}).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetRoleByID implements RoleRepository.
|
|
func (r *roleRepository) GetRoleByID(ctx context.Context, tx *gorm.DB, id string) (entities.M_Role, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
var role entities.M_Role
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Client").
|
|
Preload("Permissions").
|
|
Preload("Menus").
|
|
Preload("Menus.Parent").
|
|
Where("id = ?", id).
|
|
First(&role).Error; err != nil {
|
|
return entities.M_Role{}, err
|
|
}
|
|
return role, nil
|
|
}
|
|
|
|
// GetRolesByUserID implements RoleRepository.
|
|
func (r *roleRepository) GetRolesByUserID(ctx context.Context, tx *gorm.DB, userId string) ([]entities.M_Role, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
var roles []entities.M_Role
|
|
if err := tx.WithContext(ctx).
|
|
Model(&entities.M_Role{}).
|
|
Joins("JOIN m_user_roles ur ON ur.role_id = m_roles.id").
|
|
Where("ur.user_id = ?", userId).
|
|
Preload("Client").
|
|
Preload("Permissions").
|
|
Find(&roles).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return roles, nil
|
|
}
|
|
|
|
// RemovePermissionsFromRole implements RoleRepository.
|
|
func (r *roleRepository) RemovePermissionsFromRole(ctx context.Context, tx *gorm.DB, roleId string, permissions []string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
if err := tx.WithContext(ctx).Model(&entities.M_Role{}).Where("id = ?", roleId).Update("permissions", gorm.Expr("array_remove(permissions, ?)", permissions)).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RemoveRoleFromUser implements RoleRepository.
|
|
func (r *roleRepository) RemoveRoleFromUser(ctx context.Context, tx *gorm.DB, userId string, roleId string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
userUUID, err := uuid.Parse(userId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
roleUUID, err := uuid.Parse(roleId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var count int64
|
|
if err := tx.WithContext(ctx).
|
|
Model(&entities.M_User_Role{}).
|
|
Where("user_id = ? AND role_id = ?", userUUID, roleUUID).
|
|
Count(&count).Error; err != nil {
|
|
return err
|
|
}
|
|
if count > 0 {
|
|
return nil
|
|
}
|
|
userRole := entities.M_User_Role{
|
|
UserID: userUUID,
|
|
RoleID: roleUUID,
|
|
}
|
|
// Delete ke tabel user_roles, bukan update ke M_User
|
|
if err := tx.WithContext(ctx).Delete(&userRole).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// UpdateRole implements RoleRepository.
|
|
func (r *roleRepository) UpdateRole(ctx context.Context, tx *gorm.DB, role entities.M_Role) (entities.M_Role, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
if err := tx.WithContext(ctx).Updates(&role).Error; err != nil {
|
|
return entities.M_Role{}, err
|
|
}
|
|
return role, nil
|
|
}
|
|
|
|
func NewRoleRepository(db *gorm.DB) RoleRepository {
|
|
return &roleRepository{
|
|
db: db,
|
|
}
|
|
}
|