Merge branch 'fix/builder-roles' of github.com:Budibase/budibase into feature/opinionated-sql

This commit is contained in:
mike12345567 2021-06-04 13:10:57 +01:00
commit 8f0b25879a
22 changed files with 61 additions and 76 deletions

View File

@ -1,5 +1,5 @@
{ {
"version": "0.9.24", "version": "0.9.25",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/*" "packages/*"

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/auth", "name": "@budibase/auth",
"version": "0.9.24", "version": "0.9.25",
"description": "Authentication middlewares for budibase builder and apps", "description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js", "main": "src/index.js",
"author": "Budibase", "author": "Budibase",

View File

@ -159,7 +159,7 @@ exports.upload = async ({
* Similar to the upload function but can be used to send a file stream * Similar to the upload function but can be used to send a file stream
* through to the object store. * through to the object store.
*/ */
exports.streamUpload = async (bucketName, filename, stream) => { exports.streamUpload = async (bucketName, filename, stream, extra = {}) => {
const objectStore = exports.ObjectStore(bucketName) const objectStore = exports.ObjectStore(bucketName)
await exports.makeSureBucketExists(objectStore, bucketName) await exports.makeSureBucketExists(objectStore, bucketName)
@ -167,6 +167,7 @@ exports.streamUpload = async (bucketName, filename, stream) => {
Bucket: sanitizeBucket(bucketName), Bucket: sanitizeBucket(bucketName),
Key: sanitizeKey(filename), Key: sanitizeKey(filename),
Body: stream, Body: stream,
...extra,
} }
return objectStore.upload(params).promise() return objectStore.upload(params).promise()
} }

View File

@ -13,7 +13,6 @@ const BUILTIN_IDS = {
POWER: "POWER", POWER: "POWER",
BASIC: "BASIC", BASIC: "BASIC",
PUBLIC: "PUBLIC", PUBLIC: "PUBLIC",
BUILDER: "BUILDER",
} }
// exclude internal roles like builder // exclude internal roles like builder

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/bbui", "name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.", "description": "A UI solution used in the different Budibase projects.",
"version": "0.9.24", "version": "0.9.25",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"svelte": "src/index.js", "svelte": "src/index.js",
"module": "dist/bbui.es.js", "module": "dist/bbui.es.js",

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/builder", "name": "@budibase/builder",
"version": "0.9.24", "version": "0.9.25",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"private": true, "private": true,
"scripts": { "scripts": {
@ -65,10 +65,10 @@
} }
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.24", "@budibase/bbui": "^0.9.25",
"@budibase/client": "^0.9.24", "@budibase/client": "^0.9.25",
"@budibase/colorpicker": "1.1.2", "@budibase/colorpicker": "1.1.2",
"@budibase/string-templates": "^0.9.24", "@budibase/string-templates": "^0.9.25",
"@sentry/browser": "5.19.1", "@sentry/browser": "5.19.1",
"@spectrum-css/page": "^3.0.1", "@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1", "@spectrum-css/vars": "^3.0.1",

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/cli", "name": "@budibase/cli",
"version": "0.9.24", "version": "0.9.25",
"description": "Budibase CLI, for developers, self hosting and migrations.", "description": "Budibase CLI, for developers, self hosting and migrations.",
"main": "src/index.js", "main": "src/index.js",
"bin": { "bin": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/client", "name": "@budibase/client",
"version": "0.9.24", "version": "0.9.25",
"license": "MPL-2.0", "license": "MPL-2.0",
"module": "dist/budibase-client.js", "module": "dist/budibase-client.js",
"main": "dist/budibase-client.js", "main": "dist/budibase-client.js",
@ -18,13 +18,13 @@
"dev:builder": "rollup -cw" "dev:builder": "rollup -cw"
}, },
"dependencies": { "dependencies": {
"@budibase/string-templates": "^0.9.24", "@budibase/string-templates": "^0.9.25",
"regexparam": "^1.3.0", "regexparam": "^1.3.0",
"shortid": "^2.2.15", "shortid": "^2.2.15",
"svelte-spa-router": "^3.0.5" "svelte-spa-router": "^3.0.5"
}, },
"devDependencies": { "devDependencies": {
"@budibase/standard-components": "^0.9.24", "@budibase/standard-components": "^0.9.25",
"@rollup/plugin-commonjs": "^18.0.0", "@rollup/plugin-commonjs": "^18.0.0",
"@rollup/plugin-node-resolve": "^11.2.1", "@rollup/plugin-node-resolve": "^11.2.1",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/server", "name": "@budibase/server",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "0.9.24", "version": "0.9.25",
"description": "Budibase Web Server", "description": "Budibase Web Server",
"main": "src/electron.js", "main": "src/electron.js",
"repository": { "repository": {
@ -55,9 +55,9 @@
"author": "Budibase", "author": "Budibase",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@budibase/auth": "^0.9.24", "@budibase/auth": "^0.9.25",
"@budibase/client": "^0.9.24", "@budibase/client": "^0.9.25",
"@budibase/string-templates": "^0.9.24", "@budibase/string-templates": "^0.9.25",
"@elastic/elasticsearch": "7.10.0", "@elastic/elasticsearch": "7.10.0",
"@koa/router": "8.0.0", "@koa/router": "8.0.0",
"@sendgrid/mail": "7.1.1", "@sendgrid/mail": "7.1.1",
@ -110,7 +110,7 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.14.3", "@babel/core": "^7.14.3",
"@babel/preset-env": "^7.14.4", "@babel/preset-env": "^7.14.4",
"@budibase/standard-components": "^0.9.24", "@budibase/standard-components": "^0.9.25",
"@jest/test-sequencer": "^24.8.0", "@jest/test-sequencer": "^24.8.0",
"babel-jest": "^27.0.2", "babel-jest": "^27.0.2",
"docker-compose": "^0.23.6", "docker-compose": "^0.23.6",

View File

@ -5,7 +5,7 @@ const { getFullUser } = require("../../utilities/users")
exports.fetchSelf = async ctx => { exports.fetchSelf = async ctx => {
const appId = ctx.appId const appId = ctx.appId
const { userId } = ctx.user let userId = ctx.user.userId || ctx.user._id
/* istanbul ignore next */ /* istanbul ignore next */
if (!userId) { if (!userId) {
ctx.body = {} ctx.body = {}

View File

@ -63,10 +63,6 @@ exports.fetch = async ctx => {
exports.clientFetch = async ctx => { exports.clientFetch = async ctx => {
const routing = await getRoutingStructure(ctx.appId) const routing = await getRoutingStructure(ctx.appId)
let roleId = ctx.user.role._id let roleId = ctx.user.role._id
// builder is a special case, always return the full routing structure
if (roleId === BUILTIN_ROLE_IDS.BUILDER) {
roleId = BUILTIN_ROLE_IDS.ADMIN
}
const roleIds = await getUserRoleHierarchy(ctx.appId, roleId) const roleIds = await getUserRoleHierarchy(ctx.appId, roleId)
for (let topLevel of Object.values(routing.routes)) { for (let topLevel of Object.values(routing.routes)) {
for (let subpathKey of Object.keys(topLevel.subpaths)) { for (let subpathKey of Object.keys(topLevel.subpaths)) {

View File

@ -31,7 +31,6 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
*, *,
*:before, *:before,
*:after { *:after {
@ -41,9 +40,9 @@
</svelte:head> </svelte:head>
<body id="app"> <body id="app">
<script src={clientLibPath}> <script type="application/javascript" src={clientLibPath}>
</script> </script>
<script> <script type="application/javascript">
loadBudibase() loadBudibase()
</script> </script>
</body> </body>

View File

@ -4,7 +4,6 @@ const {
getUserMetadataParams, getUserMetadataParams,
} = require("../../db/utils") } = require("../../db/utils")
const { InternalTables } = require("../../db/utils") const { InternalTables } = require("../../db/utils")
const { BUILTIN_ROLE_IDS } = require("@budibase/auth/roles")
const { const {
getGlobalUsers, getGlobalUsers,
addAppRoleToUser, addAppRoleToUser,
@ -47,10 +46,6 @@ exports.fetchMetadata = async function (ctx) {
exports.updateSelfMetadata = async function (ctx) { exports.updateSelfMetadata = async function (ctx) {
// overwrite the ID with current users // overwrite the ID with current users
ctx.request.body._id = ctx.user._id ctx.request.body._id = ctx.user._id
if (ctx.user.builder && ctx.user.builder.global) {
// specific case, update self role in global user
await addAppRoleToUser(ctx, ctx.appId, BUILTIN_ROLE_IDS.ADMIN)
}
// make sure no stale rev // make sure no stale rev
delete ctx.request.body._rev delete ctx.request.body._rev
await exports.updateMetadata(ctx) await exports.updateMetadata(ctx)

View File

@ -28,9 +28,7 @@ describe("/routing", () => {
it("returns the correct routing for basic user", async () => { it("returns the correct routing for basic user", async () => {
workerRequests.getGlobalUsers.mockImplementationOnce((ctx, appId) => { workerRequests.getGlobalUsers.mockImplementationOnce((ctx, appId) => {
return { return {
roles: { roleId: BUILTIN_ROLE_IDS.BASIC,
[appId]: BUILTIN_ROLE_IDS.BASIC,
}
} }
}) })
const res = await request const res = await request

View File

@ -2,6 +2,7 @@ const rowController = require("../../../controllers/row")
const appController = require("../../../controllers/application") const appController = require("../../../controllers/application")
const CouchDB = require("../../../../db") const CouchDB = require("../../../../db")
const { AppStatus } = require("../../../../db/utils") const { AppStatus } = require("../../../../db/utils")
const { BUILTIN_ROLE_IDS } = require("@budibase/auth/roles")
function Request(appId, params) { function Request(appId, params) {
this.appId = appId this.appId = appId
@ -77,11 +78,17 @@ exports.checkPermissionsEndpoint = async ({
.set(passHeader) .set(passHeader)
.expect(200) .expect(200)
user = await config.createUser("fail@budibase.com", password, failRole) let failHeader
const failHeader = await config.login("fail@budibase.com", password, { if (failRole === BUILTIN_ROLE_IDS.PUBLIC) {
roleId: failRole, failHeader = config.publicHeaders()
userId: user.globalId, } else {
}) user = await config.createUser("fail@budibase.com", password, failRole)
failHeader = await config.login("fail@budibase.com", password, {
roleId: failRole,
userId: user.globalId,
builder: false,
})
}
await exports await exports
.createRequest(config.request, method, url, body) .createRequest(config.request, method, url, body)

View File

@ -33,7 +33,7 @@ module.exports = async (ctx, next) => {
updateCookie = true updateCookie = true
appId = requestAppId appId = requestAppId
// retrieving global user gets the right role // retrieving global user gets the right role
roleId = globalUser.roleId roleId = globalUser.roleId || BUILTIN_ROLE_IDS.PUBLIC
} else if (appCookie != null) { } else if (appCookie != null) {
appId = appCookie.appId appId = appCookie.appId
roleId = appCookie.roleId || BUILTIN_ROLE_IDS.PUBLIC roleId = appCookie.roleId || BUILTIN_ROLE_IDS.PUBLIC

View File

@ -101,7 +101,7 @@ class TestConfiguration {
userId: GLOBAL_USER_ID, userId: GLOBAL_USER_ID,
} }
const app = { const app = {
roleId: BUILTIN_ROLE_IDS.BUILDER, roleId: BUILTIN_ROLE_IDS.ADMIN,
appId: this.appId, appId: this.appId,
} }
const authToken = jwt.sign(auth, env.JWT_SECRET) const authToken = jwt.sign(auth, env.JWT_SECRET)
@ -306,12 +306,9 @@ class TestConfiguration {
return await this._req(config, null, controllers.layout.save) return await this._req(config, null, controllers.layout.save)
} }
async createUser(roleId = BUILTIN_ROLE_IDS.POWER) { async createUser() {
const globalId = `us_${Math.random()}` const globalId = `us_${Math.random()}`
const resp = await this.globalUser( const resp = await this.globalUser(globalId)
globalId,
roleId === BUILTIN_ROLE_IDS.BUILDER
)
return { return {
...resp, ...resp,
globalId, globalId,
@ -319,7 +316,6 @@ class TestConfiguration {
} }
async login(email, password, { roleId, userId, builder } = {}) { async login(email, password, { roleId, userId, builder } = {}) {
roleId = !roleId ? BUILTIN_ROLE_IDS.BUILDER : roleId
userId = !userId ? `us_uuid1` : userId userId = !userId ? `us_uuid1` : userId
if (!this.request) { if (!this.request) {
throw "Server has not been opened, cannot login." throw "Server has not been opened, cannot login."

View File

@ -30,5 +30,7 @@ exports.uploadClientLibrary = async appId => {
const sourcepath = require.resolve("@budibase/client") const sourcepath = require.resolve("@budibase/client")
const destPath = join(appId, "budibase-client.js") const destPath = join(appId, "budibase-client.js")
await streamUpload(BUCKET_NAME, destPath, fs.createReadStream(sourcepath)) await streamUpload(BUCKET_NAME, destPath, fs.createReadStream(sourcepath), {
ContentType: "application/javascript",
})
} }

View File

@ -9,19 +9,26 @@ function getAppRole(appId, user) {
if (!user.roles) { if (!user.roles) {
return user return user
} }
// always use the deployed app if (user.builder && user.builder.global) {
user.roleId = user.roles[getDeployedAppID(appId)] user.roleId = BUILTIN_ROLE_IDS.ADMIN
if (!user.roleId) { } else {
user.roleId = BUILTIN_ROLE_IDS.PUBLIC // always use the deployed app
user.roleId = user.roles[getDeployedAppID(appId)]
if (!user.roleId) {
user.roleId = BUILTIN_ROLE_IDS.PUBLIC
}
} }
delete user.roles delete user.roles
return user return user
} }
function request(ctx, request) { function request(ctx, request, noApiKey) {
if (!request.headers) { if (!request.headers) {
request.headers = {} request.headers = {}
} }
if (!noApiKey) {
request.headers["x-budibase-api-key"] = env.INTERNAL_API_KEY
}
if (request.body && Object.keys(request.body).length > 0) { if (request.body && Object.keys(request.body).length > 0) {
request.headers["Content-Type"] = "application/json" request.headers["Content-Type"] = "application/json"
request.body = request.body =
@ -44,9 +51,6 @@ exports.sendSmtpEmail = async (to, from, subject, contents) => {
checkSlashesInUrl(env.WORKER_URL + `/api/admin/email/send`), checkSlashesInUrl(env.WORKER_URL + `/api/admin/email/send`),
request(null, { request(null, {
method: "POST", method: "POST",
headers: {
"x-budibase-api-key": env.INTERNAL_API_KEY,
},
body: { body: {
email: to, email: to,
from, from,
@ -86,16 +90,6 @@ exports.getDeployedApps = async ctx => {
} }
} }
exports.deleteGlobalUser = async (ctx, globalId) => {
const endpoint = `/api/admin/users/${globalId}`
const reqCfg = { method: "DELETE" }
const response = await fetch(
checkSlashesInUrl(env.WORKER_URL + endpoint),
request(ctx, reqCfg)
)
return response.json()
}
exports.getGlobalUsers = async (ctx, appId = null, globalId = null) => { exports.getGlobalUsers = async (ctx, appId = null, globalId = null) => {
const endpoint = globalId const endpoint = globalId
? `/api/admin/users/${globalId}` ? `/api/admin/users/${globalId}`
@ -121,7 +115,8 @@ exports.getGlobalSelf = async (ctx, appId = null) => {
const endpoint = `/api/admin/users/self` const endpoint = `/api/admin/users/self`
const response = await fetch( const response = await fetch(
checkSlashesInUrl(env.WORKER_URL + endpoint), checkSlashesInUrl(env.WORKER_URL + endpoint),
request(ctx, { method: "GET" }) // we don't want to use API key when getting self
request(ctx, { method: "GET" }, true)
) )
if (response.status !== 200) { if (response.status !== 200) {
ctx.throw(400, "Unable to get self globally.") ctx.throw(400, "Unable to get self globally.")
@ -172,9 +167,6 @@ exports.removeAppFromUserRoles = async appId => {
checkSlashesInUrl(env.WORKER_URL + `/api/admin/roles/${deployedAppId}`), checkSlashesInUrl(env.WORKER_URL + `/api/admin/roles/${deployedAppId}`),
request(null, { request(null, {
method: "DELETE", method: "DELETE",
headers: {
"x-budibase-api-key": env.INTERNAL_API_KEY,
},
}) })
) )
if (response.status !== 200) { if (response.status !== 200) {

View File

@ -29,11 +29,11 @@
"keywords": [ "keywords": [
"svelte" "svelte"
], ],
"version": "0.9.24", "version": "0.9.25",
"license": "MIT", "license": "MIT",
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc", "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc",
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.24", "@budibase/bbui": "^0.9.25",
"@spectrum-css/page": "^3.0.1", "@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1", "@spectrum-css/vars": "^3.0.1",
"apexcharts": "^3.22.1", "apexcharts": "^3.22.1",

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/string-templates", "name": "@budibase/string-templates",
"version": "0.9.24", "version": "0.9.25",
"description": "Handlebars wrapper for Budibase templating.", "description": "Handlebars wrapper for Budibase templating.",
"main": "src/index.cjs", "main": "src/index.cjs",
"module": "dist/bundle.mjs", "module": "dist/bundle.mjs",

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/worker", "name": "@budibase/worker",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "0.9.24", "version": "0.9.25",
"description": "Budibase background service", "description": "Budibase background service",
"main": "src/index.js", "main": "src/index.js",
"repository": { "repository": {
@ -21,8 +21,8 @@
"author": "Budibase", "author": "Budibase",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@budibase/auth": "^0.9.24", "@budibase/auth": "^0.9.25",
"@budibase/string-templates": "^0.9.24", "@budibase/string-templates": "^0.9.25",
"@koa/router": "^8.0.0", "@koa/router": "^8.0.0",
"aws-sdk": "^2.811.0", "aws-sdk": "^2.811.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",