Add role management module with controller, service, repository, DTOs, and routes
This commit is contained in:
parent
f28b3a5244
commit
4bd48c3bca
|
|
@ -0,0 +1,129 @@
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/role/dto"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/role/query"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/role/service"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
|
||||||
|
"github.com/Caknoooo/go-pagination"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/samber/do"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
RoleController interface {
|
||||||
|
CreateRole(ctx *gin.Context)
|
||||||
|
GetRoles(ctx *gin.Context)
|
||||||
|
GetRoleByID(ctx *gin.Context)
|
||||||
|
UpdateRole(ctx *gin.Context)
|
||||||
|
DeleteRole(ctx *gin.Context)
|
||||||
|
AssignPermissionsToRole(ctx *gin.Context)
|
||||||
|
RemovePermissionsFromRole(ctx *gin.Context)
|
||||||
|
AssignRoleToUser(ctx *gin.Context)
|
||||||
|
RemoveRoleFromUser(ctx *gin.Context)
|
||||||
|
GetRolesByUserID(ctx *gin.Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
roleController struct {
|
||||||
|
roleService service.RoleService
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// AssignPermissionsToRole implements RoleController.
|
||||||
|
func (r *roleController) AssignPermissionsToRole(ctx *gin.Context) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssignRoleToUser implements RoleController.
|
||||||
|
func (r *roleController) AssignRoleToUser(ctx *gin.Context) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRole implements RoleController.
|
||||||
|
func (r *roleController) CreateRole(ctx *gin.Context) {
|
||||||
|
var role dto.RoleCreateRequest
|
||||||
|
if err := ctx.ShouldBind(&role); err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_DATA_FROM_BODY, err.Error(), nil)
|
||||||
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := r.roleService.CreateRole(ctx.Request.Context(), role)
|
||||||
|
if err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_REGISTER_ROLE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusBadRequest, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_REGISTER_ROLE, result)
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRole implements RoleController.
|
||||||
|
func (r *roleController) DeleteRole(ctx *gin.Context) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRoleByID implements RoleController.
|
||||||
|
func (r *roleController) GetRoleByID(ctx *gin.Context) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRoles implements RoleController.
|
||||||
|
func (r *roleController) GetRoles(ctx *gin.Context) {
|
||||||
|
clientId := ctx.MustGet("client_id").(string)
|
||||||
|
// logrus.Info("Client ID: ", clientId)
|
||||||
|
var filter = &query.RoleFilter{
|
||||||
|
ClientID: clientId,
|
||||||
|
Name: ctx.Query("name"),
|
||||||
|
}
|
||||||
|
// logrus.Info("Filter: ", filter)
|
||||||
|
filter.BindPagination(ctx)
|
||||||
|
|
||||||
|
ctx.ShouldBindQuery(filter)
|
||||||
|
|
||||||
|
roles, total, err := pagination.PaginatedQueryWithIncludable[query.M_Role](r.db, filter)
|
||||||
|
if err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_ROLE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusBadRequest, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
paginationResponse := pagination.CalculatePagination(filter.Pagination, total)
|
||||||
|
response := pagination.NewPaginatedResponse(http.StatusOK, dto.MESSAGE_SUCCESS_GET_LIST_ROLE, roles, paginationResponse)
|
||||||
|
ctx.JSON(http.StatusOK, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRolesByUserID implements RoleController.
|
||||||
|
func (r *roleController) GetRolesByUserID(ctx *gin.Context) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePermissionsFromRole implements RoleController.
|
||||||
|
func (r *roleController) RemovePermissionsFromRole(ctx *gin.Context) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveRoleFromUser implements RoleController.
|
||||||
|
func (r *roleController) RemoveRoleFromUser(ctx *gin.Context) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRole implements RoleController.
|
||||||
|
func (r *roleController) UpdateRole(ctx *gin.Context) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoleController(injector *do.Injector, rs service.RoleService) RoleController {
|
||||||
|
db := do.MustInvokeNamed[*gorm.DB](injector, constants.DB)
|
||||||
|
return &roleController{
|
||||||
|
roleService: rs,
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
package dto
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Failed
|
||||||
|
MESSAGE_FAILED_GET_DATA_FROM_BODY = "failed get data from body"
|
||||||
|
MESSAGE_FAILED_REGISTER_ROLE = "failed create user"
|
||||||
|
MESSAGE_FAILED_GET_LIST_ROLE = "failed get list user"
|
||||||
|
MESSAGE_FAILED_TOKEN_NOT_VALID = "token not valid"
|
||||||
|
MESSAGE_FAILED_TOKEN_NOT_FOUND = "token not found"
|
||||||
|
MESSAGE_FAILED_GET_ROLE = "failed get role"
|
||||||
|
MESSAGE_FAILED_LOGIN = "failed login"
|
||||||
|
MESSAGE_FAILED_UPDATE_ROLE = "failed update role"
|
||||||
|
MESSAGE_FAILED_DELETE_ROLE = "failed delete role"
|
||||||
|
MESSAGE_FAILED_PROSES_REQUEST = "failed proses request"
|
||||||
|
MESSAGE_FAILED_DENIED_ACCESS = "denied access"
|
||||||
|
MESSAGE_FAILED_VERIFY_EMAIL = "failed verify email"
|
||||||
|
|
||||||
|
// Success
|
||||||
|
MESSAGE_SUCCESS_REGISTER_ROLE = "success create role"
|
||||||
|
MESSAGE_SUCCESS_GET_LIST_ROLE = "success get list role"
|
||||||
|
MESSAGE_SUCCESS_GET_ROLE = "success get role"
|
||||||
|
MESSAGE_SUCCESS_LOGIN = "success login"
|
||||||
|
MESSAGE_SUCCESS_UPDATE_ROLE = "success update role"
|
||||||
|
MESSAGE_SUCCESS_DELETE_ROLE = "success delete role"
|
||||||
|
MESSAGE_SEND_VERIFICATION_EMAIL_SUCCESS = "success send verification email"
|
||||||
|
MESSAGE_SUCCESS_VERIFY_EMAIL = "success verify email"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrCreateRole = errors.New("failed to create role")
|
||||||
|
ErrGetRoleById = errors.New("failed to get role by id")
|
||||||
|
ErrGetRoleByName = errors.New("failed to get role by name")
|
||||||
|
ErrRoleAlreadyExists = errors.New("role already exist")
|
||||||
|
ErrUpdateRole = errors.New("failed to update role")
|
||||||
|
ErrRoleNotFound = errors.New("role not found")
|
||||||
|
ErrDeleteRole = errors.New("failed to delete role")
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoleCreateRequest struct {
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
Description string `json:"description" binding:"omitempty"`
|
||||||
|
IconUrl string `json:"icon_url" binding:"omitempty"`
|
||||||
|
Type string `json:"type" binding:"omitempty"`
|
||||||
|
HomeUrl string `json:"home_url" binding:"omitempty"`
|
||||||
|
ClientID string `json:"client_id" binding:"required,uuid4"`
|
||||||
|
|
||||||
|
RoleMenus []string `json:"role_menus" binding:"omitempty"`
|
||||||
|
RolePermissions []string `json:"role_permissions" binding:"omitempty"`
|
||||||
|
UserRoles []string `json:"user_roles" binding:"omitempty"`
|
||||||
|
Users []string `json:"users" binding:"omitempty"`
|
||||||
|
Permissions []string `json:"permissions" binding:"omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoleUpdateRequest struct {
|
||||||
|
Name string `json:"name" binding:"omitempty"`
|
||||||
|
Description string `json:"description" binding:"omitempty"`
|
||||||
|
IconUrl string `json:"icon_url" binding:"omitempty"`
|
||||||
|
Type string `json:"type" binding:"omitempty"`
|
||||||
|
HomeUrl string `json:"home_url" binding:"omitempty"`
|
||||||
|
ClientID string `json:"client_id" binding:"omitempty,uuid4"`
|
||||||
|
Permissions []string `json:"permissions" binding:"omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoleResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
IconUrl string `json:"icon_url"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
HomeUrl string `json:"home_url"`
|
||||||
|
ClientID string `json:"client_id"`
|
||||||
|
Permissions []string `json:"permissions"`
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
||||||
|
"github.com/Caknoooo/go-pagination"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type M_Role struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Permissions []entities.M_Permissions `json:"permissions" gorm:"many2many:m_role_permissions;joinForeignKey:RoleID;JoinReferences:PermissionID"`
|
||||||
|
ClientID string `json:"client_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoleFilter struct {
|
||||||
|
pagination.BaseFilter
|
||||||
|
Name string `form:"name"` // tambahkan ini
|
||||||
|
ClientID string `form:"client_id"` // tambahkan ini
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RoleFilter) ApplyFilters(query *gorm.DB) *gorm.DB {
|
||||||
|
// Apply your filters here
|
||||||
|
if f.Name != "" {
|
||||||
|
query = query.Where("name ILIKE ?", "%"+f.Name+"%")
|
||||||
|
}
|
||||||
|
if f.ClientID != "" {
|
||||||
|
query = query.Where("client_id = ?", f.ClientID)
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RoleFilter) GetTableName() string {
|
||||||
|
return "m_roles"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RoleFilter) GetSearchFields() []string {
|
||||||
|
return []string{"name"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RoleFilter) GetDefaultSort() string {
|
||||||
|
return "id asc"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RoleFilter) GetIncludes() []string {
|
||||||
|
return f.Includes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RoleFilter) GetPagination() pagination.PaginationRequest {
|
||||||
|
return f.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RoleFilter) Validate() {
|
||||||
|
var validIncludes []string
|
||||||
|
allowedIncludes := f.GetAllowedIncludes()
|
||||||
|
for _, include := range f.Includes {
|
||||||
|
if allowedIncludes[include] {
|
||||||
|
validIncludes = append(validIncludes, include)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Includes = validIncludes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RoleFilter) GetAllowedIncludes() map[string]bool {
|
||||||
|
return map[string]bool{}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,207 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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, id string, 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
type roleRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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).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).Where("user_id = ?", userId).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, id string, role entities.M_Role) (entities.M_Role, error) {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
if err := tx.WithContext(ctx).Where("id = ?", id).Updates(&role).Error; err != nil {
|
||||||
|
return entities.M_Role{}, err
|
||||||
|
}
|
||||||
|
return role, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoleRepository(db *gorm.DB) RoleRepository {
|
||||||
|
return &roleRepository{
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package role
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/middlewares"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/auth/service"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/role/controller"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/samber/do"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterRoutes(server *gin.Engine, injector *do.Injector) {
|
||||||
|
roleController := do.MustInvoke[controller.RoleController](injector)
|
||||||
|
jwtService := do.MustInvokeNamed[service.JWTService](injector, constants.JWTService)
|
||||||
|
|
||||||
|
roleRoutes := server.Group("/api/v1/role")
|
||||||
|
{
|
||||||
|
roleRoutes.POST("", middlewares.Authenticate(jwtService), roleController.CreateRole)
|
||||||
|
roleRoutes.GET("", middlewares.Authenticate(jwtService), roleController.GetRoles)
|
||||||
|
roleRoutes.GET("/:id", middlewares.Authenticate(jwtService), roleController.GetRoleByID)
|
||||||
|
roleRoutes.PUT("/:id", middlewares.Authenticate(jwtService), roleController.UpdateRole)
|
||||||
|
roleRoutes.DELETE("/:id", middlewares.Authenticate(jwtService), roleController.DeleteRole)
|
||||||
|
roleRoutes.POST("/:id/permissions", middlewares.Authenticate(jwtService), roleController.AssignPermissionsToRole)
|
||||||
|
roleRoutes.DELETE("/:id/permissions", middlewares.Authenticate(jwtService), roleController.RemovePermissionsFromRole)
|
||||||
|
roleRoutes.POST("/assign-role", middlewares.Authenticate(jwtService), roleController.AssignRoleToUser)
|
||||||
|
roleRoutes.POST("/remove-role", middlewares.Authenticate(jwtService), roleController.RemoveRoleFromUser)
|
||||||
|
roleRoutes.GET("/user/:id", middlewares.Authenticate(jwtService), roleController.GetRolesByUserID)
|
||||||
|
// roleRoutes.POST("", roleController.CreateRole)
|
||||||
|
// roleRoutes.GET("", roleController.GetRoles)
|
||||||
|
// roleRoutes.GET("/:id", roleController.GetRoleByID)
|
||||||
|
// roleRoutes.PUT("/:id", middlewares.Authenticate(jwtService), roleController.Update)
|
||||||
|
// roleRoutes.DELETE("/:id", middlewares.Authenticate(jwtService), roleController.Delete)
|
||||||
|
|
||||||
|
// userRoutes.PUT("/:id", middlewares.Authenticate(jwtService), userController.Update)
|
||||||
|
// roleRoutes.DELETE("/:id", middlewares.Authenticate(jwtService), roleController.Delete)
|
||||||
|
// roleRoutes.POST("/send-verification-email", roleController.SendVerificationEmail)
|
||||||
|
// roleRoutes.POST("/refresh", middlewares.Authenticate(jwtService), roleController.Refresh)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
||||||
|
authRepo "github.com/Caknoooo/go-gin-clean-starter/modules/auth/repository"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/auth/service"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/role/dto"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/role/query"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/role/repository"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoleService interface {
|
||||||
|
CreateRole(ctx context.Context, role dto.RoleCreateRequest) (dto.RoleResponse, error)
|
||||||
|
GetRoles(ctx context.Context, filter query.RoleFilter) ([]dto.RoleResponse, error)
|
||||||
|
GetRoleByID(ctx context.Context, id string) (dto.RoleResponse, error)
|
||||||
|
UpdateRole(ctx context.Context, id string, role dto.RoleUpdateRequest) (dto.RoleResponse, error)
|
||||||
|
DeleteRole(ctx context.Context, id string) error
|
||||||
|
AssignPermissionsToRole(ctx context.Context, roleId string, permissions []string) error
|
||||||
|
RemovePermissionsFromRole(ctx context.Context, roleId string, permissions []string) error
|
||||||
|
AssignRoleToUser(ctx context.Context, userId string, roleId string) error
|
||||||
|
RemoveRoleFromUser(ctx context.Context, userId string, roleId string) error
|
||||||
|
GetRolesByUserID(ctx context.Context, userId string) ([]dto.RoleResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type roleService struct {
|
||||||
|
roleRepo repository.RoleRepository
|
||||||
|
refreshTokenRepository authRepo.RefreshTokenRepository
|
||||||
|
jwtService service.JWTService
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssignPermissionsToRole implements RoleService.
|
||||||
|
func (r *roleService) AssignPermissionsToRole(ctx context.Context, roleId string, permissions []string) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssignRoleToUser implements RoleService.
|
||||||
|
func (r *roleService) AssignRoleToUser(ctx context.Context, userId string, roleId string) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRole implements RoleService.
|
||||||
|
func (r *roleService) CreateRole(ctx context.Context, req dto.RoleCreateRequest) (dto.RoleResponse, error) {
|
||||||
|
_, exists, err := r.roleRepo.CheckRoleName(ctx, r.db, req.Name)
|
||||||
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
|
return dto.RoleResponse{}, err
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
return dto.RoleResponse{}, dto.ErrRoleAlreadyExists
|
||||||
|
}
|
||||||
|
|
||||||
|
clientUUID, err := uuid.Parse(req.ClientID)
|
||||||
|
if err != nil {
|
||||||
|
return dto.RoleResponse{}, err
|
||||||
|
}
|
||||||
|
role := entities.M_Role{
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
IconUrl: req.IconUrl,
|
||||||
|
Type: req.Type,
|
||||||
|
HomeUrl: req.HomeUrl,
|
||||||
|
ClientID: clientUUID,
|
||||||
|
}
|
||||||
|
|
||||||
|
createdRole, err := r.roleRepo.CreateRole(ctx, r.db, role)
|
||||||
|
if err != nil {
|
||||||
|
return dto.RoleResponse{}, err
|
||||||
|
}
|
||||||
|
return dto.RoleResponse{
|
||||||
|
ID: createdRole.ID.String(),
|
||||||
|
Name: createdRole.Name,
|
||||||
|
Description: createdRole.Description,
|
||||||
|
IconUrl: createdRole.IconUrl,
|
||||||
|
Type: createdRole.Type,
|
||||||
|
HomeUrl: createdRole.HomeUrl,
|
||||||
|
ClientID: createdRole.ClientID.String(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRole implements RoleService.
|
||||||
|
func (r *roleService) DeleteRole(ctx context.Context, id string) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRoleByID implements RoleService.
|
||||||
|
func (r *roleService) GetRoleByID(ctx context.Context, id string) (dto.RoleResponse, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRoles implements RoleService.
|
||||||
|
func (r *roleService) GetRoles(ctx context.Context, filter query.RoleFilter) ([]dto.RoleResponse, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRolesByUserID implements RoleService.
|
||||||
|
func (r *roleService) GetRolesByUserID(ctx context.Context, userId string) ([]dto.RoleResponse, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePermissionsFromRole implements RoleService.
|
||||||
|
func (r *roleService) RemovePermissionsFromRole(ctx context.Context, roleId string, permissions []string) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveRoleFromUser implements RoleService.
|
||||||
|
func (r *roleService) RemoveRoleFromUser(ctx context.Context, userId string, roleId string) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRole implements RoleService.
|
||||||
|
func (r *roleService) UpdateRole(ctx context.Context, id string, role dto.RoleUpdateRequest) (dto.RoleResponse, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoleService(
|
||||||
|
roleRepo repository.RoleRepository,
|
||||||
|
refreshTokenRepo authRepo.RefreshTokenRepository,
|
||||||
|
jwtService service.JWTService,
|
||||||
|
db *gorm.DB,
|
||||||
|
) RoleService {
|
||||||
|
return &roleService{
|
||||||
|
roleRepo: roleRepo,
|
||||||
|
refreshTokenRepository: refreshTokenRepo,
|
||||||
|
jwtService: jwtService,
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue