Syncing user metadata when builder opened as well as including all global user props for filtering/searching.

This commit is contained in:
Michael Drury 2021-11-03 22:23:00 +00:00
parent 80789824b8
commit 311fe5f2eb
3 changed files with 59 additions and 14 deletions

View File

@ -44,6 +44,7 @@ const {
revertClientLibrary, revertClientLibrary,
} = require("../../utilities/fileSystem/clientLibrary") } = require("../../utilities/fileSystem/clientLibrary")
const { getTenantId, isMultiTenant } = require("@budibase/auth/tenancy") const { getTenantId, isMultiTenant } = require("@budibase/auth/tenancy")
const { syncGlobalUsers } = require("./user")
const URL_REGEX_SLASH = /\/|\\/g const URL_REGEX_SLASH = /\/|\\/g
@ -328,6 +329,8 @@ exports.sync = async ctx => {
if (!isDevAppID(appId)) { if (!isDevAppID(appId)) {
ctx.throw(400, "This action cannot be performed for production apps") ctx.throw(400, "This action cannot be performed for production apps")
} }
// replicate prod to dev
const prodAppId = getDeployedAppID(appId) const prodAppId = getDeployedAppID(appId)
const replication = new Replication({ const replication = new Replication({
source: prodAppId, source: prodAppId,
@ -343,6 +346,10 @@ exports.sync = async ctx => {
} catch (err) { } catch (err) {
error = err error = err
} }
// sync the users
await syncGlobalUsers(appId)
if (error) { if (error) {
ctx.throw(400, error) ctx.throw(400, error)
} else { } else {

View File

@ -14,6 +14,8 @@ exports.fetchSelf = async ctx => {
} }
const user = await getFullUser(ctx, userId) const user = await getFullUser(ctx, userId)
// this shouldn't be returned by the app self
delete user.roles
if (appId) { if (appId) {
const db = new CouchDB(appId) const db = new CouchDB(appId)
@ -36,6 +38,7 @@ exports.fetchSelf = async ctx => {
// user has a role of some sort, return them // user has a role of some sort, return them
else if (err.status === 404) { else if (err.status === 404) {
const metadata = { const metadata = {
...user,
_id: userId, _id: userId,
} }
const dbResp = await db.put(metadata) const dbResp = await db.put(metadata)

View File

@ -6,25 +6,58 @@ const {
const { InternalTables } = require("../../db/utils") const { InternalTables } = require("../../db/utils")
const { getGlobalUsers } = require("../../utilities/global") const { getGlobalUsers } = require("../../utilities/global")
const { getFullUser } = require("../../utilities/users") const { getFullUser } = require("../../utilities/users")
const { isEqual } = require("lodash")
const { BUILTIN_ROLE_IDS } = require("@budibase/auth/roles")
function removeGlobalProps(user) { exports.rawMetadata = async db => {
// make sure to always remove some of the global user props return (
delete user.password await db.allDocs(
delete user.roles
delete user.builder
return user
}
exports.fetchMetadata = async function (ctx) {
const database = new CouchDB(ctx.appId)
const global = await getGlobalUsers(ctx.appId)
const metadata = (
await database.allDocs(
getUserMetadataParams(null, { getUserMetadataParams(null, {
include_docs: true, include_docs: true,
}) })
) )
).rows.map(row => row.doc) ).rows.map(row => row.doc)
}
exports.syncGlobalUsers = async appId => {
// sync user metadata
const db = new CouchDB(appId)
const [users, metadata] = await Promise.all([
getGlobalUsers(appId),
exports.rawMetadata(db),
])
const toWrite = []
for (let user of users) {
// skip users with no access
if (user.roleId === BUILTIN_ROLE_IDS.PUBLIC) {
continue
}
delete user._rev
const metadataId = generateUserMetadataID(user._id)
const newDoc = {
...user,
_id: metadataId,
tableId: InternalTables.USER_METADATA,
}
const found = metadata.find(doc => doc._id === metadataId)
// copy rev over for the purposes of equality check
if (found) {
newDoc._rev = found._rev
}
if (found == null || !isEqual(newDoc, found)) {
toWrite.push({
...found,
...newDoc,
})
}
}
await db.bulkDocs(toWrite)
}
exports.fetchMetadata = async function (ctx) {
const database = new CouchDB(ctx.appId)
const global = await getGlobalUsers(ctx.appId)
const metadata = await exports.rawMetadata(database)
const users = [] const users = []
for (let user of global) { for (let user of global) {
// find the metadata that matches up to the global ID // find the metadata that matches up to the global ID
@ -52,7 +85,9 @@ exports.updateSelfMetadata = async function (ctx) {
exports.updateMetadata = async function (ctx) { exports.updateMetadata = async function (ctx) {
const appId = ctx.appId const appId = ctx.appId
const db = new CouchDB(appId) const db = new CouchDB(appId)
const user = removeGlobalProps(ctx.request.body) const user = ctx.request.body
// this isn't applicable to the user
delete user.roles
const metadata = { const metadata = {
tableId: InternalTables.USER_METADATA, tableId: InternalTables.USER_METADATA,
...user, ...user,