Browse Source

feat: admin auth - save config

pull/621/head
NGPixel 6 years ago
parent
commit
2500d8b054
6 changed files with 137 additions and 48 deletions
  1. 32
      client/app.js
  2. 101
      client/components/admin/admin-auth.vue
  3. 6
      client/graph/admin/auth/auth-mutation-save-strategies.gql
  4. 8
      client/graph/admin/auth/auth-query-groups.gql
  5. 21
      server/graph/resolvers/authentication.js
  6. 17
      server/graph/schemas/authentication.graphql

32
client/app.js

@ -49,11 +49,33 @@ moment.locale(siteConfig.lang)
const graphQLEndpoint = window.location.protocol + '//' + window.location.host + '/graphql'
const graphQLLink = createPersistedQueryLink().concat(createHttpLink({
includeExtensions: true,
uri: graphQLEndpoint,
credentials: 'include'
}))
const graphQLLink = createPersistedQueryLink().concat(
createHttpLink({
includeExtensions: true,
uri: graphQLEndpoint,
credentials: 'include',
fetch: (uri, options) => {
// Strip __typename fields from variables
let body = JSON.parse(options.body)
// body = body.map(bd => {
// return ({
// ...bd,
// variables: JSON.parse(JSON.stringify(bd.variables), (key, value) => { return key === '__typename' ? undefined : value })
// })
// })
body = {
...body,
variables: JSON.parse(JSON.stringify(body.variables), (key, value) => { return key === '__typename' ? undefined : value })
}
options.body = JSON.stringify(body)
// Inject authentication token
options.headers.Authorization = `Bearer TODO`
return fetch(uri, options)
}
})
)
window.graphQL = new ApolloClient({
link: graphQLLink,

101
client/components/admin/admin-auth.vue

@ -13,12 +13,11 @@
.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',
v-model='selectedStrategies',
:key='strategy.key',
:label='strategy.title',
:value='strategy.key',
color='primary',
v-for='strategy in strategies'
v-model='strategy.isEnabled'
:key='strategy.key'
:label='strategy.title'
color='primary'
:disabled='strategy.key === `local`'
hide-details
)
@ -38,29 +37,43 @@
)
v-divider
v-subheader.pl-0 Registration
v-switch.ml-3(
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'
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
.pr-3
v-switch.ml-3(
v-model='strategy.selfRegistration'
label='Allow self-registration'
color='primary'
hint='Allow any user successfully authorized by the strategy to access the wiki.'
persistent-hint
)
v-select.ml-3(
label='Limit to specific email domains'
v-model='strategy.domainWhitelist'
prepend-icon='mail_outline'
persistent-hint
deletable-chips
clearable
multiple
chips
tags
)
v-select.ml-3(
:items='groups'
item-text='name'
item-value='id'
label='Assign to group'
v-model='strategy.autoEnrollGroups'
prepend-icon='people'
hint='Automatically assign new users to these groups.'
persistent-hint
deletable-chips
autocomplete
clearable
multiple
chips
)
v-card-chin
v-btn(color='primary')
v-btn(color='primary', @click='save')
v-icon(left) chevron_right
span Save
v-spacer
@ -72,22 +85,20 @@
<script>
import _ from 'lodash'
import groupsQuery from 'gql/admin/auth/auth-query-groups.gql'
import strategiesQuery from 'gql/admin/auth/auth-query-strategies.gql'
import strategiesSaveMutation from 'gql/admin/auth/auth-mutation-save-strategies.gql'
export default {
data() {
return {
strategies: [],
selectedStrategies: ['local'],
selfRegistration: false,
domainWhitelist: [],
autoEnrollGroups: []
groups: [],
strategies: []
}
},
computed: {
activeStrategies() {
return _.filter(this.strategies, prv => _.includes(this.selectedStrategies, prv.key))
return _.filter(this.strategies, 'isEnabled')
}
},
methods: {
@ -99,14 +110,26 @@ export default {
icon: 'cached'
})
},
async saveProviders() {
async save() {
this.$store.commit(`loadingStart`, 'admin-auth-savestrategies')
await this.$apollo.mutate({
mutation: strategiesSaveMutation,
variables: {
strategies: this.auths
strategies: this.strategies.map(str => _.pick(str, [
'isEnabled',
'key',
'config',
'selfRegistration',
'domainWhitelist',
'autoEnrollGroups'
]))
}
})
this.$store.commit('showNotification', {
message: 'Strategies saved successfully.',
style: 'success',
icon: 'check'
})
this.$store.commit(`loadingStop`, 'admin-auth-savestrategies')
}
},
@ -114,10 +137,18 @@ export default {
strategies: {
query: strategiesQuery,
fetchPolicy: 'network-only',
update: (data) => data.authentication.strategies,
update: (data) => _.cloneDeep(data.authentication.strategies),
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-refresh')
}
},
groups: {
query: groupsQuery,
fetchPolicy: 'network-only',
update: (data) => data.groups.list,
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-groups-refresh')
}
}
}
}

6
client/graph/admin/auth/auth-mutation-save-strategies.gql

@ -1,6 +1,6 @@
mutation($locale: String!, $autoUpdate: Boolean!, $namespacing: Boolean!, $namespaces: [String]!) {
localization {
updateLocale(locale: $locale, autoUpdate: $autoUpdate, namespacing: $namespacing, namespaces: $namespaces) {
mutation($strategies: [AuthenticationStrategyInput]) {
authentication {
updateStrategies(strategies: $strategies) {
responseResult {
succeeded
errorCode

8
client/graph/admin/auth/auth-query-groups.gql

@ -0,0 +1,8 @@
query {
groups {
list {
id
name
}
}
}

21
server/graph/resolvers/authentication.js

@ -50,6 +50,27 @@ module.exports = {
} catch (err) {
return graphHelper.generateError(err)
}
},
async updateStrategies(obj, args, context) {
try {
for (let str of args.strategies) {
await WIKI.db.authentication.query().patch({
isEnabled: str.isEnabled,
config: _.reduce(str.config, (result, value, key) => {
_.set(result, value.key, value.value)
return result
}, {}),
selfRegistration: str.selfRegistration,
domainWhitelist: { v: str.domainWhitelist },
autoEnrollGroups: { v: str.autoEnrollGroups }
}).where('key', str.key)
}
return {
responseResult: graphHelper.generateSuccess('Strategies updated successfully')
}
} catch (err) {
return graphHelper.generateError(err)
}
}
},
AuthenticationStrategy: {

17
server/graph/schemas/authentication.graphql

@ -37,10 +37,8 @@ type AuthenticationMutation {
securityCode: String!
): DefaultResponse
updateStrategy(
strategy: String!
isEnabled: Boolean!
config: [KeyValuePairInput]
updateStrategies(
strategies: [AuthenticationStrategyInput]
): DefaultResponse
}
@ -58,7 +56,7 @@ type AuthenticationStrategy {
config: [KeyValuePair]
selfRegistration: Boolean!
domainWhitelist: [String]!
autoEnrollGroups: [String]!
autoEnrollGroups: [Int]!
}
type AuthenticationLoginResponse {
@ -66,3 +64,12 @@ type AuthenticationLoginResponse {
tfaRequired: Boolean
tfaLoginToken: String
}
input AuthenticationStrategyInput {
isEnabled: Boolean!
key: String!
config: [KeyValuePairInput]
selfRegistration: Boolean!
domainWhitelist: [String]!
autoEnrollGroups: [Int]!
}
Loading…
Cancel
Save