From 31c00a847b8ff31208072390eb4723f18f27107e Mon Sep 17 00:00:00 2001 From: Yang Luo Date: Thu, 18 Aug 2022 22:15:26 +0800 Subject: [PATCH] Add "add permission" button --- casdoor/adapter.go | 75 ++++++++++++++++++++++ casdoor/permission_adapter.go | 95 ++++++++++++++++++++++++++++ conf/app.conf | 2 + controllers/permission.go | 56 ++++++++++++++++ main.go | 2 + object/adapter.go | 2 +- routers/router.go | 6 ++ storage/storage_test.go | 2 +- web/src/App.js | 7 ++ web/src/FileTree.js | 11 +++- web/src/FileTreePage.js | 2 +- web/src/HomePage.js | 2 +- web/src/PermissionUtil.js | 34 ++++++++++ web/src/StoreEditPage.js | 2 +- web/src/backend/PermissionBackend.js | 49 ++++++++++++++ web/src/locales/en/data.json | 2 + web/src/locales/zh/data.json | 4 +- 17 files changed, 345 insertions(+), 8 deletions(-) create mode 100644 casdoor/adapter.go create mode 100644 casdoor/permission_adapter.go create mode 100644 controllers/permission.go create mode 100644 web/src/PermissionUtil.js create mode 100644 web/src/backend/PermissionBackend.js diff --git a/casdoor/adapter.go b/casdoor/adapter.go new file mode 100644 index 0000000..74bdbc4 --- /dev/null +++ b/casdoor/adapter.go @@ -0,0 +1,75 @@ +package casdoor + +import ( + "runtime" + + "github.com/astaxie/beego" + _ "github.com/go-sql-driver/mysql" + "xorm.io/xorm" +) + +var adapter *Adapter = nil +var CasdoorOrganization string + +type Session struct { + SessionKey string `xorm:"char(64) notnull pk"` + SessionData []uint8 `xorm:"blob"` + SessionExpiry int `xorm:"notnull"` +} + +func InitCasdoorAdapter() { + casdoorDbName := beego.AppConfig.String("casdoorDbName") + if casdoorDbName == "" { + return + } + + adapter = NewAdapter(beego.AppConfig.String("driverName"), beego.AppConfig.String("dataSourceName"), beego.AppConfig.String("casdoorDbName")) + + CasdoorOrganization = beego.AppConfig.String("casdoorOrganization") +} + +// Adapter represents the MySQL adapter for policy storage. +type Adapter struct { + driverName string + dataSourceName string + dbName string + Engine *xorm.Engine +} + +// finalizer is the destructor for Adapter. +func finalizer(a *Adapter) { + err := a.Engine.Close() + if err != nil { + panic(err) + } +} + +// NewAdapter is the constructor for Adapter. +func NewAdapter(driverName string, dataSourceName string, dbName string) *Adapter { + a := &Adapter{} + a.driverName = driverName + a.dataSourceName = dataSourceName + a.dbName = dbName + + // Open the DB, create it if not existed. + a.open() + + // Call the destructor when the object is released. + runtime.SetFinalizer(a, finalizer) + + return a +} + +func (a *Adapter) open() { + Engine, err := xorm.NewEngine(a.driverName, a.dataSourceName+a.dbName) + if err != nil { + panic(err) + } + + a.Engine = Engine +} + +func (a *Adapter) close() { + a.Engine.Close() + a.Engine = nil +} diff --git a/casdoor/permission_adapter.go b/casdoor/permission_adapter.go new file mode 100644 index 0000000..be61ec6 --- /dev/null +++ b/casdoor/permission_adapter.go @@ -0,0 +1,95 @@ +package casdoor + +import ( + "github.com/casbin/casbase/util" + "xorm.io/core" +) + +type Permission 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"` + DisplayName string `xorm:"varchar(100)" json:"displayName"` + + Users []string `xorm:"mediumtext" json:"users"` + Roles []string `xorm:"mediumtext" json:"roles"` + Domains []string `xorm:"mediumtext" json:"domains"` + + Model string `xorm:"varchar(100)" json:"model"` + ResourceType string `xorm:"varchar(100)" json:"resourceType"` + Resources []string `xorm:"mediumtext" json:"resources"` + Actions []string `xorm:"mediumtext" json:"actions"` + Effect string `xorm:"varchar(100)" json:"effect"` + IsEnabled bool `json:"isEnabled"` + + Submitter string `xorm:"varchar(100)" json:"submitter"` + Approver string `xorm:"varchar(100)" json:"approver"` + ApproveTime string `xorm:"varchar(100)" json:"approveTime"` + State string `xorm:"varchar(100)" json:"state"` +} + +func GetPermissions(owner string) []*Permission { + permissions := []*Permission{} + err := adapter.Engine.Desc("created_time").Find(&permissions, &Permission{Owner: owner}) + if err != nil { + panic(err) + } + + return permissions +} + +func getPermission(owner string, name string) *Permission { + if owner == "" || name == "" { + return nil + } + + permission := Permission{Owner: owner, Name: name} + existed, err := adapter.Engine.Get(&permission) + if err != nil { + panic(err) + } + + if existed { + return &permission + } else { + return nil + } +} + +func GetPermission(id string) *Permission { + owner, name := util.GetOwnerAndNameFromId(id) + return getPermission(owner, name) +} + +func UpdatePermission(id string, permission *Permission) bool { + owner, name := util.GetOwnerAndNameFromId(id) + oldPermission := getPermission(owner, name) + if oldPermission == nil { + return false + } + + affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(permission) + if err != nil { + panic(err) + } + + return affected != 0 +} + +func AddPermission(permission *Permission) bool { + affected, err := adapter.Engine.Insert(permission) + if err != nil { + panic(err) + } + + return affected != 0 +} + +func DeletePermission(permission *Permission) bool { + affected, err := adapter.Engine.ID(core.PK{permission.Owner, permission.Name}).Delete(&Permission{}) + if err != nil { + panic(err) + } + + return affected != 0 +} diff --git a/conf/app.conf b/conf/app.conf index cd081a9..6f63195 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -3,6 +3,7 @@ httpport = 14000 runmode = dev SessionOn = true copyrequestbody = true +driverName = mysql dataSourceName = root:123@tcp(localhost:3306)/ dbName = casbase redisEndpoint = @@ -10,5 +11,6 @@ landingFolder = casbase-landing casdoorEndpoint = http://localhost:8000 clientId = af6b5aa958822fb9dc33 clientSecret = 8bc3010c1c951c8d876b1f311a901ff8deeb93bc +casdoorDbName = casdoor casdoorOrganization = "casbin" casdoorApplication = "app-casbase" \ No newline at end of file diff --git a/controllers/permission.go b/controllers/permission.go new file mode 100644 index 0000000..932a120 --- /dev/null +++ b/controllers/permission.go @@ -0,0 +1,56 @@ +package controllers + +import ( + "encoding/json" + + "github.com/casbin/casbase/casdoor" +) + +func (c *ApiController) GetPermissions() { + owner := c.Input().Get("owner") + + c.Data["json"] = casdoor.GetPermissions(owner) + c.ServeJSON() +} + +func (c *ApiController) GetPermission() { + id := c.Input().Get("id") + + c.Data["json"] = casdoor.GetPermission(id) + c.ServeJSON() +} + +func (c *ApiController) UpdatePermission() { + id := c.Input().Get("id") + + var permission casdoor.Permission + err := json.Unmarshal(c.Ctx.Input.RequestBody, &permission) + if err != nil { + panic(err) + } + + c.Data["json"] = casdoor.UpdatePermission(id, &permission) + c.ServeJSON() +} + +func (c *ApiController) AddPermission() { + var permission casdoor.Permission + err := json.Unmarshal(c.Ctx.Input.RequestBody, &permission) + if err != nil { + panic(err) + } + + c.Data["json"] = casdoor.AddPermission(&permission) + c.ServeJSON() +} + +func (c *ApiController) DeletePermission() { + var permission casdoor.Permission + err := json.Unmarshal(c.Ctx.Input.RequestBody, &permission) + if err != nil { + panic(err) + } + + c.Data["json"] = casdoor.DeletePermission(&permission) + c.ServeJSON() +} diff --git a/main.go b/main.go index 13efdc3..075a51c 100644 --- a/main.go +++ b/main.go @@ -4,12 +4,14 @@ import ( "github.com/astaxie/beego" "github.com/astaxie/beego/plugins/cors" _ "github.com/astaxie/beego/session/redis" + "github.com/casbin/casbase/casdoor" "github.com/casbin/casbase/object" "github.com/casbin/casbase/routers" ) func main() { object.InitAdapter() + casdoor.InitCasdoorAdapter() beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{ AllowOrigins: []string{"*"}, diff --git a/object/adapter.go b/object/adapter.go index 693a179..de61ae6 100644 --- a/object/adapter.go +++ b/object/adapter.go @@ -21,7 +21,7 @@ func InitConfig() { } func InitAdapter() { - adapter = NewAdapter("mysql", beego.AppConfig.String("dataSourceName")) + adapter = NewAdapter(beego.AppConfig.String("driverName"), beego.AppConfig.String("dataSourceName")) } // Adapter represents the MySQL adapter for policy storage. diff --git a/routers/router.go b/routers/router.go index 882572e..8e5a4c1 100644 --- a/routers/router.go +++ b/routers/router.go @@ -55,4 +55,10 @@ func initAPI() { beego.Router("/api/update-file", &controllers.ApiController{}, "POST:UpdateFile") beego.Router("/api/add-file", &controllers.ApiController{}, "POST:AddFile") beego.Router("/api/delete-file", &controllers.ApiController{}, "POST:DeleteFile") + + beego.Router("/api/get-permissions", &controllers.ApiController{}, "GET:GetPermissions") + beego.Router("/api/get-permission", &controllers.ApiController{}, "GET:GetPermission") + beego.Router("/api/update-permission", &controllers.ApiController{}, "POST:UpdatePermission") + beego.Router("/api/add-permission", &controllers.ApiController{}, "POST:AddPermission") + beego.Router("/api/delete-permission", &controllers.ApiController{}, "POST:DeletePermission") } diff --git a/storage/storage_test.go b/storage/storage_test.go index aa52d00..e4f1a13 100644 --- a/storage/storage_test.go +++ b/storage/storage_test.go @@ -3,5 +3,5 @@ package storage import "testing" func TestStorage(t *testing.T) { - ListObjects("casbase") + ListObjects("casbase", "") } diff --git a/web/src/App.js b/web/src/App.js index ff63b23..0b90ca2 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -228,6 +228,13 @@ class App extends Component { ); + res.push( + + + {i18next.t("general:Permissions")} + + + ); // res.push( // // diff --git a/web/src/FileTree.js b/web/src/FileTree.js index f2f8bd3..8676d2d 100644 --- a/web/src/FileTree.js +++ b/web/src/FileTree.js @@ -1,11 +1,12 @@ import React from "react"; import {Button, Col, Empty, Input, Popconfirm, Row, Spin, Tooltip, Tree, Upload} from 'antd'; -import {CloudUploadOutlined, createFromIconfontCN, DeleteOutlined, DownloadOutlined, FolderAddOutlined} from "@ant-design/icons"; +import {CloudUploadOutlined, createFromIconfontCN, DeleteOutlined, DownloadOutlined, FileDoneOutlined, FolderAddOutlined} from "@ant-design/icons"; import * as Setting from "./Setting"; import * as FileBackend from "./backend/FileBackend"; import DocViewer, { DocViewerRenderers } from "react-doc-viewer"; import FileViewer from 'react-file-viewer'; import i18next from "i18next"; +import * as PermissionUtil from "./PermissionUtil"; import {Controlled as CodeMirror} from "react-codemirror2"; import "codemirror/lib/codemirror.css"; @@ -286,10 +287,16 @@ class FileTree extends React.Component { okText="OK" cancelText="Cancel" > -