check-certs.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /**
  2. * Checks that all institutional sso provider certs are still current with the
  3. * data provided by the ukamf export file.
  4. *
  5. * Run with: node check-certs /path/ukamf.xml
  6. *
  7. * The ukamf metadata xml file can be downloaded from:
  8. * http://metadata.ukfederation.org.uk/
  9. */
  10. import { Certificate } from '@fidm/x509'
  11. import UKAMFDB from './ukamf-db.js'
  12. import V1ApiModule from '../../app/src/Features/V1/V1Api.js'
  13. import { db } from '../../app/src/infrastructure/mongodb.js'
  14. import moment from 'moment'
  15. const { promises: V1Api } = V1ApiModule
  16. async function main() {
  17. const [, , file] = process.argv
  18. console.log(`loading file ${file}`)
  19. const ukamfDB = new UKAMFDB(file)
  20. await ukamfDB.init()
  21. const activeProviderIds = await getActiveProviderIds()
  22. for (const providerId of activeProviderIds) {
  23. await checkCert(ukamfDB, providerId)
  24. }
  25. }
  26. async function checkCert(ukamfDB, providerId) {
  27. console.log(`Checking certificates for providerId: ${providerId}`)
  28. try {
  29. const { body } = await V1Api.request({
  30. json: true,
  31. qs: { university_id: providerId },
  32. uri: '/api/v1/overleaf/university_saml',
  33. })
  34. // show notice if sso not currently enabled
  35. if (body.sso_enabled === true) {
  36. console.log(` * SSO enabled`)
  37. } else {
  38. console.log(` ! SSO NOT enabled`)
  39. }
  40. // lookup entity id in ukamf database
  41. const entity = ukamfDB.findByEntityID(body.sso_entity_id)
  42. // if entity found then compare certs
  43. if (entity) {
  44. const samlConfig = entity.getSamlConfig()
  45. // check if certificates match
  46. if (samlConfig.idpCert === body.sso_cert) {
  47. console.log(' * UKAMF certificate matches configuration')
  48. } else {
  49. console.log(' ! UKAMF certificate DOES NOT match configuration')
  50. }
  51. } else {
  52. console.log(` ! No UKAMF entity found for ${body.sso_entity_id}`)
  53. }
  54. // check expiration on configured certificate
  55. const certificate = Certificate.fromPEM(
  56. Buffer.from(
  57. `-----BEGIN CERTIFICATE-----\n${body.sso_cert}\n-----END CERTIFICATE-----`,
  58. 'utf8'
  59. )
  60. )
  61. const validFrom = moment(certificate.validFrom)
  62. const validTo = moment(certificate.validTo)
  63. if (validFrom.isAfter(moment())) {
  64. console.log(` ! Certificate not valid till: ${validFrom.format('LLL')}`)
  65. } else if (validTo.isBefore(moment())) {
  66. console.log(` ! Certificate expired: ${validTo.format('LLL')}`)
  67. } else if (validTo.isBefore(moment().add(60, 'days'))) {
  68. console.log(` ! Certificate expires: ${validTo.format('LLL')}`)
  69. } else {
  70. console.log(` * Certificate expires: ${validTo.format('LLL')}`)
  71. }
  72. } catch (err) {
  73. console.log(` ! ${err.statusCode} Error getting university config from v1`)
  74. }
  75. }
  76. async function getActiveProviderIds() {
  77. return db.users.distinct('samlIdentifiers.providerId', {
  78. 'samlIdentifiers.externalUserId': { $exists: true },
  79. })
  80. }
  81. try {
  82. await main()
  83. } catch (error) {
  84. console.error(error.stack)
  85. }
  86. process.exit()