authentication.js 3.64 KB
Newer Older
1
const Model = require('objection').Model
2
const fs = require('fs-extra')
3 4
const path = require('path')
const _ = require('lodash')
5
const yaml = require('js-yaml')
6
const commonHelper = require('../helpers/common')
7 8 9 10 11 12 13 14

/* global WIKI */

/**
 * Authentication model
 */
module.exports = class Authentication extends Model {
  static get tableName() { return 'authentication' }
15
  static get idColumn() { return 'key' }
16 17 18 19

  static get jsonSchema () {
    return {
      type: 'object',
20
      required: ['key'],
21 22 23

      properties: {
        key: {type: 'string'},
24
        selfRegistration: {type: 'boolean'}
25 26 27 28
      }
    }
  }

29 30 31 32
  static get jsonAttributes() {
    return ['config', 'domainWhitelist', 'autoEnrollGroups']
  }

33 34 35 36
  static async getStrategy(key) {
    return WIKI.models.authentication.query().findOne({ key })
  }

37 38
  static async getStrategies() {
    const strategies = await WIKI.models.authentication.query().orderBy('order')
39
    return strategies.map(str => ({
40 41 42
      ...str,
      domainWhitelist: _.get(str.domainWhitelist, 'v', []),
      autoEnrollGroups: _.get(str.autoEnrollGroups, 'v', [])
43
    }))
44 45
  }

46
  static async getStrategiesForLegacyClient() {
47
    const strategies = await WIKI.models.authentication.query().select('key', 'selfRegistration')
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    let formStrategies = []
    let socialStrategies = []

    for (let stg of strategies) {
      const stgInfo = _.find(WIKI.data.authentication, ['key', stg.key]) || {}
      if (stgInfo.useForm) {
        formStrategies.push({
          key: stg.key,
          title: stgInfo.title
        })
      } else {
        socialStrategies.push({
          ...stgInfo,
          ...stg,
          icon: await fs.readFile(path.join(WIKI.ROOTPATH, `assets/svg/auth-icon-${stg.key}.svg`), 'utf8').catch(err => {
            if (err.code === 'ENOENT') {
              return null
            }
            throw err
          })
        })
      }
    }

    return {
      formStrategies,
      socialStrategies
    }
  }

78 79
  static async refreshStrategiesFromDisk() {
    try {
80
      const dbStrategies = await WIKI.models.authentication.query()
81 82 83

      // -> Fetch definitions from disk
      const authDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/authentication'))
84
      WIKI.data.authentication = []
85
      for (let dir of authDirs) {
86 87 88 89 90 91
        const defRaw = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/authentication', dir, 'definition.yml'), 'utf8')
        const def = yaml.safeLoad(defRaw)
        WIKI.data.authentication.push({
          ...def,
          props: commonHelper.parseModuleProps(def.props)
        })
92 93
      }

94 95
      for (const strategy of dbStrategies) {
        const strategyDef = _.find(WIKI.data.authentication, ['key', strategy.strategyKey])
96 97 98 99 100
        if (!strategyDef) {
          await WIKI.models.authentication.query().delete().where('key', strategy.key)
          WIKI.logger.info(`Authentication strategy ${strategy.strategyKey} was removed from disk: [ REMOVED ]`)
          continue
        }
101 102 103 104 105 106 107 108 109
        strategy.config = _.transform(strategyDef.props, (result, value, key) => {
          if (!_.has(result, key)) {
            _.set(result, key, value.default)
          }
          return result
        }, strategy.config)

        // Fix pre-2.5 strategies displayName
        if (!strategy.displayName) {
110
          await WIKI.models.authentication.query().patch({
111
            displayName: strategyDef.title
112
          }).where('key', strategy.key)
113
        }
114
      }
115 116

      WIKI.logger.info(`Loaded ${WIKI.data.authentication.length} authentication strategies: [ OK ]`)
117 118 119 120 121 122
    } catch (err) {
      WIKI.logger.error(`Failed to scan or load new authentication providers: [ FAILED ]`)
      WIKI.logger.error(err)
    }
  }
}