mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
feat: move policy table from adapter to enforcer and improve it (#2228)
* feat: improve policiy table * feat: add connection test in AdapterEditPage.js * feat: update button style
This commit is contained in:
parent
d12117324c
commit
a41f6880a2
@ -20,7 +20,6 @@ import (
|
|||||||
"github.com/beego/beego/utils/pagination"
|
"github.com/beego/beego/utils/pagination"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetAdapters
|
// GetAdapters
|
||||||
@ -144,92 +143,3 @@ func (c *ApiController) DeleteAdapter() {
|
|||||||
c.Data["json"] = wrapActionResponse(object.DeleteAdapter(&adapter))
|
c.Data["json"] = wrapActionResponse(object.DeleteAdapter(&adapter))
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApiController) GetPolicies() {
|
|
||||||
id := c.Input().Get("id")
|
|
||||||
adapter, err := object.GetAdapter(id)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
policies, err := object.GetPolicies(adapter)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.ResponseOk(policies)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ApiController) UpdatePolicy() {
|
|
||||||
id := c.Input().Get("id")
|
|
||||||
adapter, err := object.GetAdapter(id)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var policies []xormadapter.CasbinRule
|
|
||||||
err = json.Unmarshal(c.Ctx.Input.RequestBody, &policies)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
affected, err := object.UpdatePolicy(util.CasbinToSlice(policies[0]), util.CasbinToSlice(policies[1]), adapter)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Data["json"] = wrapActionResponse(affected)
|
|
||||||
c.ServeJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ApiController) AddPolicy() {
|
|
||||||
id := c.Input().Get("id")
|
|
||||||
adapter, err := object.GetAdapter(id)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var policy xormadapter.CasbinRule
|
|
||||||
err = json.Unmarshal(c.Ctx.Input.RequestBody, &policy)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
affected, err := object.AddPolicy(util.CasbinToSlice(policy), adapter)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Data["json"] = wrapActionResponse(affected)
|
|
||||||
c.ServeJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ApiController) RemovePolicy() {
|
|
||||||
id := c.Input().Get("id")
|
|
||||||
adapter, err := object.GetAdapter(id)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var policy xormadapter.CasbinRule
|
|
||||||
err = json.Unmarshal(c.Ctx.Input.RequestBody, &policy)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
affected, err := object.RemovePolicy(util.CasbinToSlice(policy), adapter)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Data["json"] = wrapActionResponse(affected)
|
|
||||||
c.ServeJSON()
|
|
||||||
}
|
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/beego/beego/utils/pagination"
|
"github.com/beego/beego/utils/pagination"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
|
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetEnforcers
|
// GetEnforcers
|
||||||
@ -74,6 +75,7 @@ func (c *ApiController) GetEnforcers() {
|
|||||||
// @router /get-enforcer [get]
|
// @router /get-enforcer [get]
|
||||||
func (c *ApiController) GetEnforcer() {
|
func (c *ApiController) GetEnforcer() {
|
||||||
id := c.Input().Get("id")
|
id := c.Input().Get("id")
|
||||||
|
loadModelCfg := c.Input().Get("loadModelCfg")
|
||||||
|
|
||||||
enforcer, err := object.GetEnforcer(id)
|
enforcer, err := object.GetEnforcer(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -81,6 +83,13 @@ func (c *ApiController) GetEnforcer() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if loadModelCfg == "true" {
|
||||||
|
err := enforcer.LoadModelCfg()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.ResponseOk(enforcer)
|
c.ResponseOk(enforcer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,3 +152,88 @@ func (c *ApiController) DeleteEnforcer() {
|
|||||||
c.Data["json"] = wrapActionResponse(object.DeleteEnforcer(&enforcer))
|
c.Data["json"] = wrapActionResponse(object.DeleteEnforcer(&enforcer))
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) GetPolicies() {
|
||||||
|
id := c.Input().Get("id")
|
||||||
|
adapterId := c.Input().Get("adapterId")
|
||||||
|
|
||||||
|
if adapterId != "" {
|
||||||
|
adapter, err := object.GetAdapter(adapterId)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = adapter.InitAdapter()
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.ResponseOk()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
policies, err := object.GetPolicies(id)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ResponseOk(policies)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) UpdatePolicy() {
|
||||||
|
id := c.Input().Get("id")
|
||||||
|
|
||||||
|
var policies []xormadapter.CasbinRule
|
||||||
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &policies)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, err := object.UpdatePolicy(id, util.CasbinToSlice(policies[0]), util.CasbinToSlice(policies[1]))
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = wrapActionResponse(affected)
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) AddPolicy() {
|
||||||
|
id := c.Input().Get("id")
|
||||||
|
|
||||||
|
var policy xormadapter.CasbinRule
|
||||||
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &policy)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, err := object.AddPolicy(id, util.CasbinToSlice(policy))
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = wrapActionResponse(affected)
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) RemovePolicy() {
|
||||||
|
id := c.Input().Get("id")
|
||||||
|
|
||||||
|
var policy xormadapter.CasbinRule
|
||||||
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &policy)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, err := object.RemovePolicy(id, util.CasbinToSlice(policy))
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = wrapActionResponse(affected)
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
||||||
|
@ -18,7 +18,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casbin/casbin/v2/model"
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||||
@ -150,7 +149,7 @@ func (adapter *Adapter) getTable() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (adapter *Adapter) initAdapter() error {
|
func (adapter *Adapter) InitAdapter() error {
|
||||||
if adapter.Adapter == nil {
|
if adapter.Adapter == nil {
|
||||||
var dataSourceName string
|
var dataSourceName string
|
||||||
|
|
||||||
@ -214,119 +213,6 @@ func adapterChangeTrigger(oldName string, newName string) error {
|
|||||||
return session.Commit()
|
return session.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func safeReturn(policy []string, i int) string {
|
|
||||||
if len(policy) > i {
|
|
||||||
return policy[i]
|
|
||||||
} else {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func matrixToCasbinRules(Ptype string, policies [][]string) []*xormadapter.CasbinRule {
|
|
||||||
res := []*xormadapter.CasbinRule{}
|
|
||||||
|
|
||||||
for _, policy := range policies {
|
|
||||||
line := xormadapter.CasbinRule{
|
|
||||||
Ptype: Ptype,
|
|
||||||
V0: safeReturn(policy, 0),
|
|
||||||
V1: safeReturn(policy, 1),
|
|
||||||
V2: safeReturn(policy, 2),
|
|
||||||
V3: safeReturn(policy, 3),
|
|
||||||
V4: safeReturn(policy, 4),
|
|
||||||
V5: safeReturn(policy, 5),
|
|
||||||
}
|
|
||||||
res = append(res, &line)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetPolicies(adapter *Adapter) ([]*xormadapter.CasbinRule, error) {
|
|
||||||
err := adapter.initAdapter()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
casbinModel := getModelDef()
|
|
||||||
err = adapter.LoadPolicy(casbinModel)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
policies := matrixToCasbinRules("p", casbinModel.GetPolicy("p", "p"))
|
|
||||||
policies = append(policies, matrixToCasbinRules("g", casbinModel.GetPolicy("g", "g"))...)
|
|
||||||
return policies, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdatePolicy(oldPolicy, newPolicy []string, adapter *Adapter) (bool, error) {
|
|
||||||
err := adapter.initAdapter()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
casbinModel := getModelDef()
|
|
||||||
err = adapter.LoadPolicy(casbinModel)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
affected := casbinModel.UpdatePolicy("p", "p", oldPolicy, newPolicy)
|
|
||||||
if err != nil {
|
|
||||||
return affected, err
|
|
||||||
}
|
|
||||||
err = adapter.SavePolicy(casbinModel)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return affected, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddPolicy(policy []string, adapter *Adapter) (bool, error) {
|
|
||||||
err := adapter.initAdapter()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
casbinModel := getModelDef()
|
|
||||||
err = adapter.LoadPolicy(casbinModel)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
casbinModel.AddPolicy("p", "p", policy)
|
|
||||||
err = adapter.SavePolicy(casbinModel)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemovePolicy(policy []string, adapter *Adapter) (bool, error) {
|
|
||||||
err := adapter.initAdapter()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
casbinModel := getModelDef()
|
|
||||||
err = adapter.LoadPolicy(casbinModel)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
affected := casbinModel.RemovePolicy("p", "p", policy)
|
|
||||||
if err != nil {
|
|
||||||
return affected, err
|
|
||||||
}
|
|
||||||
err = adapter.SavePolicy(casbinModel)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return affected, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (adapter *Adapter) builtInAdapter() bool {
|
func (adapter *Adapter) builtInAdapter() bool {
|
||||||
if adapter.Owner != "built-in" {
|
if adapter.Owner != "built-in" {
|
||||||
return false
|
return false
|
||||||
@ -334,10 +220,3 @@ func (adapter *Adapter) builtInAdapter() bool {
|
|||||||
|
|
||||||
return adapter.Name == "user-adapter-built-in" || adapter.Name == "api-adapter-built-in"
|
return adapter.Name == "user-adapter-built-in" || adapter.Name == "api-adapter-built-in"
|
||||||
}
|
}
|
||||||
|
|
||||||
func getModelDef() model.Model {
|
|
||||||
casbinModel := model.NewModel()
|
|
||||||
casbinModel.AddDef("p", "p", "_, _, _, _, _, _")
|
|
||||||
casbinModel.AddDef("g", "g", "_, _, _, _, _, _")
|
|
||||||
return casbinModel
|
|
||||||
}
|
|
||||||
|
@ -18,7 +18,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/casbin/casbin/v2"
|
"github.com/casbin/casbin/v2"
|
||||||
|
"github.com/casbin/casbin/v2/config"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
|
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||||
"github.com/xorm-io/core"
|
"github.com/xorm-io/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,6 +36,7 @@ type Enforcer struct {
|
|||||||
Adapter string `xorm:"varchar(100)" json:"adapter"`
|
Adapter string `xorm:"varchar(100)" json:"adapter"`
|
||||||
IsEnabled bool `json:"isEnabled"`
|
IsEnabled bool `json:"isEnabled"`
|
||||||
|
|
||||||
|
ModelCfg map[string]string `xorm:"-" json:"modelCfg"`
|
||||||
*casbin.Enforcer
|
*casbin.Enforcer
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,8 +123,8 @@ func DeleteEnforcer(enforcer *Enforcer) (bool, error) {
|
|||||||
return affected != 0, nil
|
return affected != 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Enforcer) GetId() string {
|
func (enforcer *Enforcer) GetId() string {
|
||||||
return fmt.Sprintf("%s/%s", p.Owner, p.Name)
|
return fmt.Sprintf("%s/%s", enforcer.Owner, enforcer.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (enforcer *Enforcer) InitEnforcer() error {
|
func (enforcer *Enforcer) InitEnforcer() error {
|
||||||
@ -154,7 +157,7 @@ func (enforcer *Enforcer) InitEnforcer() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = a.initAdapter()
|
err = a.InitAdapter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -182,3 +185,70 @@ func GetInitializedEnforcer(enforcerId string) (*Enforcer, error) {
|
|||||||
}
|
}
|
||||||
return enforcer, nil
|
return enforcer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetPolicies(id string) ([]*xormadapter.CasbinRule, error) {
|
||||||
|
enforcer, err := GetInitializedEnforcer(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
policies := util.MatrixToCasbinRules("p", enforcer.GetPolicy())
|
||||||
|
if enforcer.GetModel()["g"] != nil {
|
||||||
|
policies = append(policies, util.MatrixToCasbinRules("g", enforcer.GetGroupingPolicy())...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return policies, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdatePolicy(id string, oldPolicy, newPolicy []string) (bool, error) {
|
||||||
|
enforcer, err := GetInitializedEnforcer(id)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return enforcer.UpdatePolicy(oldPolicy, newPolicy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddPolicy(id string, policy []string) (bool, error) {
|
||||||
|
enforcer, err := GetInitializedEnforcer(id)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return enforcer.AddPolicy(policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemovePolicy(id string, policy []string) (bool, error) {
|
||||||
|
enforcer, err := GetInitializedEnforcer(id)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return enforcer.RemovePolicy(policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enforcer *Enforcer) LoadModelCfg() error {
|
||||||
|
if enforcer.ModelCfg != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
model, err := GetModel(enforcer.Model)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if model == nil {
|
||||||
|
return fmt.Errorf("the model: %s for enforcer: %s is not found", enforcer.Model, enforcer.GetId())
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := config.NewConfigFromText(model.ModelText)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
enforcer.ModelCfg = make(map[string]string)
|
||||||
|
enforcer.ModelCfg["p"] = cfg.String("policy_definition::p")
|
||||||
|
if cfg.String("role_definition::g") != "" {
|
||||||
|
enforcer.ModelCfg["g"] = cfg.String("role_definition::g")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -34,3 +34,30 @@ func CasbinToSlice(casbinRule xormadapter.CasbinRule) []string {
|
|||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func safeReturn(policy []string, i int) string {
|
||||||
|
if len(policy) > i {
|
||||||
|
return policy[i]
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MatrixToCasbinRules(Ptype string, policies [][]string) []*xormadapter.CasbinRule {
|
||||||
|
res := []*xormadapter.CasbinRule{}
|
||||||
|
|
||||||
|
for _, policy := range policies {
|
||||||
|
line := xormadapter.CasbinRule{
|
||||||
|
Ptype: Ptype,
|
||||||
|
V0: safeReturn(policy, 0),
|
||||||
|
V1: safeReturn(policy, 1),
|
||||||
|
V2: safeReturn(policy, 2),
|
||||||
|
V3: safeReturn(policy, 3),
|
||||||
|
V4: safeReturn(policy, 4),
|
||||||
|
V5: safeReturn(policy, 5),
|
||||||
|
}
|
||||||
|
res = append(res, &line)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
@ -19,11 +19,6 @@ import * as OrganizationBackend from "./backend/OrganizationBackend";
|
|||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
import "codemirror/lib/codemirror.css";
|
|
||||||
import PolicyTable from "./table/PoliciyTable";
|
|
||||||
require("codemirror/theme/material-darker.css");
|
|
||||||
require("codemirror/mode/javascript/javascript");
|
|
||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
class AdapterEditPage extends React.Component {
|
class AdapterEditPage extends React.Component {
|
||||||
@ -232,10 +227,23 @@ class AdapterEditPage extends React.Component {
|
|||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{Setting.getLabel(i18next.t("adapter:Policies"), i18next.t("adapter:Policies - Tooltip"))} :
|
{Setting.getLabel(i18next.t("provider:DB Test"), i18next.t("provider:DB Test - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22}>
|
<Col span={2} >
|
||||||
<PolicyTable owner={this.state.organizationName} name={this.state.adapterName} mode={this.state.mode} />
|
<Button type={"primary"} onClick={() => {
|
||||||
|
AdapterBackend.getPolicies("", "", `${this.state.organizationName}/${this.state.adapterName}`)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status === "ok") {
|
||||||
|
Setting.showMessage("success", i18next.t("syncer:Connect successfully"));
|
||||||
|
} else {
|
||||||
|
Setting.showMessage("error", i18next.t("syncer:Failed to connect") + ": " + res.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}>{i18next.t("syncer:Test DB Connection")}</Button>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
@ -18,6 +18,7 @@ import * as AdapterBackend from "./backend/AdapterBackend";
|
|||||||
import * as EnforcerBackend from "./backend/EnforcerBackend";
|
import * as EnforcerBackend from "./backend/EnforcerBackend";
|
||||||
import * as ModelBackend from "./backend/ModelBackend";
|
import * as ModelBackend from "./backend/ModelBackend";
|
||||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||||
|
import PolicyTable from "./table/PolicyTable";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ class EnforcerEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getEnforcer() {
|
getEnforcer() {
|
||||||
EnforcerBackend.getEnforcer(this.state.organizationName, this.state.enforcerName)
|
EnforcerBackend.getEnforcer(this.state.organizationName, this.state.enforcerName, true)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.data === null) {
|
if (res.data === null) {
|
||||||
this.props.history.push("/404");
|
this.props.history.push("/404");
|
||||||
@ -185,6 +186,14 @@ class EnforcerEditPage extends React.Component {
|
|||||||
} />
|
} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("adapter:Policies"), i18next.t("adapter:Policies - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22}>
|
||||||
|
<PolicyTable enforcer={this.state.enforcer} modelCfg={this.state.enforcer?.modelCfg} mode={this.state.mode} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 19 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 19 : 2}>
|
||||||
{Setting.getLabel(i18next.t("general:Is enabled"), i18next.t("general:Is enabled - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:Is enabled"), i18next.t("general:Is enabled - Tooltip"))} :
|
||||||
|
@ -103,8 +103,8 @@ export function RemovePolicy(owner, name, policy) {
|
|||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPolicies(owner, name) {
|
export function getPolicies(owner, name, adapterId = "") {
|
||||||
return fetch(`${Setting.ServerUrl}/api/get-policies?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-policies?id=${owner}/${encodeURIComponent(name)}&adapterId=${adapterId}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -24,8 +24,8 @@ export function getEnforcers(owner, page = "", pageSize = "", field = "", value
|
|||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEnforcer(owner, name) {
|
export function getEnforcer(owner, name, loadModelCfg = false) {
|
||||||
return fetch(`${Setting.ServerUrl}/api/get-enforcer?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-enforcer?id=${owner}/${encodeURIComponent(name)}&loadModelCfg=${loadModelCfg}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {DeleteOutlined, EditOutlined} from "@ant-design/icons";
|
import {DeleteOutlined, EditOutlined} from "@ant-design/icons";
|
||||||
import {Button, Input, Popconfirm, Table, Tooltip} from "antd";
|
import {Button, Input, Popconfirm, Select, Table, Tooltip} from "antd";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
import * as AdapterBackend from "../backend/AdapterBackend";
|
import * as AdapterBackend from "../backend/AdapterBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
@ -42,7 +42,7 @@ class PolicyTable extends React.Component {
|
|||||||
|
|
||||||
UNSAFE_componentWillMount() {
|
UNSAFE_componentWillMount() {
|
||||||
if (this.props.mode === "edit") {
|
if (this.props.mode === "edit") {
|
||||||
this.synPolicies();
|
this.getPolicies();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,9 +100,9 @@ class PolicyTable extends React.Component {
|
|||||||
this.state.add ? this.addPolicy(table, i) : this.updatePolicy(table, i);
|
this.state.add ? this.addPolicy(table, i) : this.updatePolicy(table, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
synPolicies() {
|
getPolicies() {
|
||||||
this.setState({loading: true});
|
this.setState({loading: true});
|
||||||
AdapterBackend.getPolicies(this.props.owner, this.props.name)
|
AdapterBackend.getPolicies(this.props.enforcer.owner, this.props.enforcer.name)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", i18next.t("adapter:Sync policies successfully"));
|
Setting.showMessage("success", i18next.t("adapter:Sync policies successfully"));
|
||||||
@ -124,7 +124,7 @@ class PolicyTable extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updatePolicy(table, i) {
|
updatePolicy(table, i) {
|
||||||
AdapterBackend.UpdatePolicy(this.props.owner, this.props.name, [this.state.oldPolicy, table[i]]).then(res => {
|
AdapterBackend.UpdatePolicy(this.props.enforcer.owner, this.props.enforcer.name, [this.state.oldPolicy, table[i]]).then(res => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
this.setState({editingIndex: "", oldPolicy: ""});
|
this.setState({editingIndex: "", oldPolicy: ""});
|
||||||
Setting.showMessage("success", i18next.t("general:Successfully saved"));
|
Setting.showMessage("success", i18next.t("general:Successfully saved"));
|
||||||
@ -135,7 +135,7 @@ class PolicyTable extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addPolicy(table, i) {
|
addPolicy(table, i) {
|
||||||
AdapterBackend.AddPolicy(this.props.owner, this.props.name, table[i]).then(res => {
|
AdapterBackend.AddPolicy(this.props.enforcer.owner, this.props.enforcer.name, table[i]).then(res => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
this.setState({editingIndex: "", oldPolicy: "", add: false});
|
this.setState({editingIndex: "", oldPolicy: "", add: false});
|
||||||
if (res.data !== "Affected") {
|
if (res.data !== "Affected") {
|
||||||
@ -151,7 +151,7 @@ class PolicyTable extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deletePolicy(table, index) {
|
deletePolicy(table, index) {
|
||||||
AdapterBackend.RemovePolicy(this.props.owner, this.props.name, table[this.getIndex(index)]).then(res => {
|
AdapterBackend.RemovePolicy(this.props.enforcer.owner, this.props.enforcer.name, table[this.getIndex(index)]).then(res => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||||
|
|
||||||
@ -163,140 +163,76 @@ class PolicyTable extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderTable(table) {
|
renderTable(table) {
|
||||||
|
if (this.props.modelCfg === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: i18next.t("adapter:Rule type"),
|
title: i18next.t("adapter:Rule type"),
|
||||||
dataIndex: "Ptype",
|
dataIndex: "Ptype",
|
||||||
width: "100px",
|
width: "100px",
|
||||||
// render: (text, record, index) => {
|
|
||||||
// const editing = this.isEditing(index);
|
|
||||||
// return (
|
|
||||||
// editing ?
|
|
||||||
// <Input value={text} onChange={e => {
|
|
||||||
// this.updateField(table, index, "Ptype", e.target.value);
|
|
||||||
// }} />
|
|
||||||
// : text
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "V0",
|
|
||||||
dataIndex: "V0",
|
|
||||||
width: "100px",
|
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
const editing = this.isEditing(index);
|
const editing = this.isEditing(index);
|
||||||
return (
|
return (
|
||||||
editing ?
|
editing ?
|
||||||
<Input value={text} onChange={e => {
|
<Select options={Object.keys(this.props.modelCfg).map(item => Setting.getOption(item, item))} value={text} onChange={value => {
|
||||||
this.updateField(table, index, "V0", e.target.value);
|
this.updateField(table, index, "Ptype", value);
|
||||||
}} />
|
}} />
|
||||||
: text
|
: text
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
];
|
||||||
title: "V1",
|
|
||||||
dataIndex: "V1",
|
const columnKeys = ["V0", "V1", "V2", "V3", "V4", "V5"];
|
||||||
width: "100px",
|
const columnTitles = this.props.modelCfg["p"].split(",");
|
||||||
|
columnTitles.forEach((title, i) => {
|
||||||
|
columns.push({
|
||||||
|
title: title,
|
||||||
|
dataIndex: columnKeys[i],
|
||||||
|
width: "200px",
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
const editing = this.isEditing(index);
|
const editing = this.isEditing(index);
|
||||||
return (
|
return (
|
||||||
editing ?
|
editing ?
|
||||||
<Input value={text} onChange={e => {
|
<Input value={text} onChange={e => {
|
||||||
this.updateField(table, index, "V1", e.target.value);
|
this.updateField(table, index, columnKeys[i], e.target.value);
|
||||||
}} />
|
}} />
|
||||||
: text
|
: text
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
{
|
});
|
||||||
title: "V2",
|
|
||||||
dataIndex: "V2",
|
columns.push({
|
||||||
width: "100px",
|
title: i18next.t("general:Action"),
|
||||||
render: (text, record, index) => {
|
dataIndex: "",
|
||||||
const editing = this.isEditing(index);
|
key: "op",
|
||||||
return (
|
width: "100px",
|
||||||
editing ?
|
render: (text, record, index) => {
|
||||||
<Input value={text} onChange={e => {
|
const editable = this.isEditing(index);
|
||||||
this.updateField(table, index, "V2", e.target.value);
|
return editable ? (
|
||||||
}} />
|
<span>
|
||||||
: text
|
<Button style={{marginRight: 8}} onClick={() => this.save(table, index)}>
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "V3",
|
|
||||||
dataIndex: "V3",
|
|
||||||
width: "100px",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const editing = this.isEditing(index);
|
|
||||||
return (
|
|
||||||
editing ?
|
|
||||||
<Input value={text} onChange={e => {
|
|
||||||
this.updateField(table, index, "V3", e.target.value);
|
|
||||||
}} />
|
|
||||||
: text
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "V4",
|
|
||||||
dataIndex: "V4",
|
|
||||||
width: "100px",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const editing = this.isEditing(index);
|
|
||||||
return (
|
|
||||||
editing ?
|
|
||||||
<Input value={text} onChange={e => {
|
|
||||||
this.updateField(table, index, "V4", e.target.value);
|
|
||||||
}} />
|
|
||||||
: text
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "V5",
|
|
||||||
dataIndex: "V5",
|
|
||||||
width: "100px",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const editing = this.isEditing(index);
|
|
||||||
return (
|
|
||||||
editing ?
|
|
||||||
<Input value={text} onChange={e => {
|
|
||||||
this.updateField(table, index, "V5", e.target.value);
|
|
||||||
}} />
|
|
||||||
: text
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18next.t("general:Action"),
|
|
||||||
dataIndex: "",
|
|
||||||
key: "op",
|
|
||||||
width: "100px",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const editable = this.isEditing(index);
|
|
||||||
return editable ? (
|
|
||||||
<span>
|
|
||||||
<Button style={{marginRight: 8}} onClick={() => this.save(table, index)}>
|
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Popconfirm title="Sure to cancel?" onConfirm={() => this.cancel(table, index)}>
|
<Popconfirm title="Sure to cancel?" onConfirm={() => this.cancel(table, index)}>
|
||||||
<a>Cancel</a>
|
<a>Cancel</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<Tooltip placement="topLeft" title="Edit">
|
<Tooltip placement="topLeft" title="Edit">
|
||||||
<Button disabled={this.state.editingIndex !== "" || Setting.builtInObject({owner: this.props.owner, name: this.props.name})} style={{marginRight: "5px"}} icon={<EditOutlined />} size="small" onClick={() => this.edit(record, index)} />
|
<Button disabled={this.state.editingIndex !== "" || Setting.builtInObject(this.props.enforcer)} style={{marginRight: "5px"}} icon={<EditOutlined />} size="small" onClick={() => this.edit(record, index)} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip placement="topLeft" title="Delete">
|
<Tooltip placement="topLeft" title="Delete">
|
||||||
<Button disabled={this.state.editingIndex !== "" || Setting.builtInObject({owner: this.props.owner, name: this.props.name})} style={{marginRight: "5px"}} icon={<DeleteOutlined />} size="small" onClick={() => this.deletePolicy(table, index)} />
|
<Button disabled={this.state.editingIndex !== "" || Setting.builtInObject(this.props.enforcer)} style={{marginRight: "5px"}} icon={<DeleteOutlined />} size="small" onClick={() => this.deletePolicy(table, index)} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}];
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
@ -311,7 +247,7 @@ class PolicyTable extends React.Component {
|
|||||||
loading={this.state.loading}
|
loading={this.state.loading}
|
||||||
title={() => (
|
title={() => (
|
||||||
<div>
|
<div>
|
||||||
<Button disabled={this.state.editingIndex !== "" || Setting.builtInObject({owner: this.props.owner, name: this.props.name})} style={{marginRight: "5px"}} type="primary" size="small" onClick={() => this.addRow(table)}>{i18next.t("general:Add")}</Button>
|
<Button disabled={this.state.editingIndex !== "" || Setting.builtInObject(this.props.enforcer)} style={{marginRight: "5px"}} type="primary" size="small" onClick={() => this.addRow(table)}>{i18next.t("general:Add")}</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@ -321,7 +257,7 @@ class PolicyTable extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Button type="primary" disabled={this.state.editingIndex !== ""} onClick={() => {this.synPolicies();}}>
|
<Button type="primary" disabled={this.state.editingIndex !== ""} onClick={() => {this.getPolicies();}}>
|
||||||
{i18next.t("general:Sync")}
|
{i18next.t("general:Sync")}
|
||||||
</Button>
|
</Button>
|
||||||
{
|
{
|
Loading…
x
Reference in New Issue
Block a user