1
0
mirror of https://github.com/bitwarden/directory-connector synced 2025-12-11 13:53:22 +00:00

CLI support for SSO Login (#57)

* sso login support

* fix build and lint issues

* allow web vault URL to be set
This commit is contained in:
Kyle Spearrin
2020-08-04 14:19:53 -04:00
committed by GitHub
parent fb122cbbdb
commit 2b2d8a9fab
10 changed files with 59 additions and 9 deletions

2
jslib

Submodule jslib updated: 57ace40845...14b01f2e5d

27
package-lock.json generated
View File

@@ -9906,6 +9906,11 @@
}
}
},
"is-docker": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz",
"integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ=="
},
"is-extendable": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
@@ -10102,6 +10107,14 @@
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
"dev": true
},
"is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"requires": {
"is-docker": "^2.0.0"
}
},
"is-yarn-global": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
@@ -12077,6 +12090,15 @@
"mimic-fn": "^1.0.0"
}
},
"open": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/open/-/open-7.1.0.tgz",
"integrity": "sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA==",
"requires": {
"is-docker": "^2.0.0",
"is-wsl": "^2.1.1"
}
},
"optionator": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
@@ -17324,6 +17346,11 @@
"version": "0.8.28",
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.28.tgz",
"integrity": "sha512-MjwlvV0wr65IQiT0WSHedo/zUhAqtypMdTUjqroV81RohGj1XANwHuC37dwYxphTRbZBYidk0gNS0dQrU2Q3Pw=="
},
"zxcvbn": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
"integrity": "sha1-KOwXzwl0PtyrBW3dixsGJizHPDA="
}
}
}

View File

@@ -220,7 +220,9 @@
"lunr": "2.3.3",
"node-fetch": "2.2.0",
"node-forge": "0.7.6",
"open": "7.1.0",
"rxjs": "6.3.3",
"zone.js": "0.8.28"
"zone.js": "0.8.28",
"zxcvbn": "4.4.2"
}
}

View File

@@ -17,6 +17,11 @@
</div>
<h4>{{'customEnvironment' | i18n}}</h4>
<p>{{'customEnvironmentFooter' | i18n}}</p>
<div class="form-group">
<label for="webVaultUrl">{{'webVaultUrl' | i18n}}</label>
<input id="webVaultUrl" type="text" name="WebVaultUrl" [(ngModel)]="webVaultUrl"
class="form-control">
</div>
<div class="form-group">
<label for="apiUrl">{{'apiUrl' | i18n}}</label>
<input id="apiUrl" type="text" name="ApiUrl" [(ngModel)]="apiUrl" class="form-control">

View File

@@ -33,6 +33,7 @@ import { ContainerService } from 'jslib/services/container.service';
import { CryptoService } from 'jslib/services/crypto.service';
import { EnvironmentService } from 'jslib/services/environment.service';
import { NodeCryptoFunctionService } from 'jslib/services/nodeCryptoFunction.service';
import { PasswordGenerationService } from 'jslib/services/passwordGeneration.service';
import { StateService } from 'jslib/services/state.service';
import { TokenService } from 'jslib/services/token.service';
import { UserService } from 'jslib/services/user.service';
@@ -46,6 +47,9 @@ import { EnvironmentService as EnvironmentServiceAbstraction } from 'jslib/abstr
import { I18nService as I18nServiceAbstraction } from 'jslib/abstractions/i18n.service';
import { LogService as LogServiceAbstraction } from 'jslib/abstractions/log.service';
import { MessagingService as MessagingServiceAbstraction } from 'jslib/abstractions/messaging.service';
import {
PasswordGenerationService as PasswordGenerationServiceAbstraction,
} from 'jslib/abstractions/passwordGeneration.service';
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from 'jslib/abstractions/platformUtils.service';
import { StateService as StateServiceAbstraction } from 'jslib/abstractions/state.service';
import { StorageService as StorageServiceAbstraction } from 'jslib/abstractions/storage.service';
@@ -57,8 +61,8 @@ const i18nService = new I18nService(window.navigator.language, './locales');
const stateService = new StateService();
const broadcasterService = new BroadcasterService();
const messagingService = new ElectronRendererMessagingService(broadcasterService);
const platformUtilsService = new ElectronPlatformUtilsService(i18nService, messagingService, true);
const storageService: StorageServiceAbstraction = new ElectronStorageService(remote.app.getPath('userData'));
const platformUtilsService = new ElectronPlatformUtilsService(i18nService, messagingService, true, storageService);
const secureStorageService: StorageServiceAbstraction = new ElectronRendererSecureStorageService();
const cryptoFunctionService: CryptoFunctionServiceAbstraction = new NodeCryptoFunctionService();
const cryptoService = new CryptoService(storageService, secureStorageService, cryptoFunctionService);
@@ -70,10 +74,11 @@ const environmentService = new EnvironmentService(apiService, storageService, nu
const userService = new UserService(tokenService, storageService);
const containerService = new ContainerService(cryptoService);
const authService = new AuthService(cryptoService, apiService, userService, tokenService, appIdService,
i18nService, platformUtilsService, messagingService, false);
i18nService, platformUtilsService, messagingService, null, false);
const configurationService = new ConfigurationService(storageService, secureStorageService);
const syncService = new SyncService(configurationService, logService, cryptoFunctionService, apiService,
messagingService, i18nService);
const passwordGenerationService = new PasswordGenerationService(cryptoService, storageService, null);
const analytics = new Analytics(window, () => true, platformUtilsService, storageService, appIdService);
containerService.attachToWindow(window);
@@ -134,6 +139,7 @@ export function initFactory(): Function {
{ provide: LogServiceAbstraction, useValue: logService },
{ provide: ConfigurationService, useValue: configurationService },
{ provide: SyncService, useValue: syncService },
{ provide: PasswordGenerationServiceAbstraction, useValue: passwordGenerationService },
{
provide: APP_INITIALIZER,
useFactory: initFactory,

View File

@@ -22,6 +22,7 @@ import { LowdbStorageService } from 'jslib/services/lowdbStorage.service';
import { NodeApiService } from 'jslib/services/nodeApi.service';
import { NodeCryptoFunctionService } from 'jslib/services/nodeCryptoFunction.service';
import { NoopMessagingService } from 'jslib/services/noopMessaging.service';
import { PasswordGenerationService } from 'jslib/services/passwordGeneration.service';
import { TokenService } from 'jslib/services/token.service';
import { UserService } from 'jslib/services/user.service';
@@ -52,6 +53,7 @@ export class Main {
authService: AuthService;
configurationService: ConfigurationService;
syncService: SyncService;
passwordGenerationService: PasswordGenerationService;
program: Program;
constructor() {
@@ -92,11 +94,12 @@ export class Main {
this.userService = new UserService(this.tokenService, this.storageService);
this.containerService = new ContainerService(this.cryptoService);
this.authService = new AuthService(this.cryptoService, this.apiService, this.userService, this.tokenService,
this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService, true);
this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService, null, false);
this.configurationService = new ConfigurationService(this.storageService, this.secureStorageService,
process.env.BITWARDENCLI_CONNECTOR_PLAINTEXT_SECRETS !== 'true');
this.syncService = new SyncService(this.configurationService, this.logService, this.cryptoFunctionService,
this.apiService, this.messagingService, this.i18nService);
this.passwordGenerationService = new PasswordGenerationService(this.cryptoService, this.storageService, null);
this.program = new Program(this);
}

View File

@@ -140,6 +140,9 @@
"baseUrl": {
"message": "Server URL"
},
"webVaultUrl": {
"message": "Web Vault Server URL"
},
"apiUrl": {
"message": "API Server URL"
},

View File

@@ -86,6 +86,7 @@ export class Program extends BaseProgram {
.description('Log into a user account.')
.option('--method <method>', 'Two-step login method.')
.option('--code <code>', 'Two-step login code.')
.option('--sso', 'Log in with Single-Sign On.')
.on('--help', () => {
writeLn('\n Notes:');
writeLn('');
@@ -96,11 +97,14 @@ export class Program extends BaseProgram {
writeLn(' bw login');
writeLn(' bw login john@example.com myPassword321');
writeLn(' bw login john@example.com myPassword321 --method 1 --code 249213');
writeLn(' bw login --sso');
writeLn('', true);
})
.action(async (email: string, password: string, cmd: program.Command) => {
await this.exitIfAuthed();
const command = new LoginCommand(this.main.authService, this.main.apiService, this.main.i18nService);
const command = new LoginCommand(this.main.authService, this.main.apiService, this.main.i18nService,
this.main.environmentService, this.main.passwordGenerationService, this.main.cryptoFunctionService,
'connector');
const response = await command.run(email, password, cmd);
this.processResponse(response);
});

View File

@@ -5,8 +5,8 @@ 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 { OneLoginConfiguration } from 'src/models/oneLoginConfiguration';
const StoredSecurely = '[STORED SECURELY]';
const Keys = {

View File

@@ -160,8 +160,8 @@ export class OneLoginDirectoryService extends BaseDirectoryService implements Di
const req: RequestInit = {
method: 'GET',
headers: new Headers({
'Authorization': 'bearer:' + this.accessToken,
'Accept': 'application/json',
Authorization: 'bearer:' + this.accessToken,
Accept: 'application/json',
}),
};
const response = await fetch(new Request(url, req));