Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File upload component for azure blob #12530

Draft
wants to merge 20 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
24e37e1
Azure Blob Storage integration
melohagan Dec 8, 2023
cee9152
Azure Storage File upload
melohagan Dec 8, 2023
568a5e3
Refactor manifest
melohagan Dec 8, 2023
84fe660
Merge branch 'master' into budi-5550-file-upload-component-for-azure-…
melohagan Dec 8, 2023
01f2159
Merge branch 'master' into budi-5550-file-upload-component-for-azure-…
melohagan Jan 3, 2024
e425479
Merge branch 'master' into budi-5550-file-upload-component-for-azure-…
melohagan Jan 3, 2024
a3ecdb4
Merge branch 'master' into budi-5550-file-upload-component-for-azure-…
melohagan Jan 4, 2024
ad036b7
Merge branch 'master' into budi-5550-file-upload-component-for-azure-…
melohagan Feb 12, 2024
b7ccc20
Merge branch 'master' into budi-5550-file-upload-component-for-azure-…
melohagan Feb 14, 2024
52ebc05
update account portal
melohagan Feb 14, 2024
c69175c
Merge branch 'master' into budi-5550-file-upload-component-for-azure-…
melohagan Feb 27, 2024
0344bef
update account portal
melohagan Feb 27, 2024
3130202
Add free_trial to deploy camunda script
melohagan Apr 26, 2024
38ffeb5
Merge branch 'master' of https://github.com/Budibase/budibase
melohagan Apr 26, 2024
488f8cb
Merge branch 'master' of https://github.com/Budibase/budibase
melohagan May 3, 2024
316eaee
Merge branch 'master' of https://github.com/Budibase/budibase
melohagan May 3, 2024
a8d0fd3
Merge branch 'master' of https://github.com/Budibase/budibase
melohagan May 7, 2024
4173761
Merge branch 'master' of https://github.com/Budibase/budibase
melohagan May 8, 2024
49b24b7
Merge branch 'master' into budi-5550-file-upload-component-for-azure-…
melohagan May 8, 2024
c139c6f
Fix types
melohagan May 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/account-portal
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<script>
export let width = "100"
export let height = "100"
</script>

<svg xmlns="http://www.w3.org/2000/svg" {width} {height} viewBox="0 0 96 96">
<defs>
<linearGradient
id="e399c19f-b68f-429d-b176-18c2117ff73c"
x1="-1032.172"
x2="-1059.213"
y1="145.312"
y2="65.426"
gradientTransform="matrix(1 0 0 -1 1075 158)"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#114a8b" />
<stop offset="1" stop-color="#0669bc" />
</linearGradient>
<linearGradient
id="ac2a6fc2-ca48-4327-9a3c-d4dcc3256e15"
x1="-1023.725"
x2="-1029.98"
y1="108.083"
y2="105.968"
gradientTransform="matrix(1 0 0 -1 1075 158)"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-opacity=".3" />
<stop offset=".071" stop-opacity=".2" />
<stop offset=".321" stop-opacity=".1" />
<stop offset=".623" stop-opacity=".05" />
<stop offset="1" stop-opacity="0" />
</linearGradient>
<linearGradient
id="a7fee970-a784-4bb1-af8d-63d18e5f7db9"
x1="-1027.165"
x2="-997.482"
y1="147.642"
y2="68.561"
gradientTransform="matrix(1 0 0 -1 1075 158)"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#3ccbf4" />
<stop offset="1" stop-color="#2892df" />
</linearGradient>
</defs>
<path
fill="url(#e399c19f-b68f-429d-b176-18c2117ff73c)"
d="M33.338 6.544h26.038l-27.03 80.087a4.152 4.152 0 0 1-3.933 2.824H8.149a4.145 4.145 0 0 1-3.928-5.47L29.404 9.368a4.152 4.152 0 0 1 3.934-2.825z"
/>
<path
fill="#0078d4"
d="M71.175 60.261h-41.29a1.911 1.911 0 0 0-1.305 3.309l26.532 24.764a4.171 4.171 0 0 0 2.846 1.121h23.38z"
/>
<path
fill="url(#ac2a6fc2-ca48-4327-9a3c-d4dcc3256e15)"
d="M33.338 6.544a4.118 4.118 0 0 0-3.943 2.879L4.252 83.917a4.14 4.14 0 0 0 3.908 5.538h20.787a4.443 4.443 0 0 0 3.41-2.9l5.014-14.777 17.91 16.705a4.237 4.237 0 0 0 2.666.972H81.24L71.024 60.261l-29.781.007L59.47 6.544z"
/>
<path
fill="url(#a7fee970-a784-4bb1-af8d-63d18e5f7db9)"
d="M66.595 9.364a4.145 4.145 0 0 0-3.928-2.82H33.648a4.146 4.146 0 0 1 3.928 2.82l25.184 74.62a4.146 4.146 0 0 1-3.928 5.472h29.02a4.146 4.146 0 0 0 3.927-5.472z"
/>
</svg>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import GoogleSheets from "./GoogleSheets.svelte"
import Firebase from "./Firebase.svelte"
import Redis from "./Redis.svelte"
import Snowflake from "./Snowflake.svelte"
import Azure from "./Azure.svelte"
import Custom from "./Custom.svelte"
import { integrations } from "stores/builder"
import { get } from "svelte/store"
Expand All @@ -28,6 +29,7 @@ const ICONS = {
COUCHDB: CouchDB,
SQL_SERVER: SqlServer,
S3: S3,
AZURE: Azure,
AIRTABLE: Airtable,
MYSQL: MySQL,
ARANGODB: ArangoDB,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Checkbox, Select, RadioGroup, Stepper, Input } from "@budibase/bbui"
import { licensing } from "stores/portal"
import { get } from "svelte/store"
import DataSourceSelect from "./controls/DataSourceSelect/DataSourceSelect.svelte"
import S3DataSourceSelect from "./controls/S3DataSourceSelect.svelte"
import ObjectStoreSelect from "./controls/ObjectStoreSelect.svelte"
import DataProviderSelect from "./controls/DataProviderSelect.svelte"
import ButtonActionEditor from "./controls/ButtonActionEditor/ButtonActionEditor.svelte"
import TableSelect from "./controls/TableSelect.svelte"
Expand Down Expand Up @@ -37,7 +37,7 @@ const componentMap = {
select: Select,
radio: RadioGroup,
dataSource: DataSourceSelect,
"dataSource/s3": S3DataSourceSelect,
"dataSource/objectStore": ObjectStoreSelect,
dataProvider: DataProviderSelect,
boolean: Checkbox,
number: Stepper,
Expand Down Expand Up @@ -70,6 +70,7 @@ const componentMap = {
"field/longform": FormFieldSelect,
"field/datetime": FormFieldSelect,
"field/attachment": FormFieldSelect,
"field/upload": Input,
"field/attachment_single": FormFieldSelect,
"field/s3": Input,
"field/link": FormFieldSelect,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
export let parameters

$: components = findAllMatchingComponents($selectedScreen?.props, component =>
component._component.endsWith("s3upload")
component._component.endsWith("fileupload")
)
</script>

<div class="root">
<Label small>S3 Upload Component</Label>
<Label small>File Upload Component</Label>
<Select
bind:value={parameters.componentId}
options={components}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export { default as ChangeFormStep } from "./ChangeFormStep.svelte"
export { default as UpdateState } from "./UpdateState.svelte"
export { default as RefreshDataProvider } from "./RefreshDataProvider.svelte"
export { default as DuplicateRow } from "./DuplicateRow.svelte"
export { default as S3Upload } from "./S3Upload.svelte"
export { default as FileUpload } from "./FileUpload.svelte"
export { default as ExportData } from "./ExportData.svelte"
export { default as ContinueIf } from "./ContinueIf.svelte"
export { default as UpdateFieldValue } from "./UpdateFieldValue.svelte"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@
"dependsOnFeature": "state"
},
{
"name": "Upload File to S3",
"name": "Upload File",
"type": "data",
"component": "S3Upload",
"component": "FileUpload",
"context": [
{
"label": "File URL",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
export let value = null

$: dataSources = $datasources.list
.filter(ds => ds.source === "S3" && !ds.config?.endpoint)
.filter(ds => ["S3", "AZURE"].includes(ds.source) && !ds.config?.endpoint)
.map(ds => ({
label: ds.name,
value: ds._id,
Expand Down
2 changes: 2 additions & 0 deletions packages/builder/src/constants/backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ export const IntegrationTypes = {
MONGODB: "MONGODB",
COUCHDB: "COUCHDB",
S3: "S3",
AZURE: "AZURE",
MYSQL: "MYSQL",
REST: "REST",
DYNAMODB: "DYNAMODB",
Expand All @@ -233,6 +234,7 @@ export const IntegrationNames = {
[IntegrationTypes.MONGODB]: "MongoDB",
[IntegrationTypes.COUCHDB]: "CouchDB",
[IntegrationTypes.S3]: "S3",
[IntegrationTypes.AZURE]: "AZURE",
[IntegrationTypes.MYSQL]: "MySQL",
[IntegrationTypes.REST]: "REST",
[IntegrationTypes.DYNAMODB]: "DynamoDB",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"relationshipfield",
"datetimefield",
"multifieldselect",
"s3upload",
"fileupload",
"codescanner",
"bbreferencefield"
]
Expand Down
12 changes: 6 additions & 6 deletions packages/client/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4617,8 +4617,8 @@
}
]
},
"s3upload": {
"name": "S3 File Upload",
"fileupload": {
"name": "File Upload",
"icon": "UploadToCloud",
"styles": ["size"],
"editable": true,
Expand All @@ -4628,7 +4628,7 @@
},
"settings": [
{
"type": "field/s3",
"type": "field/upload",
"label": "Field",
"key": "field",
"required": true
Expand All @@ -4639,14 +4639,14 @@
"key": "label"
},
{
"type": "dataSource/s3",
"label": "S3 datasource",
"type": "dataSource/objectStore",
"label": "Object store",
"key": "datasourceId",
"info": "This component can't be used with S3 datasources that use custom endpoints"
},
{
"type": "text",
"label": "Bucket",
"label": "Bucket / Container",
"key": "bucket"
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
{field}
{disabled}
{validation}
type="s3upload"
type="fileupload"
bind:fieldState
bind:fieldApi
defaultValue={[]}
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/components/app/forms/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ export { default as relationshipfield } from "./RelationshipField.svelte"
export { default as passwordfield } from "./PasswordField.svelte"
export { default as formstep } from "./FormStep.svelte"
export { default as jsonfield } from "./JSONField.svelte"
export { default as s3upload } from "./S3Upload.svelte"
export { default as fileupload } from "./FileUpload.svelte"
export { default as codescanner } from "./CodeScannerField.svelte"
export { default as bbreferencefield } from "./BBReferenceField.svelte"
4 changes: 2 additions & 2 deletions packages/client/src/utils/buttonActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ const updateStateHandler = action => {
}
}

const s3UploadHandler = async action => {
const uploadHandler = async action => {
const { componentId } = action.parameters
if (!componentId) {
return
Expand Down Expand Up @@ -458,7 +458,7 @@ const handlerMap = {
["Log Out"]: logoutHandler,
["Close Screen Modal"]: closeScreenModalHandler,
["Update State"]: updateStateHandler,
["Upload File to S3"]: s3UploadHandler,
["Upload File"]: uploadHandler,
["Export Data"]: exportDataHandler,
["Continue if / Stop if"]: continueIfHandler,
["Show Notification"]: showNotificationHandler,
Expand Down
2 changes: 2 additions & 0 deletions packages/frontend-core/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ export const createAPIClient = config => {
headers[Header.SESSION_ID] = APISessionID
if (!external) {
headers[Header.API_VER] = ApiVersion
} else {
headers["x-ms-blob-type"] = "BlockBlob"
}
if (json) {
headers["Content-Type"] = "application/json"
Expand Down
1 change: 1 addition & 0 deletions packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"license": "GPL-3.0",
"dependencies": {
"@apidevtools/swagger-parser": "10.0.3",
"@azure/storage-blob": "^12.17.0",
"@budibase/backend-core": "0.0.0",
"@budibase/client": "0.0.0",
"@budibase/frontend-core": "0.0.0",
Expand Down
35 changes: 35 additions & 0 deletions packages/server/src/api/controllers/static/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ import {
utils,
} from "@budibase/backend-core"
import AWS from "aws-sdk"
import {
StorageSharedKeyCredential,
generateBlobSASQueryParameters,
BlobSASPermissions,
BlobServiceClient,
} from "@azure/storage-blob"
import fs from "fs"
import sdk from "../../../sdk"
import * as pro from "@budibase/pro"
Expand Down Expand Up @@ -320,6 +326,35 @@ export const getSignedUploadURL = async function (ctx: Ctx) {
} catch (error: any) {
ctx.throw(400, error)
}
} else if (datasource?.source === "AZURE") {
const { bucket, key } = ctx.request.body || {}
if (!bucket || !key) {
ctx.throw(400, "container and key values are required")
}
try {
const containerClient = BlobServiceClient.fromConnectionString(
`DefaultEndpointsProtocol=https;AccountName=${datasource?.config?.accountName};AccountKey=${datasource?.config?.accountKey};EndpointSuffix=core.windows.net`
).getContainerClient(bucket)

const blobSAS = generateBlobSASQueryParameters(
{
containerName: bucket,
blobName: key,
permissions: BlobSASPermissions.parse("racwd"),
startsOn: new Date(),
expiresOn: new Date(new Date().valueOf() + 86400),
},
new StorageSharedKeyCredential(
datasource?.config?.accountName,
datasource?.config?.accountKey
)
).toString()

publicUrl = containerClient.getBlobClient(key).url
signedUrl = `${publicUrl}?${blobSAS}`
} catch (error: any) {
ctx.throw(400, error)
}
}

ctx.body = { signedUrl, publicUrl }
Expand Down
Loading
Loading