From 0afa65fa58404399b71db16a4e779a86cdf42f17 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Mon, 25 Jun 2018 02:44:40 -0400 Subject: [PATCH] feat: auth self-registration config + gql grouping --- client/components/admin/admin-auth.vue | 37 +++++++++++++++---- client/components/admin/admin-groups-edit.vue | 10 ++--- client/components/admin/admin-groups.vue | 8 ++-- client/components/admin/admin-locale.vue | 6 +-- client/components/admin/admin-system.vue | 2 +- client/components/admin/admin-theme.vue | 2 +- client/components/common/user-search.vue | 2 +- client/components/login.vue | 6 +-- client/components/profile.vue | 9 +++-- client/components/profile/preferences.vue | 10 +++-- client/components/profile/profile.vue | 16 ++++++-- .../auth/auth-mutation-save-strategies.gql} | 0 .../auth/auth-query-strategies.gql} | 5 ++- .../groups/groups-mutation-assign.gql} | 0 .../groups/groups-mutation-create.gql} | 0 .../groups/groups-mutation-delete.gql} | 0 .../groups/groups-mutation-unassign.gql} | 0 .../groups/groups-mutation-update.gql} | 0 .../groups/groups-query-list.gql} | 0 .../groups/groups-query-single.gql} | 0 .../locale/locale-mutation-download.gql} | 0 .../locale/locale-mutation-save.gql} | 0 .../locale/locale-query-list.gql} | 0 .../system/system-query-info.gql} | 0 .../theme/theme-mutation-save.gql} | 0 .../users/users-query-list.gql} | 0 .../{ => common}/common-locale-query.gql | 0 .../common-users-query-search.gql | 0 .../{ => login}/login-mutation-login.gql | 0 .../graph/{ => login}/login-mutation-tfa.gql | 0 .../{ => login}/login-query-strategies.gql | 0 client/modules/localization.js | 2 +- server/core/auth.js | 8 ++-- server/db/migrations/2.0.0.js | 3 ++ server/db/models/authentication.js | 19 ++++++++-- server/graph/resolvers/authentication.js | 2 +- server/graph/schemas/authentication.graphql | 3 ++ server/helpers/graph.js | 2 +- server/modules/authentication/google.js | 2 +- 39 files changed, 104 insertions(+), 50 deletions(-) rename client/graph/{admin-auth-mutation-save-strategies.gql => admin/auth/auth-mutation-save-strategies.gql} (100%) rename client/graph/{admin-auth-query-strategies.gql => admin/auth/auth-query-strategies.gql} (58%) rename client/graph/{admin-groups-mutation-assign.gql => admin/groups/groups-mutation-assign.gql} (100%) rename client/graph/{admin-groups-mutation-create.gql => admin/groups/groups-mutation-create.gql} (100%) rename client/graph/{admin-groups-mutation-delete.gql => admin/groups/groups-mutation-delete.gql} (100%) rename client/graph/{admin-groups-mutation-unassign.gql => admin/groups/groups-mutation-unassign.gql} (100%) rename client/graph/{admin-groups-mutation-update.gql => admin/groups/groups-mutation-update.gql} (100%) rename client/graph/{admin-groups-query-list.gql => admin/groups/groups-query-list.gql} (100%) rename client/graph/{admin-groups-query-single.gql => admin/groups/groups-query-single.gql} (100%) rename client/graph/{admin-locale-mutation-download.gql => admin/locale/locale-mutation-download.gql} (100%) rename client/graph/{admin-locale-mutation-save.gql => admin/locale/locale-mutation-save.gql} (100%) rename client/graph/{admin-locale-query-list.gql => admin/locale/locale-query-list.gql} (100%) rename client/graph/{admin-system-query-info.gql => admin/system/system-query-info.gql} (100%) rename client/graph/{admin-theme-mutation-save.gql => admin/theme/theme-mutation-save.gql} (100%) rename client/graph/{admin-users-query-list.gql => admin/users/users-query-list.gql} (100%) rename client/graph/{ => common}/common-locale-query.gql (100%) rename client/graph/{ => common}/common-users-query-search.gql (100%) rename client/graph/{ => login}/login-mutation-login.gql (100%) rename client/graph/{ => login}/login-mutation-tfa.gql (100%) rename client/graph/{ => login}/login-query-strategies.gql (100%) diff --git a/client/components/admin/admin-auth.vue b/client/components/admin/admin-auth.vue index 58ce5c8c..5d5cb861 100644 --- a/client/components/admin/admin-auth.vue +++ b/client/components/admin/admin-auth.vue @@ -9,7 +9,8 @@ v-tab-item(key='settings', :transition='false', :reverse-transition='false') v-card.pa-3(flat, tile) - v-subheader.pl-0.pb-2 Select which authentication strategies to enable: + .body-2.grey--text.text--darken-1 Select which authentication strategies to enable: + .caption.grey--text.pb-2 Some strategies require additional configuration in their dedicated tab (when selected). v-form v-checkbox( v-for='strategy in strategies', @@ -27,19 +28,36 @@ v-form v-subheader.pl-0 Strategy Configuration .body-1.ml-3(v-if='!strategy.config || strategy.config.length < 1') This strategy has no configuration options you can modify. - v-text-field(v-else, v-for='cfg in strategy.config', :key='cfg.key', :label='cfg.key', prepend-icon='settings_applications') + v-text-field( + v-else + v-for='cfg in strategy.config' + :key='cfg.key' + :label='cfg.key' + v-model='cfg.value' + prepend-icon='settings_applications' + ) v-divider v-subheader.pl-0 Registration v-switch.ml-3( - v-model='auths', + v-model='allowSelfRegistration', label='Allow self-registration', :value='true', color='primary', hint='Allow any user successfully authorized by the strategy to access the wiki.', persistent-hint ) - v-text-field.ml-3(label='Limit to specific email domains', prepend-icon='mail_outline') - v-text-field.ml-3(label='Assign to group', prepend-icon='people') + v-text-field.ml-3( + label='Limit to specific email domains' + prepend-icon='mail_outline' + hint='Domain(s) seperated by comma. (e.g. domain1.com, domain2.com)' + persistent-hint + ) + v-text-field.ml-3( + label='Assign to group' + prepend-icon='people' + hint='Automatically assign new users to these groups.' + persistent-hint + ) v-card-chin v-btn(color='primary') @@ -54,14 +72,17 @@ diff --git a/client/components/profile/profile.vue b/client/components/profile/profile.vue index 621a5a50..daab57fe 100644 --- a/client/components/profile/profile.vue +++ b/client/components/profile/profile.vue @@ -17,8 +17,7 @@ v-text-field(label='Name', :counter='255', v-model='name', prepend-icon='person') v-text-field(label='Job Title', :counter='255', prepend-icon='accessibility') v-text-field(label='Location / Office', :counter='255', prepend-icon='location_on') - v-divider.my-0 - v-card-actions.grey.lighten-4 + v-card-chin v-spacer v-btn(color='primary') v-icon(left) chevron_right @@ -29,8 +28,13 @@ .subheading Authentication v-card-text v-subheader.pl-0 Provider - v-toolbar(flat, color='purple lighten-5', dense).purple--text.text--darken-4 - v-icon(color='purple darken-4') supervised_user_circle + v-toolbar( + flat + :color='darkMode ? "grey darken-2" : "purple lighten-5"' + dense + :class='darkMode ? "grey--text text--lighten-1" : "purple--text text--darken-4"' + ) + v-icon(:color='darkMode ? "grey lighten-1" : "purple darken-4"') supervised_user_circle .subheading.ml-3 Local v-divider v-subheader.pl-0 Two-Factor Authentication (2FA) @@ -72,12 +76,16 @@ diff --git a/client/graph/admin-auth-mutation-save-strategies.gql b/client/graph/admin/auth/auth-mutation-save-strategies.gql similarity index 100% rename from client/graph/admin-auth-mutation-save-strategies.gql rename to client/graph/admin/auth/auth-mutation-save-strategies.gql diff --git a/client/graph/admin-auth-query-strategies.gql b/client/graph/admin/auth/auth-query-strategies.gql similarity index 58% rename from client/graph/admin-auth-query-strategies.gql rename to client/graph/admin/auth/auth-query-strategies.gql index aa3b2374..ca6ddcd1 100644 --- a/client/graph/admin-auth-query-strategies.gql +++ b/client/graph/admin/auth/auth-query-strategies.gql @@ -1,6 +1,6 @@ query { authentication { - strategies { + strategies(orderBy: "title ASC") { isEnabled key props @@ -10,6 +10,9 @@ query { key value } + selfRegistration + domainWhitelist + autoEnrollGroups } } } diff --git a/client/graph/admin-groups-mutation-assign.gql b/client/graph/admin/groups/groups-mutation-assign.gql similarity index 100% rename from client/graph/admin-groups-mutation-assign.gql rename to client/graph/admin/groups/groups-mutation-assign.gql diff --git a/client/graph/admin-groups-mutation-create.gql b/client/graph/admin/groups/groups-mutation-create.gql similarity index 100% rename from client/graph/admin-groups-mutation-create.gql rename to client/graph/admin/groups/groups-mutation-create.gql diff --git a/client/graph/admin-groups-mutation-delete.gql b/client/graph/admin/groups/groups-mutation-delete.gql similarity index 100% rename from client/graph/admin-groups-mutation-delete.gql rename to client/graph/admin/groups/groups-mutation-delete.gql diff --git a/client/graph/admin-groups-mutation-unassign.gql b/client/graph/admin/groups/groups-mutation-unassign.gql similarity index 100% rename from client/graph/admin-groups-mutation-unassign.gql rename to client/graph/admin/groups/groups-mutation-unassign.gql diff --git a/client/graph/admin-groups-mutation-update.gql b/client/graph/admin/groups/groups-mutation-update.gql similarity index 100% rename from client/graph/admin-groups-mutation-update.gql rename to client/graph/admin/groups/groups-mutation-update.gql diff --git a/client/graph/admin-groups-query-list.gql b/client/graph/admin/groups/groups-query-list.gql similarity index 100% rename from client/graph/admin-groups-query-list.gql rename to client/graph/admin/groups/groups-query-list.gql diff --git a/client/graph/admin-groups-query-single.gql b/client/graph/admin/groups/groups-query-single.gql similarity index 100% rename from client/graph/admin-groups-query-single.gql rename to client/graph/admin/groups/groups-query-single.gql diff --git a/client/graph/admin-locale-mutation-download.gql b/client/graph/admin/locale/locale-mutation-download.gql similarity index 100% rename from client/graph/admin-locale-mutation-download.gql rename to client/graph/admin/locale/locale-mutation-download.gql diff --git a/client/graph/admin-locale-mutation-save.gql b/client/graph/admin/locale/locale-mutation-save.gql similarity index 100% rename from client/graph/admin-locale-mutation-save.gql rename to client/graph/admin/locale/locale-mutation-save.gql diff --git a/client/graph/admin-locale-query-list.gql b/client/graph/admin/locale/locale-query-list.gql similarity index 100% rename from client/graph/admin-locale-query-list.gql rename to client/graph/admin/locale/locale-query-list.gql diff --git a/client/graph/admin-system-query-info.gql b/client/graph/admin/system/system-query-info.gql similarity index 100% rename from client/graph/admin-system-query-info.gql rename to client/graph/admin/system/system-query-info.gql diff --git a/client/graph/admin-theme-mutation-save.gql b/client/graph/admin/theme/theme-mutation-save.gql similarity index 100% rename from client/graph/admin-theme-mutation-save.gql rename to client/graph/admin/theme/theme-mutation-save.gql diff --git a/client/graph/admin-users-query-list.gql b/client/graph/admin/users/users-query-list.gql similarity index 100% rename from client/graph/admin-users-query-list.gql rename to client/graph/admin/users/users-query-list.gql diff --git a/client/graph/common-locale-query.gql b/client/graph/common/common-locale-query.gql similarity index 100% rename from client/graph/common-locale-query.gql rename to client/graph/common/common-locale-query.gql diff --git a/client/graph/common-users-query-search.gql b/client/graph/common/common-users-query-search.gql similarity index 100% rename from client/graph/common-users-query-search.gql rename to client/graph/common/common-users-query-search.gql diff --git a/client/graph/login-mutation-login.gql b/client/graph/login/login-mutation-login.gql similarity index 100% rename from client/graph/login-mutation-login.gql rename to client/graph/login/login-mutation-login.gql diff --git a/client/graph/login-mutation-tfa.gql b/client/graph/login/login-mutation-tfa.gql similarity index 100% rename from client/graph/login-mutation-tfa.gql rename to client/graph/login/login-mutation-tfa.gql diff --git a/client/graph/login-query-strategies.gql b/client/graph/login/login-query-strategies.gql similarity index 100% rename from client/graph/login-query-strategies.gql rename to client/graph/login/login-query-strategies.gql diff --git a/client/modules/localization.js b/client/modules/localization.js index 9ee180d4..2309dcc4 100644 --- a/client/modules/localization.js +++ b/client/modules/localization.js @@ -6,7 +6,7 @@ import _ from 'lodash' /* global siteConfig, graphQL */ -import localeQuery from 'gql/common-locale-query.gql' +import localeQuery from 'gql/common/common-locale-query.gql' module.exports = { VueI18Next, diff --git a/server/core/auth.js b/server/core/auth.js index f76da129..df7514f5 100644 --- a/server/core/auth.js +++ b/server/core/auth.js @@ -39,12 +39,14 @@ module.exports = { _.pull(currentStrategies, 'session') _.forEach(currentStrategies, stg => { passport.unuse(stg) }) - // Load enable strategies - const enabledStrategies = await WIKI.db.authentication.getEnabledStrategies() - console.info(enabledStrategies) + // Load enabled strategies + const enabledStrategies = await WIKI.db.authentication.getStrategies() for (let idx in enabledStrategies) { const stg = enabledStrategies[idx] + if (!stg.isEnabled) { continue } + const strategy = require(`../modules/authentication/${stg.key}`) + stg.config.callbackURL = `${WIKI.config.host}/login/${stg.key}/callback` // TODO: config.host strategy.init(passport, stg.config) diff --git a/server/db/migrations/2.0.0.js b/server/db/migrations/2.0.0.js index 6dda725e..f431a417 100644 --- a/server/db/migrations/2.0.0.js +++ b/server/db/migrations/2.0.0.js @@ -31,6 +31,9 @@ exports.up = knex => { table.boolean('isEnabled').notNullable().defaultTo(false) table.boolean('useForm').notNullable().defaultTo(false) table.jsonb('config').notNullable() + table.boolean('selfRegistration').notNullable().defaultTo(false) + table.jsonb('domainWhitelist').notNullable() + table.jsonb('autoEnrollGroups').notNullable() }) // COMMENTS ---------------------------- .createTable('comments', table => { diff --git a/server/db/models/authentication.js b/server/db/models/authentication.js index 6016a8b5..d9c360a8 100644 --- a/server/db/models/authentication.js +++ b/server/db/models/authentication.js @@ -22,13 +22,21 @@ module.exports = class Authentication extends Model { title: {type: 'string'}, isEnabled: {type: 'boolean'}, useForm: {type: 'boolean'}, - config: {type: 'object'} + config: {type: 'object'}, + selfRegistration: {type: 'boolean'}, + domainWhitelist: {type: 'object'}, + autoEnrollGroups: {type: 'object'} } } } - static async getEnabledStrategies() { - return WIKI.db.authentication.query().where({ isEnabled: true }) + static async getStrategies() { + const strategies = await WIKI.db.authentication.query() + return strategies.map(str => ({ + ...str, + domainWhitelist: _.get(str.domainWhitelist, 'v', []), + autoEnrollGroups: _.get(str.autoEnrollGroups, 'v', []) + })) } static async refreshStrategiesFromDisk() { @@ -46,7 +54,10 @@ module.exports = class Authentication extends Model { config: _.reduce(strategy.props, (result, value, key) => { _.set(result, value, '') return result - }, {}) + }, {}), + selfRegistration: false, + domainWhitelist: { v: [] }, + autoEnrollGroups: { v: [] } }) } }) diff --git a/server/graph/resolvers/authentication.js b/server/graph/resolvers/authentication.js index 5f88a566..7df51b21 100644 --- a/server/graph/resolvers/authentication.js +++ b/server/graph/resolvers/authentication.js @@ -16,7 +16,7 @@ module.exports = { }, AuthenticationQuery: { async strategies(obj, args, context, info) { - let strategies = await WIKI.db.authentication.getEnabledStrategies() + let strategies = await WIKI.db.authentication.getStrategies() strategies = strategies.map(stg => ({ ...stg, config: _.transform(stg.config, (res, value, key) => { diff --git a/server/graph/schemas/authentication.graphql b/server/graph/schemas/authentication.graphql index 60e4a529..d3b1b91c 100644 --- a/server/graph/schemas/authentication.graphql +++ b/server/graph/schemas/authentication.graphql @@ -56,6 +56,9 @@ type AuthenticationStrategy { useForm: Boolean! icon: String config: [KeyValuePair] + selfRegistration: Boolean! + domainWhitelist: [String]! + autoEnrollGroups: [String]! } type AuthenticationLoginResponse { diff --git a/server/helpers/graph.js b/server/helpers/graph.js index c8b03a3d..93443241 100644 --- a/server/helpers/graph.js +++ b/server/helpers/graph.js @@ -24,7 +24,7 @@ module.exports = { return arr.filter(prvFilter.test) }, orderBy (arr, orderString) { - let orderParams = _.zip(orderString.split(',').map(ord => _.trim(ord).split(' ').map(_.trim))) + let orderParams = _.zip(...orderString.split(',').map(ord => _.trim(ord).split(' ').map(_.trim))) return _.orderBy(arr, orderParams[0], orderParams[1]) } } diff --git a/server/modules/authentication/google.js b/server/modules/authentication/google.js index 2553995b..100bb038 100644 --- a/server/modules/authentication/google.js +++ b/server/modules/authentication/google.js @@ -8,7 +8,7 @@ const GoogleStrategy = require('passport-google-oauth20').Strategy module.exports = { key: 'google', - title: 'Google ID', + title: 'Google', useForm: false, props: ['clientId', 'clientSecret'], init (passport, conf) {