From 8c6f0a31b6a1c075510387c63f321b3e8668ecc8 Mon Sep 17 00:00:00 2001 From: WindSpiritSR Date: Tue, 10 Aug 2021 10:43:33 +0800 Subject: [PATCH] feat: support storage provider to terms of use file (#221) Signed-off-by: WindSpiritSR --- controllers/account.go | 35 +++++++++++++-------- controllers/application.go | 1 - object/storage.go | 12 ++++++-- web/src/ApplicationEditPage.js | 37 +++++++++++++++++----- web/src/CropperDiv.js | 26 ++++++++++------ web/src/auth/SignupPage.js | 44 ++++++++++++++++++--------- web/src/backend/ApplicationBackend.js | 1 + web/src/backend/UserBackend.js | 9 +----- web/src/locales/en/data.json | 3 ++ 9 files changed, 113 insertions(+), 55 deletions(-) diff --git a/controllers/account.go b/controllers/account.go index c94f6f49..441a77e0 100644 --- a/controllers/account.go +++ b/controllers/account.go @@ -15,7 +15,6 @@ package controllers import ( - "encoding/base64" "encoding/json" "fmt" "strconv" @@ -236,26 +235,38 @@ func (c *ApiController) UploadFile() { c.ResponseError("No storage provider is found") return } - - fileString := c.Ctx.Request.Form.Get("file") - - var fileBytes []byte - pngHeader := "data:image/png;base64," - if strings.HasPrefix(fileString, pngHeader) { - fileBytes, _ = base64.StdEncoding.DecodeString(fileString[len(pngHeader):]) - } else { - fileBytes = []byte(fileString) + file, header, err := c.GetFile("file") + defer file.Close() + if err != nil { + c.ResponseError("Missing parameter") + return } - fileUrl, err := object.UploadFile(provider, folder, subFolder, fileBytes) + fileType := header.Header.Get("Content-Type") + + fileSuffix := "" + switch fileType { + case "image/png": + fileSuffix = "png" + case "text/html": + fileSuffix = "html" + } + + fileUrl, err := object.UploadFile(provider, folder, subFolder, file, fileSuffix) if err != nil { c.ResponseError(err.Error()) return } - if folder == "avatar" { + switch folder { + case "avatar": user.Avatar = fileUrl object.UpdateUser(user.GetId(), user) + case "termsofuse": + appId := fmt.Sprintf("admin/%s", strings.Split(subFolder, "/")[0]) + app := object.GetApplication(appId) + app.TermsOfUse = fileUrl + object.UpdateApplication(appId, app) } c.ResponseOk(fileUrl) diff --git a/controllers/application.go b/controllers/application.go index 150e7729..c0f41f12 100644 --- a/controllers/application.go +++ b/controllers/application.go @@ -16,7 +16,6 @@ package controllers import ( "encoding/json" - "github.com/casbin/casdoor/object" ) diff --git a/object/storage.go b/object/storage.go index 205b7f64..b33386bd 100644 --- a/object/storage.go +++ b/object/storage.go @@ -17,13 +17,15 @@ package object import ( "bytes" "fmt" + "io" + "mime/multipart" "strings" "github.com/casbin/casdoor/storage" "github.com/casbin/casdoor/util" ) -func UploadFile(provider *Provider, folder string, subFolder string, fileBytes []byte) (string, error) { +func UploadFile(provider *Provider, folder string, subFolder string, file multipart.File, suffix string) (string, error) { storageProvider := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, provider.Endpoint) if storageProvider == nil { return "", fmt.Errorf("the provider type: %s is not supported", provider.Type) @@ -34,8 +36,12 @@ func UploadFile(provider *Provider, folder string, subFolder string, fileBytes [ UpdateProvider(provider.GetId(), provider) } - path := fmt.Sprintf("%s/%s.png", util.UrlJoin(util.GetUrlPath(provider.Domain), folder), subFolder) - _, err := storageProvider.Put(path, bytes.NewReader(fileBytes)) + path := fmt.Sprintf("%s/%s.%s", util.UrlJoin(util.GetUrlPath(provider.Domain), folder), subFolder, suffix) + fileBuf := bytes.NewBuffer(nil) + if _, err := io.Copy(fileBuf, file); err != nil { + return "", err + } + _, err := storageProvider.Put(path, fileBuf) if err != nil { return "", err } diff --git a/web/src/ApplicationEditPage.js b/web/src/ApplicationEditPage.js index 0d43439b..aef8f885 100644 --- a/web/src/ApplicationEditPage.js +++ b/web/src/ApplicationEditPage.js @@ -13,12 +13,13 @@ // limitations under the License. import React from "react"; -import {Button, Card, Col, Input, Row, Select, Switch} from 'antd'; -import {LinkOutlined} from "@ant-design/icons"; +import {Button, Card, Col, Input, Row, Select, Switch, Upload} from 'antd'; +import {LinkOutlined, UploadOutlined} from "@ant-design/icons"; import * as ApplicationBackend from "./backend/ApplicationBackend"; import * as Setting from "./Setting"; import * as ProviderBackend from "./backend/ProviderBackend"; import * as OrganizationBackend from "./backend/OrganizationBackend"; +import * as UserBackend from "./backend/UserBackend"; import SignupPage from "./auth/SignupPage"; import LoginPage from "./auth/LoginPage"; import i18next from "i18next"; @@ -26,8 +27,6 @@ import UrlTable from "./UrlTable"; import ProviderTable from "./ProviderTable"; import SignupTable from "./SignupTable"; import PromptPage from "./auth/PromptPage"; - -const { TextArea } = Input; const { Option } = Select; class ApplicationEditPage extends React.Component { @@ -39,6 +38,7 @@ class ApplicationEditPage extends React.Component { application: null, organizations: [], providers: [], + uploading: false, }; } @@ -92,6 +92,25 @@ class ApplicationEditPage extends React.Component { }); } + handleUpload(info) { + if (info.file.type !== "text/html") { + Setting.showMessage("error", i18next.t("provider:Please select a HTML file")) + return + } + this.setState({uploading: true}) + UserBackend.uploadFile("termsofuse", `${this.state.applicationName}/termsofuse`, info.file) + .then(res => { + if (res.status === "ok") { + Setting.showMessage("success", i18next.t("general:Upload success")) + this.updateApplicationField("termsOfUse", res.data) + } else { + Setting.showMessage("error", res.msg) + } + }).finally(() => { + this.setState({uploading: false}) + }) + } + renderApplication() { return ( -