fix: remove model in adapter page (#2161)

This commit is contained in:
Yaodong Yu 2023-07-29 23:42:08 +08:00 committed by GitHub
parent ea10f8e615
commit 026fb207b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 53 additions and 121 deletions

View File

@ -145,7 +145,7 @@ func (c *ApiController) DeleteAdapter() {
c.ServeJSON()
}
func (c *ApiController) SyncPolicies() {
func (c *ApiController) GetPolicies() {
id := c.Input().Get("id")
adapter, err := object.GetAdapter(id)
if err != nil {
@ -153,7 +153,7 @@ func (c *ApiController) SyncPolicies() {
return
}
policies, err := object.SyncPolicies(adapter)
policies, err := object.GetPolicies(adapter)
if err != nil {
c.ResponseError(err.Error())
return

View File

@ -18,7 +18,6 @@ import (
"fmt"
"strings"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/util"
@ -31,9 +30,7 @@ type Adapter struct {
Name string `xorm:"varchar(100) notnull pk" json:"name"`
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
Type string `xorm:"varchar(100)" json:"type"`
Model string `xorm:"varchar(100)" json:"model"`
Type string `xorm:"varchar(100)" json:"type"`
DatabaseType string `xorm:"varchar(100)" json:"databaseType"`
Host string `xorm:"varchar(100)" json:"host"`
Port string `xorm:"varchar(20)" json:"port"`
@ -46,7 +43,7 @@ type Adapter struct {
IsEnabled bool `json:"isEnabled"`
Adapter *xormadapter.Adapter `xorm:"-" json:"-"`
*xormadapter.Adapter `xorm:"-" json:"-"`
}
func GetAdapterCount(owner, field, value string) (int64, error) {
@ -153,46 +150,7 @@ func (adapter *Adapter) getTable() string {
}
}
func initEnforcer(modelObj *Model, adapter *Adapter) (*casbin.Enforcer, error) {
// init Adapter
if adapter.Adapter == nil {
var dataSourceName string
if adapter.DatabaseType == "mssql" {
dataSourceName = fmt.Sprintf("sqlserver://%s:%s@%s:%s?database=%s", adapter.User, adapter.Password, adapter.Host, adapter.Port, adapter.Database)
} else if adapter.DatabaseType == "postgres" {
dataSourceName = fmt.Sprintf("user=%s password=%s host=%s port=%s sslmode=disable dbname=%s", adapter.User, adapter.Password, adapter.Host, adapter.Port, adapter.Database)
} else {
dataSourceName = fmt.Sprintf("%s:%s@tcp(%s:%s)/", adapter.User, adapter.Password, adapter.Host, adapter.Port)
}
if !isCloudIntranet {
dataSourceName = strings.ReplaceAll(dataSourceName, "dbi.", "db.")
}
var err error
adapter.Adapter, err = xormadapter.NewAdapterByEngineWithTableName(NewAdapter(adapter.DatabaseType, dataSourceName, adapter.Database).Engine, adapter.getTable(), "")
if err != nil {
return nil, err
}
}
// init Model
m, err := model.NewModelFromString(modelObj.ModelText)
if err != nil {
return nil, err
}
// init Enforcer
enforcer, err := casbin.NewEnforcer(m, adapter.Adapter)
if err != nil {
return nil, err
}
return enforcer, nil
}
func (adapter *Adapter) initAdapter() (*xormadapter.Adapter, error) {
// init Adapter
func (adapter *Adapter) initAdapter() error {
if adapter.Adapter == nil {
var dataSourceName string
@ -215,7 +173,7 @@ func (adapter *Adapter) initAdapter() (*xormadapter.Adapter, error) {
case "sqlite3":
dataSourceName = fmt.Sprintf("file:%s", adapter.File)
default:
return nil, fmt.Errorf("unsupported database type: %s", adapter.DatabaseType)
return fmt.Errorf("unsupported database type: %s", adapter.DatabaseType)
}
}
@ -226,10 +184,10 @@ func (adapter *Adapter) initAdapter() (*xormadapter.Adapter, error) {
var err error
adapter.Adapter, err = xormadapter.NewAdapterByEngineWithTableName(NewAdapter(adapter.DatabaseType, dataSourceName, adapter.Database).Engine, adapter.getTable(), adapter.TableNamePrefix)
if err != nil {
return nil, err
return err
}
}
return adapter.Adapter, nil
return nil
}
func adapterChangeTrigger(oldName string, newName string) error {
@ -279,41 +237,36 @@ func matrixToCasbinRules(Ptype string, policies [][]string) []*xormadapter.Casbi
return res
}
func SyncPolicies(adapter *Adapter) ([]*xormadapter.CasbinRule, error) {
modelObj, err := getModel(adapter.Owner, adapter.Model)
func GetPolicies(adapter *Adapter) ([]*xormadapter.CasbinRule, error) {
err := adapter.initAdapter()
if err != nil {
return nil, err
}
if modelObj == nil {
return nil, fmt.Errorf("The model: %s does not exist", util.GetId(adapter.Owner, adapter.Model))
}
enforcer, err := initEnforcer(modelObj, adapter)
casbinModel := getModelDef()
err = adapter.LoadPolicy(casbinModel)
if err != nil {
return nil, err
}
policies := matrixToCasbinRules("p", enforcer.GetPolicy())
if strings.Contains(modelObj.ModelText, "[role_definition]") {
policies = append(policies, matrixToCasbinRules("g", enforcer.GetGroupingPolicy())...)
}
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) {
modelObj, err := getModel(adapter.Owner, adapter.Model)
err := adapter.initAdapter()
if err != nil {
return false, err
}
enforcer, err := initEnforcer(modelObj, adapter)
casbinModel := getModelDef()
err = adapter.LoadPolicy(casbinModel)
if err != nil {
return false, err
}
affected, err := enforcer.UpdatePolicy(oldPolicy, newPolicy)
affected := casbinModel.UpdatePolicy("p", "p", oldPolicy, newPolicy)
if err != nil {
return affected, err
}
@ -321,39 +274,38 @@ func UpdatePolicy(oldPolicy, newPolicy []string, adapter *Adapter) (bool, error)
}
func AddPolicy(policy []string, adapter *Adapter) (bool, error) {
modelObj, err := getModel(adapter.Owner, adapter.Model)
err := adapter.initAdapter()
if err != nil {
return false, err
}
enforcer, err := initEnforcer(modelObj, adapter)
casbinModel := getModelDef()
err = adapter.LoadPolicy(casbinModel)
if err != nil {
return false, err
}
affected, err := enforcer.AddPolicy(policy)
if err != nil {
return affected, err
}
return affected, nil
casbinModel.AddPolicy("p", "p", policy)
return true, nil
}
func RemovePolicy(policy []string, adapter *Adapter) (bool, error) {
modelObj, err := getModel(adapter.Owner, adapter.Model)
err := adapter.initAdapter()
if err != nil {
return false, err
}
enforcer, err := initEnforcer(modelObj, adapter)
casbinModel := getModelDef()
err = adapter.LoadPolicy(casbinModel)
if err != nil {
return false, err
}
affected, err := enforcer.RemovePolicy(policy)
affected := casbinModel.RemovePolicy("p", "p", policy)
if err != nil {
return affected, err
}
return affected, nil
}
@ -364,3 +316,10 @@ func (adapter *Adapter) buildInAdapter() bool {
return adapter.Name == "permission-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
}

View File

@ -144,17 +144,17 @@ func (enforcer *Enforcer) InitEnforcer() (*casbin.Enforcer, error) {
return nil, errors.New("adapter not found")
}
casbinModel, err := m.initModel()
err = m.initModel()
if err != nil {
return nil, err
}
adapter, err := a.initAdapter()
err = a.initAdapter()
if err != nil {
return nil, err
}
e, err := casbin.NewEnforcer(casbinModel, adapter)
e, err := casbin.NewEnforcer(m.Model, a.Adapter)
if err != nil {
return nil, err
}

View File

@ -31,6 +31,8 @@ type Model struct {
ModelText string `xorm:"mediumtext" json:"modelText"`
IsEnabled bool `json:"isEnabled"`
model.Model `xorm:"-" json:"-"`
}
func GetModelCount(owner, field, value string) (int64, error) {
@ -176,10 +178,14 @@ func HasRoleDefinition(m model.Model) bool {
return m["g"] != nil
}
func (m *Model) initModel() (model.Model, error) {
casbinModel, err := model.NewModelFromString(m.ModelText)
if err != nil {
return nil, err
func (m *Model) initModel() error {
if m.Model == nil {
casbinModel, err := model.NewModelFromString(m.ModelText)
if err != nil {
return err
}
m.Model = casbinModel
}
return casbinModel, nil
return nil
}

View File

@ -122,7 +122,7 @@ func initAPI() {
beego.Router("/api/update-adapter", &controllers.ApiController{}, "POST:UpdateAdapter")
beego.Router("/api/add-adapter", &controllers.ApiController{}, "POST:AddAdapter")
beego.Router("/api/delete-adapter", &controllers.ApiController{}, "POST:DeleteAdapter")
beego.Router("/api/sync-policies", &controllers.ApiController{}, "GET:SyncPolicies")
beego.Router("/api/get-policies", &controllers.ApiController{}, "GET:GetPolicies")
beego.Router("/api/update-policy", &controllers.ApiController{}, "POST:UpdatePolicy")
beego.Router("/api/add-policy", &controllers.ApiController{}, "POST:AddPolicy")
beego.Router("/api/remove-policy", &controllers.ApiController{}, "POST:RemovePolicy")

View File

@ -20,7 +20,6 @@ import * as Setting from "./Setting";
import i18next from "i18next";
import "codemirror/lib/codemirror.css";
import * as ModelBackend from "./backend/ModelBackend";
import PolicyTable from "./table/PoliciyTable";
require("codemirror/theme/material-darker.css");
require("codemirror/mode/javascript/javascript");
@ -36,7 +35,6 @@ class AdapterEditPage extends React.Component {
adapterName: props.match.params.adapterName,
adapter: null,
organizations: [],
models: [],
mode: props.location.mode !== undefined ? props.location.mode : "edit",
};
}
@ -58,8 +56,6 @@ class AdapterEditPage extends React.Component {
this.setState({
adapter: res.data,
});
this.getModels(this.state.organizationName);
}
});
}
@ -73,20 +69,6 @@ class AdapterEditPage extends React.Component {
});
}
getModels(organizationName) {
ModelBackend.getModels(organizationName)
.then((res) => {
if (res.status === "error") {
Setting.showMessage("error", res.msg);
return;
}
this.setState({
models: res.data,
});
});
}
parseAdapterField(key, value) {
// if ([].includes(key)) {
// value = Setting.myParseInt(value);
@ -187,7 +169,6 @@ class AdapterEditPage extends React.Component {
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} disabled={!Setting.isAdminUser(this.props.account) || Setting.builtInObject(this.state.adapter)} value={this.state.adapter.owner} onChange={(value => {
this.getModels(value);
this.updateAdapterField("owner", value);
})}>
{
@ -266,20 +247,6 @@ class AdapterEditPage extends React.Component {
}} />
</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.adapter.model} onChange={(model => {
this.updateAdapterField("model", model);
})}>
{
this.state.models.map((model, index) => <Option key={index} value={model.name}>{model.name}</Option>)
}
</Select>
</Col>
</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"))} :

View File

@ -103,8 +103,8 @@ export function RemovePolicy(owner, name, policy) {
}).then(res => res.json());
}
export function syncPolicies(owner, name) {
return fetch(`${Setting.ServerUrl}/api/sync-policies?id=${owner}/${encodeURIComponent(name)}`, {
export function getPolicies(owner, name) {
return fetch(`${Setting.ServerUrl}/api/get-policies?id=${owner}/${encodeURIComponent(name)}`, {
method: "GET",
credentials: "include",
headers: {

View File

@ -102,7 +102,7 @@ class PolicyTable extends React.Component {
synPolicies() {
this.setState({loading: true});
AdapterBackend.syncPolicies(this.props.owner, this.props.name)
AdapterBackend.getPolicies(this.props.owner, this.props.name)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("adapter:Sync policies successfully"));