get eligible menu

This commit is contained in:
renaldybrada
2026-02-25 09:02:11 +07:00
parent 37ed3f76f3
commit 14f5850629
5 changed files with 233 additions and 2 deletions
+23
View File
@@ -67,3 +67,26 @@ func (h AccessHandler) SyncKeycloakRole(c *gin.Context) {
Data: req,
})
}
func (h AccessHandler) GetPageByKeycloakId(c *gin.Context) {
keycloakId := c.Query("keycloak_id")
pageResult, err := h.repo.GetAvailablePageByKeycloakId(c, keycloakId)
if err != nil {
errMessage := []string{err.Error()}
c.JSON(500, shared.BaseErrorResponse{
Success: false,
Code: 500,
Message: "error fetch page by keycloak id",
Errors: errMessage,
})
return
}
c.JSON(200, shared.BaseResponse[[]AvailableMenuResponse]{
Success: true,
Code: 200,
Message: "success fetch eligible page",
Data: MapMenuModelToResponse(pageResult),
})
}
+21 -2
View File
@@ -1,5 +1,7 @@
package access
import "database/sql"
type RolePermissionModel struct {
ID string `db:"id"`
Name string `db:"name"`
@@ -7,8 +9,13 @@ type RolePermissionModel struct {
}
type RolePageModel struct {
ID string `db:"id"`
PagePath string `db:"page_path"`
ID string `db:"id"`
Name string `db:"name"`
Icon sql.NullString `db:"icon"`
Url sql.NullString `db:"url"`
Level int `db:"level"`
Sort int `db:"sort"`
ParentId sql.NullString `db:"parent"`
}
type RoleUserModel struct {
@@ -17,3 +24,15 @@ type RoleUserModel struct {
Email string `db:"email"`
KeycloakId string `db:"keycloak_id"`
}
type RoleUserPermissionModel struct {
ID string `db:"id"`
IdUser string `db:"id_user"`
IdPermission string `db:"id_permission"`
}
type RolePagePermissionModel struct {
ID string `db:"id"`
IdPermission string `db:"id_permission"`
IdPage string `db:"id_page"`
}
+144
View File
@@ -16,11 +16,14 @@ const DB_NAME = "db_role_access"
const TBL_USER = "role_users"
const TBL_PERMISSION = "role_permission"
const TBL_USER_PERMISSION = "role_user_permission"
const TBL_ROLE_PAGES = "role_pages"
const TBL_PAGE_PERMISSION = "role_page_permission"
type IAccessRepository interface {
FindUserByKeycloakId(c context.Context, id string) ([]RoleUserModel, error)
CreateUserPermission(c context.Context, req SyncKeycloakRoleRequest) error
UpdateUserPermission(c context.Context, userId string, req SyncKeycloakRoleRequest) error
GetAvailablePageByKeycloakId(c context.Context, keycloakId string) ([]RolePageModel, error)
}
type accessRepo struct {
@@ -134,6 +137,51 @@ func (r accessRepo) UpdateUserPermission(c context.Context, userId string, req S
return nil
}
func (r accessRepo) GetAvailablePageByKeycloakId(c context.Context, keycloakId string) ([]RolePageModel, error) {
var result []RolePageModel
dbconn, err := r.db.GetSQLXDB(DB_NAME)
if err != nil {
log.Printf("Unable to connect db : %s", err)
return result, err
}
fetchUsers, err := r.FindUserByKeycloakId(c, keycloakId)
if err != nil {
return nil, err
}
if len(fetchUsers) == 0 {
log.Printf("user not found, keycloak id : %s", keycloakId)
return nil, err
}
user := &fetchUsers[0]
var permissionIds []string
fetchUserPermission, err := r.getUserPermissionByUserId(c, dbconn, user.ID)
if err != nil {
return nil, err
}
for _, p := range fetchUserPermission {
permissionIds = append(permissionIds, p.IdPermission)
}
var pageIds []string
fetchPagePermission, err := r.getPageIdsByPermissionIds(c, dbconn, permissionIds)
if err != nil {
return nil, err
}
for _, pg := range fetchPagePermission {
pageIds = append(pageIds, pg.IdPage)
}
result, err = r.getPageByIds(c, dbconn, pageIds)
if err != nil {
return nil, err
}
return result, nil
}
// PRIVATE FUNCTIONS
// Table user function
@@ -348,4 +396,100 @@ func (r accessRepo) getOrCreateUserPermission(c context.Context, db *sqlx.DB, tx
return nil
}
func (r accessRepo) getUserPermissionByUserId(c context.Context, db *sqlx.DB, userId string) ([]RoleUserPermissionModel, error) {
var result []RoleUserPermissionModel
query := queryUtils.DynamicQuery{
From: TBL_USER_PERMISSION,
Fields: []queryUtils.SelectField{
{Expression: "id"},
{Expression: "id_user"},
{Expression: "id_permission"},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{Column: "id_user", Operator: queryUtils.OpEqual, Value: userId},
}, LogicOp: "AND",
},
},
}
err := r.queryBuilder.ExecuteQuery(c, db, query, &result)
if err != nil {
log.Printf("error executing fetch user permission : %v", err)
return nil, err
}
return result, nil
}
// End Table user permission functions
// Table role page permission functions
func (r accessRepo) getPageIdsByPermissionIds(c context.Context, db *sqlx.DB, permissionIds []string) ([]RolePagePermissionModel, error) {
var result []RolePagePermissionModel
query := queryUtils.DynamicQuery{
From: TBL_PAGE_PERMISSION,
Fields: []queryUtils.SelectField{
{Expression: "id"},
{Expression: "id_permission"},
{Expression: "id_page"},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{Column: "id_permission", Operator: queryUtils.OpIn, Value: permissionIds},
}, LogicOp: "AND",
},
},
}
err := r.queryBuilder.ExecuteQuery(c, db, query, &result)
if err != nil {
log.Printf("error executing fetch user permission : %v", err)
return nil, err
}
return result, nil
}
// End role page permission functions
// Table pages functions
func (r accessRepo) getPageByIds(c context.Context, db *sqlx.DB, ids []string) ([]RolePageModel, error) {
var result []RolePageModel
query := queryUtils.DynamicQuery{
From: TBL_ROLE_PAGES,
Fields: []queryUtils.SelectField{
{Expression: "id"},
{Expression: "name"},
{Expression: "icon"},
{Expression: "url"},
{Expression: "level"},
{Expression: "sort"},
{Expression: "parent"},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{Column: "id", Operator: queryUtils.OpIn, Value: ids},
}, LogicOp: "AND",
},
},
}
err := r.queryBuilder.ExecuteQuery(c, db, query, &result)
if err != nil {
log.Printf("error executing fetch pages : %v", err)
return nil, err
}
return result, nil
}
// End page functions
+44
View File
@@ -0,0 +1,44 @@
package access
type AvailableMenuChildResponse struct {
Title string `json:"title"`
Icon string `json:"icon"`
To string `json:"to"`
Children []*AvailableMenuChildResponse `json:"children"`
}
type AvailableMenuResponse struct {
ID string `json:"id"`
Header string `json:"header"`
Children []*AvailableMenuChildResponse `json:"children"`
}
func MapMenuModelToResponse(pages []RolePageModel) []AvailableMenuResponse {
pageMap := make(map[string]*AvailableMenuChildResponse)
var result []AvailableMenuResponse
for _, p := range pages {
pageMap[p.ID] = &AvailableMenuChildResponse{
Title: p.Name,
Icon: p.Icon.String,
To: p.Url.String,
}
if p.ParentId.String != "" {
pageMap[p.ParentId.String].Children = append(pageMap[p.ParentId.String].Children, pageMap[p.ID])
}
}
for _, p := range pages {
if p.ParentId.String == "" {
result = append(result, AvailableMenuResponse{
ID: p.ID,
Header: p.Name,
Children: pageMap[p.ID].Children,
})
}
}
return result
}
+1
View File
@@ -11,4 +11,5 @@ func RegisterRoutes(r *gin.RouterGroup, dbService database.Service) {
accessHandler := NewAccessHandler(accessRepo)
r.POST("/sync-keycloak-role", accessHandler.SyncKeycloakRole)
r.GET("/eligible-menu", accessHandler.GetPageByKeycloakId)
}