diff --git a/package-lock.json b/package-lock.json
index dedb1036..cef06d62 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4572,14 +4572,14 @@
}
},
"googleapis": {
- "version": "28.1.0",
- "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-28.1.0.tgz",
- "integrity": "sha512-+kDXcTq5YUGjrzNOjE6eDaSQ/92bpBrDqj5TGz/AwhnXDqNVGMQey6eRQNMPdrJMYYBSZGYHza1CSIxO/LHEeA==",
+ "version": "29.0.0",
+ "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-29.0.0.tgz",
+ "integrity": "sha512-qac2RSPObw80AOvSPV9hus8VyRxrdaTnsUmttdO6hO12fBE5jI/R9XytUOuB3Z/4LP+1NpprNyKSHm9xXuJx2w==",
"requires": {
"google-auth-library": "1.4.0",
"pify": "3.0.0",
"qs": "6.5.1",
- "string-template": "1.0.0",
+ "url-template": "2.0.8",
"uuid": "3.2.1"
}
},
@@ -8961,11 +8961,6 @@
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
"dev": true
},
- "string-template": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz",
- "integrity": "sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y="
- },
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
@@ -10068,6 +10063,11 @@
"prepend-http": "1.0.4"
}
},
+ "url-template": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
+ "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE="
+ },
"use": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz",
diff --git a/package.json b/package.json
index 6c362dfd..1a975580 100644
--- a/package.json
+++ b/package.json
@@ -96,7 +96,7 @@
"electron-log": "2.2.14",
"electron-store": "1.3.0",
"electron-updater": "2.21.4",
- "googleapis": "28.1.0",
+ "googleapis": "29.0.0",
"keytar": "4.1.0",
"ldapjs": "1.0.2",
"lunr": "2.1.6",
diff --git a/src/app/tabs/dashboard.component.html b/src/app/tabs/dashboard.component.html
index 8cd5ca7b..bc12410b 100644
--- a/src/app/tabs/dashboard.component.html
+++ b/src/app/tabs/dashboard.component.html
@@ -1,3 +1,7 @@
The dashboard!!
+
+
+
+
diff --git a/src/app/tabs/dashboard.component.ts b/src/app/tabs/dashboard.component.ts
index 1a233db0..4cf47c1a 100644
--- a/src/app/tabs/dashboard.component.ts
+++ b/src/app/tabs/dashboard.component.ts
@@ -12,6 +12,10 @@ import { I18nService } from 'jslib/abstractions/i18n.service';
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';
+
@Component({
selector: 'app-dashboard',
templateUrl: 'dashboard.component.html',
@@ -20,5 +24,20 @@ export class DashboardComponent {
@ViewChild('settings', { read: ViewContainerRef }) settingsModal: ViewContainerRef;
constructor(analytics: Angulartics2, toasterService: ToasterService,
- i18nService: I18nService, private componentFactoryResolver: ComponentFactoryResolver) {}
+ i18nService: I18nService, private componentFactoryResolver: ComponentFactoryResolver) { }
+
+ gsuite() {
+ const gsuite = new GSuiteDirectoryService();
+ const entries = gsuite.getEntries();
+ }
+
+ ldap() {
+ const gsuite = new LdapDirectoryService();
+ const entries = gsuite.getEntries();
+ }
+
+ azuread() {
+ const gsuite = new AzureDirectoryService();
+ const entries = gsuite.getEntries();
+ }
}
diff --git a/src/services/azure-directory.service.ts b/src/services/azure-directory.service.ts
index a31dbf18..4e0b8f22 100644
--- a/src/services/azure-directory.service.ts
+++ b/src/services/azure-directory.service.ts
@@ -1,12 +1,74 @@
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';
+const Key = '';
+const ApplicationId = '';
+const Tenant = '';
+
export class AzureDirectoryService implements DirectoryService {
- getEntries(force = false) {
+ private client: graph.Client;
+
+ async getEntries(force = false) {
+ this.client = graph.Client.init({
+ authProvider: (done) => {
+ const data = querystring.stringify({
+ client_id: ApplicationId,
+ client_secret: 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',
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ 'Content-Length': Buffer.byteLength(data),
+ },
+ }, (res) => {
+ res.setEncoding('utf8');
+ res.on('data', (chunk: string) => {
+ const d = JSON.parse(chunk);
+ if (res.statusCode === 200 && d.access_token != null) {
+ done(null, d.access_token);
+ } else if (d.error != null && d.error_description != null) {
+ done(d.error + ' (' + res.statusCode + '): ' + d.error_description, null);
+ } else {
+ done('Unknown error (' + res.statusCode + ').', null);
+ }
+ });
+ }).on('error', (err) => {
+ done(err, null);
+ });
+
+ req.write(data);
+ req.end();
+ },
+ });
+
+ await this.getUsers();
+ await this.getGroups();
}
- private getUsers() {
+ private async getUsers() {
+ const request = this.client.api('/users/delta');
+ const users = await request.get();
+ console.log(users);
+ }
+ private async getGroups() {
+ const request = this.client.api('/groups/delta');
+ const groups = await request.get();
+ console.log(groups);
+
+ groups.value.forEach(async (g: any) => {
+ const membersRequest = this.client.api('/groups/' + g.id + '/members');
+ const members = await membersRequest.get();
+ console.log(members);
+ });
}
}
diff --git a/src/services/gsuite-directory.service.ts b/src/services/gsuite-directory.service.ts
index 43f8be16..87de4ef8 100644
--- a/src/services/gsuite-directory.service.ts
+++ b/src/services/gsuite-directory.service.ts
@@ -1,14 +1,69 @@
+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';
+const PrivateKey = '';
+const ClientEmail = '';
+const AdminEmail = '';
+const Domain = '';
+
export class GSuiteDirectoryService implements DirectoryService {
- getEntries(force = false) {
+ private client: JWT;
+ private service: Admin;
+ private authParams: any;
+
+ constructor() {
+ this.service = google.admin('directory_v1');
+ }
+
+ async getEntries(force = false) {
+ await this.auth();
+ await this.getUsers();
+ await this.getGroups();
}
private async getUsers() {
- const service = google.admin('directory_v1');
- const groups = await service.groups.list();
+ const response = await this.service.users.list(this.authParams);
+ console.log(response);
+ }
+
+ private async getGroups() {
+ const response = await this.service.groups.list(this.authParams);
+ console.log(response);
+
+ if (response.data.groups.length === 0) {
+ return;
+ }
+
+ response.data.groups.forEach(async (g) => {
+ const params: any = Object.assign({
+ groupKey: g.id,
+ }, this.authParams);
+ const members = await this.service.members.list(params);
+ console.log(members);
+ });
+ }
+
+ private async auth() {
+ this.client = new google.auth.JWT({
+ email: ClientEmail,
+ key: PrivateKey,
+ subject: AdminEmail,
+ scopes: [
+ 'https://www.googleapis.com/auth/admin.directory.user.readonly',
+ 'https://www.googleapis.com/auth/admin.directory.group.readonly',
+ 'https://www.googleapis.com/auth/admin.directory.group.member.readonly',
+ ],
+ });
+
+ await this.client.authorize();
+ this.authParams = {
+ auth: this.client,
+ domain: Domain,
+ };
+
+ // TODO: add customer?
}
}
diff --git a/src/services/ldap-directory.service.ts b/src/services/ldap-directory.service.ts
index 7521c4d3..6a94632e 100644
--- a/src/services/ldap-directory.service.ts
+++ b/src/services/ldap-directory.service.ts
@@ -2,37 +2,63 @@ import * as ldap from 'ldapjs';
import { DirectoryService } from 'src/services/directory.service';
+const Url = 'ldap://ldap.forumsys.com:389';
+const Username = 'cn=read-only-admin,dc=example,dc=com';
+const Password = 'password';
+
export class LdapDirectoryService implements DirectoryService {
- getEntries(force = false) {
+ private client: ldap.Client;
+
+ async getEntries(force = false) {
+ await this.auth();
+ await this.getUsers();
}
private getUsers() {
- const client = ldap.createClient({
- url: 'ldap://127.0.0.1:1389'
- });
-
const options: ldap.SearchOptions = {
- filter: '(&(l=Seattle)(email=*@foo.com))',
+ filter: null,
scope: 'sub',
- attributes: ['dn', 'sn', 'cn']
+ attributes: ['dn', 'sn', 'cn'],
};
- client.search('o=example', options, (error, response) => {
- if (error != null) {
+ return new Promise((resolve, reject) => {
+ this.client.search('dc=example,dc=com', options, (err, res) => {
+ if (err != null) {
+ console.error('search error: ' + err);
+ reject(err);
+ return;
+ }
+ res.on('searchEntry', (entry) => {
+ console.log(entry);
+ });
+ res.on('searchReference', (referral) => {
+ console.log('referral: ' + referral.uris.join());
+ });
+ res.on('error', (resErr) => {
+ console.error('error: ' + resErr.message);
+ reject(resErr);
+ });
+ res.on('end', (result) => {
+ console.log('status: ' + result.status);
+ });
- }
+ resolve();
+ });
+ });
+ }
- response.on('searchEntry', (entry) => {
- console.log('entry: ' + JSON.stringify(entry.object));
+ private async auth() {
+ return new Promise((resolve, reject) => {
+ this.client = ldap.createClient({
+ url: Url,
});
- response.on('searchReference', (referral) => {
- console.log('referral: ' + referral.uris.join());
- });
- response.on('error', (err) => {
- console.error('error: ' + err.message);
- });
- response.on('end', (result) => {
- console.log('status: ' + result.status);
+
+ this.client.bind(Username, Password, (err) => {
+ if (err != null) {
+ reject(err);
+ } else {
+ resolve();
+ }
});
});
}
diff --git a/webpack.renderer.js b/webpack.renderer.js
index 28f2584c..687edc51 100644
--- a/webpack.renderer.js
+++ b/webpack.renderer.js
@@ -46,7 +46,7 @@ const common = {
},
plugins: [],
resolve: {
- extensions: ['.tsx', '.ts', '.js'],
+ extensions: ['.tsx', '.ts', '.js', '.json'],
alias: {
jslib: path.join(__dirname, 'jslib/src')
},
@@ -136,6 +136,7 @@ const renderer = {
filename: '[name].js.map',
include: ['app/main.js']
}),
+ new webpack.DefinePlugin({ 'global.GENTLY': false }),
extractCss
]
};