feat: support Casdoor storage API (#594)
* feat: Casdoor storage API * chore: fmt casdoor.go using gofumpt * feat: add global casdoor config variables
This commit is contained in:
parent
95db4c2edd
commit
789241364c
|
@ -23,8 +23,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
adapter *Adapter = nil
|
adapter *Adapter = nil
|
||||||
CasdoorOrganization string
|
Organization string
|
||||||
|
Application string
|
||||||
)
|
)
|
||||||
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
|
@ -41,7 +42,8 @@ func InitCasdoorAdapter() {
|
||||||
|
|
||||||
adapter = NewAdapter(beego.AppConfig.String("driverName"), beego.AppConfig.String("dataSourceName"), beego.AppConfig.String("casdoorDbName"))
|
adapter = NewAdapter(beego.AppConfig.String("driverName"), beego.AppConfig.String("dataSourceName"), beego.AppConfig.String("casdoorDbName"))
|
||||||
|
|
||||||
CasdoorOrganization = beego.AppConfig.String("casdoorOrganization")
|
Organization = beego.AppConfig.String("casdoorOrganization")
|
||||||
|
Application = beego.AppConfig.String("casdoorApplication")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adapter represents the MySQL adapter for policy storage.
|
// Adapter represents the MySQL adapter for policy storage.
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package casdoor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego"
|
||||||
|
"github.com/casbin/casibase/util"
|
||||||
|
"github.com/casdoor/casdoor-go-sdk/casdoorsdk"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ListResources(prefix string) ([]*casdoorsdk.Resource, error) {
|
||||||
|
prefix = util.GetIdFromOwnerAndName(fmt.Sprintf("/resource/%s/%s/casibase",
|
||||||
|
beego.AppConfig.String("casdoorOrganization"),
|
||||||
|
beego.AppConfig.String("casdoorApplication")), prefix)
|
||||||
|
|
||||||
|
result := make([]*casdoorsdk.Resource, 0)
|
||||||
|
err := adapter.Engine.Where("name like ?", prefix+"%").Find(&result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetResource(key string) (*casdoorsdk.Resource, error) {
|
||||||
|
id := fmt.Sprintf("/resource/%s/%s/casibase/%s", Organization, Application, key)
|
||||||
|
resource := casdoorsdk.Resource{Owner: Organization, Name: id}
|
||||||
|
existed, err := adapter.Engine.Get(&resource)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if existed {
|
||||||
|
return &resource, nil
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("resource %s not found", key)
|
||||||
|
}
|
||||||
|
}
|
2
go.mod
2
go.mod
|
@ -7,7 +7,7 @@ require (
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible
|
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible
|
||||||
github.com/astaxie/beego v1.12.3
|
github.com/astaxie/beego v1.12.3
|
||||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
|
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
|
||||||
github.com/casdoor/casdoor-go-sdk v0.9.1
|
github.com/casdoor/casdoor-go-sdk v0.25.0
|
||||||
github.com/danaugrs/go-tsne/tsne v0.0.0-20220306155740-2250969e057f
|
github.com/danaugrs/go-tsne/tsne v0.0.0-20220306155740-2250969e057f
|
||||||
github.com/go-sql-driver/mysql v1.6.0
|
github.com/go-sql-driver/mysql v1.6.0
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -705,8 +705,8 @@ github.com/calebcase/tmpfile v1.0.3 h1:BZrOWZ79gJqQ3XbAQlihYZf/YCV0H4KPIdM5K5oMp
|
||||||
github.com/calebcase/tmpfile v1.0.3/go.mod h1:UAUc01aHeC+pudPagY/lWvt2qS9ZO5Zzof6/tIUzqeI=
|
github.com/calebcase/tmpfile v1.0.3/go.mod h1:UAUc01aHeC+pudPagY/lWvt2qS9ZO5Zzof6/tIUzqeI=
|
||||||
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
||||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||||
github.com/casdoor/casdoor-go-sdk v0.9.1 h1:z+5nJ4IvP9cNUodLf8wS42AYtDoUCvN6McRB5M+1SAQ=
|
github.com/casdoor/casdoor-go-sdk v0.25.0 h1:hrx10mgpLgWqNsgFKQN/ljJsnD1i0cytW+S+2XxmxyQ=
|
||||||
github.com/casdoor/casdoor-go-sdk v0.9.1/go.mod h1:MBed3ISHQfXTtoOCAk5T8l5lt4wFvsyynrw0awggydY=
|
github.com/casdoor/casdoor-go-sdk v0.25.0/go.mod h1:MBed3ISHQfXTtoOCAk5T8l5lt4wFvsyynrw0awggydY=
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego"
|
||||||
|
"github.com/casbin/casibase/casdoor"
|
||||||
|
"github.com/casbin/casibase/util"
|
||||||
|
"github.com/casdoor/casdoor-go-sdk/casdoorsdk"
|
||||||
|
)
|
||||||
|
|
||||||
|
type casdoorClient struct {
|
||||||
|
Storage
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCasdoorStorage() Storage {
|
||||||
|
return &casdoorClient{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *casdoorClient) Get(key string) (io.ReadCloser, error) {
|
||||||
|
res, err := casdoor.GetResource(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := http.Get(res.Url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.Body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *casdoorClient) Put(user, key string, bytes []byte) error {
|
||||||
|
_, _, err := casdoorsdk.UploadResource(user, "Casibase", "Casibase",
|
||||||
|
fmt.Sprintf("/resource/%s/%s/%s",
|
||||||
|
casdoor.Organization, casdoor.Application, key),
|
||||||
|
bytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *casdoorClient) Delete(key string) error {
|
||||||
|
_, err := casdoorsdk.DeleteResource(util.GetIdFromOwnerAndName(fmt.Sprintf("/resource/%s/%s/casibase",
|
||||||
|
beego.AppConfig.String("casdoorOrganization"),
|
||||||
|
beego.AppConfig.String("casdoorApplication")), key))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *casdoorClient) List(prefix string) ([]*Object, error) {
|
||||||
|
res, err := casdoor.ListResources(prefix)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]*Object, 0)
|
||||||
|
for _, r := range res {
|
||||||
|
created, _ := time.Parse(time.RFC3339, r.CreatedTime)
|
||||||
|
result = append(result, &Object{
|
||||||
|
Key: util.GetNameFromIdNoCheck(r.Name),
|
||||||
|
LastModified: &created,
|
||||||
|
Storage: s,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Storage interface {
|
||||||
|
Get(key string) (io.ReadCloser, error)
|
||||||
|
Put(user, key string, bytes []byte) error
|
||||||
|
Delete(key string) error
|
||||||
|
List(prefix string) ([]*Object, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Object struct {
|
||||||
|
Key string
|
||||||
|
LastModified *time.Time
|
||||||
|
Storage Storage
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStorageProvider(provider string) Storage {
|
||||||
|
switch provider {
|
||||||
|
case "casdoor":
|
||||||
|
return NewCasdoorStorage()
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,13 +15,70 @@
|
||||||
//go:build !skipCi
|
//go:build !skipCi
|
||||||
// +build !skipCi
|
// +build !skipCi
|
||||||
|
|
||||||
package storage
|
package storage_test
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/casbin/casibase/casdoor"
|
||||||
|
"github.com/casbin/casibase/controllers"
|
||||||
|
"github.com/casbin/casibase/storage"
|
||||||
|
)
|
||||||
|
|
||||||
func TestStorage(t *testing.T) {
|
func TestStorage(t *testing.T) {
|
||||||
_, err := ListObjects("casibase", "")
|
_, err := storage.ListObjects("casibase", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCasdoor(t *testing.T) {
|
||||||
|
controllers.InitAuthConfig()
|
||||||
|
casdoor.InitCasdoorAdapter()
|
||||||
|
s := storage.NewCasdoorStorage()
|
||||||
|
|
||||||
|
// Test Put
|
||||||
|
err := s.Put("admin", "test", []byte("test"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test List
|
||||||
|
objs, err := s.List("admin")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, obj := range objs {
|
||||||
|
t.Log(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Get
|
||||||
|
in, err := s.Get("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := io.ReadAll(in)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log(string(bytes))
|
||||||
|
|
||||||
|
// Test Delete
|
||||||
|
err = s.Delete("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
objs, err = s.List("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, obj := range objs {
|
||||||
|
t.Log(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -93,6 +93,12 @@ func GetOwnerAndNameFromId3New(id string) (string, string, string) {
|
||||||
return tokens[0], tokens[1], tokens[2]
|
return tokens[0], tokens[1], tokens[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetNameFromIdNoCheck(id string) string {
|
||||||
|
tokens := strings.Split(id, "/")
|
||||||
|
|
||||||
|
return tokens[len(tokens)-1]
|
||||||
|
}
|
||||||
|
|
||||||
func GetIdFromOwnerAndName(owner string, name string) string {
|
func GetIdFromOwnerAndName(owner string, name string) string {
|
||||||
return fmt.Sprintf("%s/%s", owner, name)
|
return fmt.Sprintf("%s/%s", owner, name)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue