mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-05 23:53:21 +00:00
stub out OneLogin connector
This commit is contained in:
@@ -147,6 +147,26 @@
|
||||
[(ngModel)]="okta.token">
|
||||
</div>
|
||||
</div>
|
||||
<div [hidden]="directory != directoryType.OneLogin">
|
||||
<div class="form-group">
|
||||
<label for="oneLoginClientId">{{'clientId' | i18n}}</label>
|
||||
<input type="text" class="form-control" id="oneLoginClientId" name="OneLoginClientId"
|
||||
[(ngModel)]="oneLogin.clientId">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oneLoginClientSecret">{{'clientSecret' | i18n}}</label>
|
||||
<input type="text" class="form-control" id="oneLoginClientSecret" name="OneLoginClientSecret"
|
||||
[(ngModel)]="oneLogin.clientSecret">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oneLoginRegion">{{'region' | i18n}}</label>
|
||||
<select class="form-control" id="oneLoginRegion" name="OneLoginRegion"
|
||||
[(ngModel)]="oneLogin.region">
|
||||
<option value="us">US</option>
|
||||
<option value="eu">EU</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div [hidden]="directory != directoryType.GSuite">
|
||||
<div class="form-group">
|
||||
<label for="domain">{{'domain' | i18n}}</label>
|
||||
|
||||
@@ -19,6 +19,7 @@ import { AzureConfiguration } from '../../models/azureConfiguration';
|
||||
import { GSuiteConfiguration } from '../../models/gsuiteConfiguration';
|
||||
import { LdapConfiguration } from '../../models/ldapConfiguration';
|
||||
import { OktaConfiguration } from '../../models/oktaConfiguration';
|
||||
import { OneLoginConfiguration } from '../../models/oneLoginConfiguration';
|
||||
import { SyncConfiguration } from '../../models/syncConfiguration';
|
||||
|
||||
import { ConnectorUtils } from '../../utils';
|
||||
@@ -34,6 +35,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
gsuite = new GSuiteConfiguration();
|
||||
azure = new AzureConfiguration();
|
||||
okta = new OktaConfiguration();
|
||||
oneLogin = new OneLoginConfiguration();
|
||||
sync = new SyncConfiguration();
|
||||
organizationId: string;
|
||||
directoryOptions: any[];
|
||||
@@ -48,6 +50,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
{ name: 'Azure Active Directory', value: DirectoryType.AzureActiveDirectory },
|
||||
{ name: 'G Suite (Google)', value: DirectoryType.GSuite },
|
||||
{ name: 'Okta', value: DirectoryType.Okta },
|
||||
// { name: 'OneLogin', value: DirectoryType.OneLogin },
|
||||
];
|
||||
}
|
||||
|
||||
@@ -70,6 +73,8 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
DirectoryType.AzureActiveDirectory)) || this.azure;
|
||||
this.okta = (await this.configurationService.getDirectory<OktaConfiguration>(
|
||||
DirectoryType.Okta)) || this.okta;
|
||||
this.oneLogin = (await this.configurationService.getDirectory<OneLoginConfiguration>(
|
||||
DirectoryType.OneLogin)) || this.oneLogin;
|
||||
this.sync = (await this.configurationService.getSync()) || this.sync;
|
||||
}
|
||||
|
||||
@@ -85,6 +90,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
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.saveDirectory(DirectoryType.OneLogin, this.oneLogin);
|
||||
await this.configurationService.saveSync(this.sync);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,4 +3,5 @@ export enum DirectoryType {
|
||||
AzureActiveDirectory = 1,
|
||||
GSuite = 2,
|
||||
Okta = 3,
|
||||
OneLogin = 4,
|
||||
}
|
||||
|
||||
@@ -582,8 +582,8 @@
|
||||
"message": "Hide to Tray"
|
||||
},
|
||||
"alwaysOnTop": {
|
||||
"message": "Always on Top",
|
||||
"description": "Application window should always stay on top of other windows"
|
||||
"message": "Always on Top",
|
||||
"description": "Application window should always stay on top of other windows"
|
||||
},
|
||||
"hideToMenuBar": {
|
||||
"message": "Hide to Menu Bar"
|
||||
@@ -599,5 +599,14 @@
|
||||
},
|
||||
"overwriteExisting": {
|
||||
"message": "Overwrite existing organization users based on current sync settings."
|
||||
},
|
||||
"clientId": {
|
||||
"message": "Client ID"
|
||||
},
|
||||
"clientSecret": {
|
||||
"message": "Client Secret"
|
||||
},
|
||||
"region": {
|
||||
"message": "Region"
|
||||
}
|
||||
}
|
||||
|
||||
5
src/models/oneLoginConfiguration.ts
Normal file
5
src/models/oneLoginConfiguration.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export class OneLoginConfiguration {
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
region = 'us';
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { GSuiteConfiguration } from '../models/gsuiteConfiguration';
|
||||
import { LdapConfiguration } from '../models/ldapConfiguration';
|
||||
import { OktaConfiguration } from '../models/oktaConfiguration';
|
||||
import { SyncConfiguration } from '../models/syncConfiguration';
|
||||
import { OneLoginConfiguration } from 'src/models/oneLoginConfiguration';
|
||||
|
||||
const StoredSecurely = '[STORED SECURELY]';
|
||||
const Keys = {
|
||||
@@ -13,6 +14,7 @@ const Keys = {
|
||||
gsuite: 'gsuitePrivateKey',
|
||||
azure: 'azureKey',
|
||||
okta: 'oktaToken',
|
||||
oneLogin: 'oneLoginClientSecret',
|
||||
directoryConfigPrefix: 'directoryConfig_',
|
||||
sync: 'syncConfig',
|
||||
directoryType: 'directoryType',
|
||||
@@ -48,13 +50,17 @@ export class ConfigurationService {
|
||||
case DirectoryType.GSuite:
|
||||
(config as any).privateKey = await this.secureStorageService.get<string>(Keys.gsuite);
|
||||
break;
|
||||
case DirectoryType.OneLogin:
|
||||
(config as any).clientSecret = await this.secureStorageService.get<string>(Keys.oneLogin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
async saveDirectory(type: DirectoryType,
|
||||
config: LdapConfiguration | GSuiteConfiguration | AzureConfiguration | OktaConfiguration): Promise<any> {
|
||||
config: LdapConfiguration | GSuiteConfiguration | AzureConfiguration | OktaConfiguration |
|
||||
OneLoginConfiguration): Promise<any> {
|
||||
const savedConfig: any = Object.assign({}, config);
|
||||
if (this.useSecureStorageForSecrets) {
|
||||
switch (type) {
|
||||
@@ -92,6 +98,14 @@ export class ConfigurationService {
|
||||
savedConfig.privateKey = StoredSecurely;
|
||||
}
|
||||
break;
|
||||
case DirectoryType.OneLogin:
|
||||
if (savedConfig.clientSecret == null) {
|
||||
await this.secureStorageService.remove(Keys.oneLogin);
|
||||
} else {
|
||||
await this.secureStorageService.save(Keys.oneLogin, savedConfig.clientSecret);
|
||||
savedConfig.clientSecret = StoredSecurely;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
await this.storageService.save(Keys.directoryConfigPrefix + type, savedConfig);
|
||||
|
||||
137
src/services/onelogin-directory.service.ts
Normal file
137
src/services/onelogin-directory.service.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import { DirectoryType } from '../enums/directoryType';
|
||||
|
||||
import { GroupEntry } from '../models/groupEntry';
|
||||
import { OneLoginConfiguration } from '../models/oneLoginConfiguration';
|
||||
import { SyncConfiguration } from '../models/syncConfiguration';
|
||||
import { UserEntry } from '../models/userEntry';
|
||||
|
||||
import { BaseDirectoryService } from './baseDirectory.service';
|
||||
import { ConfigurationService } from './configuration.service';
|
||||
import { DirectoryService } from './directory.service';
|
||||
|
||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||
import { LogService } from 'jslib/abstractions/log.service';
|
||||
|
||||
export class OneLoginDirectoryService extends BaseDirectoryService implements DirectoryService {
|
||||
private dirConfig: OneLoginConfiguration;
|
||||
private syncConfig: SyncConfiguration;
|
||||
private accessToken: string;
|
||||
|
||||
constructor(private configurationService: ConfigurationService, private logService: LogService,
|
||||
private i18nService: I18nService) {
|
||||
super();
|
||||
}
|
||||
|
||||
async getEntries(force: boolean, test: boolean): Promise<[GroupEntry[], UserEntry[]]> {
|
||||
const type = await this.configurationService.getDirectoryType();
|
||||
if (type !== DirectoryType.OneLogin) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dirConfig = await this.configurationService.getDirectory<OneLoginConfiguration>(DirectoryType.OneLogin);
|
||||
if (this.dirConfig == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.syncConfig = await this.configurationService.getSync();
|
||||
if (this.syncConfig == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.dirConfig.clientId == null || this.dirConfig.clientSecret == null) {
|
||||
throw new Error(this.i18nService.t('dirConfigIncomplete'));
|
||||
}
|
||||
|
||||
this.accessToken = await this.getAccessToken();
|
||||
if (this.accessToken == null) {
|
||||
throw new Error('Could not get access token');
|
||||
}
|
||||
|
||||
let users: UserEntry[];
|
||||
if (this.syncConfig.users) {
|
||||
users = await this.getUsers(force);
|
||||
}
|
||||
|
||||
let groups: GroupEntry[];
|
||||
if (this.syncConfig.groups) {
|
||||
const setFilter = this.createCustomSet(this.syncConfig.groupFilter);
|
||||
groups = await this.getGroups(this.forceGroup(force, users), setFilter);
|
||||
users = this.filterUsersFromGroupsSet(users, groups, setFilter);
|
||||
}
|
||||
|
||||
return [groups, users];
|
||||
}
|
||||
|
||||
private async getUsers(force: boolean): Promise<UserEntry[]> {
|
||||
const entries: UserEntry[] = [];
|
||||
const lastSync = await this.configurationService.getLastUserSyncDate();
|
||||
// const oktaFilter = this.buildOktaFilter(this.syncConfig.userFilter, force, lastSync);
|
||||
const setFilter = this.createCustomSet(this.syncConfig.userFilter);
|
||||
|
||||
this.logService.info('Querying users.');
|
||||
/*
|
||||
const usersPromise = this.client.listUsers({ filter: oktaFilter }).each((user: any) => {
|
||||
const entry = this.buildUser(user);
|
||||
if (entry != null && !this.filterOutResult(setFilter, entry.email)) {
|
||||
entries.push(entry);
|
||||
}
|
||||
});
|
||||
*/
|
||||
const users = await this.client.apis.users.get_users(
|
||||
{},
|
||||
this.requestInterceptor());
|
||||
const u2 = this.getApi('users');
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
private async getGroups(force: boolean, setFilter: [boolean, Set<string>]): Promise<GroupEntry[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
private requestInterceptor(): any {
|
||||
return {
|
||||
requestInterceptor: (req: any) => {
|
||||
req.headers.Authorization = 'bearer:' + this.accessToken;
|
||||
return req;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private async getAccessToken() {
|
||||
const response = await fetch(`https://api.${this.dirConfig.region}.onelogin.com/auth/oauth2/v2/token`, {
|
||||
method: 'POST',
|
||||
headers: new Headers({
|
||||
'Authorization': 'Basic ' + btoa(this.dirConfig.clientId + ':' + this.dirConfig.clientSecret),
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
'Accept': 'application/json',
|
||||
}),
|
||||
body: JSON.stringify({
|
||||
grant_type: 'client_credentials',
|
||||
}),
|
||||
});
|
||||
if (response.status === 200) {
|
||||
const responseJson = await response.json();
|
||||
if (responseJson.access_token != null) {
|
||||
return responseJson.access_token;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private async getApi(endpoint: string): Promise<any> {
|
||||
const req: RequestInit = {
|
||||
method: 'GET',
|
||||
headers: new Headers({
|
||||
'Authorization': 'bearer:' + this.accessToken,
|
||||
'Accept': 'application/json',
|
||||
}),
|
||||
};
|
||||
const response = await fetch(
|
||||
new Request(`https://api.${this.dirConfig.region}.onelogin.com/api/1/${endpoint}`, req));
|
||||
if (response.status === 200) {
|
||||
const responseJson = await response.json();
|
||||
return responseJson;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import { DirectoryService } from './directory.service';
|
||||
import { GSuiteDirectoryService } from './gsuite-directory.service';
|
||||
import { LdapDirectoryService } from './ldap-directory.service';
|
||||
import { OktaDirectoryService } from './okta-directory.service';
|
||||
import { OneLoginDirectoryService } from './onelogin-directory.service';
|
||||
|
||||
export class SyncService {
|
||||
private dirType: DirectoryType;
|
||||
@@ -123,6 +124,8 @@ export class SyncService {
|
||||
return new LdapDirectoryService(this.configurationService, this.logService, this.i18nService);
|
||||
case DirectoryType.Okta:
|
||||
return new OktaDirectoryService(this.configurationService, this.logService, this.i18nService);
|
||||
case DirectoryType.OneLogin:
|
||||
return new OneLoginDirectoryService(this.configurationService, this.logService, this.i18nService);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user