From c08f2b1f3f0fd17c14a7494de8798b740a3ae64c Mon Sep 17 00:00:00 2001 From: DacongDA Date: Tue, 27 Aug 2024 23:54:03 +0800 Subject: [PATCH] feat: support Casdoor storage provider (#3147) * feat: support Casdoor storage provider * fix: fix code format and nil pointer error * feat: change cert if statement --- deployment/deploy.go | 13 ++++++++++++- go.mod | 4 ++-- go.sum | 9 ++++++--- object/storage.go | 19 +++++++++++++++++-- storage/casdoor.go | 19 +++++++++++++++++++ storage/storage.go | 4 +++- web/src/ProviderEditPage.js | 30 +++++++++++++++++++++++------- web/src/Setting.js | 5 +++++ 8 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 storage/casdoor.go diff --git a/deployment/deploy.go b/deployment/deploy.go index d4e5921b..77122e65 100644 --- a/deployment/deploy.go +++ b/deployment/deploy.go @@ -27,7 +27,18 @@ import ( ) func deployStaticFiles(provider *object.Provider) { - storageProvider, err := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, provider.Endpoint) + certificate := "" + if provider.Category == "Storage" && provider.Type == "Casdoor" { + cert, err := object.GetCert(util.GetId(provider.Owner, provider.Cert)) + if err != nil { + panic(err) + } + if cert == nil { + panic(err) + } + certificate = cert.Certificate + } + storageProvider, err := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, provider.Endpoint, certificate, provider.Content) if err != nil { panic(err) } diff --git a/go.mod b/go.mod index 1ef349eb..728d0ac2 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/casdoor/go-sms-sender v0.24.0 github.com/casdoor/gomail/v2 v2.0.1 github.com/casdoor/notify v0.45.0 - github.com/casdoor/oss v1.7.0 + github.com/casdoor/oss v1.8.0 github.com/casdoor/xorm-adapter/v3 v3.1.0 github.com/casvisor/casvisor-go-sdk v1.4.0 github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f @@ -30,7 +30,7 @@ require ( github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible github.com/go-webauthn/webauthn v0.6.0 github.com/golang-jwt/jwt/v4 v4.5.0 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.6.0 github.com/json-iterator/go v1.1.12 github.com/lestrrat-go/jwx v1.2.29 github.com/lib/pq v1.10.9 diff --git a/go.sum b/go.sum index b63841ed..d3652200 100644 --- a/go.sum +++ b/go.sum @@ -1083,6 +1083,8 @@ github.com/casbin/casbin/v2 v2.28.3/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRt github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= github.com/casbin/casbin/v2 v2.77.2 h1:yQinn/w9x8AswiwqwtrXz93VU48R1aYTXdHEx4RI3jM= github.com/casbin/casbin/v2 v2.77.2/go.mod h1:mzGx0hYW9/ksOSpw3wNjk3NRAroq5VMFYUQ6G43iGPk= +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/casdoor/go-reddit/v2 v2.1.0 h1:kIbfdJ7AA7H0uTQ8s0q4GGZqSS5V9wVE74RrXyD9XPs= github.com/casdoor/go-reddit/v2 v2.1.0/go.mod h1:eagkvwlZ4Hcsuc/uQsLHYEulz5jN65SVSwV/AIE7zsc= github.com/casdoor/go-sms-sender v0.24.0 h1:LNLsce3EG/87I3JS6UiajF3LlQmdIiCgebEu0IE4wSM= @@ -1091,8 +1093,8 @@ github.com/casdoor/gomail/v2 v2.0.1 h1:J+FG6x80s9e5lBHUn8Sv0Y56mud34KiWih5YdmudR github.com/casdoor/gomail/v2 v2.0.1/go.mod h1:VnGPslEAtpix5FjHisR/WKB1qvZDBaujbikxDe9d+2Q= github.com/casdoor/notify v0.45.0 h1:OlaFvcQFjGOgA4mRx07M8AH1gvb5xNo21mcqrVGlLgk= github.com/casdoor/notify v0.45.0/go.mod h1:wNHQu0tiDROMBIvz0j3Om3Lhd5yZ+AIfnFb8MYb8OLQ= -github.com/casdoor/oss v1.7.0 h1:VCOuD+CcD0MAA99p6JTyUak14bVR6UsaeyuTaVg0Mrs= -github.com/casdoor/oss v1.7.0/go.mod h1:rJAWA0hLhtu94t6IRpotLUkXO1NWMASirywQYaGizJE= +github.com/casdoor/oss v1.8.0 h1:uuyKhDIp7ydOtV4lpqhAY23Ban2Ln8La8+QT36CwylM= +github.com/casdoor/oss v1.8.0/go.mod h1:uaqO7KBI2lnZcnB8rF7O6C2bN7llIbfC5Ql8ex1yR1U= github.com/casdoor/xorm-adapter/v3 v3.1.0 h1:NodWayRtSLVSeCvL9H3Hc61k0G17KhV9IymTCNfh3kk= github.com/casdoor/xorm-adapter/v3 v3.1.0/go.mod h1:4WTcUw+bTgBylGHeGHzTtBvuTXRS23dtwzFLl9tsgFM= github.com/casvisor/casvisor-go-sdk v1.4.0 h1:hbZEGGJ1cwdHFAxeXrMoNw6yha6Oyg2F0qQhBNCN/dg= @@ -1460,8 +1462,9 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/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.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= diff --git a/object/storage.go b/object/storage.go index cdf3fb67..fcfb8e92 100644 --- a/object/storage.go +++ b/object/storage.go @@ -117,7 +117,18 @@ func GetUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool func getStorageProvider(provider *Provider, lang string) (oss.StorageInterface, error) { endpoint := getProviderEndpoint(provider) - storageProvider, err := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint) + certificate := "" + if provider.Category == "Storage" && provider.Type == "Casdoor" { + cert, err := GetCert(util.GetId(provider.Owner, provider.Cert)) + if err != nil { + return nil, err + } + if cert == nil { + return nil, fmt.Errorf("no cert for %s", provider.Cert) + } + certificate = cert.Certificate + } + storageProvider, err := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint, certificate, provider.Content) if err != nil { return nil, err } @@ -145,11 +156,15 @@ func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffe fileUrl, objectKey := GetUploadFileUrl(provider, fullFilePath, true) objectKeyRefined := refineObjectKey(provider, objectKey) - _, err = storageProvider.Put(objectKeyRefined, fileBuffer) + object, err := storageProvider.Put(objectKeyRefined, fileBuffer) if err != nil { return "", "", err } + if provider.Type == "Casdoor" { + fileUrl = object.Path + } + return fileUrl, objectKey, nil } diff --git a/storage/casdoor.go b/storage/casdoor.go new file mode 100644 index 00000000..40c9d7ba --- /dev/null +++ b/storage/casdoor.go @@ -0,0 +1,19 @@ +package storage + +import ( + "github.com/casdoor/oss" + "github.com/casdoor/oss/casdoor" +) + +func NewCasdoorStorageProvider(providerType string, clientId string, clientSecret string, region string, bucket string, endpoint string, cert string, content string) oss.StorageInterface { + sp := casdoor.New(&casdoor.Config{ + clientId, + clientSecret, + endpoint, + cert, + region, + content, + bucket, + }) + return sp +} diff --git a/storage/storage.go b/storage/storage.go index bf0a09f4..4d129fa3 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -16,7 +16,7 @@ package storage import "github.com/casdoor/oss" -func GetStorageProvider(providerType string, clientId string, clientSecret string, region string, bucket string, endpoint string) (oss.StorageInterface, error) { +func GetStorageProvider(providerType string, clientId string, clientSecret string, region string, bucket string, endpoint string, cert string, content string) (oss.StorageInterface, error) { switch providerType { case "Local File System": return NewLocalFileSystemStorageProvider(), nil @@ -36,6 +36,8 @@ func GetStorageProvider(providerType string, clientId string, clientSecret strin return NewGoogleCloudStorageProvider(clientSecret, bucket, endpoint), nil case "Synology": return NewSynologyNasStorageProvider(clientId, clientSecret, endpoint), nil + case "Casdoor": + return NewCasdoorStorageProvider(providerType, clientId, clientSecret, region, bucket, endpoint, cert, content), nil } return nil, nil diff --git a/web/src/ProviderEditPage.js b/web/src/ProviderEditPage.js index 71350702..77cc69dd 100644 --- a/web/src/ProviderEditPage.js +++ b/web/src/ProviderEditPage.js @@ -843,7 +843,7 @@ class ProviderEditPage extends React.Component { ) } { - this.state.provider.type !== "ADFS" && this.state.provider.type !== "AzureAD" && this.state.provider.type !== "AzureADB2C" && this.state.provider.type !== "Casdoor" && this.state.provider.type !== "Okta" ? null : ( + this.state.provider.type !== "ADFS" && this.state.provider.type !== "AzureAD" && this.state.provider.type !== "AzureADB2C" && (this.state.provider.type !== "Casdoor" && this.state.category !== "Storage") && this.state.provider.type !== "Okta" ? null : ( {Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} : @@ -870,7 +870,7 @@ class ProviderEditPage extends React.Component { )} - {["Custom HTTP SMS", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology"].includes(this.state.provider.type) ? null : ( + {["Custom HTTP SMS", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology", "Casdoor"].includes(this.state.provider.type) ? null : ( {Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} : @@ -885,7 +885,9 @@ class ProviderEditPage extends React.Component { {["Custom HTTP SMS", "Local File System"].includes(this.state.provider.type) ? null : ( - {Setting.getLabel(i18next.t("provider:Bucket"), i18next.t("provider:Bucket - Tooltip"))} : + {["Casdoor"].includes(this.state.provider.type) ? + Setting.getLabel(i18next.t("general:Provider"), i18next.t("provider:Provider - Tooltip")) + : Setting.getLabel(i18next.t("provider:Bucket"), i18next.t("provider:Bucket - Tooltip"))} : { @@ -906,7 +908,7 @@ class ProviderEditPage extends React.Component { )} - {["Custom HTTP SMS", "Qiniu Cloud Kodo", "Synology"].includes(this.state.provider.type) ? null : ( + {["Custom HTTP SMS", "Qiniu Cloud Kodo", "Synology", "Casdoor"].includes(this.state.provider.type) ? null : ( {Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} : @@ -918,10 +920,24 @@ class ProviderEditPage extends React.Component { )} - {["AWS S3", "Tencent Cloud COS", "Qiniu Cloud Kodo"].includes(this.state.provider.type) ? ( + {["Casdoor"].includes(this.state.provider.type) ? ( - {Setting.getLabel(i18next.t("provider:Region ID"), i18next.t("provider:Region ID - Tooltip"))} : + {Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} : + + + { + this.updateProviderField("content", e.target.value); + }} /> + + + ) : null} + {["AWS S3", "Tencent Cloud COS", "Qiniu Cloud Kodo", "Casdoor"].includes(this.state.provider.type) ? ( + + + {["Casdoor"].includes(this.state.provider.type) ? + Setting.getLabel(i18next.t("general:Application"), i18next.t("general:Application - Tooltip")) : + Setting.getLabel(i18next.t("provider:Region ID"), i18next.t("provider:Region ID - Tooltip"))} : { @@ -1298,7 +1314,7 @@ class ProviderEditPage extends React.Component { ) : null } { - (this.state.provider.type === "Alipay" || this.state.provider.type === "WeChat Pay") ? ( + (this.state.provider.type === "Alipay" || this.state.provider.type === "WeChat Pay" || this.state.provider.type === "Casdoor") ? ( {Setting.getLabel(i18next.t("general:Cert"), i18next.t("general:Cert - Tooltip"))} : diff --git a/web/src/Setting.js b/web/src/Setting.js index d30aed8c..11fdf416 100644 --- a/web/src/Setting.js +++ b/web/src/Setting.js @@ -229,6 +229,10 @@ export const OtherProviderInfo = { logo: `${StaticBaseUrl}/img/social_synology.png`, url: "https://www.synology.com/en-global/dsm/feature/file_sharing", }, + "Casdoor": { + logo: `${StaticBaseUrl}/img/casdoor.png`, + url: "https://casdoor.org/docs/provider/storage/overview", + }, }, SAML: { "Aliyun IDaaS": { @@ -1062,6 +1066,7 @@ export function getProviderTypeOptions(category) { {id: "Qiniu Cloud Kodo", name: "Qiniu Cloud Kodo"}, {id: "Google Cloud Storage", name: "Google Cloud Storage"}, {id: "Synology", name: "Synology"}, + {id: "Casdoor", name: "Casdoor"}, ] ); } else if (category === "SAML") {