2021-06-08 17:06:30 +02:00
|
|
|
const {
|
|
|
|
getMultiIDParams,
|
|
|
|
getGlobalIDFromUserMetadataID,
|
|
|
|
} = require("../db/utils")
|
2022-01-10 20:33:00 +01:00
|
|
|
const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
|
|
|
|
const { getDeployedAppID } = require("@budibase/backend-core/db")
|
|
|
|
const { getGlobalUserParams } = require("@budibase/backend-core/db")
|
|
|
|
const { user: userCache } = require("@budibase/backend-core/cache")
|
|
|
|
const {
|
|
|
|
getGlobalDB,
|
|
|
|
isUserInAppTenant,
|
|
|
|
} = require("@budibase/backend-core/tenancy")
|
2021-10-07 16:49:26 +02:00
|
|
|
const env = require("../environment")
|
2021-06-08 17:06:30 +02:00
|
|
|
|
|
|
|
exports.updateAppRole = (appId, user) => {
|
2021-10-07 16:49:26 +02:00
|
|
|
if (!user || !user.roles) {
|
|
|
|
return user
|
|
|
|
}
|
|
|
|
// if in an multi-tenancy environment make sure roles are never updated
|
|
|
|
if (env.MULTI_TENANCY && !isUserInAppTenant(appId, user)) {
|
|
|
|
delete user.builder
|
|
|
|
delete user.admin
|
|
|
|
user.roleId = BUILTIN_ROLE_IDS.PUBLIC
|
2021-06-08 17:06:30 +02:00
|
|
|
return user
|
|
|
|
}
|
2021-06-14 16:23:24 +02:00
|
|
|
// always use the deployed app
|
|
|
|
user.roleId = user.roles[getDeployedAppID(appId)]
|
|
|
|
// if a role wasn't found then either set as admin (builder) or public (everyone else)
|
|
|
|
if (!user.roleId && user.builder && user.builder.global) {
|
2021-06-08 17:06:30 +02:00
|
|
|
user.roleId = BUILTIN_ROLE_IDS.ADMIN
|
2021-06-14 16:23:24 +02:00
|
|
|
} else if (!user.roleId) {
|
2021-10-12 11:05:57 +02:00
|
|
|
user.roleId = BUILTIN_ROLE_IDS.PUBLIC
|
2021-06-08 17:06:30 +02:00
|
|
|
}
|
|
|
|
delete user.roles
|
|
|
|
return user
|
|
|
|
}
|
|
|
|
|
2021-07-06 19:10:04 +02:00
|
|
|
function processUser(appId, user) {
|
2021-06-08 17:06:30 +02:00
|
|
|
if (user) {
|
|
|
|
delete user.password
|
|
|
|
}
|
|
|
|
return exports.updateAppRole(appId, user)
|
|
|
|
}
|
|
|
|
|
2021-07-06 19:10:04 +02:00
|
|
|
exports.getCachedSelf = async (ctx, appId) => {
|
2021-08-05 10:59:08 +02:00
|
|
|
// this has to be tenant aware, can't depend on the context to find it out
|
|
|
|
// running some middlewares before the tenancy causes context to break
|
2021-08-03 16:32:25 +02:00
|
|
|
const user = await userCache.getUser(ctx.user._id)
|
2021-07-06 19:10:04 +02:00
|
|
|
return processUser(appId, user)
|
|
|
|
}
|
|
|
|
|
2021-11-04 00:15:38 +01:00
|
|
|
exports.getRawGlobalUser = async userId => {
|
2021-08-05 10:59:08 +02:00
|
|
|
const db = getGlobalDB()
|
2021-11-04 00:15:38 +01:00
|
|
|
return db.get(getGlobalIDFromUserMetadataID(userId))
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.getGlobalUser = async (appId, userId) => {
|
|
|
|
let user = await exports.getRawGlobalUser(userId)
|
2021-07-06 19:10:04 +02:00
|
|
|
return processUser(appId, user)
|
|
|
|
}
|
|
|
|
|
2021-09-02 18:13:00 +02:00
|
|
|
exports.getGlobalUsers = async (appId = null, users = null) => {
|
2021-08-05 10:59:08 +02:00
|
|
|
const db = getGlobalDB()
|
2021-06-08 17:06:30 +02:00
|
|
|
let globalUsers
|
|
|
|
if (users) {
|
|
|
|
const globalIds = users.map(user => getGlobalIDFromUserMetadataID(user._id))
|
|
|
|
globalUsers = (await db.allDocs(getMultiIDParams(globalIds))).rows.map(
|
|
|
|
row => row.doc
|
|
|
|
)
|
|
|
|
} else {
|
2021-06-08 17:11:46 +02:00
|
|
|
globalUsers = (
|
|
|
|
await db.allDocs(
|
|
|
|
getGlobalUserParams(null, {
|
|
|
|
include_docs: true,
|
|
|
|
})
|
|
|
|
)
|
|
|
|
).rows.map(row => row.doc)
|
2021-06-08 17:06:30 +02:00
|
|
|
}
|
2021-06-08 17:11:46 +02:00
|
|
|
globalUsers = globalUsers
|
|
|
|
.filter(user => user != null)
|
|
|
|
.map(user => {
|
|
|
|
delete user.password
|
2021-11-04 15:53:03 +01:00
|
|
|
delete user.forceResetPassword
|
2021-06-08 17:11:46 +02:00
|
|
|
return user
|
|
|
|
})
|
2021-06-08 17:06:30 +02:00
|
|
|
if (!appId) {
|
|
|
|
return globalUsers
|
|
|
|
}
|
|
|
|
return globalUsers.map(user => exports.updateAppRole(appId, user))
|
2021-06-08 17:11:46 +02:00
|
|
|
}
|
2021-09-02 18:13:00 +02:00
|
|
|
|
|
|
|
exports.getGlobalUsersFromMetadata = async (appId, users) => {
|
|
|
|
const globalUsers = await exports.getGlobalUsers(appId, users)
|
|
|
|
return users.map(user => {
|
|
|
|
const globalUser = globalUsers.find(
|
|
|
|
globalUser => globalUser && user._id.includes(globalUser._id)
|
|
|
|
)
|
|
|
|
return {
|
|
|
|
...globalUser,
|
|
|
|
// doing user second overwrites the id and rev (always metadata)
|
|
|
|
...user,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|