Skip to content

Commit

Permalink
feat: add casdoor as storage provider (#19)
Browse files Browse the repository at this point in the history
* feat: add casdoor as storage provider

* fix: fix url error

* fix: sort import list
  • Loading branch information
dacongda authored Aug 27, 2024
1 parent d9cc8ee commit c76acc3
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 5 deletions.
207 changes: 207 additions & 0 deletions casdoor/casdoor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
// 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 casdoor

import (
"fmt"
"io"
"net/http"
"net/url"
"os"
"path"
"strings"
"time"

"github.com/casdoor/casdoor-go-sdk/casdoorsdk"
"github.com/casdoor/oss"
)

type Client struct {
*casdoorsdk.Client
Config *Config
Prefix string
CustomDomain string
httpClient *http.Client
}

type Config struct {
AccessID string
AccessKey string
Endpoint string
Certificate string
ApplicationName string
OrganizationName string
Provider string
}

func New(config *Config) *Client {
casdoorClient := casdoorsdk.NewClient(config.Endpoint, config.AccessID, config.AccessKey, config.Certificate, config.OrganizationName, config.ApplicationName)
client := &Client{
casdoorClient,
config,
"",
"",
&http.Client{},
}
provider, err := client.GetProvider(config.Provider)
if err != nil {
panic(err)
}
client.Prefix = path.Join(provider.Bucket, provider.PathPrefix)
client.CustomDomain = provider.Domain
if strings.HasSuffix(client.CustomDomain, "/") {
client.CustomDomain = client.CustomDomain[:len(client.CustomDomain)-1]
}
return client
}

func (client Client) Get(path string) (file *os.File, err error) {
readCloser, err := client.GetStream(path)
if err != nil {
return nil, err
}

defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
return
}
}(readCloser)

if file, err = os.CreateTemp(os.TempDir(), "casdoor"); err != nil {
defer readCloser.Close()
_, err = io.Copy(file, readCloser)
file.Seek(0, 0)
}

return file, err

}

func (client Client) GetStream(path string) (io.ReadCloser, error) {
path, err := client.GetURL(path)
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", path, nil)
if err != nil {
return nil, err
}

resp, err := client.httpClient.Do(req)
if err != nil {
return nil, err
}
//defer func(Body io.ReadCloser) {
// err := Body.Close()
// if err != nil {
// return
// }
//}(resp.Body)

respBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusForbidden {
return nil, fmt.Errorf("%s", string(respBytes))
}

return resp.Body, nil
}

func (client Client) Put(urlPath string, reader io.Reader) (r *oss.Object, err error) {
if seeker, ok := reader.(io.ReadSeeker); ok {
seeker.Seek(0, 0)
}

var buffer []byte
buffer, err = io.ReadAll(reader)

//urlPath = client.transUrl(urlPath)

fileUrl, name, err := client.UploadResource("casdoor-oss", "", "", client.transUrl(urlPath), buffer)

now := time.Now()
return &oss.Object{
Path: fileUrl,
Name: name,
LastModified: &now,
StorageInterface: client,
}, err
}

func (client Client) Delete(path string) error {
name, err := client.getName(path)
if err != nil {
return err
}
_, err = client.DeleteResource(&casdoorsdk.Resource{Application: client.ApplicationName, Provider: client.Config.Provider, Name: name})
return err
}

func (client Client) List(rawPath string) ([]*oss.Object, error) {
var objects []*oss.Object
rawPath, err := client.getName(rawPath)
if err != nil {
return nil, err
}

if strings.HasPrefix(rawPath, "/") {
rawPath = rawPath[1:]
}

resourceList, err := client.GetResources(client.Config.OrganizationName, "casdoor-oss", "provider", client.Config.Provider, "Direct", rawPath)
if err != nil {
return nil, err
}

for _, item := range resourceList {
t, err := time.Parse(time.RFC3339, item.CreatedTime)
if err != nil {
return nil, err
}

objects = append(objects, &oss.Object{
Path: item.Url,
Name: item.Name,
LastModified: &t,
StorageInterface: client,
})
}

return objects, nil
}

func (client Client) GetEndpoint() string {
return client.Config.Endpoint
}

func (client Client) getName(rawPath string) (string, error) {
urlPath, err := url.Parse(client.CustomDomain)
if err != nil {
return "", err
}
return path.Join(urlPath.Path, client.transUrl(rawPath)), nil
}

func (client Client) GetURL(path string) (url string, err error) {
return client.CustomDomain + client.transUrl(path), nil
}

func (client Client) transUrl(urlPath string) string {
return strings.Replace(urlPath, "\\", "/", -1)
}
66 changes: 66 additions & 0 deletions casdoor/casdoor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package casdoor_test

import (
"testing"

"github.com/casdoor/oss/casdoor"
"github.com/casdoor/oss/tests"
)

var client *casdoor.Client

var (
TestCasdoorEndpoint = "https://demo.casdoor.com"
TestClientId = "294b09fbc17f95daf2fe"
TestClientSecret = "dd8982f7046ccba1bbd7851d5c1ece4e52bf039d"
TestCasdoorOrganization = "casbin"
TestCasdoorApplication = "app-vue-python-example"
TestCasdoorProvider = "provider_storage_aliyun_oss"
)

var TestJwtPublicKey = `-----BEGIN CERTIFICATE-----
MIIE+TCCAuGgAwIBAgIDAeJAMA0GCSqGSIb3DQEBCwUAMDYxHTAbBgNVBAoTFENh
c2Rvb3IgT3JnYW5pemF0aW9uMRUwEwYDVQQDEwxDYXNkb29yIENlcnQwHhcNMjEx
MDE1MDgxMTUyWhcNNDExMDE1MDgxMTUyWjA2MR0wGwYDVQQKExRDYXNkb29yIE9y
Z2FuaXphdGlvbjEVMBMGA1UEAxMMQ2FzZG9vciBDZXJ0MIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEAsInpb5E1/ym0f1RfSDSSE8IR7y+lw+RJjI74e5ej
rq4b8zMYk7HeHCyZr/hmNEwEVXnhXu1P0mBeQ5ypp/QGo8vgEmjAETNmzkI1NjOQ
CjCYwUrasO/f/MnI1C0j13vx6mV1kHZjSrKsMhYY1vaxTEP3+VB8Hjg3MHFWrb07
uvFMCJe5W8+0rKErZCKTR8+9VB3janeBz//zQePFVh79bFZate/hLirPK0Go9P1g
OvwIoC1A3sarHTP4Qm/LQRt0rHqZFybdySpyWAQvhNaDFE7mTstRSBb/wUjNCUBD
PTSLVjC04WllSf6Nkfx0Z7KvmbPstSj+btvcqsvRAGtvdsB9h62Kptjs1Yn7GAuo
I3qt/4zoKbiURYxkQJXIvwCQsEftUuk5ew5zuPSlDRLoLByQTLbx0JqLAFNfW3g/
pzSDjgd/60d6HTmvbZni4SmjdyFhXCDb1Kn7N+xTojnfaNkwep2REV+RMc0fx4Gu
hRsnLsmkmUDeyIZ9aBL9oj11YEQfM2JZEq+RVtUx+wB4y8K/tD1bcY+IfnG5rBpw
IDpS262boq4SRSvb3Z7bB0w4ZxvOfJ/1VLoRftjPbLIf0bhfr/AeZMHpIKOXvfz4
yE+hqzi68wdF0VR9xYc/RbSAf7323OsjYnjjEgInUtRohnRgCpjIk/Mt2Kt84Kb0
wn8CAwEAAaMQMA4wDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAn2lf
DKkLX+F1vKRO/5gJ+Plr8P5NKuQkmwH97b8CS2gS1phDyNgIc4/LSdzuf4Awe6ve
C06lVdWSIis8UPUPdjmT2uMPSNjwLxG3QsrimMURNwFlLTfRem/heJe0Zgur9J1M
8haawdSdJjH2RgmFoDeE2r8NVRfhbR8KnCO1ddTJKuS1N0/irHz21W4jt4rxzCvl
2nR42Fybap3O/g2JXMhNNROwZmNjgpsF7XVENCSuFO1jTywLaqjuXCg54IL7XVLG
omKNNNcc8h1FCeKj/nnbGMhodnFWKDTsJcbNmcOPNHo6ixzqMy/Hqc+mWYv7maAG
Jtevs3qgMZ8F9Qzr3HpUc6R3ZYYWDY/xxPisuKftOPZgtH979XC4mdf0WPnOBLqL
2DJ1zaBmjiGJolvb7XNVKcUfDXYw85ZTZQ5b9clI4e+6bmyWqQItlwt+Ati/uFEV
XzCj70B4lALX6xau1kLEpV9O1GERizYRz5P9NJNA7KoO5AVMp9w0DQTkt+LbXnZE
HHnWKy8xHQKZF9sR7YBPGLs/Ac6tviv5Ua15OgJ/8dLRZ/veyFfGo2yZsI+hKVU5
nCCJHBcAyFnm1hdvdwEdH33jDBjNB6ciotJZrf/3VYaIWSalADosHAgMWfXuWP+h
8XKXmzlxuHbTMQYtZPDgspS5aK+S4Q9wb8RRAYo=
-----END CERTIFICATE-----`

func init() {
config := &casdoor.Config{
AccessID: TestClientId,
AccessKey: TestClientSecret,
Endpoint: TestCasdoorEndpoint,
Certificate: TestJwtPublicKey,
ApplicationName: TestCasdoorApplication,
OrganizationName: TestCasdoorOrganization,
Provider: TestCasdoorProvider,
}
client = casdoor.New(config)
}

func TestAll(t *testing.T) {
tests.TestAll(client, t)
}
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/Azure/azure-storage-blob-go v0.15.0
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible
github.com/aws/aws-sdk-go v1.44.4
github.com/casdoor/casdoor-go-sdk v0.50.0
github.com/jinzhu/configor v1.2.1
github.com/qiniu/go-sdk/v7 v7.12.1
golang.org/x/oauth2 v0.13.0
Expand All @@ -21,11 +22,11 @@ require (
github.com/Azure/azure-pipeline-go v0.2.3 // indirect
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/uuid v1.4.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
Expand Down
9 changes: 6 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ github.com/aws/aws-sdk-go v1.44.4 h1:ePN0CVJMdiz2vYUcJH96eyxRrtKGSDMgyhP6rah2OgE
github.com/aws/aws-sdk-go v1.44.4/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/casdoor/casdoor-go-sdk v0.50.0 h1:bUYbz/MzJuWfLKJbJM0+U0YpYewAur+THp5TKnufWZM=
github.com/casdoor/casdoor-go-sdk v0.50.0/go.mod h1:cMnkCQJgMYpgAlgEx8reSt1AVaDIQLcJ1zk5pzBaz+4=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
Expand All @@ -51,6 +53,8 @@ github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
Expand All @@ -77,14 +81,13 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
Expand Down

0 comments on commit c76acc3

Please sign in to comment.