Browse Source

feat: support Casdoor storage API (#594)

* feat: Casdoor storage API

* chore: fmt casdoor.go using gofumpt

* feat: add global casdoor config variables
HEAD
WintBit GitHub 2 years ago
parent
commit
789241364c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 215 additions and 9 deletions
  1. +5
    -3
      casdoor/adapter.go
  2. +38
    -0
      casdoor/resource_adaptor.go
  3. +1
    -1
      go.mod
  4. +2
    -2
      go.sum
  5. +75
    -0
      storage/casdoor.go
  6. +28
    -0
      storage/storage.go
  7. +60
    -3
      storage/storage_test.go
  8. +6
    -0
      util/string.go

+ 5
- 3
casdoor/adapter.go View File

@@ -23,8 +23,9 @@ import (
)

var (
adapter *Adapter = nil
CasdoorOrganization string
adapter *Adapter = nil
Organization string
Application string
)

type Session struct {
@@ -41,7 +42,8 @@ func InitCasdoorAdapter() {

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.


+ 38
- 0
casdoor/resource_adaptor.go View File

@@ -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)
}
}

+ 1
- 1
go.mod View File

@@ -7,7 +7,7 @@ require (
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible
github.com/astaxie/beego v1.12.3
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/go-sql-driver/mysql v1.6.0
github.com/google/uuid v1.3.0


+ 2
- 2
go.sum View File

@@ -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/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
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.9.1/go.mod h1:MBed3ISHQfXTtoOCAk5T8l5lt4wFvsyynrw0awggydY=
github.com/casdoor/casdoor-go-sdk v0.25.0 h1:hrx10mgpLgWqNsgFKQN/ljJsnD1i0cytW+S+2XxmxyQ=
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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=


+ 75
- 0
storage/casdoor.go View File

@@ -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
}

+ 28
- 0
storage/storage.go View File

@@ -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
}
}

+ 60
- 3
storage/storage_test.go View File

@@ -15,13 +15,70 @@
//go: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) {
_, err := ListObjects("casibase", "")
_, err := storage.ListObjects("casibase", "")
if err != nil {
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)
}
}

+ 6
- 0
util/string.go View File

@@ -93,6 +93,12 @@ func GetOwnerAndNameFromId3New(id string) (string, string, string) {
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 {
return fmt.Sprintf("%s/%s", owner, name)
}


Loading…
Cancel
Save