Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User에 대한 Permission 리스트 출력 API 개발 #297

Merged
merged 5 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/delivery/api/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const (
VerifyIdentityForLostId
VerifyIdentityForLostPassword
VerifyToken
DeleteToken

// User
CreateUser
Expand Down Expand Up @@ -195,6 +194,7 @@ const (
GetPermissionTemplates
GetPermissionsByRoleId
UpdatePermissionsByRoleId
GetPermissionsByAccountId

// Admin_User
Admin_CreateUser
Expand Down
70 changes: 70 additions & 0 deletions internal/delivery/api/endpoints_permission_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package api_test

import (
"github.com/openinfradev/tks-api/internal/delivery/api"
"github.com/openinfradev/tks-api/internal/model"
"testing"
)

func TestEndpointsUsage(t *testing.T) {
var allEndpoints []string
for _, v := range api.ApiMap {
allEndpoints = append(allEndpoints, v.Name)
}
//allEndpoints := []Endpoint{
// Login, Logout, RefreshToken, FindId, // 계속해서 모든 Endpoint 추가
// // 나머지 Endpoint 상수들을 여기에 추가
//}
usageCount := make(map[string]int)
ps := model.NewAdminPermissionSet()

permissions := []*model.Permission{
ps.Dashboard,
ps.Notification,
ps.Configuration,
ps.ProjectManagement,
ps.Stack,
ps.Policy,
ps.Common,
ps.Admin,
}

leafPermissions := make([]*model.Permission, 0)

for _, perm := range permissions {
leafPermissions = model.GetEdgePermission(perm, leafPermissions, nil)
}

// Permission 설정에서 Endpoint 사용 횟수 카운트
for _, perm := range leafPermissions {
countEndpoints(perm, usageCount)
}

var unusedEndpoints, duplicatedEndpoints []string

// 미사용 또는 중복 사용된 Endpoint 확인 및 출력
for _, endpoint := range allEndpoints {
count, exists := usageCount[endpoint]
if !exists {
unusedEndpoints = append(unusedEndpoints, endpoint)
} else if count > 1 {
duplicatedEndpoints = append(duplicatedEndpoints, endpoint)
}
}

for _, endpoint := range unusedEndpoints {
t.Logf("Unused Endpoint: %s", endpoint)
}

t.Logf("\n")
for _, endpoint := range duplicatedEndpoints {
t.Logf("Duplicated Endpoint: %s", endpoint)
}

}

func countEndpoints(perm *model.Permission, usageCount map[string]int) {
for _, endpoint := range perm.Endpoints {
usageCount[endpoint.Name]++
}
}
16 changes: 8 additions & 8 deletions internal/delivery/api/generated_endpoints.go.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ var ApiMap = map[Endpoint]EndpointInfo{
Name: "VerifyToken",
Group: "Auth",
},
DeleteToken: {
Name: "DeleteToken",
Group: "Auth",
},
CreateUser: {
Name: "CreateUser",
Group: "User",
Expand Down Expand Up @@ -603,6 +599,10 @@ var ApiMap = map[Endpoint]EndpointInfo{
Name: "UpdatePermissionsByRoleId",
Group: "Permission",
},
GetPermissionsByAccountId: {
Name: "GetPermissionsByAccountId",
Group: "Permission",
},
Admin_CreateUser: {
Name: "Admin_CreateUser",
Group: "Admin_User",
Expand Down Expand Up @@ -826,8 +826,6 @@ func (e Endpoint) String() string {
return "VerifyIdentityForLostPassword"
case VerifyToken:
return "VerifyToken"
case DeleteToken:
return "DeleteToken"
case CreateUser:
return "CreateUser"
case ListUser:
Expand Down Expand Up @@ -1110,6 +1108,8 @@ func (e Endpoint) String() string {
return "GetPermissionsByRoleId"
case UpdatePermissionsByRoleId:
return "UpdatePermissionsByRoleId"
case GetPermissionsByAccountId:
return "GetPermissionsByAccountId"
case Admin_CreateUser:
return "Admin_CreateUser"
case Admin_ListUser:
Expand Down Expand Up @@ -1234,8 +1234,6 @@ func GetEndpoint(name string) Endpoint {
return VerifyIdentityForLostPassword
case "VerifyToken":
return VerifyToken
case "DeleteToken":
return DeleteToken
case "CreateUser":
return CreateUser
case "ListUser":
Expand Down Expand Up @@ -1518,6 +1516,8 @@ func GetEndpoint(name string) Endpoint {
return GetPermissionsByRoleId
case "UpdatePermissionsByRoleId":
return UpdatePermissionsByRoleId
case "GetPermissionsByAccountId":
return GetPermissionsByAccountId
case "Admin_CreateUser":
return Admin_CreateUser
case "Admin_ListUser":
Expand Down
171 changes: 145 additions & 26 deletions internal/delivery/http/permission.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
package http

import (
"context"
"net/http"

"github.com/gorilla/mux"
"github.com/openinfradev/tks-api/internal/model"
"github.com/openinfradev/tks-api/internal/serializer"
"github.com/openinfradev/tks-api/internal/usecase"
"github.com/openinfradev/tks-api/pkg/domain"
"github.com/openinfradev/tks-api/pkg/httpErrors"
"github.com/openinfradev/tks-api/pkg/log"
)

type IPermissionHandler interface {
GetPermissionTemplates(w http.ResponseWriter, r *http.Request)
GetPermissionsByRoleId(w http.ResponseWriter, r *http.Request)
UpdatePermissionsByRoleId(w http.ResponseWriter, r *http.Request)
GetPermissionsByAccountId(w http.ResponseWriter, r *http.Request)
}

type PermissionHandler struct {
permissionUsecase usecase.IPermissionUsecase
userUsecase usecase.IUserUsecase
}

func NewPermissionHandler(usecase usecase.Usecase) *PermissionHandler {
func NewPermissionHandler(usecase usecase.Usecase) IPermissionHandler {
return &PermissionHandler{
permissionUsecase: usecase.Permission,
userUsecase: usecase.User,
}
}

Expand All @@ -41,20 +43,110 @@ func NewPermissionHandler(usecase usecase.Usecase) *PermissionHandler {
func (h PermissionHandler) GetPermissionTemplates(w http.ResponseWriter, r *http.Request) {
permissionSet := model.NewDefaultPermissionSet()

var premissionSetResponse domain.PermissionSetResponse
if err := serializer.Map(r.Context(), permissionSet, &premissionSetResponse); err != nil {
log.Info(r.Context(), err)
var out domain.GetPermissionTemplatesResponse
out.Permissions = new(domain.PermissionTemplateResponse)

out.Permissions.Dashboard = convertModelToPermissionTemplateResponse(r.Context(), permissionSet.Dashboard)
out.Permissions.Stack = convertModelToPermissionTemplateResponse(r.Context(), permissionSet.Stack)
out.Permissions.Policy = convertModelToPermissionTemplateResponse(r.Context(), permissionSet.Policy)
out.Permissions.ProjectManagement = convertModelToPermissionTemplateResponse(r.Context(), permissionSet.ProjectManagement)
out.Permissions.Notification = convertModelToPermissionTemplateResponse(r.Context(), permissionSet.Notification)
out.Permissions.Configuration = convertModelToPermissionTemplateResponse(r.Context(), permissionSet.Configuration)

ResponseJSON(w, r, http.StatusOK, out)
}

func convertModelToPermissionTemplateResponse(ctx context.Context, permission *model.Permission) *domain.TemplateResponse {
var permissionResponse domain.TemplateResponse

permissionResponse.Key = permission.Key
permissionResponse.Name = permission.Name
if permission.IsAllowed != nil {
permissionResponse.IsAllowed = permission.IsAllowed
}

var out domain.GetPermissionTemplatesResponse
out.Permissions = append(out.Permissions, premissionSetResponse.Dashboard)
out.Permissions = append(out.Permissions, premissionSetResponse.Stack)
out.Permissions = append(out.Permissions, premissionSetResponse.SecurityPolicy)
out.Permissions = append(out.Permissions, premissionSetResponse.ProjectManagement)
out.Permissions = append(out.Permissions, premissionSetResponse.Notification)
out.Permissions = append(out.Permissions, premissionSetResponse.Configuration)
for _, child := range permission.Children {
permissionResponse.Children = append(permissionResponse.Children, convertModelToPermissionTemplateResponse(ctx, child))
}

return &permissionResponse
}

// GetPermissionsByAccountId godoc
//
// @Tags Permission
// @Summary Get Permissions By Account ID
// @Description Get Permissions By Account ID
// @Accept json
// @Produce json
// @Success 200 {object} domain.GetUsersPermissionsResponse
// @Router /organizations/{organizationId}/users/{accountId}/permissions [get]
// @Security JWT
func (h PermissionHandler) GetPermissionsByAccountId(w http.ResponseWriter, r *http.Request) {
var organizationId, accountId string

vars := mux.Vars(r)
if v, ok := vars["accountId"]; !ok {
ErrorJSON(w, r, httpErrors.NewBadRequestError(nil, "", ""))
return
} else {
accountId = v
}
if v, ok := vars["organizationId"]; !ok {
ErrorJSON(w, r, httpErrors.NewBadRequestError(nil, "", ""))
return
} else {
organizationId = v
}

user, err := h.userUsecase.GetByAccountId(r.Context(), accountId, organizationId)
if err != nil {
ErrorJSON(w, r, httpErrors.NewInternalServerError(err, "", ""))
return
}

var roles []*model.Role
roles = append(roles, &user.Role)

var permissionSets []*model.PermissionSet
for _, role := range roles {
permissionSet, err := h.permissionUsecase.GetPermissionSetByRoleId(r.Context(), role.ID)
if err != nil {
ErrorJSON(w, r, httpErrors.NewInternalServerError(err, "", ""))
return
}
permissionSets = append(permissionSets, permissionSet)
}

mergedPermissionSet := h.permissionUsecase.MergePermissionWithOrOperator(r.Context(), permissionSets...)

var permissions domain.MergedPermissionSetResponse
permissions.Dashboard = convertModelToMergedPermissionSetResponse(r.Context(), mergedPermissionSet.Dashboard)
permissions.Stack = convertModelToMergedPermissionSetResponse(r.Context(), mergedPermissionSet.Stack)
permissions.Policy = convertModelToMergedPermissionSetResponse(r.Context(), mergedPermissionSet.Policy)
permissions.ProjectManagement = convertModelToMergedPermissionSetResponse(r.Context(), mergedPermissionSet.ProjectManagement)
permissions.Notification = convertModelToMergedPermissionSetResponse(r.Context(), mergedPermissionSet.Notification)
permissions.Configuration = convertModelToMergedPermissionSetResponse(r.Context(), mergedPermissionSet.Configuration)

var out domain.GetUsersPermissionsResponse
out.Permissions = &permissions
ResponseJSON(w, r, http.StatusOK, out)

}

func convertModelToMergedPermissionSetResponse(ctx context.Context, permission *model.Permission) *domain.MergePermissionResponse {
var permissionResponse domain.MergePermissionResponse

permissionResponse.Key = permission.Key
if permission.IsAllowed != nil {
permissionResponse.IsAllowed = permission.IsAllowed
}

for _, child := range permission.Children {
permissionResponse.Children = append(permissionResponse.Children, convertModelToMergedPermissionSetResponse(ctx, child))
}

return &permissionResponse
}

// GetPermissionsByRoleId godoc
Expand Down Expand Up @@ -85,22 +177,50 @@ func (h PermissionHandler) GetPermissionsByRoleId(w http.ResponseWriter, r *http
return
}

var premissionSetResponse domain.PermissionSetResponse
if err := serializer.Map(r.Context(), permissionSet, &premissionSetResponse); err != nil {
log.Info(r.Context(), err)
}
var permissionSetResponse domain.PermissionSetResponse
permissionSetResponse.Dashboard = convertModelToPermissionResponse(r.Context(), permissionSet.Dashboard)
permissionSetResponse.Stack = convertModelToPermissionResponse(r.Context(), permissionSet.Stack)
permissionSetResponse.Policy = convertModelToPermissionResponse(r.Context(), permissionSet.Policy)
permissionSetResponse.ProjectManagement = convertModelToPermissionResponse(r.Context(), permissionSet.ProjectManagement)
permissionSetResponse.Notification = convertModelToPermissionResponse(r.Context(), permissionSet.Notification)
permissionSetResponse.Configuration = convertModelToPermissionResponse(r.Context(), permissionSet.Configuration)

var out domain.GetPermissionsByRoleIdResponse
out.Permissions = append(out.Permissions, premissionSetResponse.Dashboard)
out.Permissions = append(out.Permissions, premissionSetResponse.Stack)
out.Permissions = append(out.Permissions, premissionSetResponse.SecurityPolicy)
out.Permissions = append(out.Permissions, premissionSetResponse.ProjectManagement)
out.Permissions = append(out.Permissions, premissionSetResponse.Notification)
out.Permissions = append(out.Permissions, premissionSetResponse.Configuration)
out.Permissions = &permissionSetResponse

ResponseJSON(w, r, http.StatusOK, out)
}

func convertModelToPermissionResponse(ctx context.Context, permission *model.Permission) *domain.PermissionResponse {
var permissionResponse domain.PermissionResponse

permissionResponse.ID = permission.ID
permissionResponse.Key = permission.Key
permissionResponse.Name = permission.Name
if permission.IsAllowed != nil {
permissionResponse.IsAllowed = permission.IsAllowed
}

for _, endpoint := range permission.Endpoints {
permissionResponse.Endpoints = append(permissionResponse.Endpoints, convertModelToEndpointResponse(ctx, endpoint))
}

for _, child := range permission.Children {
permissionResponse.Children = append(permissionResponse.Children, convertModelToPermissionResponse(ctx, child))
}

return &permissionResponse
}

func convertModelToEndpointResponse(ctx context.Context, endpoint *model.Endpoint) *domain.EndpointResponse {
var endpointResponse domain.EndpointResponse

endpointResponse.Name = endpoint.Name
endpointResponse.Group = endpoint.Group

return &endpointResponse
}

// UpdatePermissionsByRoleId godoc
//
// @Tags Permission
Expand All @@ -124,9 +244,8 @@ func (h PermissionHandler) UpdatePermissionsByRoleId(w http.ResponseWriter, r *h

for _, permissionResponse := range input.Permissions {
var permission model.Permission
if err := serializer.Map(r.Context(), permissionResponse, &permission); err != nil {
log.Info(r.Context(), err)
}
permission.ID = permissionResponse.ID
permission.IsAllowed = permissionResponse.IsAllowed

if err := h.permissionUsecase.UpdatePermission(r.Context(), &permission); err != nil {
ErrorJSON(w, r, httpErrors.NewInternalServerError(err, "", ""))
Expand Down
Loading
Loading