mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-03 04:10:20 +08:00
feat: add basic enforcer manager (#2130)
* feat: add basic enforcer manager * chore: generate swagger
This commit is contained in:
145
controllers/enforcer.go
Normal file
145
controllers/enforcer.go
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/beego/beego/utils/pagination"
|
||||||
|
"github.com/casdoor/casdoor/object"
|
||||||
|
"github.com/casdoor/casdoor/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetEnforcers
|
||||||
|
// @Title GetEnforcers
|
||||||
|
// @Tag Enforcer API
|
||||||
|
// @Description get enforcers
|
||||||
|
// @Param owner query string true "The owner of enforcers"
|
||||||
|
// @Success 200 {array} object.Enforcer
|
||||||
|
// @router /get-enforcers [get]
|
||||||
|
func (c *ApiController) GetEnforcers() {
|
||||||
|
owner := c.Input().Get("owner")
|
||||||
|
limit := c.Input().Get("pageSize")
|
||||||
|
page := c.Input().Get("p")
|
||||||
|
field := c.Input().Get("field")
|
||||||
|
value := c.Input().Get("value")
|
||||||
|
sortField := c.Input().Get("sortField")
|
||||||
|
sortOrder := c.Input().Get("sortOrder")
|
||||||
|
|
||||||
|
if limit == "" || page == "" {
|
||||||
|
enforcers, err := object.GetEnforcers(owner)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ResponseOk(enforcers)
|
||||||
|
} else {
|
||||||
|
limit := util.ParseInt(limit)
|
||||||
|
count, err := object.GetEnforcerCount(owner, field, value)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
paginator := pagination.SetPaginator(c.Ctx, limit, count)
|
||||||
|
enforcers, err := object.GetPaginationEnforcers(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ResponseOk(enforcers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEnforcer
|
||||||
|
// @Title GetEnforcer
|
||||||
|
// @Tag Enforcer API
|
||||||
|
// @Description get enforcer
|
||||||
|
// @Param id query string true "The id ( owner/name ) of enforcer"
|
||||||
|
// @Success 200 {object} object
|
||||||
|
// @router /get-enforcer [get]
|
||||||
|
func (c *ApiController) GetEnforcer() {
|
||||||
|
id := c.Input().Get("id")
|
||||||
|
|
||||||
|
enforcer, err := object.GetEnforcer(id)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ResponseOk(enforcer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateEnforcer
|
||||||
|
// @Title UpdateEnforcer
|
||||||
|
// @Tag Enforcer API
|
||||||
|
// @Description update enforcer
|
||||||
|
// @Param id query string true "The id ( owner/name ) of enforcer"
|
||||||
|
// @Param enforcer body object true "The enforcer object"
|
||||||
|
// @Success 200 {object} object
|
||||||
|
// @router /update-enforcer [post]
|
||||||
|
func (c *ApiController) UpdateEnforcer() {
|
||||||
|
id := c.Input().Get("id")
|
||||||
|
|
||||||
|
enforcer := object.Enforcer{}
|
||||||
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &enforcer)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = wrapActionResponse(object.UpdateEnforcer(id, &enforcer))
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddEnforcer
|
||||||
|
// @Title AddEnforcer
|
||||||
|
// @Tag Enforcer API
|
||||||
|
// @Description add enforcer
|
||||||
|
// @Param enforcer body object true "The enforcer object"
|
||||||
|
// @Success 200 {object} object
|
||||||
|
// @router /add-enforcer [post]
|
||||||
|
func (c *ApiController) AddEnforcer() {
|
||||||
|
enforcer := object.Enforcer{}
|
||||||
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &enforcer)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = wrapActionResponse(object.AddEnforcer(&enforcer))
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteEnforcer
|
||||||
|
// @Title DeleteEnforcer
|
||||||
|
// @Tag Enforcer API
|
||||||
|
// @Description delete enforcer
|
||||||
|
// @Param body body object.Enforce true "The enforcer object"
|
||||||
|
// @Success 200 {object} object
|
||||||
|
// @router /delete-enforcer [post]
|
||||||
|
func (c *ApiController) DeleteEnforcer() {
|
||||||
|
var enforcer object.Enforcer
|
||||||
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &enforcer)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = wrapActionResponse(object.DeleteEnforcer(&enforcer))
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
@ -197,6 +197,11 @@ func (a *Adapter) createTable() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = a.Engine.Sync2(new(Enforcer))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
err = a.Engine.Sync2(new(Provider))
|
err = a.Engine.Sync2(new(Provider))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -100,6 +100,13 @@ func UpdateCasbinAdapter(id string, casbinAdapter *CasbinAdapter) (bool, error)
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != casbinAdapter.Name {
|
||||||
|
err := casbinAdapterChangeTrigger(name, casbinAdapter.Name)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
|
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
|
||||||
if casbinAdapter.Password == "***" {
|
if casbinAdapter.Password == "***" {
|
||||||
session.Omit("password")
|
session.Omit("password")
|
||||||
@ -180,6 +187,26 @@ func initEnforcer(modelObj *Model, casbinAdapter *CasbinAdapter) (*casbin.Enforc
|
|||||||
return enforcer, nil
|
return enforcer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func casbinAdapterChangeTrigger(oldName string, newName string) error {
|
||||||
|
session := adapter.Engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
err := session.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
enforcer := new(Enforcer)
|
||||||
|
enforcer.Adapter = newName
|
||||||
|
_, err = session.Where("adapter=?", oldName).Update(enforcer)
|
||||||
|
if err != nil {
|
||||||
|
session.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
func safeReturn(policy []string, i int) string {
|
func safeReturn(policy []string, i int) string {
|
||||||
if len(policy) > i {
|
if len(policy) > i {
|
||||||
return policy[i]
|
return policy[i]
|
||||||
|
@ -365,7 +365,7 @@ func CheckAccessPermission(userId string, application *Application) (bool, error
|
|||||||
if containsAsterisk {
|
if containsAsterisk {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getPermissionEnforcer(permission)
|
||||||
if allowed, err = enforcer.Enforce(userId, application.Name, "read"); allowed {
|
if allowed, err = enforcer.Enforce(userId, application.Name, "read"); allowed {
|
||||||
return allowed, err
|
return allowed, err
|
||||||
}
|
}
|
||||||
|
119
object/enforcer.go
Normal file
119
object/enforcer.go
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package object
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/casbin/casbin/v2"
|
||||||
|
"github.com/casdoor/casdoor/util"
|
||||||
|
"github.com/xorm-io/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Enforcer struct {
|
||||||
|
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
|
||||||
|
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
||||||
|
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
||||||
|
UpdatedTime string `xorm:"varchar(100) updated" json:"updatedTime"`
|
||||||
|
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||||
|
Description string `xorm:"varchar(100)" json:"description"`
|
||||||
|
|
||||||
|
Model string `xorm:"varchar(100)" json:"model"`
|
||||||
|
Adapter string `xorm:"varchar(100)" json:"adapter"`
|
||||||
|
IsEnabled bool `json:"isEnabled"`
|
||||||
|
|
||||||
|
*casbin.Enforcer
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEnforcerCount(owner, field, value string) (int64, error) {
|
||||||
|
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||||
|
return session.Count(&Enforcer{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEnforcers(owner string) ([]*Enforcer, error) {
|
||||||
|
enforcers := []*Enforcer{}
|
||||||
|
err := adapter.Engine.Desc("created_time").Find(&enforcers, &Enforcer{Owner: owner})
|
||||||
|
if err != nil {
|
||||||
|
return enforcers, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return enforcers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPaginationEnforcers(owner string, offset, limit int, field, value, sortField, sortOrder string) ([]*Enforcer, error) {
|
||||||
|
enforcers := []*Enforcer{}
|
||||||
|
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||||
|
err := session.Find(&enforcers)
|
||||||
|
if err != nil {
|
||||||
|
return enforcers, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return enforcers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEnforcer(owner string, name string) (*Enforcer, error) {
|
||||||
|
if owner == "" || name == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
enforcer := Enforcer{Owner: owner, Name: name}
|
||||||
|
existed, err := adapter.Engine.Get(&enforcer)
|
||||||
|
if err != nil {
|
||||||
|
return &enforcer, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if existed {
|
||||||
|
return &enforcer, nil
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEnforcer(id string) (*Enforcer, error) {
|
||||||
|
owner, name := util.GetOwnerAndNameFromId(id)
|
||||||
|
return getEnforcer(owner, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateEnforcer(id string, enforcer *Enforcer) (bool, error) {
|
||||||
|
owner, name := util.GetOwnerAndNameFromId(id)
|
||||||
|
if oldEnforcer, err := getEnforcer(owner, name); err != nil {
|
||||||
|
return false, err
|
||||||
|
} else if oldEnforcer == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(enforcer)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return affected != 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddEnforcer(enforcer *Enforcer) (bool, error) {
|
||||||
|
affected, err := adapter.Engine.Insert(enforcer)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return affected != 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteEnforcer(enforcer *Enforcer) (bool, error) {
|
||||||
|
affected, err := adapter.Engine.ID(core.PK{enforcer.Owner, enforcer.Name}).Delete(&Enforcer{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return affected != 0, nil
|
||||||
|
}
|
@ -154,6 +154,15 @@ func modelChangeTrigger(oldName string, newName string) error {
|
|||||||
permission.Model = newName
|
permission.Model = newName
|
||||||
_, err = session.Where("model=?", oldName).Update(permission)
|
_, err = session.Where("model=?", oldName).Update(permission)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
session.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
enforcer := new(Enforcer)
|
||||||
|
enforcer.Model = newName
|
||||||
|
_, err = session.Where("model=?", oldName).Update(enforcer)
|
||||||
|
if err != nil {
|
||||||
|
session.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ func GetPermission(id string) (*Permission, error) {
|
|||||||
|
|
||||||
// checkPermissionValid verifies if the permission is valid
|
// checkPermissionValid verifies if the permission is valid
|
||||||
func checkPermissionValid(permission *Permission) error {
|
func checkPermissionValid(permission *Permission) error {
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getPermissionEnforcer(permission)
|
||||||
enforcer.EnableAutoSave(false)
|
enforcer.EnableAutoSave(false)
|
||||||
|
|
||||||
policies := getPolicies(permission)
|
policies := getPolicies(permission)
|
||||||
|
@ -26,7 +26,7 @@ import (
|
|||||||
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getEnforcer(p *Permission, permissionIDs ...string) *casbin.Enforcer {
|
func getPermissionEnforcer(p *Permission, permissionIDs ...string) *casbin.Enforcer {
|
||||||
// Init an enforcer instance without specifying a model or adapter.
|
// Init an enforcer instance without specifying a model or adapter.
|
||||||
// If you specify an adapter, it will load all policies, which is a
|
// If you specify an adapter, it will load all policies, which is a
|
||||||
// heavy process that can slow down the application.
|
// heavy process that can slow down the application.
|
||||||
@ -204,7 +204,7 @@ func getGroupingPolicies(permission *Permission) [][]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func addPolicies(permission *Permission) {
|
func addPolicies(permission *Permission) {
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getPermissionEnforcer(permission)
|
||||||
policies := getPolicies(permission)
|
policies := getPolicies(permission)
|
||||||
|
|
||||||
_, err := enforcer.AddPolicies(policies)
|
_, err := enforcer.AddPolicies(policies)
|
||||||
@ -214,7 +214,7 @@ func addPolicies(permission *Permission) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func addGroupingPolicies(permission *Permission) {
|
func addGroupingPolicies(permission *Permission) {
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getPermissionEnforcer(permission)
|
||||||
groupingPolicies := getGroupingPolicies(permission)
|
groupingPolicies := getGroupingPolicies(permission)
|
||||||
|
|
||||||
if len(groupingPolicies) > 0 {
|
if len(groupingPolicies) > 0 {
|
||||||
@ -226,7 +226,7 @@ func addGroupingPolicies(permission *Permission) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func removeGroupingPolicies(permission *Permission) {
|
func removeGroupingPolicies(permission *Permission) {
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getPermissionEnforcer(permission)
|
||||||
groupingPolicies := getGroupingPolicies(permission)
|
groupingPolicies := getGroupingPolicies(permission)
|
||||||
|
|
||||||
if len(groupingPolicies) > 0 {
|
if len(groupingPolicies) > 0 {
|
||||||
@ -238,7 +238,7 @@ func removeGroupingPolicies(permission *Permission) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func removePolicies(permission *Permission) {
|
func removePolicies(permission *Permission) {
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getPermissionEnforcer(permission)
|
||||||
policies := getPolicies(permission)
|
policies := getPolicies(permission)
|
||||||
|
|
||||||
_, err := enforcer.RemovePolicies(policies)
|
_, err := enforcer.RemovePolicies(policies)
|
||||||
@ -250,12 +250,12 @@ func removePolicies(permission *Permission) {
|
|||||||
type CasbinRequest = []interface{}
|
type CasbinRequest = []interface{}
|
||||||
|
|
||||||
func Enforce(permission *Permission, request *CasbinRequest, permissionIds ...string) (bool, error) {
|
func Enforce(permission *Permission, request *CasbinRequest, permissionIds ...string) (bool, error) {
|
||||||
enforcer := getEnforcer(permission, permissionIds...)
|
enforcer := getPermissionEnforcer(permission, permissionIds...)
|
||||||
return enforcer.Enforce(*request...)
|
return enforcer.Enforce(*request...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BatchEnforce(permission *Permission, requests *[]CasbinRequest, permissionIds ...string) ([]bool, error) {
|
func BatchEnforce(permission *Permission, requests *[]CasbinRequest, permissionIds ...string) ([]bool, error) {
|
||||||
enforcer := getEnforcer(permission, permissionIds...)
|
enforcer := getPermissionEnforcer(permission, permissionIds...)
|
||||||
return enforcer.BatchEnforce(*requests)
|
return enforcer.BatchEnforce(*requests)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ func getAllValues(userId string, fn func(enforcer *casbin.Enforcer) []string) []
|
|||||||
|
|
||||||
var values []string
|
var values []string
|
||||||
for _, permission := range permissions {
|
for _, permission := range permissions {
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getPermissionEnforcer(permission)
|
||||||
values = append(values, fn(enforcer)...)
|
values = append(values, fn(enforcer)...)
|
||||||
}
|
}
|
||||||
return values
|
return values
|
||||||
|
@ -123,6 +123,12 @@ func initAPI() {
|
|||||||
beego.Router("/api/add-policy", &controllers.ApiController{}, "POST:AddPolicy")
|
beego.Router("/api/add-policy", &controllers.ApiController{}, "POST:AddPolicy")
|
||||||
beego.Router("/api/remove-policy", &controllers.ApiController{}, "POST:RemovePolicy")
|
beego.Router("/api/remove-policy", &controllers.ApiController{}, "POST:RemovePolicy")
|
||||||
|
|
||||||
|
beego.Router("/api/get-enforcers", &controllers.ApiController{}, "GET:GetEnforcers")
|
||||||
|
beego.Router("/api/get-enforcer", &controllers.ApiController{}, "GET:GetEnforcer")
|
||||||
|
beego.Router("/api/update-enforcer", &controllers.ApiController{}, "POST:UpdateEnforcer")
|
||||||
|
beego.Router("/api/add-enforcer", &controllers.ApiController{}, "POST:AddEnforcer")
|
||||||
|
beego.Router("/api/delete-enforcer", &controllers.ApiController{}, "POST:DeleteEnforcer")
|
||||||
|
|
||||||
beego.Router("/api/set-password", &controllers.ApiController{}, "POST:SetPassword")
|
beego.Router("/api/set-password", &controllers.ApiController{}, "POST:SetPassword")
|
||||||
beego.Router("/api/check-user-password", &controllers.ApiController{}, "POST:CheckUserPassword")
|
beego.Router("/api/check-user-password", &controllers.ApiController{}, "POST:CheckUserPassword")
|
||||||
beego.Router("/api/get-email-and-phone", &controllers.ApiController{}, "GET:GetEmailAndPhone")
|
beego.Router("/api/get-email-and-phone", &controllers.ApiController{}, "GET:GetEmailAndPhone")
|
||||||
|
@ -155,6 +155,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/add-enforcer": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Enforcer API"
|
||||||
|
],
|
||||||
|
"description": "add enforcer",
|
||||||
|
"operationId": "ApiController.AddEnforcer",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "body",
|
||||||
|
"name": "enforcer",
|
||||||
|
"description": "The enforcer object",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/add-group": {
|
"/api/add-group": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -1073,6 +1101,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/delete-enforcer": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Enforcer API"
|
||||||
|
],
|
||||||
|
"description": "delete enforcer",
|
||||||
|
"operationId": "ApiController.DeleteEnforcer",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "The enforcer object",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object.Enforce"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/delete-group": {
|
"/api/delete-group": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -2018,6 +2074,61 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/get-enforcer": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Enforcer API"
|
||||||
|
],
|
||||||
|
"description": "get enforcer",
|
||||||
|
"operationId": "ApiController.GetEnforcer",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "id",
|
||||||
|
"description": "The id ( owner/name ) of enforcer",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/get-enforcers": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Enforcer API"
|
||||||
|
],
|
||||||
|
"description": "get enforcers",
|
||||||
|
"operationId": "ApiController.GetEnforcers",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "owner",
|
||||||
|
"description": "The owner of enforcers",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/object.Enforcer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/get-global-providers": {
|
"/api/get-global-providers": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -4394,6 +4505,41 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/update-enforcer": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Enforcer API"
|
||||||
|
],
|
||||||
|
"description": "update enforcer",
|
||||||
|
"operationId": "ApiController.UpdateEnforcer",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "id",
|
||||||
|
"description": "The id ( owner/name ) of enforcer",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "body",
|
||||||
|
"name": "enforcer",
|
||||||
|
"description": "The enforcer object",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/update-group": {
|
"/api/update-group": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -5273,6 +5419,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
"1225.0xc000333110.false": {
|
||||||
|
"title": "false",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"1260.0xc000333140.false": {
|
||||||
|
"title": "false",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"LaravelResponse": {
|
"LaravelResponse": {
|
||||||
"title": "LaravelResponse",
|
"title": "LaravelResponse",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
@ -5289,6 +5443,10 @@
|
|||||||
"title": "Response",
|
"title": "Response",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"casbin.Enforcer": {
|
||||||
|
"title": "Enforcer",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"controllers.AuthForm": {
|
"controllers.AuthForm": {
|
||||||
"title": "AuthForm",
|
"title": "AuthForm",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
@ -5322,16 +5480,10 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"additionalProperties": {
|
"$ref": "#/definitions/1225.0xc000333110.false"
|
||||||
"description": "support string, struct or []struct",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"data2": {
|
"data2": {
|
||||||
"additionalProperties": {
|
"$ref": "#/definitions/1260.0xc000333140.false"
|
||||||
"description": "support string, struct or []struct",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"msg": {
|
"msg": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -5373,6 +5525,10 @@
|
|||||||
"title": "object",
|
"title": "object",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"object.\u0026{197582 0xc000ace360 false}": {
|
||||||
|
"title": "\u0026{197582 0xc000ace360 false}",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"object.AccountItem": {
|
"object.AccountItem": {
|
||||||
"title": "AccountItem",
|
"title": "AccountItem",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -5566,7 +5722,7 @@
|
|||||||
"title": "CasbinRequest",
|
"title": "CasbinRequest",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/object.CasbinRequest"
|
"$ref": "#/definitions/object.\u0026{197582 0xc000ace360 false}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"object.Cert": {
|
"object.Cert": {
|
||||||
@ -5662,6 +5818,43 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"object.Enforce": {
|
||||||
|
"title": "Enforce",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"object.Enforcer": {
|
||||||
|
"title": "Enforcer",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"adapter": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"createdTime": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"displayName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"isEnabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updatedTime": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"object.GaugeVecInfo": {
|
"object.GaugeVecInfo": {
|
||||||
"title": "GaugeVecInfo",
|
"title": "GaugeVecInfo",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -7323,6 +7516,9 @@
|
|||||||
"meetup": {
|
"meetup": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"metamask": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"mfaEmailEnabled": {
|
"mfaEmailEnabled": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
@ -100,6 +100,24 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controllers.Response'
|
$ref: '#/definitions/controllers.Response'
|
||||||
|
/api/add-enforcer:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Enforcer API
|
||||||
|
description: add enforcer
|
||||||
|
operationId: ApiController.AddEnforcer
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: enforcer
|
||||||
|
description: The enforcer object
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object'
|
||||||
/api/add-group:
|
/api/add-group:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -693,6 +711,24 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controllers.Response'
|
$ref: '#/definitions/controllers.Response'
|
||||||
|
/api/delete-enforcer:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Enforcer API
|
||||||
|
description: delete enforcer
|
||||||
|
operationId: ApiController.DeleteEnforcer
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: The enforcer object
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object.Enforce'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object'
|
||||||
/api/delete-group:
|
/api/delete-group:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -1307,6 +1343,42 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controllers.Response'
|
$ref: '#/definitions/controllers.Response'
|
||||||
|
/api/get-enforcer:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Enforcer API
|
||||||
|
description: get enforcer
|
||||||
|
operationId: ApiController.GetEnforcer
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: id
|
||||||
|
description: The id ( owner/name ) of enforcer
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object'
|
||||||
|
/api/get-enforcers:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Enforcer API
|
||||||
|
description: get enforcers
|
||||||
|
operationId: ApiController.GetEnforcers
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: owner
|
||||||
|
description: The owner of enforcers
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/object.Enforcer'
|
||||||
/api/get-global-providers:
|
/api/get-global-providers:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -2869,6 +2941,29 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controllers.Response'
|
$ref: '#/definitions/controllers.Response'
|
||||||
|
/api/update-enforcer:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Enforcer API
|
||||||
|
description: update enforcer
|
||||||
|
operationId: ApiController.UpdateEnforcer
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: id
|
||||||
|
description: The id ( owner/name ) of enforcer
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- in: body
|
||||||
|
name: enforcer
|
||||||
|
description: The enforcer object
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object'
|
||||||
/api/update-group:
|
/api/update-group:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -3446,6 +3541,12 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controllers.Response'
|
$ref: '#/definitions/controllers.Response'
|
||||||
definitions:
|
definitions:
|
||||||
|
1225.0xc000333110.false:
|
||||||
|
title: "false"
|
||||||
|
type: object
|
||||||
|
1260.0xc000333140.false:
|
||||||
|
title: "false"
|
||||||
|
type: object
|
||||||
LaravelResponse:
|
LaravelResponse:
|
||||||
title: LaravelResponse
|
title: LaravelResponse
|
||||||
type: object
|
type: object
|
||||||
@ -3458,6 +3559,9 @@ definitions:
|
|||||||
Response:
|
Response:
|
||||||
title: Response
|
title: Response
|
||||||
type: object
|
type: object
|
||||||
|
casbin.Enforcer:
|
||||||
|
title: Enforcer
|
||||||
|
type: object
|
||||||
controllers.AuthForm:
|
controllers.AuthForm:
|
||||||
title: AuthForm
|
title: AuthForm
|
||||||
type: object
|
type: object
|
||||||
@ -3482,13 +3586,9 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
data:
|
data:
|
||||||
additionalProperties:
|
$ref: '#/definitions/1225.0xc000333110.false'
|
||||||
description: support string, struct or []struct
|
|
||||||
type: string
|
|
||||||
data2:
|
data2:
|
||||||
additionalProperties:
|
$ref: '#/definitions/1260.0xc000333140.false'
|
||||||
description: support string, struct or []struct
|
|
||||||
type: string
|
|
||||||
msg:
|
msg:
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
@ -3515,6 +3615,9 @@ definitions:
|
|||||||
object:
|
object:
|
||||||
title: object
|
title: object
|
||||||
type: object
|
type: object
|
||||||
|
object.&{197582 0xc000ace360 false}:
|
||||||
|
title: '&{197582 0xc000ace360 false}'
|
||||||
|
type: object
|
||||||
object.AccountItem:
|
object.AccountItem:
|
||||||
title: AccountItem
|
title: AccountItem
|
||||||
type: object
|
type: object
|
||||||
@ -3646,7 +3749,7 @@ definitions:
|
|||||||
title: CasbinRequest
|
title: CasbinRequest
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/object.CasbinRequest'
|
$ref: '#/definitions/object.&{197582 0xc000ace360 false}'
|
||||||
object.Cert:
|
object.Cert:
|
||||||
title: Cert
|
title: Cert
|
||||||
type: object
|
type: object
|
||||||
@ -3710,6 +3813,31 @@ definitions:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
|
object.Enforce:
|
||||||
|
title: Enforce
|
||||||
|
type: object
|
||||||
|
object.Enforcer:
|
||||||
|
title: Enforcer
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
adapter:
|
||||||
|
type: string
|
||||||
|
createdTime:
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
displayName:
|
||||||
|
type: string
|
||||||
|
isEnabled:
|
||||||
|
type: boolean
|
||||||
|
model:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
owner:
|
||||||
|
type: string
|
||||||
|
updatedTime:
|
||||||
|
type: string
|
||||||
object.GaugeVecInfo:
|
object.GaugeVecInfo:
|
||||||
title: GaugeVecInfo
|
title: GaugeVecInfo
|
||||||
type: object
|
type: object
|
||||||
@ -4828,6 +4956,8 @@ definitions:
|
|||||||
$ref: '#/definitions/object.ManagedAccount'
|
$ref: '#/definitions/object.ManagedAccount'
|
||||||
meetup:
|
meetup:
|
||||||
type: string
|
type: string
|
||||||
|
metamask:
|
||||||
|
type: string
|
||||||
mfaEmailEnabled:
|
mfaEmailEnabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
mfaPhoneEnabled:
|
mfaPhoneEnabled:
|
||||||
|
@ -15,10 +15,6 @@
|
|||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import "./App.less";
|
import "./App.less";
|
||||||
import {Helmet} from "react-helmet";
|
import {Helmet} from "react-helmet";
|
||||||
import EnableMfaNotification from "./common/notifaction/EnableMfaNotification";
|
|
||||||
import GroupTreePage from "./GroupTreePage";
|
|
||||||
import GroupEditPage from "./GroupEdit";
|
|
||||||
import GroupListPage from "./GroupList";
|
|
||||||
import {MfaRuleRequired} from "./Setting";
|
import {MfaRuleRequired} from "./Setting";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import {StyleProvider, legacyLogicalPropertiesTransformer} from "@ant-design/cssinjs";
|
import {StyleProvider, legacyLogicalPropertiesTransformer} from "@ant-design/cssinjs";
|
||||||
@ -33,6 +29,11 @@ import RoleListPage from "./RoleListPage";
|
|||||||
import RoleEditPage from "./RoleEditPage";
|
import RoleEditPage from "./RoleEditPage";
|
||||||
import PermissionListPage from "./PermissionListPage";
|
import PermissionListPage from "./PermissionListPage";
|
||||||
import PermissionEditPage from "./PermissionEditPage";
|
import PermissionEditPage from "./PermissionEditPage";
|
||||||
|
import EnforcerEditPage from "./EnforcerEditPage";
|
||||||
|
import EnforcerListPage from "./EnforcerListPage";
|
||||||
|
import GroupTreePage from "./GroupTreePage";
|
||||||
|
import GroupEditPage from "./GroupEdit";
|
||||||
|
import GroupListPage from "./GroupList";
|
||||||
import ProviderListPage from "./ProviderListPage";
|
import ProviderListPage from "./ProviderListPage";
|
||||||
import ProviderEditPage from "./ProviderEditPage";
|
import ProviderEditPage from "./ProviderEditPage";
|
||||||
import ApplicationListPage from "./ApplicationListPage";
|
import ApplicationListPage from "./ApplicationListPage";
|
||||||
@ -86,6 +87,7 @@ import OdicDiscoveryPage from "./auth/OidcDiscoveryPage";
|
|||||||
import SamlCallback from "./auth/SamlCallback";
|
import SamlCallback from "./auth/SamlCallback";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import {withTranslation} from "react-i18next";
|
import {withTranslation} from "react-i18next";
|
||||||
|
import EnableMfaNotification from "./common/notifaction/EnableMfaNotification";
|
||||||
import LanguageSelect from "./common/select/LanguageSelect";
|
import LanguageSelect from "./common/select/LanguageSelect";
|
||||||
import ThemeSelect from "./common/select/ThemeSelect";
|
import ThemeSelect from "./common/select/ThemeSelect";
|
||||||
import OrganizationSelect from "./common/select/OrganizationSelect";
|
import OrganizationSelect from "./common/select/OrganizationSelect";
|
||||||
@ -164,6 +166,8 @@ class App extends Component {
|
|||||||
this.setState({selectedMenuKey: "/models"});
|
this.setState({selectedMenuKey: "/models"});
|
||||||
} else if (uri.includes("/adapters")) {
|
} else if (uri.includes("/adapters")) {
|
||||||
this.setState({selectedMenuKey: "/adapters"});
|
this.setState({selectedMenuKey: "/adapters"});
|
||||||
|
} else if (uri.includes("/enforcers")) {
|
||||||
|
this.setState({selectedMenuKey: "/enforcers"});
|
||||||
} else if (uri.includes("/providers")) {
|
} else if (uri.includes("/providers")) {
|
||||||
this.setState({selectedMenuKey: "/providers"});
|
this.setState({selectedMenuKey: "/providers"});
|
||||||
} else if (uri.includes("/applications")) {
|
} else if (uri.includes("/applications")) {
|
||||||
@ -481,6 +485,10 @@ class App extends Component {
|
|||||||
res.push(Setting.getItem(<Link to="/adapters">{i18next.t("general:Adapters")}</Link>,
|
res.push(Setting.getItem(<Link to="/adapters">{i18next.t("general:Adapters")}</Link>,
|
||||||
"/adapters"
|
"/adapters"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
res.push(Setting.getItem(<Link to="/enforcers">{i18next.t("general:Enforcers")}</Link>,
|
||||||
|
"/enforcers"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Setting.isLocalAdminUser(this.state.account)) {
|
if (Setting.isLocalAdminUser(this.state.account)) {
|
||||||
@ -599,6 +607,8 @@ class App extends Component {
|
|||||||
<Route exact path="/permissions/:organizationName/:permissionName" render={(props) => this.renderLoginIfNotLoggedIn(<PermissionEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/permissions/:organizationName/:permissionName" render={(props) => this.renderLoginIfNotLoggedIn(<PermissionEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/models" render={(props) => this.renderLoginIfNotLoggedIn(<ModelListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/models" render={(props) => this.renderLoginIfNotLoggedIn(<ModelListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/models/:organizationName/:modelName" render={(props) => this.renderLoginIfNotLoggedIn(<ModelEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/models/:organizationName/:modelName" render={(props) => this.renderLoginIfNotLoggedIn(<ModelEditPage account={this.state.account} {...props} />)} />
|
||||||
|
<Route exact path="/enforcers" render={(props) => this.renderLoginIfNotLoggedIn(<EnforcerListPage account={this.state.account} {...props} />)} />
|
||||||
|
<Route exact path="/enforcers/:organizationName/:enforcerName" render={(props) => this.renderLoginIfNotLoggedIn(<EnforcerEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/adapters" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/adapters" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/adapters/:organizationName/:adapterName" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/adapters/:organizationName/:adapterName" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/providers" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/providers" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderListPage account={this.state.account} {...props} />)} />
|
||||||
|
257
web/src/EnforcerEditPage.js
Normal file
257
web/src/EnforcerEditPage.js
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import {Button, Card, Col, Input, Row, Select, Switch} from "antd";
|
||||||
|
import * as AdapterBackend from "./backend/AdapterBackend";
|
||||||
|
import * as EnforcerBackend from "./backend/EnforcerBackend";
|
||||||
|
import * as ModelBackend from "./backend/ModelBackend";
|
||||||
|
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||||
|
import * as Setting from "./Setting";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
class EnforcerEditPage extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
classes: props,
|
||||||
|
organizationName: props.organizationName !== undefined ? props.organizationName : props.match.params.organizationName,
|
||||||
|
enforcerName: props.match.params.enforcerName,
|
||||||
|
enforcer: null,
|
||||||
|
organizations: [],
|
||||||
|
models: [],
|
||||||
|
adapters: [],
|
||||||
|
mode: props.location.mode !== undefined ? props.location.mode : "edit",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
UNSAFE_componentWillMount() {
|
||||||
|
this.getEnforcer();
|
||||||
|
this.getOrganizations();
|
||||||
|
}
|
||||||
|
|
||||||
|
getEnforcer() {
|
||||||
|
EnforcerBackend.getEnforcer(this.state.organizationName, this.state.enforcerName)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.data === null) {
|
||||||
|
this.props.history.push("/404");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status === "error") {
|
||||||
|
Setting.showMessage("error", res.msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
enforcer: res.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.getModels(this.state.organizationName);
|
||||||
|
this.getAdapters(this.state.organizationName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getOrganizations() {
|
||||||
|
OrganizationBackend.getOrganizations("admin")
|
||||||
|
.then((res) => {
|
||||||
|
this.setState({
|
||||||
|
organizations: res.data || [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getModels(organizationName) {
|
||||||
|
ModelBackend.getModels(organizationName)
|
||||||
|
.then((res) => {
|
||||||
|
this.setState({
|
||||||
|
models: res.data || [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getAdapters(organizationName) {
|
||||||
|
AdapterBackend.getAdapters(organizationName)
|
||||||
|
.then((res) => {
|
||||||
|
this.setState({
|
||||||
|
adapters: res.data || [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
parseEnforcerField(key, value) {
|
||||||
|
if ([""].includes(key)) {
|
||||||
|
value = Setting.myParseInt(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateEnforcerField(key, value) {
|
||||||
|
value = this.parseEnforcerField(key, value);
|
||||||
|
|
||||||
|
const enforcer = this.state.enforcer;
|
||||||
|
enforcer[key] = value;
|
||||||
|
this.setState({
|
||||||
|
enforcer: enforcer,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderEnforcer() {
|
||||||
|
return (
|
||||||
|
<Card size="small" title={
|
||||||
|
<div>
|
||||||
|
{this.state.mode === "add" ? i18next.t("enforcer:New Enforcer") : i18next.t("enforcer:Edit Enforcer")}
|
||||||
|
<Button onClick={() => this.submitEnforcerEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||||
|
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitEnforcerEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||||
|
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteEnforcer()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||||
|
</div>
|
||||||
|
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
|
||||||
|
<Row style={{marginTop: "10px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<Select virtual={false} style={{width: "100%"}} disabled={!Setting.isAdminUser(this.props.account)} value={this.state.enforcer.owner} onChange={(owner => {
|
||||||
|
this.updateEnforcerField("owner", owner);
|
||||||
|
this.getModels(owner);
|
||||||
|
this.getAdapters(owner);
|
||||||
|
})}
|
||||||
|
options={this.state.organizations.map((organization) => Setting.getOption(organization.name, organization.name))
|
||||||
|
} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("general:Name"), i18next.t("general:Name - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<Input value={this.state.enforcer.name} onChange={e => {
|
||||||
|
this.updateEnforcerField("name", e.target.value);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("general:Display name"), i18next.t("general:Display name - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<Input value={this.state.enforcer.displayName} onChange={e => {
|
||||||
|
this.updateEnforcerField("displayName", e.target.value);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("general:Description"), i18next.t("general:Description - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<Input value={this.state.enforcer.description} onChange={e => {
|
||||||
|
this.updateEnforcerField("description", e.target.value);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("general:Model"), i18next.t("general:Model - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<Select virtual={false} style={{width: "100%"}} value={this.state.enforcer.model} onChange={(model => {
|
||||||
|
this.updateEnforcerField("model", model);
|
||||||
|
})}
|
||||||
|
options={this.state.models.map((model) => Setting.getOption(model.displayName, model.name))
|
||||||
|
} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("general:Adapter"), i18next.t("general:Adapter - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<Select virtual={false} style={{width: "100%"}} value={this.state.enforcer.adapter} onChange={(adapter => {
|
||||||
|
this.updateEnforcerField("adapter", adapter);
|
||||||
|
})}
|
||||||
|
options={this.state.adapters.map((adapter) => Setting.getOption(adapter.name, adapter.name))
|
||||||
|
} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 19 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("general:Is enabled"), i18next.t("general:Is enabled - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={1} >
|
||||||
|
<Switch checked={this.state.enforcer.isEnabled} onChange={checked => {
|
||||||
|
this.updateEnforcerField("isEnabled", checked);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
submitEnforcerEdit(willExist) {
|
||||||
|
const enforcer = Setting.deepCopy(this.state.enforcer);
|
||||||
|
EnforcerBackend.updateEnforcer(this.state.organizationName, this.state.enforcerName, enforcer)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status === "ok") {
|
||||||
|
Setting.showMessage("success", i18next.t("general:Successfully saved"));
|
||||||
|
this.setState({
|
||||||
|
enforcerName: this.state.enforcer.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (willExist) {
|
||||||
|
this.props.history.push("/enforcers");
|
||||||
|
} else {
|
||||||
|
this.props.history.push(`/enforcers/${this.state.enforcer.owner}/${this.state.enforcer.name}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
|
||||||
|
this.updateEnforcerField("name", this.state.enforcerName);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteEnforcer() {
|
||||||
|
EnforcerBackend.deleteEnforcer(this.state.enforcer)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status === "ok") {
|
||||||
|
this.props.history.push("/enforcers");
|
||||||
|
} else {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
this.state.enforcer !== null ? this.renderEnforcer() : null
|
||||||
|
}
|
||||||
|
<div style={{marginTop: "20px", marginLeft: "40px"}}>
|
||||||
|
<Button size="large" onClick={() => this.submitEnforcerEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||||
|
<Button style={{marginLeft: "20px"}} type="primary" size="large" onClick={() => this.submitEnforcerEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||||
|
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} size="large" onClick={() => this.deleteEnforcer()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EnforcerEditPage;
|
218
web/src/EnforcerListPage.js
Normal file
218
web/src/EnforcerListPage.js
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import {Link} from "react-router-dom";
|
||||||
|
import {Button, Switch, Table} from "antd";
|
||||||
|
import moment from "moment";
|
||||||
|
import * as Setting from "./Setting";
|
||||||
|
import * as EnforcerBackend from "./backend/EnforcerBackend";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import BaseListPage from "./BaseListPage";
|
||||||
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
|
class EnforcerListPage extends BaseListPage {
|
||||||
|
newEnforcer() {
|
||||||
|
const randomName = Setting.getRandomName();
|
||||||
|
const owner = Setting.getRequestOrganization(this.props.account);
|
||||||
|
return {
|
||||||
|
owner: owner,
|
||||||
|
name: `enforcer_${randomName}`,
|
||||||
|
createdTime: moment().format(),
|
||||||
|
displayName: `New Enforcer - ${randomName}`,
|
||||||
|
isEnabled: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
addEnforcer() {
|
||||||
|
const newEnforcer = this.newEnforcer();
|
||||||
|
EnforcerBackend.addEnforcer(newEnforcer)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status === "ok") {
|
||||||
|
this.props.history.push({pathname: `/enforcers/${newEnforcer.owner}/${newEnforcer.name}`, mode: "add"});
|
||||||
|
Setting.showMessage("success", i18next.t("general:Successfully added"));
|
||||||
|
} else {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteEnforcer(i) {
|
||||||
|
EnforcerBackend.deleteEnforcer(this.state.data[i])
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status === "ok") {
|
||||||
|
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||||
|
this.setState({
|
||||||
|
data: Setting.deleteRow(this.state.data, i),
|
||||||
|
pagination: {total: this.state.pagination.total - 1},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderTable(enforcers) {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Name"),
|
||||||
|
dataIndex: "name",
|
||||||
|
key: "name",
|
||||||
|
width: "150px",
|
||||||
|
fixed: "left",
|
||||||
|
sorter: true,
|
||||||
|
...this.getColumnSearchProps("name"),
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return (
|
||||||
|
<Link to={`/enforcers/${record.owner}/${text}`}>
|
||||||
|
{text}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Organization"),
|
||||||
|
dataIndex: "owner",
|
||||||
|
key: "owner",
|
||||||
|
width: "120px",
|
||||||
|
sorter: true,
|
||||||
|
...this.getColumnSearchProps("owner"),
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return (
|
||||||
|
<Link to={`/organizations/${text}`}>
|
||||||
|
{text}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Created time"),
|
||||||
|
dataIndex: "createdTime",
|
||||||
|
key: "createdTime",
|
||||||
|
width: "160px",
|
||||||
|
sorter: true,
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return Setting.getFormattedDate(text);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Display name"),
|
||||||
|
dataIndex: "displayName",
|
||||||
|
key: "displayName",
|
||||||
|
width: "200px",
|
||||||
|
sorter: true,
|
||||||
|
...this.getColumnSearchProps("displayName"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Is enabled"),
|
||||||
|
dataIndex: "isEnabled",
|
||||||
|
key: "isEnabled",
|
||||||
|
width: "120px",
|
||||||
|
sorter: true,
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return (
|
||||||
|
<Switch disabled checkedChildren="ON" unCheckedChildren="OFF" checked={text} />
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Action"),
|
||||||
|
dataIndex: "",
|
||||||
|
key: "op",
|
||||||
|
width: "170px",
|
||||||
|
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary"
|
||||||
|
onClick={() => this.props.history.push(`/enforcers/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||||
|
<PopconfirmModal
|
||||||
|
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||||
|
onConfirm={() => this.deleteEnforcer(index)}
|
||||||
|
>
|
||||||
|
</PopconfirmModal>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const paginationProps = {
|
||||||
|
total: this.state.pagination.total,
|
||||||
|
showQuickJumper: true,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table scroll={{x: "max-content"}} columns={columns} dataSource={enforcers} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered
|
||||||
|
pagination={paginationProps}
|
||||||
|
title={() => (
|
||||||
|
<div>
|
||||||
|
{i18next.t("general:Enforcers")}
|
||||||
|
<Button type="primary" size="small"
|
||||||
|
onClick={this.addEnforcer.bind(this)}>{i18next.t("general:Add")}</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
loading={this.state.loading}
|
||||||
|
onChange={this.handleTableChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch = (params = {}) => {
|
||||||
|
let field = params.searchedColumn, value = params.searchText;
|
||||||
|
const sortField = params.sortField, sortOrder = params.sortOrder;
|
||||||
|
if (params.type !== undefined && params.type !== null) {
|
||||||
|
field = "type";
|
||||||
|
value = params.type;
|
||||||
|
}
|
||||||
|
this.setState({loading: true});
|
||||||
|
EnforcerBackend.getEnforcers(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
||||||
|
.then((res) => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
if (res.status === "ok") {
|
||||||
|
this.setState({
|
||||||
|
data: res.data,
|
||||||
|
pagination: {
|
||||||
|
...params.pagination,
|
||||||
|
total: res.data2,
|
||||||
|
},
|
||||||
|
searchText: params.searchText,
|
||||||
|
searchedColumn: params.searchedColumn,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (Setting.isResponseDenied(res)) {
|
||||||
|
this.setState({
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Setting.showMessage("error", res.msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EnforcerListPage;
|
71
web/src/backend/EnforcerBackend.js
Normal file
71
web/src/backend/EnforcerBackend.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import * as Setting from "../Setting";
|
||||||
|
|
||||||
|
export function getEnforcers(owner, page = "", pageSize = "", field = "", value = "", sortField = "", sortOrder = "") {
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/get-enforcers?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
|
method: "GET",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getEnforcer(owner, name) {
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/get-enforcer?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
|
method: "GET",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateEnforcer(owner, name, enforcer) {
|
||||||
|
const newEnforcer = Setting.deepCopy(enforcer);
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/update-enforcer?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
|
body: JSON.stringify(newEnforcer),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addEnforcer(enforcer) {
|
||||||
|
const newEnforcer = Setting.deepCopy(enforcer);
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/add-enforcer`, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
|
body: JSON.stringify(newEnforcer),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteEnforcer(enforcer) {
|
||||||
|
const newEnforcer = Setting.deepCopy(enforcer);
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/delete-enforcer`, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
|
body: JSON.stringify(newEnforcer),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
Reference in New Issue
Block a user