From 2e0f861fb2b05be1aa88201994810b816858c1f0 Mon Sep 17 00:00:00 2001 From: Nick Date: Sun, 29 Sep 2019 20:53:41 -0400 Subject: [PATCH] feat: import users group creation logic --- client/themes/default/scss/app.scss | 21 +++++-- server/graph/resolvers/system.js | 86 +++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 4 deletions(-) diff --git a/client/themes/default/scss/app.scss b/client/themes/default/scss/app.scss index 4902ac7b..dfa014c8 100644 --- a/client/themes/default/scss/app.scss +++ b/client/themes/default/scss/app.scss @@ -1,6 +1,6 @@ /* THEME SPECIFIC STYLES */ -.v-application .contents { +.v-content .contents { color: mc('grey', '800'); padding: .5rem 0 50px; position: relative; @@ -464,7 +464,7 @@ display: none; } - @at-root .v-application.theme--dark .contents code { + @at-root .theme--dark & { background-color: darken(mc('grey', '900'), 5%); color: mc('indigo', '100'); } @@ -697,7 +697,8 @@ .v-navigation-drawer, .v-footer, .v-btn--fab, - .page-col-sd + .page-col-sd, + .v-tooltip__content { display: none !important; } @@ -721,13 +722,25 @@ .v-content { padding: 0 !important; font-size: 14px; + background-color: #FFF; } - .v-application .contents { + .v-content .contents { + color: #000; + background-color: #FFF; + + @at-root .theme--dark & { + color: #000; + } + .prismjs{ box-shadow: none; background-color: #FFF; + @at-root .theme--dark & { + background-color: #FFF; + } + > code { color: #000; box-shadow: none; diff --git a/server/graph/resolvers/system.js b/server/graph/resolvers/system.js index 4f2261f1..7b867d1b 100644 --- a/server/graph/resolvers/system.js +++ b/server/graph/resolvers/system.js @@ -8,6 +8,8 @@ const fs = require('fs-extra') const moment = require('moment') const graphHelper = require('../../helpers/graph') const request = require('request-promise') +const crypto = require('crypto') +const nanoid = require('nanoid/non-secure/generate') /* global WIKI */ @@ -85,28 +87,106 @@ module.exports = { return graphHelper.generateError(err) } }, + /** + * Import Users from a v1 installation + */ async importUsersFromV1(obj, args, context) { try { const MongoClient = require('mongodb').MongoClient if (args.mongoDbConnString && args.mongoDbConnString.length > 10) { + // -> Connect to DB + const client = await MongoClient.connect(args.mongoDbConnString, { appname: `Wiki.js ${WIKI.version} Migration Tool` }) const dbUsers = client.db().collection('users') const userCursor = dbUsers.find({ email: { '$ne': 'guest' } }) + const curDateISO = new Date().toISOString() + let failed = [] let usersCount = 0 let groupsCount = 0 + let assignableGroups = [] + let reuseGroups = [] + + // -> Create SINGLE group + + if (args.groupMode === `SINGLE`) { + const singleGroup = await WIKI.models.groups.query().insert({ + name: `Import_${curDateISO}`, + permissions: JSON.stringify(WIKI.data.groups.defaultPermissions), + pageRules: JSON.stringify(WIKI.data.groups.defaultPageRules) + }) + groupsCount++ + assignableGroups.push(singleGroup.id) + } + + // -> Iterate all users while (await userCursor.hasNext()) { const usr = await userCursor.next() + + let usrGroup = [] + if (args.groupMode === `MULTI`) { + // -> Check if global admin + + if (_.some(usr.rights, ['role', 'admin'])) { + usrGroup.push(1) + } else { + // -> Check if identical group already exists + + const currentRights = _.sortBy(_.map(usr.rights, r => _.pick(r, ['role', 'path', 'exact', 'deny'])), ['role', 'path', 'exact', 'deny']) + const ruleSetId = crypto.createHash('sha1').update(JSON.stringify(currentRights)).digest('base64') + const existingGroup = _.find(reuseGroups, ['hash', ruleSetId]) + if (existingGroup) { + usrGroup.push(existingGroup.groupId) + } else { + // -> Build new group + + const pageRules = _.map(usr.rights, r => { + let roles = ['read:pages', 'read:assets', 'read:comments', 'write:comments'] + if (r.role === `write`) { + roles = _.concat(roles, ['write:pages', 'manage:pages', 'read:source', 'read:history', 'write:assets', 'manage:assets']) + } + return { + id: nanoid('1234567890abcdef', 10), + roles: roles, + match: r.exact ? 'EXACT' : 'START', + deny: r.deny, + path: (r.path.indexOf('/') === 0) ? r.path.substring(1) : r.path, + locales: [] + } + }) + + const perms = _.chain(pageRules).reject('deny').map('roles').union().flatten().value() + + // -> Create new group + + const newGroup = await WIKI.models.groups.query().insert({ + name: `Import_${curDateISO}_${groupsCount + 1}`, + permissions: JSON.stringify(perms), + pageRules: JSON.stringify(pageRules) + }) + reuseGroups.push({ + groupId: newGroup.id, + hash: ruleSetId + }) + groupsCount++ + usrGroup.push(newGroup.id) + } + } + } + + // -> Create User + try { await WIKI.models.users.createNewUser({ providerKey: usr.provider, email: usr.email, name: usr.name, passwordRaw: usr.password, + groups: (usrGroup.length > 0) ? usrGroup : assignableGroups, mustChangePassword: false, sendWelcomeEmail: false }) @@ -121,6 +201,12 @@ module.exports = { } } + // -> Reload group permissions + + if (args.groupMode !== `NONE`) { + await WIKI.auth.reloadGroups() + } + client.close() return { responseResult: graphHelper.generateSuccess('Import completed.'),