Merge pull request #2368 from overleaf/ew-ukamf-metadata-processor-cli

ukamf metadata processor cli

GitOrigin-RevId: f823a1dca231546f3ab67c47f6443e56b50e30d1
This commit is contained in:
Eric Mc Sween 2019-11-21 07:42:45 -05:00 committed by sharelatex
parent 1c0dc0a13f
commit df6d0625f1
3 changed files with 118 additions and 0 deletions

View file

@ -0,0 +1,42 @@
'use strict'
/**
* Run with: node metadata-processor /path/ukamf.xml http://idp/entity/id
*
* The ukamf metadata xml file can be downloaded from:
* http://metadata.ukfederation.org.uk/
*
* The entity id should be provided by the university.
*/
const UKAMFDB = require('./ukamf-db')
main().catch(err => {
console.error(err.stack)
})
async function main() {
const [, , file, entityId] = process.argv
console.log(`loading file ${file}`)
const ukamfDB = new UKAMFDB(file)
await ukamfDB.init()
const entity = ukamfDB.findByEntityID(entityId)
if (!entity) {
throw new Error(`could not find entity for ${entityId}`)
}
const samlConfig = entity.getSamlConfig()
console.log(`UPDATE universities SET
sso_entity_id = '${entityId}',
sso_entry_point = '${samlConfig.entryPoint}',
sso_cert = '${samlConfig.cert}',
sso_user_id_attribute = 'eduPersonPrincipalName',
sso_user_email_attribute = 'mail',
sso_license_entitlement_attribute = 'eduPersonPrincipalName',
sso_license_entitlement_matcher = '.'
WHERE id =
`)
}

View file

@ -0,0 +1,31 @@
'use strict'
const fs = require('fs-extra')
const xml2js = require('xml2js')
const UKAMFEntity = require('./ukamf-entity')
class UKAMFDB {
constructor(file) {
this.file = file
}
async init() {
const data = await fs.readFile(this.file, 'utf8')
const parser = new xml2js.Parser()
const xml = await parser.parseStringPromise(data)
this.entities = xml.EntitiesDescriptor.EntityDescriptor
}
findByEntityID(matcher) {
const entity = this.entities.find(
matcher instanceof RegExp
? e => e.$.entityID.match(matcher)
: e => e.$.entityID === matcher
)
return entity ? new UKAMFEntity(entity) : null
}
}
module.exports = UKAMFDB

View file

@ -0,0 +1,45 @@
'use strict'
const _ = require('lodash')
class UKAMFEntity {
constructor(data) {
this.data = data
}
getSamlConfig() {
const idp = this.data.IDPSSODescriptor[0]
const keys = idp.KeyDescriptor
const signingKey = keys.find(key => _.get(key, ['$', 'use']) === 'signing')
let cert = _.get(signingKey, [
'ds:KeyInfo',
0,
'ds:X509Data',
0,
'ds:X509Certificate',
0
])
if (!cert) {
throw new Error('no cert')
}
cert = cert.replace(/\s/g, '')
let entryPoint = idp.SingleSignOnService.find(
sso =>
_.get(sso, ['$', 'Binding']) ===
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
)
entryPoint = _.get(entryPoint, ['$', 'Location'])
if (!entryPoint) {
throw new Error('no entryPoint')
}
return {
cert,
entryPoint
}
}
}
module.exports = UKAMFEntity