Merge branch 'master' into instrument-couch
This commit is contained in:
commit
0ef42ae347
|
@ -15,109 +15,106 @@ import { UserCtx, ContextUser } from "@budibase/types"
|
||||||
import tracer from "dd-trace"
|
import tracer from "dd-trace"
|
||||||
|
|
||||||
export default async (ctx: UserCtx, next: any) => {
|
export default async (ctx: UserCtx, next: any) => {
|
||||||
return tracer.trace("currentapp middleware", {}, async span => {
|
// try to get the appID from the request
|
||||||
// try to get the appID from the request
|
let requestAppId = await utils.getAppIdFromCtx(ctx)
|
||||||
let requestAppId = await utils.getAppIdFromCtx(ctx)
|
if (!requestAppId) {
|
||||||
if (!requestAppId) {
|
return next()
|
||||||
return next()
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (requestAppId) {
|
if (requestAppId) {
|
||||||
span?.addTags({ app_id: requestAppId })
|
const span = tracer.scope().active()
|
||||||
}
|
span?.addTags({ app_id: requestAppId })
|
||||||
|
}
|
||||||
|
|
||||||
// deny access to application preview
|
// deny access to application preview
|
||||||
if (!env.isTest()) {
|
if (!env.isTest()) {
|
||||||
if (
|
|
||||||
isDevAppID(requestAppId) &&
|
|
||||||
!isWebhookEndpoint(ctx) &&
|
|
||||||
!users.isBuilder(ctx.user, requestAppId)
|
|
||||||
) {
|
|
||||||
return ctx.redirect("/")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let appId: string | undefined,
|
|
||||||
roleId = roles.BUILTIN_ROLE_IDS.PUBLIC
|
|
||||||
if (!ctx.user?._id) {
|
|
||||||
// not logged in, try to set a cookie for public apps
|
|
||||||
appId = requestAppId
|
|
||||||
} else if (requestAppId != null) {
|
|
||||||
// Different App ID means cookie needs reset, or if the same public user has logged in
|
|
||||||
const globalUser = await getCachedSelf(ctx, requestAppId)
|
|
||||||
appId = requestAppId
|
|
||||||
// retrieving global user gets the right role
|
|
||||||
roleId = globalUser.roleId || roleId
|
|
||||||
|
|
||||||
// Allow builders to specify their role via a header
|
|
||||||
const isBuilder = users.isBuilder(globalUser, appId)
|
|
||||||
const isDevApp = appId && isDevAppID(appId)
|
|
||||||
const roleHeader =
|
|
||||||
ctx.request &&
|
|
||||||
(ctx.request.headers[constants.Header.PREVIEW_ROLE] as string)
|
|
||||||
if (isBuilder && isDevApp && roleHeader) {
|
|
||||||
// Ensure the role is valid by ensuring a definition exists
|
|
||||||
try {
|
|
||||||
if (roleHeader) {
|
|
||||||
await roles.getRole(roleHeader)
|
|
||||||
roleId = roleHeader
|
|
||||||
|
|
||||||
// Delete admin and builder flags so that the specified role is honoured
|
|
||||||
ctx.user = users.removePortalUserPermissions(
|
|
||||||
ctx.user
|
|
||||||
) as ContextUser
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// Swallow error and do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// nothing more to do
|
|
||||||
if (!appId) {
|
|
||||||
return next()
|
|
||||||
}
|
|
||||||
|
|
||||||
const userId = ctx.user ? generateUserMetadataID(ctx.user._id!) : undefined
|
|
||||||
|
|
||||||
// if the user is not in the right tenant then make sure to wipe their cookie
|
|
||||||
// also cleanse any information about them that has been allocated
|
|
||||||
// this avoids apps making calls to say the worker which are cross tenant,
|
|
||||||
// we simply remove the authentication
|
|
||||||
if (
|
if (
|
||||||
env.MULTI_TENANCY &&
|
isDevAppID(requestAppId) &&
|
||||||
userId &&
|
!isWebhookEndpoint(ctx) &&
|
||||||
requestAppId &&
|
!users.isBuilder(ctx.user, requestAppId)
|
||||||
!tenancy.isUserInAppTenant(requestAppId, ctx.user)
|
|
||||||
) {
|
) {
|
||||||
// clear out the user
|
return ctx.redirect("/")
|
||||||
ctx.user = users.cleanseUserObject(ctx.user) as ContextUser
|
}
|
||||||
ctx.isAuthenticated = false
|
}
|
||||||
roleId = roles.BUILTIN_ROLE_IDS.PUBLIC
|
|
||||||
// remove the cookie, so future calls are public
|
let appId: string | undefined,
|
||||||
await auth.platformLogout({
|
roleId = roles.BUILTIN_ROLE_IDS.PUBLIC
|
||||||
ctx,
|
if (!ctx.user?._id) {
|
||||||
|
// not logged in, try to set a cookie for public apps
|
||||||
|
appId = requestAppId
|
||||||
|
} else if (requestAppId != null) {
|
||||||
|
// Different App ID means cookie needs reset, or if the same public user has logged in
|
||||||
|
const globalUser = await getCachedSelf(ctx, requestAppId)
|
||||||
|
appId = requestAppId
|
||||||
|
// retrieving global user gets the right role
|
||||||
|
roleId = globalUser.roleId || roleId
|
||||||
|
|
||||||
|
// Allow builders to specify their role via a header
|
||||||
|
const isBuilder = users.isBuilder(globalUser, appId)
|
||||||
|
const isDevApp = appId && isDevAppID(appId)
|
||||||
|
const roleHeader =
|
||||||
|
ctx.request &&
|
||||||
|
(ctx.request.headers[constants.Header.PREVIEW_ROLE] as string)
|
||||||
|
if (isBuilder && isDevApp && roleHeader) {
|
||||||
|
// Ensure the role is valid by ensuring a definition exists
|
||||||
|
try {
|
||||||
|
if (roleHeader) {
|
||||||
|
await roles.getRole(roleHeader)
|
||||||
|
roleId = roleHeader
|
||||||
|
|
||||||
|
// Delete admin and builder flags so that the specified role is honoured
|
||||||
|
ctx.user = users.removePortalUserPermissions(ctx.user) as ContextUser
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Swallow error and do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing more to do
|
||||||
|
if (!appId) {
|
||||||
|
return next()
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = ctx.user ? generateUserMetadataID(ctx.user._id!) : undefined
|
||||||
|
|
||||||
|
// if the user is not in the right tenant then make sure to wipe their cookie
|
||||||
|
// also cleanse any information about them that has been allocated
|
||||||
|
// this avoids apps making calls to say the worker which are cross tenant,
|
||||||
|
// we simply remove the authentication
|
||||||
|
if (
|
||||||
|
env.MULTI_TENANCY &&
|
||||||
|
userId &&
|
||||||
|
requestAppId &&
|
||||||
|
!tenancy.isUserInAppTenant(requestAppId, ctx.user)
|
||||||
|
) {
|
||||||
|
// clear out the user
|
||||||
|
ctx.user = users.cleanseUserObject(ctx.user) as ContextUser
|
||||||
|
ctx.isAuthenticated = false
|
||||||
|
roleId = roles.BUILTIN_ROLE_IDS.PUBLIC
|
||||||
|
// remove the cookie, so future calls are public
|
||||||
|
await auth.platformLogout({
|
||||||
|
ctx,
|
||||||
|
userId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.doInAppContext(appId, async () => {
|
||||||
|
ctx.appId = appId
|
||||||
|
if (roleId) {
|
||||||
|
ctx.roleId = roleId
|
||||||
|
const globalId = ctx.user ? ctx.user._id : undefined
|
||||||
|
ctx.user = {
|
||||||
|
...ctx.user!,
|
||||||
|
// override userID with metadata one
|
||||||
|
_id: userId,
|
||||||
userId,
|
userId,
|
||||||
})
|
globalId,
|
||||||
|
roleId,
|
||||||
|
role: await roles.getRole(roleId, { defaultPublic: true }),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.doInAppContext(appId, async () => {
|
return next()
|
||||||
ctx.appId = appId
|
|
||||||
if (roleId) {
|
|
||||||
ctx.roleId = roleId
|
|
||||||
const globalId = ctx.user ? ctx.user._id : undefined
|
|
||||||
ctx.user = {
|
|
||||||
...ctx.user!,
|
|
||||||
// override userID with metadata one
|
|
||||||
_id: userId,
|
|
||||||
userId,
|
|
||||||
globalId,
|
|
||||||
roleId,
|
|
||||||
role: await roles.getRole(roleId, { defaultPublic: true }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return next()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,8 @@ export function processFormulas<T extends Row | Row[]>(
|
||||||
{ dynamic, contextRows }: FormulaOpts = { dynamic: true }
|
{ dynamic, contextRows }: FormulaOpts = { dynamic: true }
|
||||||
): T {
|
): T {
|
||||||
return tracer.trace("processFormulas", {}, span => {
|
return tracer.trace("processFormulas", {}, span => {
|
||||||
span?.addTags({ table_id: table._id })
|
const numRows = Array.isArray(inputRows) ? inputRows.length : 1
|
||||||
|
span?.addTags({ table_id: table._id, dynamic, numRows })
|
||||||
const rows = Array.isArray(inputRows) ? inputRows : [inputRows]
|
const rows = Array.isArray(inputRows) ? inputRows : [inputRows]
|
||||||
if (rows) {
|
if (rows) {
|
||||||
for (let [column, schema] of Object.entries(table.schema)) {
|
for (let [column, schema] of Object.entries(table.schema)) {
|
||||||
|
@ -77,7 +78,7 @@ export function processFormulas<T extends Row | Row[]>(
|
||||||
rows[i] = {
|
rows[i] = {
|
||||||
...row,
|
...row,
|
||||||
[column]: tracer.trace("processStringSync", {}, span => {
|
[column]: tracer.trace("processStringSync", {}, span => {
|
||||||
span?.addTags({ column })
|
span?.addTags({ table_id: table._id, column, static: isStatic })
|
||||||
return processStringSync(formula, context)
|
return processStringSync(formula, context)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue