Updating locks to store the whole global user as well as implementing the locks on dev apps fetch.
This commit is contained in:
parent
61a5b109f5
commit
799b3fc138
|
@ -35,6 +35,7 @@ const { getAllApps } = require("../../utilities")
|
||||||
const { USERS_TABLE_SCHEMA } = require("../../constants")
|
const { USERS_TABLE_SCHEMA } = require("../../constants")
|
||||||
const { getDeployedApps } = require("../../utilities/workerRequests")
|
const { getDeployedApps } = require("../../utilities/workerRequests")
|
||||||
const { clientLibraryPath } = require("../../utilities")
|
const { clientLibraryPath } = require("../../utilities")
|
||||||
|
const { getAllLocks } = require("../../utilities/redis")
|
||||||
|
|
||||||
const URL_REGEX_SLASH = /\/|\\/g
|
const URL_REGEX_SLASH = /\/|\\/g
|
||||||
|
|
||||||
|
@ -122,15 +123,23 @@ async function createInstance(template) {
|
||||||
exports.fetch = async function (ctx) {
|
exports.fetch = async function (ctx) {
|
||||||
let apps = await getAllApps()
|
let apps = await getAllApps()
|
||||||
|
|
||||||
const appStatus = ctx.query.status
|
const isDev = ctx.query.status === AppStatus.DEV
|
||||||
if (appStatus) {
|
|
||||||
apps = apps.filter(app => {
|
apps = apps.filter(app => {
|
||||||
if (appStatus === AppStatus.DEV) {
|
if (isDev) {
|
||||||
return app._id.startsWith(DocumentTypes.APP_DEV)
|
return app._id.startsWith(DocumentTypes.APP_DEV)
|
||||||
}
|
}
|
||||||
|
|
||||||
return !app._id.startsWith(DocumentTypes.APP_DEV)
|
return !app._id.startsWith(DocumentTypes.APP_DEV)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// get the locks for all the dev apps
|
||||||
|
if (isDev) {
|
||||||
|
const locks = await getAllLocks()
|
||||||
|
for (let app of apps) {
|
||||||
|
const lock = locks.find(lock => lock.appId === app._id)
|
||||||
|
if (lock) {
|
||||||
|
app.lockedBy = lock.user
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.body = apps
|
ctx.body = apps
|
||||||
|
|
|
@ -37,9 +37,8 @@ exports.redirectDelete = async ctx => {
|
||||||
|
|
||||||
exports.removeLock = async ctx => {
|
exports.removeLock = async ctx => {
|
||||||
const { appId } = ctx.params
|
const { appId } = ctx.params
|
||||||
const globalUserId = getGlobalIDFromUserMetadataID(ctx.user._id)
|
|
||||||
try {
|
try {
|
||||||
await clearLock(appId, globalUserId)
|
await clearLock(appId, ctx.user)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ctx.throw(400, "Unable to remove lock.")
|
ctx.throw(400, "Unable to remove lock.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ const {
|
||||||
doesHaveResourcePermission,
|
doesHaveResourcePermission,
|
||||||
doesHaveBasePermission,
|
doesHaveBasePermission,
|
||||||
} = require("../utilities/security/permissions")
|
} = require("../utilities/security/permissions")
|
||||||
const { APP_DEV_PREFIX, getGlobalIDFromUserMetadataID } = require("../db/utils")
|
const { APP_DEV_PREFIX } = require("../db/utils")
|
||||||
const { doesUserHaveLock, updateLock } = require("../utilities/redis")
|
const { doesUserHaveLock, updateLock } = require("../utilities/redis")
|
||||||
|
|
||||||
function hasResource(ctx) {
|
function hasResource(ctx) {
|
||||||
|
@ -19,17 +19,15 @@ async function checkDevAppLocks(ctx) {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
|
|
||||||
// not a development app, don't need to do anything
|
// not a development app, don't need to do anything
|
||||||
if (!appId.startsWith(APP_DEV_PREFIX)) {
|
if (!appId || !appId.startsWith(APP_DEV_PREFIX)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// get the user which is currently using the dev app
|
if (!(await doesUserHaveLock(appId, ctx.user))) {
|
||||||
const userId = getGlobalIDFromUserMetadataID(ctx.user._id)
|
|
||||||
if (!(await doesUserHaveLock(appId, userId))) {
|
|
||||||
ctx.throw(403, "User does not hold app lock.")
|
ctx.throw(403, "User does not hold app lock.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// they do have lock, update it
|
// they do have lock, update it
|
||||||
await updateLock(appId, userId)
|
await updateLock(appId, ctx.user)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const { Client, utils } = require("@budibase/auth").redis
|
const { Client, utils } = require("@budibase/auth").redis
|
||||||
|
const { getGlobalIDFromUserMetadataID } = require("../db/utils")
|
||||||
|
|
||||||
const APP_DEV_LOCK_SECONDS = 600
|
const APP_DEV_LOCK_SECONDS = 600
|
||||||
const DB_NAME = utils.Databases.DEV_LOCKS
|
const DB_NAME = utils.Databases.DEV_LOCKS
|
||||||
|
@ -10,20 +11,40 @@ exports.init = async () => {
|
||||||
devAppClient = await new Client(DB_NAME).init()
|
devAppClient = await new Client(DB_NAME).init()
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.doesUserHaveLock = async (devAppId, userId) => {
|
exports.doesUserHaveLock = async (devAppId, user) => {
|
||||||
const value = await devAppClient.get(devAppId)
|
const value = await devAppClient.get(devAppId)
|
||||||
return value == null || value === userId
|
if (!value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// make sure both IDs are global
|
||||||
|
const expected = getGlobalIDFromUserMetadataID(value._id)
|
||||||
|
const userId = getGlobalIDFromUserMetadataID(user._id)
|
||||||
|
return expected === userId
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.updateLock = async (devAppId, userId) => {
|
exports.getAllLocks = async () => {
|
||||||
await devAppClient.store(devAppId, userId, APP_DEV_LOCK_SECONDS)
|
const locks = await devAppClient.scan()
|
||||||
|
return locks.map(lock => ({
|
||||||
|
appId: lock.key,
|
||||||
|
user: lock.value,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.clearLock = async (devAppId, userId) => {
|
exports.updateLock = async (devAppId, user) => {
|
||||||
|
// make sure always global user ID
|
||||||
|
const inputUser = {
|
||||||
|
...user,
|
||||||
|
_id: getGlobalIDFromUserMetadataID(user._id),
|
||||||
|
}
|
||||||
|
await devAppClient.store(devAppId, inputUser, APP_DEV_LOCK_SECONDS)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.clearLock = async (devAppId, user) => {
|
||||||
const value = await devAppClient.get(devAppId)
|
const value = await devAppClient.get(devAppId)
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const userId = getGlobalIDFromUserMetadataID(user._id)
|
||||||
if (value !== userId) {
|
if (value !== userId) {
|
||||||
throw "User does not hold lock, cannot clear it."
|
throw "User does not hold lock, cannot clear it."
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue