diff --git a/authz/authz.go b/authz/authz.go index 81389723..b3690805 100644 --- a/authz/authz.go +++ b/authz/authz.go @@ -98,6 +98,7 @@ p, *, *, GET, /api/get-organization-names, *, * p, *, *, GET, /api/get-all-objects, *, * p, *, *, GET, /api/get-all-actions, *, * p, *, *, GET, /api/get-all-roles, *, * +p, *, *, GET, /api/run-casbin-command, *, * p, *, *, GET, /api/get-invitation-info, *, * p, *, *, GET, /api/faceid-signin-begin, *, * ` diff --git a/controllers/casbin_api.go b/controllers/casbin_api.go index 0d1a06c8..ab67a6f6 100644 --- a/controllers/casbin_api.go +++ b/controllers/casbin_api.go @@ -17,12 +17,7 @@ package controllers import ( "encoding/json" "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - fileadapter "github.com/casbin/casbin/v2/persist/file-adapter" "github.com/casdoor/casdoor/object" "github.com/casdoor/casdoor/util" ) @@ -332,68 +327,3 @@ func (c *ApiController) GetAllRoles() { c.ResponseOk(roles) } - -// CasbinCli -// @Title CasbinCli -// @Tag Enforcer API -// @Description Call casbin-go-cli -// @Param enforcerId query string false "enforcer id" -// @Success 200 {object} controllers.Response The Response object -// @router /casbin-cli [get] -func (c *ApiController) CasbinCli() { - enforcerId := c.Input().Get("enforcerId") - command := c.Input().Get("command") - args := c.Input().Get("args") - - cliPath, err := filepath.Abs("casbin-go-cli") - if err != nil { - c.ResponseError(err.Error()) - return - } - tmpDir := "./tmp" - modelPath := filepath.Join(tmpDir, "tmpModel.conf") - policyPath := filepath.Join(tmpDir, "tmpPolicy.csv") - - if _, err := os.Stat(tmpDir); os.IsNotExist(err) { - err = os.Mkdir(tmpDir, os.ModePerm) - if err != nil { - c.ResponseError(err.Error()) - return - } - } - - inputArgs := []string{command, "-m", modelPath, "-p", policyPath} - if args != "" { - inputArgs = append(inputArgs, strings.Split(args, " ")...) - } - - enforcer, err := object.GetInitializedEnforcer(enforcerId) - if err != nil { - c.ResponseError(err.Error()) - return - } - - if enforcer == nil { - c.ResponseError(fmt.Sprintf(c.T("enforcer:The enforcer: \"%s\" doesn't exist"), enforcerId)) - return - } - - util.WriteStringToPath(enforcer.GetModel().ToText(), modelPath) - - adapter := fileadapter.NewAdapter(policyPath) - enforcer.SetAdapter(adapter) - err = enforcer.SavePolicy() - if err != nil { - c.ResponseError(err.Error()) - return - } - - casbinCli := exec.Command(cliPath, inputArgs...) - output, err := casbinCli.CombinedOutput() - if err != nil { - c.ResponseError(err.Error()) - return - } - - c.ResponseOk(string(output)) -} diff --git a/controllers/casbin_cli_api.go b/controllers/casbin_cli_api.go new file mode 100644 index 00000000..0a017e24 --- /dev/null +++ b/controllers/casbin_cli_api.go @@ -0,0 +1,66 @@ +// Copyright 2024 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 ( + "fmt" + "os/exec" + "strings" +) + +// RunCasbinCommand +// @Title RunCasbinCommand +// @Tag Enforcer API +// @Description Call Casbin CLI commands +// @Success 200 {object} controllers.Response The Response object +// @router /run-casbin-command [get] +func (c *ApiController) RunCasbinCommand() { + language := c.Input().Get("language") + argString := c.Input().Get("args") + + if language == "" { + language = "go" + } + // use "casbin-go-cli" by default, can be also "casbin-java-cli", "casbin-node-cli", etc. + // the pre-built binary of "casbin-go-cli" can be found at: https://github.com/casbin/casbin-go-cli/releases + binaryName := fmt.Sprintf("casbin-%s-cli", language) + + _, err := exec.LookPath(binaryName) + if err != nil { + c.ResponseError(fmt.Sprintf("executable file: %s not found in PATH", binaryName)) + return + } + + // argString's example: + // enforce -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" "alice" "data1" "read" + // see: https://github.com/jcasbin/casbin-java-cli?tab=readme-ov-file#get-started + args := strings.Split(argString, " ") + + command := exec.Command(binaryName, args...) + outputBytes, err := command.CombinedOutput() + if outputBytes != nil { + output := string(outputBytes) + c.ResponseError(output) + return + } + + if err != nil { + c.ResponseError(err.Error()) + return + } + + output := string(outputBytes) + c.ResponseOk(output) +} diff --git a/routers/router.go b/routers/router.go index 93bd7ad6..109c84d2 100644 --- a/routers/router.go +++ b/routers/router.go @@ -173,7 +173,8 @@ func initAPI() { beego.Router("/api/get-all-objects", &controllers.ApiController{}, "GET:GetAllObjects") beego.Router("/api/get-all-actions", &controllers.ApiController{}, "GET:GetAllActions") beego.Router("/api/get-all-roles", &controllers.ApiController{}, "GET:GetAllRoles") - beego.Router("/api/casbin-cli", &controllers.ApiController{}, "GET:CasbinCli") + + beego.Router("/api/run-casbin-command", &controllers.ApiController{}, "GET:RunCasbinCommand") beego.Router("/api/get-sessions", &controllers.ApiController{}, "GET:GetSessions") beego.Router("/api/get-session", &controllers.ApiController{}, "GET:GetSingleSession")