diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts
index 01ac192c..56c500ab 100644
--- a/src/app/services/services.module.ts
+++ b/src/app/services/services.module.ts
@@ -17,6 +17,7 @@ import { LaunchGuardService } from './launch-guard.service';
import { ConfigurationService } from '../../services/configuration.service';
import { I18nService } from '../../services/i18n.service';
+import { SyncService } from '../../services/sync.service';
import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
import { ValidationService } from 'jslib/angular/services/validation.service';
@@ -70,6 +71,7 @@ const containerService = new ContainerService(cryptoService, platformUtilsServic
const authService = new AuthService(cryptoService, apiService, userService, tokenService, appIdService,
i18nService, platformUtilsService, messagingService, false);
const configurationService = new ConfigurationService(storageService, secureStorageService);
+const syncSevrice = new SyncService(configurationService);
const analytics = new Analytics(window, () => true, platformUtilsService, storageService, appIdService);
containerService.attachToWindow(window);
@@ -123,6 +125,7 @@ export function initFactory(): Function {
{ provide: StateServiceAbstraction, useValue: stateService },
{ provide: LogServiceAbstraction, useValue: logService },
{ provide: ConfigurationService, useValue: configurationService },
+ { provide: SyncService, useValue: syncSevrice },
{
provide: APP_INITIALIZER,
useFactory: initFactory,
diff --git a/src/app/tabs/dashboard.component.html b/src/app/tabs/dashboard.component.html
index bc12410b..81345fca 100644
--- a/src/app/tabs/dashboard.component.html
+++ b/src/app/tabs/dashboard.component.html
@@ -1,7 +1,2 @@
-
-
-The dashboard!!
-
-
-
-
+
+
diff --git a/src/app/tabs/dashboard.component.ts b/src/app/tabs/dashboard.component.ts
index 4cf47c1a..59a21530 100644
--- a/src/app/tabs/dashboard.component.ts
+++ b/src/app/tabs/dashboard.component.ts
@@ -15,6 +15,7 @@ import { ModalComponent } from 'jslib/angular/components/modal.component';
import { AzureDirectoryService } from '../../services/azure-directory.service';
import { GSuiteDirectoryService } from '../../services/gsuite-directory.service';
import { LdapDirectoryService } from '../../services/ldap-directory.service';
+import { SyncService } from '../../services/sync.service';
@Component({
selector: 'app-dashboard',
@@ -24,20 +25,14 @@ export class DashboardComponent {
@ViewChild('settings', { read: ViewContainerRef }) settingsModal: ViewContainerRef;
constructor(analytics: Angulartics2, toasterService: ToasterService,
- i18nService: I18nService, private componentFactoryResolver: ComponentFactoryResolver) { }
+ i18nService: I18nService, private componentFactoryResolver: ComponentFactoryResolver,
+ private syncService: SyncService) { }
- gsuite() {
- const gsuite = new GSuiteDirectoryService();
- const entries = gsuite.getEntries();
+ async sync() {
+ await this.syncService.sync(true, true);
}
- ldap() {
- const gsuite = new LdapDirectoryService();
- const entries = gsuite.getEntries();
- }
-
- azuread() {
- const gsuite = new AzureDirectoryService();
- const entries = gsuite.getEntries();
+ async simulate() {
+ await this.syncService.sync(true, false);
}
}
diff --git a/src/app/tabs/settings.component.html b/src/app/tabs/settings.component.html
index 7934f9bf..c1262681 100644
--- a/src/app/tabs/settings.component.html
+++ b/src/app/tabs/settings.component.html
@@ -85,7 +85,7 @@
-
diff --git a/src/app/tabs/settings.component.ts b/src/app/tabs/settings.component.ts
index 8f4bf58d..d158f97e 100644
--- a/src/app/tabs/settings.component.ts
+++ b/src/app/tabs/settings.component.ts
@@ -10,7 +10,6 @@ import { ToasterService } from 'angular2-toaster';
import { Angulartics2 } from 'angulartics2';
import { I18nService } from 'jslib/abstractions/i18n.service';
-import { StorageService } from 'jslib/abstractions/storage.service';
import { ConfigurationService } from '../../services/configuration.service';
@@ -36,7 +35,7 @@ export class SettingsComponent implements OnInit {
constructor(analytics: Angulartics2, toasterService: ToasterService,
i18nService: I18nService, private componentFactoryResolver: ComponentFactoryResolver,
- private configurationService: ConfigurationService, private storageService: StorageService) {
+ private configurationService: ConfigurationService) {
this.directoryOptions = [
{ name: i18nService.t('select'), value: null },
{ name: 'Active Directory / LDAP', value: DirectoryType.Ldap },
@@ -46,21 +45,21 @@ export class SettingsComponent implements OnInit {
}
async ngOnInit() {
- this.directory = await this.storageService.get('directory');
- this.ldap = (await this.configurationService.get(DirectoryType.Ldap)) ||
+ this.directory = await this.configurationService.getDirectoryType();
+ this.ldap = (await this.configurationService.getDirectory(DirectoryType.Ldap)) ||
this.ldap;
- this.gsuite = (await this.configurationService.get(DirectoryType.GSuite)) ||
+ this.gsuite = (await this.configurationService.getDirectory(DirectoryType.GSuite)) ||
this.gsuite;
- this.azure = (await this.configurationService.get(DirectoryType.AzureActiveDirectory)) ||
- this.azure;
- this.sync = (await this.storageService.get('syncConfig')) || this.sync;
+ this.azure = (await this.configurationService.getDirectory(
+ DirectoryType.AzureActiveDirectory)) || this.azure;
+ this.sync = (await this.configurationService.getSync()) || this.sync;
}
async submit() {
- await this.storageService.save('directory', this.directory);
- await this.configurationService.save(DirectoryType.Ldap, this.ldap);
- await this.configurationService.save(DirectoryType.GSuite, this.gsuite);
- await this.configurationService.save(DirectoryType.AzureActiveDirectory, this.azure);
- await this.storageService.save('syncConfig', this.sync);
+ await this.configurationService.saveDirectoryType(this.directory);
+ 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.saveSync(this.sync);
}
}
diff --git a/src/services/azure-directory.service.ts b/src/services/azure-directory.service.ts
index 4e0b8f22..35138238 100644
--- a/src/services/azure-directory.service.ts
+++ b/src/services/azure-directory.service.ts
@@ -2,28 +2,32 @@ import * as graph from '@microsoft/microsoft-graph-client';
import * as https from 'https';
import * as querystring from 'querystring';
-import { DirectoryService } from 'src/services/directory.service';
+import { DirectoryType } from '../enums/directoryType';
-const Key = '';
-const ApplicationId = '';
-const Tenant = '';
+import { AzureConfiguration } from '../models/azureConfiguration';
+import { SyncConfiguration } from '../models/syncConfiguration';
+
+import { ConfigurationService } from './configuration.service';
+import { DirectoryService } from './directory.service';
export class AzureDirectoryService implements DirectoryService {
private client: graph.Client;
+ private dirConfig: AzureConfiguration;
+ private syncConfig: SyncConfiguration;
- async getEntries(force = false) {
+ constructor(private configurationService: ConfigurationService) {
this.client = graph.Client.init({
authProvider: (done) => {
const data = querystring.stringify({
- client_id: ApplicationId,
- client_secret: Key,
+ client_id: this.dirConfig.applicationId,
+ client_secret: this.dirConfig.key,
grant_type: 'client_credentials',
scope: 'https://graph.microsoft.com/.default',
});
const req = https.request({
host: 'login.microsoftonline.com',
- path: '/' + Tenant + '/oauth2/v2.0/token',
+ path: '/' + this.dirConfig.tenant + '/oauth2/v2.0/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
@@ -49,6 +53,24 @@ export class AzureDirectoryService implements DirectoryService {
req.end();
},
});
+ }
+
+ async getEntries(force = false) {
+ const type = await this.configurationService.getDirectoryType();
+ if (type !== DirectoryType.AzureActiveDirectory) {
+ return;
+ }
+
+ this.dirConfig = await this.configurationService.getDirectory(
+ DirectoryType.AzureActiveDirectory);
+ if (this.dirConfig == null) {
+ return;
+ }
+
+ this.syncConfig = await this.configurationService.getSync();
+ if (this.syncConfig == null) {
+ return;
+ }
await this.getUsers();
await this.getGroups();
diff --git a/src/services/configuration.service.ts b/src/services/configuration.service.ts
index 14a187da..80e93db4 100644
--- a/src/services/configuration.service.ts
+++ b/src/services/configuration.service.ts
@@ -1,6 +1,10 @@
import { DirectoryType } from '../enums/directoryType';
import { StorageService } from 'jslib/abstractions/storage.service';
+import { AzureConfiguration } from '../models/azureConfiguration';
+import { GSuiteConfiguration } from '../models/gsuiteConfiguration';
+import { LdapConfiguration } from '../models/ldapConfiguration';
+import { SyncConfiguration } from '../models/syncConfiguration';
const StoredSecurely = '[STORED SECURELY]';
const Keys = {
@@ -8,12 +12,14 @@ const Keys = {
gsuite: 'gsuitePrivateKey',
azure: 'azureKey',
directoryConfigPrefix: 'directoryConfig_',
+ sync: 'syncConfig',
+ directoryType: 'directoryType',
};
export class ConfigurationService {
constructor(private storageService: StorageService, private secureStorageService: StorageService) { }
- async get(type: DirectoryType): Promise {
+ async getDirectory(type: DirectoryType): Promise {
const config = await this.storageService.get(Keys.directoryConfigPrefix + type);
if (config == null) {
return config;
@@ -33,7 +39,8 @@ export class ConfigurationService {
return config;
}
- async save(type: DirectoryType, config: T): Promise {
+ async saveDirectory(type: DirectoryType,
+ config: LdapConfiguration | GSuiteConfiguration | AzureConfiguration): Promise {
const savedConfig: any = Object.assign({}, config);
switch (type) {
case DirectoryType.Ldap:
@@ -56,6 +63,8 @@ export class ConfigurationService {
if (savedConfig.privateKey == null) {
await this.secureStorageService.remove(Keys.gsuite);
} else {
+ (config as any).privateKey = savedConfig.privateKey =
+ savedConfig.privateKey.replace(/\\n/g, '\n');
await this.secureStorageService.save(Keys.gsuite, savedConfig.privateKey);
savedConfig.privateKey = StoredSecurely;
}
@@ -63,4 +72,20 @@ export class ConfigurationService {
}
await this.storageService.save(Keys.directoryConfigPrefix + type, savedConfig);
}
+
+ async getSync(): Promise {
+ return this.storageService.get(Keys.sync);
+ }
+
+ async saveSync(config: SyncConfiguration) {
+ return this.storageService.save(Keys.sync, config);
+ }
+
+ async getDirectoryType(): Promise {
+ return this.storageService.get(Keys.directoryType);
+ }
+
+ async saveDirectoryType(type: DirectoryType) {
+ return this.storageService.save(Keys.directoryType, type);
+ }
}
diff --git a/src/services/gsuite-directory.service.ts b/src/services/gsuite-directory.service.ts
index 87de4ef8..7a3744ea 100644
--- a/src/services/gsuite-directory.service.ts
+++ b/src/services/gsuite-directory.service.ts
@@ -2,23 +2,41 @@ import { JWT } from 'google-auth-library';
import { google, GoogleApis } from 'googleapis';
import { Admin } from 'googleapis/build/src/apis/admin/directory_v1';
-import { DirectoryService } from 'src/services/directory.service';
+import { DirectoryType } from '../enums/directoryType';
-const PrivateKey = '';
-const ClientEmail = '';
-const AdminEmail = '';
-const Domain = '';
+import { GSuiteConfiguration } from '../models/gsuiteConfiguration';
+import { SyncConfiguration } from '../models/syncConfiguration';
+
+import { ConfigurationService } from './configuration.service';
+import { DirectoryService } from './directory.service';
export class GSuiteDirectoryService implements DirectoryService {
private client: JWT;
private service: Admin;
private authParams: any;
+ private dirConfig: GSuiteConfiguration;
+ private syncConfig: SyncConfiguration;
- constructor() {
+ constructor(private configurationService: ConfigurationService) {
this.service = google.admin('directory_v1');
}
async getEntries(force = false) {
+ const type = await this.configurationService.getDirectoryType();
+ if (type !== DirectoryType.GSuite) {
+ return;
+ }
+
+ this.dirConfig = await this.configurationService.getDirectory(DirectoryType.GSuite);
+ if (this.dirConfig == null) {
+ return;
+ }
+
+ this.syncConfig = await this.configurationService.getSync();
+ if (this.syncConfig == null) {
+ return;
+ }
+
await this.auth();
await this.getUsers();
await this.getGroups();
@@ -48,9 +66,9 @@ export class GSuiteDirectoryService implements DirectoryService {
private async auth() {
this.client = new google.auth.JWT({
- email: ClientEmail,
- key: PrivateKey,
- subject: AdminEmail,
+ email: this.dirConfig.clientEmail,
+ key: this.dirConfig.privateKey,
+ subject: this.dirConfig.adminUser,
scopes: [
'https://www.googleapis.com/auth/admin.directory.user.readonly',
'https://www.googleapis.com/auth/admin.directory.group.readonly',
@@ -59,11 +77,13 @@ export class GSuiteDirectoryService implements DirectoryService {
});
await this.client.authorize();
+
this.authParams = {
auth: this.client,
- domain: Domain,
+ domain: this.dirConfig.domain,
};
-
- // TODO: add customer?
+ if (this.dirConfig.customer != null) {
+ this.authParams.customer = this.dirConfig.customer;
+ }
}
}
diff --git a/src/services/ldap-directory.service.ts b/src/services/ldap-directory.service.ts
index 6a94632e..620dd8a8 100644
--- a/src/services/ldap-directory.service.ts
+++ b/src/services/ldap-directory.service.ts
@@ -1,15 +1,36 @@
import * as ldap from 'ldapjs';
-import { DirectoryService } from 'src/services/directory.service';
+import { DirectoryType } from '../enums/directoryType';
-const Url = 'ldap://ldap.forumsys.com:389';
-const Username = 'cn=read-only-admin,dc=example,dc=com';
-const Password = 'password';
+import { LdapConfiguration } from '../models/ldapConfiguration';
+import { SyncConfiguration } from '../models/syncConfiguration';
+
+import { ConfigurationService } from './configuration.service';
+import { DirectoryService } from './directory.service';
export class LdapDirectoryService implements DirectoryService {
private client: ldap.Client;
+ private dirConfig: LdapConfiguration;
+ private syncConfig: SyncConfiguration;
+
+ constructor(private configurationService: ConfigurationService) { }
async getEntries(force = false) {
+ const type = await this.configurationService.getDirectoryType();
+ if (type !== DirectoryType.Ldap) {
+ return;
+ }
+
+ this.dirConfig = await this.configurationService.getDirectory(DirectoryType.Ldap);
+ if (this.dirConfig == null) {
+ return;
+ }
+
+ this.syncConfig = await this.configurationService.getSync();
+ if (this.syncConfig == null) {
+ return;
+ }
+
await this.auth();
await this.getUsers();
}
@@ -49,11 +70,13 @@ export class LdapDirectoryService implements DirectoryService {
private async auth() {
return new Promise((resolve, reject) => {
+ const url = 'ldap' + (this.dirConfig.ssl ? 's' : '') + '://' + this.dirConfig.hostname +
+ ':' + this.dirConfig.port;
this.client = ldap.createClient({
- url: Url,
+ url: url,
});
- this.client.bind(Username, Password, (err) => {
+ this.client.bind(this.dirConfig.username, this.dirConfig.password, (err) => {
if (err != null) {
reject(err);
} else {
diff --git a/src/services/sync.service.ts b/src/services/sync.service.ts
new file mode 100644
index 00000000..78884a2d
--- /dev/null
+++ b/src/services/sync.service.ts
@@ -0,0 +1,45 @@
+import { DirectoryType } from '../enums/directoryType';
+
+import { StorageService } from 'jslib/abstractions/storage.service';
+
+import { AzureDirectoryService } from './azure-directory.service';
+import { ConfigurationService } from './configuration.service';
+import { DirectoryService } from './directory.service';
+import { GSuiteDirectoryService } from './gsuite-directory.service';
+import { LdapDirectoryService } from './ldap-directory.service';
+
+const Keys = {
+};
+
+export class SyncService {
+ private dirType: DirectoryType;
+
+ constructor(private configurationService: ConfigurationService) { }
+
+ async sync(force = true, sendToServer = true): Promise {
+ this.dirType = await this.configurationService.getDirectoryType();
+ if (this.dirType == null) {
+ return;
+ }
+
+ const directoryService = this.getDirectoryService();
+ if (directoryService == null) {
+ return;
+ }
+
+ directoryService.getEntries(force);
+ }
+
+ private getDirectoryService(): DirectoryService {
+ switch (this.dirType) {
+ case DirectoryType.GSuite:
+ return new GSuiteDirectoryService(this.configurationService);
+ case DirectoryType.AzureActiveDirectory:
+ return new AzureDirectoryService(this.configurationService);
+ case DirectoryType.Ldap:
+ return new LdapDirectoryService(this.configurationService);
+ default:
+ return null;
+ }
+ }
+}