1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 01:03:35 +00:00

[Require SSO] Enterprise policy adjustment (#676)

* Commits for policies/edit/strings

* more initial commits of policy/edit/strings

* More changes for require sso

* Updated strings to match policy string patterns

* Updated false enable on error

* Removed sso prevalidate prereq // adjusted callout

* Updated policy array creation and added display value
This commit is contained in:
Vincent Salucci
2020-10-26 11:56:02 -05:00
committed by GitHub
parent a51331d6b2
commit beebe7c98b
5 changed files with 121 additions and 70 deletions

View File

@@ -13,7 +13,7 @@
<table class="table table-hover table-list" *ngIf="!loading"> <table class="table table-hover table-list" *ngIf="!loading">
<tbody> <tbody>
<tr *ngFor="let p of policies"> <tr *ngFor="let p of policies">
<td> <td *ngIf="p.display">
<a href="#" appStopClick (click)="edit(p)">{{p.name}}</a> <a href="#" appStopClick (click)="edit(p)">{{p.name}}</a>
<span class="badge badge-success" *ngIf="p.enabled">{{'enabled' | i18n}}</span> <span class="badge badge-success" *ngIf="p.enabled">{{'enabled' | i18n}}</span>
<small class="text-muted d-block">{{p.description}}</small> <small class="text-muted d-block">{{p.description}}</small>

View File

@@ -47,34 +47,7 @@ export class PoliciesComponent implements OnInit {
constructor(private apiService: ApiService, private route: ActivatedRoute, constructor(private apiService: ApiService, private route: ActivatedRoute,
private i18nService: I18nService, private componentFactoryResolver: ComponentFactoryResolver, private i18nService: I18nService, private componentFactoryResolver: ComponentFactoryResolver,
private platformUtilsService: PlatformUtilsService, private userService: UserService, private platformUtilsService: PlatformUtilsService, private userService: UserService,
private router: Router, private environmentService: EnvironmentService) { private router: Router, private environmentService: EnvironmentService) { }
this.policies = [
{
name: i18nService.t('twoStepLogin'),
description: i18nService.t('twoStepLoginPolicyDesc'),
type: PolicyType.TwoFactorAuthentication,
enabled: false,
},
{
name: i18nService.t('masterPass'),
description: i18nService.t('masterPassPolicyDesc'),
type: PolicyType.MasterPassword,
enabled: false,
},
{
name: i18nService.t('passwordGenerator'),
description: i18nService.t('passwordGeneratorPolicyDesc'),
type: PolicyType.PasswordGenerator,
enabled: false,
},
{
name: i18nService.t('onlyOrg'),
description: i18nService.t('onlyOrgDesc'),
type: PolicyType.OnlyOrg,
enabled: false,
},
];
}
async ngOnInit() { async ngOnInit() {
this.route.parent.parent.params.subscribe(async (params) => { this.route.parent.parent.params.subscribe(async (params) => {
@@ -84,6 +57,43 @@ export class PoliciesComponent implements OnInit {
this.router.navigate(['/organizations', this.organizationId]); this.router.navigate(['/organizations', this.organizationId]);
return; return;
} }
this.policies = [
{
name: this.i18nService.t('twoStepLogin'),
description: this.i18nService.t('twoStepLoginPolicyDesc'),
type: PolicyType.TwoFactorAuthentication,
enabled: false,
display: true,
},
{
name: this.i18nService.t('masterPass'),
description: this.i18nService.t('masterPassPolicyDesc'),
type: PolicyType.MasterPassword,
enabled: false,
display: true,
},
{
name: this.i18nService.t('passwordGenerator'),
description: this.i18nService.t('passwordGeneratorPolicyDesc'),
type: PolicyType.PasswordGenerator,
enabled: false,
display: true,
},
{
name: this.i18nService.t('onlyOrg'),
description: this.i18nService.t('onlyOrgDesc'),
type: PolicyType.OnlyOrg,
enabled: false,
display: true,
},
{
name: this.i18nService.t('requireSso'),
description: this.i18nService.t('requireSsoPolicyDesc'),
type: PolicyType.RequireSso,
enabled: false,
display: organization.useSso,
},
];
await this.load(); await this.load();
}); });
@@ -122,6 +132,7 @@ export class PoliciesComponent implements OnInit {
childComponent.description = p.description; childComponent.description = p.description;
childComponent.type = p.type; childComponent.type = p.type;
childComponent.organizationId = this.organizationId; childComponent.organizationId = this.organizationId;
childComponent.policiesEnabledMap = this.policiesEnabledMap;
childComponent.onSavedPolicy.subscribe(() => { childComponent.onSavedPolicy.subscribe(() => {
this.modal.close(); this.modal.close();
this.load(); this.load();

View File

@@ -17,10 +17,13 @@
title="{{'warning' | i18n}}" icon="fa-warning"> title="{{'warning' | i18n}}" icon="fa-warning">
{{'twoStepLoginPolicyWarning' | i18n}} {{'twoStepLoginPolicyWarning' | i18n}}
</app-callout> </app-callout>
<app-callout type="warning" *ngIf="type === policyType.OnlyOrg" <app-callout type="warning" *ngIf="type === policyType.OnlyOrg" title="{{'warning' | i18n}}"
title="{{'warning' | i18n}}" icon="fa-warning"> icon="fa-warning">
{{'onlyOrgPolicyWarning' | i18n}} {{'onlyOrgPolicyWarning' | i18n}}
</app-callout> </app-callout>
<app-callout type="tip" title="{{'prerequisite' | i18n}}" *ngIf="type === policyType.RequireSso">
{{'requireSsoPolicyReq' | i18n}}
</app-callout>
<div class="form-group"> <div class="form-group">
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="enabled" [(ngModel)]="enabled" <input class="form-check-input" type="checkbox" id="enabled" [(ngModel)]="enabled"

View File

@@ -27,6 +27,7 @@ export class PolicyEditComponent implements OnInit {
@Input() description: string; @Input() description: string;
@Input() type: PolicyType; @Input() type: PolicyType;
@Input() organizationId: string; @Input() organizationId: string;
@Input() policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>();
@Output() onSavedPolicy = new EventEmitter(); @Output() onSavedPolicy = new EventEmitter();
policyType = PolicyType; policyType = PolicyType;
@@ -127,6 +128,7 @@ export class PolicyEditComponent implements OnInit {
} }
async submit() { async submit() {
if (this.preValidate()) {
const request = new PolicyRequest(); const request = new PolicyRequest();
request.enabled = this.enabled; request.enabled = this.enabled;
request.type = this.type; request.type = this.type;
@@ -168,4 +170,24 @@ export class PolicyEditComponent implements OnInit {
this.onSavedPolicy.emit(); this.onSavedPolicy.emit();
} catch { } } catch { }
} }
}
private preValidate(): boolean {
switch (this.type) {
case PolicyType.RequireSso:
if (!this.enabled) { // Don't need prevalidation checks if submitting to disable
return true;
}
// Have OnlyOrg policy enabled?
if (!(this.policiesEnabledMap.has(PolicyType.OnlyOrg)
&& this.policiesEnabledMap.get(PolicyType.OnlyOrg))) {
this.toasterService.popAsync('error', null, this.i18nService.t('requireSsoPolicyReqError'));
return false;
}
return true;
default:
return true;
}
}
} }

View File

@@ -3221,5 +3221,20 @@
}, },
"onlyOrgPolicyWarning": { "onlyOrgPolicyWarning": {
"message": "Organization members who are already a member of another organization will be removed from your organization." "message": "Organization members who are already a member of another organization will be removed from your organization."
},
"requireSso": {
"message": "Single Sign-On Authentication"
},
"requireSsoPolicyDesc": {
"message": "Require users to log in with the Enterprise Single Sign-On method."
},
"prerequisite": {
"message": "Prerequisite"
},
"requireSsoPolicyReq": {
"message": "The Single Organization enterprise policy must be enabled before activating this policy."
},
"requireSsoPolicyReqError": {
"message": "Single Organization policy not enabled."
} }
} }