Renaming groups to workspaces.

This commit is contained in:
mike12345567 2021-07-13 17:27:04 +01:00
parent e692223661
commit 004f719dde
14 changed files with 70 additions and 74 deletions

View File

@ -12,7 +12,7 @@ exports.GlobalRoles = {
OWNER: "owner",
ADMIN: "admin",
BUILDER: "builder",
GROUP_MANAGER: "group_manager",
WORKSPACE_MANAGER: "workspace_manager",
}
exports.Configs = {

View File

@ -19,7 +19,7 @@ exports.StaticDatabases = {
const DocumentTypes = {
USER: "us",
GROUP: "group",
WORKSPACE: "workspace",
CONFIG: "config",
TEMPLATE: "template",
APP: "app",
@ -61,21 +61,21 @@ function getDocParams(docType, docId = null, otherProps = {}) {
}
/**
* Generates a new group ID.
* @returns {string} The new group ID which the group doc can be stored under.
* Generates a new workspace ID.
* @returns {string} The new workspace ID which the workspace doc can be stored under.
*/
exports.generateGroupID = () => {
return `${DocumentTypes.GROUP}${SEPARATOR}${newid()}`
exports.generateWorkspaceID = () => {
return `${DocumentTypes.WORKSPACE}${SEPARATOR}${newid()}`
}
/**
* Gets parameters for retrieving groups.
* Gets parameters for retrieving workspaces.
*/
exports.getGroupParams = (id = "", otherProps = {}) => {
exports.getWorkspaceParams = (id = "", otherProps = {}) => {
return {
...otherProps,
startkey: `${DocumentTypes.GROUP}${SEPARATOR}${id}`,
endkey: `${DocumentTypes.GROUP}${SEPARATOR}${id}${UNICODE_MAX}`,
startkey: `${DocumentTypes.WORKSPACE}${SEPARATOR}${id}`,
endkey: `${DocumentTypes.WORKSPACE}${SEPARATOR}${id}${UNICODE_MAX}`,
}
}
@ -103,14 +103,14 @@ exports.getGlobalUserParams = (globalId, otherProps = {}) => {
/**
* Generates a template ID.
* @param ownerId The owner/user of the template, this could be global or a group level.
* @param ownerId The owner/user of the template, this could be global or a workspace level.
*/
exports.generateTemplateID = ownerId => {
return `${DocumentTypes.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}${newid()}`
}
/**
* Gets parameters for retrieving templates. Owner ID must be specified, either global or a group level.
* Gets parameters for retrieving templates. Owner ID must be specified, either global or a workspace level.
*/
exports.getTemplateParams = (ownerId, templateId, otherProps = {}) => {
if (!templateId) {
@ -214,8 +214,8 @@ exports.dbExists = async (CouchDB, dbName) => {
* Generates a new configuration ID.
* @returns {string} The new configuration ID which the config doc can be stored under.
*/
const generateConfigID = ({ type, group, user }) => {
const scope = [type, group, user].filter(Boolean).join(SEPARATOR)
const generateConfigID = ({ type, workspace, user }) => {
const scope = [type, workspace, user].filter(Boolean).join(SEPARATOR)
return `${DocumentTypes.CONFIG}${SEPARATOR}${scope}`
}
@ -223,8 +223,8 @@ const generateConfigID = ({ type, group, user }) => {
/**
* Gets parameters for retrieving configurations.
*/
const getConfigParams = ({ type, group, user }, otherProps = {}) => {
const scope = [type, group, user].filter(Boolean).join(SEPARATOR)
const getConfigParams = ({ type, workspace, user }, otherProps = {}) => {
const scope = [type, workspace, user].filter(Boolean).join(SEPARATOR)
return {
...otherProps,
@ -234,15 +234,15 @@ const getConfigParams = ({ type, group, user }, otherProps = {}) => {
}
/**
* Returns the most granular configuration document from the DB based on the type, group and userID passed.
* Returns the most granular configuration document from the DB based on the type, workspace and userID passed.
* @param {Object} db - db instance to query
* @param {Object} scopes - the type, group and userID scopes of the configuration.
* @param {Object} scopes - the type, workspace and userID scopes of the configuration.
* @returns The most granular configuration document based on the scope.
*/
const getScopedFullConfig = async function (db, { type, user, group }) {
const getScopedFullConfig = async function (db, { type, user, workspace }) {
const response = await db.allDocs(
getConfigParams(
{ type, user, group },
{ type, user, workspace },
{
include_docs: true,
}
@ -252,14 +252,14 @@ const getScopedFullConfig = async function (db, { type, user, group }) {
function determineScore(row) {
const config = row.doc
// Config is specific to a user and a group
if (config._id.includes(generateConfigID({ type, user, group }))) {
// Config is specific to a user and a workspace
if (config._id.includes(generateConfigID({ type, user, workspace }))) {
return 4
} else if (config._id.includes(generateConfigID({ type, user }))) {
// Config is specific to a user only
return 3
} else if (config._id.includes(generateConfigID({ type, group }))) {
// Config is specific to a group only
} else if (config._id.includes(generateConfigID({ type, workspace }))) {
// Config is specific to a workspace only
return 2
} else if (config._id.includes(generateConfigID({ type }))) {
// Config is specific to a type only

View File

@ -19,7 +19,7 @@ module.exports.definition = {
properties: {
text: {
type: "string",
title: "URL",
title: "Log",
},
},
required: ["text"],

View File

@ -102,7 +102,7 @@ exports.googlePreAuth = async (ctx, next) => {
const db = new CouchDB(GLOBAL_DB)
const config = await authPkg.db.getScopedConfig(db, {
type: Configs.GOOGLE,
group: ctx.query.group,
workspace: ctx.query.workspace,
})
const strategy = await google.strategyFactory(config)
@ -116,7 +116,7 @@ exports.googleAuth = async (ctx, next) => {
const config = await authPkg.db.getScopedConfig(db, {
type: Configs.GOOGLE,
group: ctx.query.group,
workspace: ctx.query.workspace,
})
const strategy = await google.strategyFactory(config)

View File

@ -16,13 +16,13 @@ const GLOBAL_DB = StaticDatabases.GLOBAL.name
exports.save = async function (ctx) {
const db = new CouchDB(GLOBAL_DB)
const { type, group, user, config } = ctx.request.body
const { type, workspace, user, config } = ctx.request.body
// Config does not exist yet
if (!ctx.request.body._id) {
ctx.request.body._id = generateConfigID({
type,
group,
workspace,
user,
})
}
@ -65,17 +65,17 @@ exports.fetch = async function (ctx) {
/**
* Gets the most granular config for a particular configuration type.
* The hierarchy is type -> group -> user.
* The hierarchy is type -> workspace -> user.
*/
exports.find = async function (ctx) {
const db = new CouchDB(GLOBAL_DB)
const { userId, groupId } = ctx.query
if (groupId && userId) {
const group = await db.get(groupId)
const userInGroup = group.users.some(groupUser => groupUser === userId)
if (!ctx.user.admin && !userInGroup) {
ctx.throw(400, `User is not in specified group: ${group}.`)
const { userId, workspaceId } = ctx.query
if (workspaceId && userId) {
const workspace = await db.get(workspaceId)
const userInWorkspace = workspace.users.some(workspaceUser => workspaceUser === userId)
if (!ctx.user.admin && !userInWorkspace) {
ctx.throw(400, `User is not in specified workspace: ${workspace}.`)
}
}
@ -84,7 +84,7 @@ exports.find = async function (ctx) {
const scopedConfig = await getScopedFullConfig(db, {
type: ctx.params.type,
user: userId,
group: groupId,
workspace: workspaceId,
})
if (scopedConfig) {

View File

@ -5,7 +5,7 @@ const authPkg = require("@budibase/auth")
const GLOBAL_DB = authPkg.StaticDatabases.GLOBAL.name
exports.sendEmail = async ctx => {
const { groupId, email, userId, purpose, contents, from, subject } =
const { workspaceId, email, userId, purpose, contents, from, subject } =
ctx.request.body
let user
if (userId) {
@ -13,7 +13,7 @@ exports.sendEmail = async ctx => {
user = await db.get(userId)
}
const response = await sendEmail(email, purpose, {
groupId,
workspaceId,
user,
contents,
from,

View File

@ -1,20 +1,20 @@
const CouchDB = require("../../../db")
const { getGroupParams, generateGroupID, StaticDatabases } =
const { getWorkspaceParams, generateWorkspaceID, StaticDatabases } =
require("@budibase/auth").db
const GLOBAL_DB = StaticDatabases.GLOBAL.name
exports.save = async function (ctx) {
const db = new CouchDB(GLOBAL_DB)
const groupDoc = ctx.request.body
const workspaceDoc = ctx.request.body
// Group does not exist yet
if (!groupDoc._id) {
groupDoc._id = generateGroupID()
// workspace does not exist yet
if (!workspaceDoc._id) {
workspaceDoc._id = generateWorkspaceID()
}
try {
const response = await db.post(groupDoc)
const response = await db.post(workspaceDoc)
ctx.body = {
_id: response.id,
_rev: response.rev,
@ -27,7 +27,7 @@ exports.save = async function (ctx) {
exports.fetch = async function (ctx) {
const db = new CouchDB(GLOBAL_DB)
const response = await db.allDocs(
getGroupParams(undefined, {
getWorkspaceParams(undefined, {
include_docs: true,
})
)
@ -49,7 +49,7 @@ exports.destroy = async function (ctx) {
try {
await db.remove(id, rev)
ctx.body = { message: "Group deleted successfully" }
ctx.body = { message: "Workspace deleted successfully" }
} catch (err) {
ctx.throw(err.status, err)
}

View File

@ -46,7 +46,7 @@ function buildConfigSaveValidation() {
return joiValidator.body(Joi.object({
_id: Joi.string().optional(),
_rev: Joi.string().optional(),
group: Joi.string().optional(),
workspace: Joi.string().optional(),
type: Joi.string().valid(...Object.values(Configs)).required(),
config: Joi.alternatives()
.conditional("type", {

View File

@ -12,8 +12,8 @@ function buildEmailSendValidation() {
return joiValidator.body(Joi.object({
email: Joi.string().email(),
purpose: Joi.string().valid(...Object.values(EmailTemplatePurpose)),
groupId: Joi.string().allow("", null),
fromt: Joi.string().allow("", null),
workspaceId: Joi.string().allow("", null),
from: Joi.string().allow("", null),
contents: Joi.string().allow("", null),
subject: Joi.string().allow("", null),
}).required().unknown(true))

View File

@ -1,12 +1,12 @@
const Router = require("@koa/router")
const controller = require("../../controllers/admin/groups")
const controller = require("../../controllers/admin/workspaces")
const joiValidator = require("../../../middleware/joi-validator")
const adminOnly = require("../../../middleware/adminOnly")
const Joi = require("joi")
const router = Router()
function buildGroupSaveValidation() {
function buildWorkspaceSaveValidation() {
// prettier-ignore
return joiValidator.body(Joi.object({
_id: Joi.string().optional(),
@ -26,13 +26,13 @@ function buildGroupSaveValidation() {
router
.post(
"/api/admin/groups",
"/api/admin/workspaces",
adminOnly,
buildGroupSaveValidation(),
buildWorkspaceSaveValidation(),
controller.save
)
.get("/api/admin/groups", controller.fetch)
.delete("/api/admin/groups/:id", adminOnly, controller.destroy)
.get("/api/admin/groups/:id", controller.find)
.delete("/api/admin/workspaces/:id", adminOnly, controller.destroy)
.get("/api/admin/workspaces", controller.fetch)
.get("/api/admin/workspaces/:id", controller.find)
module.exports = router

View File

@ -1,6 +1,6 @@
const userRoutes = require("./admin/users")
const configRoutes = require("./admin/configs")
const groupRoutes = require("./admin/groups")
const workspaceRoutes = require("./admin/workspaces")
const templateRoutes = require("./admin/templates")
const emailRoutes = require("./admin/email")
const authRoutes = require("./admin/auth")
@ -11,7 +11,7 @@ const appRoutes = require("./app")
exports.routes = [
configRoutes,
userRoutes,
groupRoutes,
workspaceRoutes,
authRoutes,
appRoutes,
templateRoutes,

View File

@ -1,6 +1,6 @@
module.exports = {
email: require("../../../controllers/admin/email"),
groups: require("../../../controllers/admin/groups"),
workspaces: require("../../../controllers/admin/workspaces"),
config: require("../../../controllers/admin/configs"),
templates: require("../../../controllers/admin/templates"),
users: require("../../../controllers/admin/users"),

View File

@ -8,10 +8,6 @@ exports.UserStatus = {
INACTIVE: "inactive",
}
exports.Groups = {
ALL_USERS: "all_users",
}
exports.Configs = Configs
exports.ConfigUploads = {

View File

@ -101,31 +101,31 @@ async function buildEmail(purpose, email, context, { user, contents } = {}) {
/**
* Utility function for finding most valid SMTP configuration.
* @param {object} db The CouchDB database which is to be looked up within.
* @param {string|null} groupId If using finer grain control of configs a group can be used.
* @param {string|null} workspaceId If using finer grain control of configs a workspace can be used.
* @return {Promise<object|null>} returns the SMTP configuration if it exists
*/
async function getSmtpConfiguration(db, groupId = null) {
async function getSmtpConfiguration(db, workspaceId = null) {
const params = {
type: Configs.SMTP,
}
if (groupId) {
params.group = groupId
if (workspaceId) {
params.workspace = workspaceId
}
return getScopedConfig(db, params)
}
/**
* Checks if a SMTP config exists based on passed in parameters.
* @param groupId
* @param workspaceId
* @return {Promise<boolean>} returns true if there is a configuration that can be used.
*/
exports.isEmailConfigured = async (groupId = null) => {
exports.isEmailConfigured = async (workspaceId = null) => {
// when "testing" simply return true
if (TEST_MODE) {
return true
}
const db = new CouchDB(GLOBAL_DB)
const config = await getSmtpConfiguration(db, groupId)
const config = await getSmtpConfiguration(db, workspaceId)
return config != null
}
@ -134,7 +134,7 @@ exports.isEmailConfigured = async (groupId = null) => {
* send an email using it.
* @param {string} email The email address to send to.
* @param {string} purpose The purpose of the email being sent (e.g. reset password).
* @param {string|undefined} groupId If finer grain controls being used then this will lookup config for group.
* @param {string|undefined} workspaceId If finer grain controls being used then this will lookup config for workspace.
* @param {object|undefined} user If sending to an existing user the object can be provided, this is used in the context.
* @param {string|undefined} from If sending from an address that is not what is configured in the SMTP config.
* @param {string|undefined} contents If sending a custom email then can supply contents which will be added to it.
@ -146,10 +146,10 @@ exports.isEmailConfigured = async (groupId = null) => {
exports.sendEmail = async (
email,
purpose,
{ groupId, user, from, contents, subject, info } = {}
{ workspaceId, user, from, contents, subject, info } = {}
) => {
const db = new CouchDB(GLOBAL_DB)
let config = (await getSmtpConfiguration(db, groupId)) || {}
let config = (await getSmtpConfiguration(db, workspaceId)) || {}
if (Object.keys(config).length === 0 && !TEST_MODE) {
throw "Unable to find SMTP configuration."
}