From a8b741bb2258805182928e921b13f2a76f736b71 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Wed, 2 May 2018 23:31:49 -0400 Subject: [PATCH] stub out okta directory service --- package-lock.json | 227 +++++++++++++++++++++---- package.json | 1 + src/app/tabs/settings.component.html | 15 +- src/app/tabs/settings.component.ts | 6 + src/enums/directoryType.ts | 1 + src/locales/en/messages.json | 6 + src/models/oktaConfiguration.ts | 4 + src/services/configuration.service.ts | 15 +- src/services/okta-directory.service.ts | 82 +++++++++ src/services/sync.service.ts | 3 + 10 files changed, 326 insertions(+), 34 deletions(-) create mode 100644 src/models/oktaConfiguration.ts create mode 100644 src/services/okta-directory.service.ts diff --git a/package-lock.json b/package-lock.json index cef06d62..7e05e753 100644 --- a/package-lock.json +++ b/package-lock.json @@ -175,6 +175,58 @@ } } }, + "@okta/okta-sdk-nodejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@okta/okta-sdk-nodejs/-/okta-sdk-nodejs-1.1.0.tgz", + "integrity": "sha1-FnMUFKrLCcgJwtA6kutTHfbiNeo=", + "requires": { + "@okta/openapi": "0.13.0", + "flat": "2.0.1", + "isomorphic-fetch": "2.2.1", + "js-yaml": "3.11.0", + "lodash": "4.17.5", + "parse-link-header": "1.0.0" + } + }, + "@okta/openapi": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@okta/openapi/-/openapi-0.13.0.tgz", + "integrity": "sha1-OaXIyCoAPmUq5B9P52aRGvoFOqg=", + "requires": { + "commander": "2.9.0", + "fs-extra": "3.0.1", + "handlebars": "4.0.8", + "json-stable-stringify": "1.0.1" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": "1.0.1" + } + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "3.0.1", + "universalify": "0.1.1" + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "requires": { + "graceful-fs": "4.1.11" + } + } + } + }, "@types/events": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", @@ -266,7 +318,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, "requires": { "kind-of": "3.2.2", "longest": "1.0.1", @@ -282,8 +333,7 @@ "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" }, "angular2-toaster": { "version": "4.0.2", @@ -1189,7 +1239,6 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, "requires": { "align-text": "0.1.4", "lazy-cache": "1.0.4" @@ -2056,8 +2105,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", @@ -2834,7 +2882,6 @@ "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "dev": true, "requires": { "iconv-lite": "0.4.21" } @@ -3272,6 +3319,14 @@ "locate-path": "2.0.0" } }, + "flat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-2.0.1.tgz", + "integrity": "sha1-cOKRiKdL4MPIlAnu0fqVd5B64y8=", + "requires": { + "is-buffer": "1.1.6" + } + }, "flatten": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", @@ -3834,7 +3889,8 @@ "jsbn": { "version": "0.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "json-schema": { "version": "0.2.3", @@ -4607,6 +4663,11 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, "gtoken": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.0.tgz", @@ -4619,6 +4680,80 @@ "pify": "3.0.0" } }, + "handlebars": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.8.tgz", + "integrity": "sha1-Irh1zT8ObL6jAxTxROgrx6cv9CA=", + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "optional": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": "1.0.1" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "optional": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "optional": true + } + } + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -4922,7 +5057,6 @@ "version": "0.4.21", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", - "dev": true, "requires": { "safer-buffer": "2.1.2" } @@ -5335,8 +5469,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-svg": { "version": "2.1.0", @@ -5391,6 +5524,15 @@ "isarray": "1.0.0" } }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "1.7.3", + "whatwg-fetch": "2.0.4" + } + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -5449,6 +5591,14 @@ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", "dev": true }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "0.0.0" + } + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -5469,6 +5619,11 @@ "graceful-fs": "4.1.11" } }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, "jsonpointer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", @@ -5528,7 +5683,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "1.1.6" } @@ -5554,8 +5708,7 @@ "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" }, "lazy-val": { "version": "1.0.3", @@ -5653,8 +5806,7 @@ "lodash": { "version": "4.17.5", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", - "dev": true + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" }, "lodash.assign": { "version": "4.2.0", @@ -5720,8 +5872,7 @@ "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, "loud-rejection": { "version": "1.6.0", @@ -6146,7 +6297,6 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "dev": true, "requires": { "encoding": "0.1.12", "is-stream": "1.1.0" @@ -6681,6 +6831,15 @@ "mimic-fn": "1.2.0" } }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.2" + } + }, "ora": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ora/-/ora-1.4.0.tgz", @@ -6848,6 +7007,14 @@ "error-ex": "1.3.1" } }, + "parse-link-header": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-1.0.0.tgz", + "integrity": "sha1-34N7t0vowC55MYAUVo+qidw05jc=", + "requires": { + "xtend": "4.0.1" + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -8124,8 +8291,7 @@ "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "repeating": { "version": "2.0.1", @@ -8218,7 +8384,6 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, "requires": { "align-text": "0.1.4" } @@ -8315,8 +8480,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sanitize-filename": { "version": "1.6.1", @@ -9781,7 +9945,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true, "optional": true }, "uglifyjs-webpack-plugin": { @@ -10773,6 +10936,11 @@ "source-map": "0.6.1" } }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + }, "whet.extend": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", @@ -10848,14 +11016,12 @@ "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" }, "wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" }, "wrap-ansi": { "version": "2.1.0", @@ -10903,8 +11069,7 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "4.0.0", diff --git a/package.json b/package.json index 1a975580..b4fb6921 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "@angular/router": "5.2.0", "@angular/upgrade": "5.2.0", "@microsoft/microsoft-graph-client": "1.0.0", + "@okta/okta-sdk-nodejs": "1.1.0", "angular2-toaster": "4.0.2", "angulartics2": "5.0.1", "bootstrap": "4.1.0", diff --git a/src/app/tabs/settings.component.html b/src/app/tabs/settings.component.html index b579b216..1553d5cc 100644 --- a/src/app/tabs/settings.component.html +++ b/src/app/tabs/settings.component.html @@ -1,6 +1,6 @@
-
+

{{'directory' | i18n}}

@@ -67,7 +67,18 @@
- + +
+
+
+
+ + + {{'ex' | i18n}} https://mycompany.okta.com/ +
+
+ +
diff --git a/src/app/tabs/settings.component.ts b/src/app/tabs/settings.component.ts index e97fb3b1..a3a553f3 100644 --- a/src/app/tabs/settings.component.ts +++ b/src/app/tabs/settings.component.ts @@ -15,6 +15,7 @@ import { DirectoryType } from '../../enums/directoryType'; import { AzureConfiguration } from '../../models/azureConfiguration'; import { GSuiteConfiguration } from '../../models/gsuiteConfiguration'; import { LdapConfiguration } from '../../models/ldapConfiguration'; +import { OktaConfiguration } from '../../models/oktaConfiguration'; import { SyncConfiguration } from '../../models/syncConfiguration'; @Component({ @@ -27,6 +28,7 @@ export class SettingsComponent implements OnInit, OnDestroy { ldap = new LdapConfiguration(); gsuite = new GSuiteConfiguration(); azure = new AzureConfiguration(); + okta = new OktaConfiguration(); sync = new SyncConfiguration(); directoryOptions: any[]; @@ -37,6 +39,7 @@ export class SettingsComponent implements OnInit, OnDestroy { { name: 'Active Directory / LDAP', value: DirectoryType.Ldap }, { name: 'Azure Active Directory', value: DirectoryType.AzureActiveDirectory }, { name: 'G Suite (Google)', value: DirectoryType.GSuite }, + { name: 'Okta', value: DirectoryType.Okta }, ]; } @@ -48,6 +51,8 @@ export class SettingsComponent implements OnInit, OnDestroy { this.gsuite; this.azure = (await this.configurationService.getDirectory( DirectoryType.AzureActiveDirectory)) || this.azure; + this.okta = (await this.configurationService.getDirectory( + DirectoryType.Okta)) || this.okta; this.sync = (await this.configurationService.getSync()) || this.sync; } @@ -73,6 +78,7 @@ export class SettingsComponent implements OnInit, OnDestroy { await this.configurationService.saveDirectory(DirectoryType.Ldap, this.ldap); await this.configurationService.saveDirectory(DirectoryType.GSuite, this.gsuite); await this.configurationService.saveDirectory(DirectoryType.AzureActiveDirectory, this.azure); + await this.configurationService.saveDirectory(DirectoryType.Okta, this.okta); await this.configurationService.saveSync(this.sync); } diff --git a/src/enums/directoryType.ts b/src/enums/directoryType.ts index 0ba3f952..521c78cd 100644 --- a/src/enums/directoryType.ts +++ b/src/enums/directoryType.ts @@ -2,4 +2,5 @@ export enum DirectoryType { Ldap = 0, AzureActiveDirectory = 1, GSuite = 2, + Okta = 3, } diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index 39d90872..e58e7528 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -434,5 +434,11 @@ }, "other": { "message": "Other" + }, + "organizationUrl": { + "message": "Organization URL" + }, + "token": { + "message": "Token" } } diff --git a/src/models/oktaConfiguration.ts b/src/models/oktaConfiguration.ts new file mode 100644 index 00000000..3e983026 --- /dev/null +++ b/src/models/oktaConfiguration.ts @@ -0,0 +1,4 @@ +export class OktaConfiguration { + orgUrl: string; + token: string; +} diff --git a/src/services/configuration.service.ts b/src/services/configuration.service.ts index 39836229..e8e65eed 100644 --- a/src/services/configuration.service.ts +++ b/src/services/configuration.service.ts @@ -4,6 +4,7 @@ import { StorageService } from 'jslib/abstractions/storage.service'; import { AzureConfiguration } from '../models/azureConfiguration'; import { GSuiteConfiguration } from '../models/gsuiteConfiguration'; import { LdapConfiguration } from '../models/ldapConfiguration'; +import { OktaConfiguration } from '../models/oktaConfiguration'; import { SyncConfiguration } from '../models/syncConfiguration'; const StoredSecurely = '[STORED SECURELY]'; @@ -11,6 +12,7 @@ const Keys = { ldap: 'ldapPassword', gsuite: 'gsuitePrivateKey', azure: 'azureKey', + okta: 'oktaToken', directoryConfigPrefix: 'directoryConfig_', sync: 'syncConfig', directoryType: 'directoryType', @@ -38,6 +40,9 @@ export class ConfigurationService { case DirectoryType.AzureActiveDirectory: (config as any).key = await this.secureStorageService.get(Keys.azure); break; + case DirectoryType.Okta: + (config as any).token = await this.secureStorageService.get(Keys.okta); + break; case DirectoryType.GSuite: (config as any).privateKey = await this.secureStorageService.get(Keys.gsuite); break; @@ -46,7 +51,7 @@ export class ConfigurationService { } async saveDirectory(type: DirectoryType, - config: LdapConfiguration | GSuiteConfiguration | AzureConfiguration): Promise { + config: LdapConfiguration | GSuiteConfiguration | AzureConfiguration | OktaConfiguration): Promise { const savedConfig: any = Object.assign({}, config); switch (type) { case DirectoryType.Ldap: @@ -65,6 +70,14 @@ export class ConfigurationService { savedConfig.key = StoredSecurely; } break; + case DirectoryType.Okta: + if (savedConfig.token == null) { + await this.secureStorageService.remove(Keys.okta); + } else { + await this.secureStorageService.save(Keys.okta, savedConfig.token); + savedConfig.token = StoredSecurely; + } + break; case DirectoryType.GSuite: if (savedConfig.privateKey == null) { await this.secureStorageService.remove(Keys.gsuite); diff --git a/src/services/okta-directory.service.ts b/src/services/okta-directory.service.ts new file mode 100644 index 00000000..665d1af9 --- /dev/null +++ b/src/services/okta-directory.service.ts @@ -0,0 +1,82 @@ +import { DirectoryType } from '../enums/directoryType'; + +import { GroupEntry } from '../models/groupEntry'; +import { OktaConfiguration } from '../models/oktaConfiguration'; +import { SyncConfiguration } from '../models/syncConfiguration'; +import { UserEntry } from '../models/userEntry'; + +import { ConfigurationService } from './configuration.service'; +import { DirectoryService } from './directory.service'; + +import { LogService } from 'jslib/abstractions/log.service'; + +// tslint:disable-next-line +const okta = require('@okta/okta-sdk-nodejs'); + +export class OktaDirectoryService implements DirectoryService { + private dirConfig: OktaConfiguration; + private syncConfig: SyncConfiguration; + private client: any; + + constructor(private configurationService: ConfigurationService, private logService: LogService) { } + + async getEntries(force: boolean, test: boolean): Promise<[GroupEntry[], UserEntry[]]> { + const type = await this.configurationService.getDirectoryType(); + if (type !== DirectoryType.Okta) { + return; + } + + this.dirConfig = await this.configurationService.getDirectory(DirectoryType.Okta); + if (this.dirConfig == null) { + return; + } + + this.syncConfig = await this.configurationService.getSync(); + if (this.syncConfig == null) { + return; + } + + this.client = new okta.Client({ + orgUrl: this.dirConfig.orgUrl, + token: this.dirConfig.token, + }); + + let users: UserEntry[]; + if (this.syncConfig.users) { + users = await this.getUsers(force); + } + + let groups: GroupEntry[]; + if (this.syncConfig.groups) { + groups = await this.getGroups(force); + } + + return [groups, users]; + } + + private async getUsers(force: boolean): Promise { + const entries: UserEntry[] = []; + this.logService.info('Querying users.'); + return entries; + } + + private buildUser(user: any) { + if ((user.emails == null || user.emails === '') && !user.deleted) { + return null; + } + + const entry = new UserEntry(); + return entry; + } + + private async getGroups(force: boolean): Promise { + const entries: GroupEntry[] = []; + this.logService.info('Querying groups.'); + return entries; + } + + private async buildGroup(group: any) { + const entry = new GroupEntry(); + return entry; + } +} diff --git a/src/services/sync.service.ts b/src/services/sync.service.ts index 2493b67b..b4a23555 100644 --- a/src/services/sync.service.ts +++ b/src/services/sync.service.ts @@ -19,6 +19,7 @@ import { ConfigurationService } from './configuration.service'; import { DirectoryService } from './directory.service'; import { GSuiteDirectoryService } from './gsuite-directory.service'; import { LdapDirectoryService } from './ldap-directory.service'; +import { OktaDirectoryService } from './okta-directory.service'; const Keys = { }; @@ -116,6 +117,8 @@ export class SyncService { return new AzureDirectoryService(this.configurationService); case DirectoryType.Ldap: return new LdapDirectoryService(this.configurationService, this.logService); + case DirectoryType.Okta: + return new OktaDirectoryService(this.configurationService, this.logService); default: return null; }