2020-03-18 10:26:34 -04:00
|
|
|
'use strict'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks that all institutional sso provider certs are still current with the
|
|
|
|
* data provided by the ukamf export file.
|
|
|
|
*
|
|
|
|
* Run with: node check-certs /path/ukamf.xml
|
|
|
|
*
|
|
|
|
* The ukamf metadata xml file can be downloaded from:
|
|
|
|
* http://metadata.ukfederation.org.uk/
|
|
|
|
*/
|
|
|
|
|
|
|
|
const { Certificate } = require('@fidm/x509')
|
|
|
|
const UKAMFDB = require('./ukamf-db')
|
2023-11-02 04:18:32 -04:00
|
|
|
const V1Api = require('../../app/src/Features/V1/V1Api').promises
|
2020-10-07 09:17:49 -04:00
|
|
|
const { db, waitForDb } = require('../../app/src/infrastructure/mongodb')
|
2020-03-18 10:26:34 -04:00
|
|
|
const moment = require('moment')
|
|
|
|
|
2020-10-07 09:17:49 -04:00
|
|
|
waitForDb()
|
|
|
|
.then(main)
|
2020-03-18 10:26:34 -04:00
|
|
|
.catch(err => {
|
|
|
|
console.error(err.stack)
|
|
|
|
})
|
|
|
|
.then(() => process.exit())
|
|
|
|
|
|
|
|
async function main() {
|
|
|
|
const [, , file] = process.argv
|
|
|
|
|
|
|
|
console.log(`loading file ${file}`)
|
|
|
|
|
|
|
|
const ukamfDB = new UKAMFDB(file)
|
|
|
|
await ukamfDB.init()
|
|
|
|
|
|
|
|
const activeProviderIds = await getActiveProviderIds()
|
|
|
|
|
|
|
|
for (const providerId of activeProviderIds) {
|
|
|
|
await checkCert(ukamfDB, providerId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function checkCert(ukamfDB, providerId) {
|
|
|
|
console.log(`Checking certificates for providerId: ${providerId}`)
|
|
|
|
try {
|
|
|
|
const { body } = await V1Api.request({
|
|
|
|
json: true,
|
|
|
|
qs: { university_id: providerId },
|
2024-02-12 05:36:44 -05:00
|
|
|
uri: '/api/v1/overleaf/university_saml',
|
2020-03-18 10:26:34 -04:00
|
|
|
})
|
|
|
|
// show notice if sso not currently enabled
|
|
|
|
if (body.sso_enabled === true) {
|
|
|
|
console.log(` * SSO enabled`)
|
|
|
|
} else {
|
|
|
|
console.log(` ! SSO NOT enabled`)
|
|
|
|
}
|
|
|
|
// lookup entity id in ukamf database
|
|
|
|
const entity = ukamfDB.findByEntityID(body.sso_entity_id)
|
|
|
|
// if entity found then compare certs
|
|
|
|
if (entity) {
|
|
|
|
const samlConfig = entity.getSamlConfig()
|
|
|
|
// check if certificates match
|
|
|
|
if (samlConfig.cert === body.sso_cert) {
|
|
|
|
console.log(' * UKAMF certificate matches configuration')
|
|
|
|
} else {
|
|
|
|
console.log(' ! UKAMF certificate DOES NOT match configuration')
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
console.log(` ! No UKAMF entity found for ${body.sso_entity_id}`)
|
|
|
|
}
|
|
|
|
// check expiration on configured certificate
|
|
|
|
const certificate = Certificate.fromPEM(
|
|
|
|
Buffer.from(
|
2020-12-15 05:23:54 -05:00
|
|
|
`-----BEGIN CERTIFICATE-----\n${body.sso_cert}\n-----END CERTIFICATE-----`,
|
2020-03-18 10:26:34 -04:00
|
|
|
'utf8'
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
const validFrom = moment(certificate.validFrom)
|
|
|
|
const validTo = moment(certificate.validTo)
|
|
|
|
|
|
|
|
if (validFrom.isAfter(moment())) {
|
|
|
|
console.log(` ! Certificate not valid till: ${validFrom.format('LLL')}`)
|
|
|
|
} else if (validTo.isBefore(moment())) {
|
|
|
|
console.log(` ! Certificate expired: ${validTo.format('LLL')}`)
|
|
|
|
} else if (validTo.isBefore(moment().add(60, 'days'))) {
|
|
|
|
console.log(` ! Certificate expires: ${validTo.format('LLL')}`)
|
|
|
|
} else {
|
|
|
|
console.log(` * Certificate expires: ${validTo.format('LLL')}`)
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
console.log(` ! ${err.statusCode} Error getting university config from v1`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getActiveProviderIds() {
|
2020-10-07 09:17:49 -04:00
|
|
|
return db.users.distinct('samlIdentifiers.providerId', {
|
2021-04-27 03:52:58 -04:00
|
|
|
'samlIdentifiers.externalUserId': { $exists: true },
|
2020-03-18 10:26:34 -04:00
|
|
|
})
|
|
|
|
}
|