mirror of
https://github.com/bitwarden/directory-connector
synced 2026-01-07 19:13:31 +00:00
stub out okta directory service
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<div class="card">
|
||||
<div class="card mb-3">
|
||||
<h3 class="card-header">{{'directory' | i18n}}</h3>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
@@ -67,7 +67,18 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="secretKey">{{'secretKey' | i18n}}</label>
|
||||
<input type="password" class="form-control" id="secretKey" name="SecretKey" [(ngModel)]="azure.key">
|
||||
<input type="text" class="form-control" id="secretKey" name="SecretKey" [(ngModel)]="azure.key">
|
||||
</div>
|
||||
</div>
|
||||
<div [hidden]="directory != directoryType.Okta">
|
||||
<div class="form-group">
|
||||
<label for="orgUrl">{{'organizationUrl' | i18n}}</label>
|
||||
<input type="text" class="form-control" id="orgUrl" name="OrgUrl" [(ngModel)]="okta.orgUrl">
|
||||
<small class="text-muted form-text">{{'ex' | i18n}} https://mycompany.okta.com/</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oktaToken">{{'token' | i18n}}</label>
|
||||
<input type="text" class="form-control" id="oktaToken" name="OktaToken" [(ngModel)]="okta.token">
|
||||
</div>
|
||||
</div>
|
||||
<div [hidden]="directory != directoryType.GSuite">
|
||||
|
||||
@@ -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<AzureConfiguration>(
|
||||
DirectoryType.AzureActiveDirectory)) || this.azure;
|
||||
this.okta = (await this.configurationService.getDirectory<OktaConfiguration>(
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@ export enum DirectoryType {
|
||||
Ldap = 0,
|
||||
AzureActiveDirectory = 1,
|
||||
GSuite = 2,
|
||||
Okta = 3,
|
||||
}
|
||||
|
||||
@@ -434,5 +434,11 @@
|
||||
},
|
||||
"other": {
|
||||
"message": "Other"
|
||||
},
|
||||
"organizationUrl": {
|
||||
"message": "Organization URL"
|
||||
},
|
||||
"token": {
|
||||
"message": "Token"
|
||||
}
|
||||
}
|
||||
|
||||
4
src/models/oktaConfiguration.ts
Normal file
4
src/models/oktaConfiguration.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export class OktaConfiguration {
|
||||
orgUrl: string;
|
||||
token: string;
|
||||
}
|
||||
@@ -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<string>(Keys.azure);
|
||||
break;
|
||||
case DirectoryType.Okta:
|
||||
(config as any).token = await this.secureStorageService.get<string>(Keys.okta);
|
||||
break;
|
||||
case DirectoryType.GSuite:
|
||||
(config as any).privateKey = await this.secureStorageService.get<string>(Keys.gsuite);
|
||||
break;
|
||||
@@ -46,7 +51,7 @@ export class ConfigurationService {
|
||||
}
|
||||
|
||||
async saveDirectory(type: DirectoryType,
|
||||
config: LdapConfiguration | GSuiteConfiguration | AzureConfiguration): Promise<any> {
|
||||
config: LdapConfiguration | GSuiteConfiguration | AzureConfiguration | OktaConfiguration): Promise<any> {
|
||||
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);
|
||||
|
||||
82
src/services/okta-directory.service.ts
Normal file
82
src/services/okta-directory.service.ts
Normal file
@@ -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<OktaConfiguration>(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<UserEntry[]> {
|
||||
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<GroupEntry[]> {
|
||||
const entries: GroupEntry[] = [];
|
||||
this.logService.info('Querying groups.');
|
||||
return entries;
|
||||
}
|
||||
|
||||
private async buildGroup(group: any) {
|
||||
const entry = new GroupEntry();
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user