From f55877eb706d755ea96b68e9813ca36caa0debca Mon Sep 17 00:00:00 2001 From: Max Peintner Date: Mon, 13 Mar 2023 11:01:09 +0100 Subject: [PATCH] feat(console): GitHub identity provider template (#5403) Github idp template for console --- .../idp-table/idp-table.component.html | 5 + .../modules/idp-table/idp-table.component.ts | 2 + .../idp-settings/idp-settings.component.html | 15 +- .../provider-github-routing.module.ts | 18 ++ .../provider-github.component.html | 94 ++++++ .../provider-github.component.scss | 99 +++++++ .../provider-github.component.spec.ts | 24 ++ .../provider-github.component.ts | 267 ++++++++++++++++++ .../provider-github/provider-github.module.ts | 43 +++ .../provider-google.component.ts | 11 +- .../provider-jwt/provider-jwt.component.ts | 11 +- .../provider-oidc/provider-oidc.component.ts | 11 +- .../pages/instance/instance-routing.module.ts | 13 + .../src/app/pages/orgs/org-routing.module.ts | 13 + console/src/app/services/admin.service.ts | 12 + console/src/app/services/mgmt.service.ts | 12 + console/src/assets/i18n/de.json | 4 + console/src/assets/i18n/en.json | 4 + console/src/assets/i18n/fr.json | 4 + console/src/assets/i18n/it.json | 4 + console/src/assets/i18n/pl.json | 4 + console/src/assets/i18n/zh.json | 8 +- console/src/component-themes.scss | 2 + 23 files changed, 657 insertions(+), 23 deletions(-) create mode 100644 console/src/app/modules/providers/provider-github/provider-github-routing.module.ts create mode 100644 console/src/app/modules/providers/provider-github/provider-github.component.html create mode 100644 console/src/app/modules/providers/provider-github/provider-github.component.scss create mode 100644 console/src/app/modules/providers/provider-github/provider-github.component.spec.ts create mode 100644 console/src/app/modules/providers/provider-github/provider-github.component.ts create mode 100644 console/src/app/modules/providers/provider-github/provider-github.module.ts diff --git a/console/src/app/modules/idp-table/idp-table.component.html b/console/src/app/modules/idp-table/idp-table.component.html index 79bfeb6a17..a3e620f4d2 100644 --- a/console/src/app/modules/idp-table/idp-table.component.html +++ b/console/src/app/modules/idp-table/idp-table.component.html @@ -42,6 +42,11 @@ Google +
+ + + GitHub +
Generic OIDC diff --git a/console/src/app/modules/idp-table/idp-table.component.ts b/console/src/app/modules/idp-table/idp-table.component.ts index 1449d57029..0322c0d158 100644 --- a/console/src/app/modules/idp-table/idp-table.component.ts +++ b/console/src/app/modules/idp-table/idp-table.component.ts @@ -234,6 +234,8 @@ export class IdpTableComponent implements OnInit { return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'jwt', row.id]; case ProviderType.PROVIDER_TYPE_GOOGLE: return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'google', row.id]; + case ProviderType.PROVIDER_TYPE_GITHUB: + return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'github', row.id]; } } } diff --git a/console/src/app/modules/policies/idp-settings/idp-settings.component.html b/console/src/app/modules/policies/idp-settings/idp-settings.component.html index 1b9f7f40b7..b37fb9f52d 100644 --- a/console/src/app/modules/policies/idp-settings/idp-settings.component.html +++ b/console/src/app/modules/policies/idp-settings/idp-settings.component.html @@ -32,15 +32,24 @@
-
- {{ 'ACTIONS.COMINGSOON' | translate }} +
GitHub
-
+
{{ 'ACTIONS.COMINGSOON' | translate }} diff --git a/console/src/app/modules/providers/provider-github/provider-github-routing.module.ts b/console/src/app/modules/providers/provider-github/provider-github-routing.module.ts new file mode 100644 index 0000000000..d5014162d2 --- /dev/null +++ b/console/src/app/modules/providers/provider-github/provider-github-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { ProviderGithubComponent } from './provider-github.component'; + +const routes: Routes = [ + { + path: '', + component: ProviderGithubComponent, + data: { animation: 'DetailPage' }, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class ProviderGithubRoutingModule {} diff --git a/console/src/app/modules/providers/provider-github/provider-github.component.html b/console/src/app/modules/providers/provider-github/provider-github.component.html new file mode 100644 index 0000000000..9723db0501 --- /dev/null +++ b/console/src/app/modules/providers/provider-github/provider-github.component.html @@ -0,0 +1,94 @@ + +
+
+ + +

{{ 'IDP.CREATE.GITHUB.TITLE' | translate }}

+ +
+ +

+ {{ !provider ? ('IDP.CREATE.GITHUB.DESCRIPTION' | translate) : ('IDP.DETAIL.DESCRIPTION' | translate) }} +

+ +
+
+ + {{ 'IDP.CLIENTID' | translate }} + + + + {{ + 'IDP.UPDATECLIENTSECRET' | translate + }} + + {{ 'IDP.CLIENTSECRET' | translate }} + + + +
+

{{ 'IDP.OPTIONAL' | translate }}

+ +
+
+
+
+ + {{ 'IDP.SCOPESLIST' | translate }} + + + + +
+ + + + + {{ scope }} cancel + + + +
+ + + {{ 'IDP.NAME' | translate }} + + {{ 'IDP.NAMEHINT' | translate }} + + + +
+
+ +
+ +
+
+
+
diff --git a/console/src/app/modules/providers/provider-github/provider-github.component.scss b/console/src/app/modules/providers/provider-github/provider-github.component.scss new file mode 100644 index 0000000000..006149e38f --- /dev/null +++ b/console/src/app/modules/providers/provider-github/provider-github.component.scss @@ -0,0 +1,99 @@ +.desc { + font-size: 14px; +} + +@mixin provider-github-theme($theme) { + $is-dark-theme: map-get($theme, is-dark); + + .github-create-content { + .title-row { + display: flex; + align-items: center; + + .idp-logo { + height: 36px; + width: 36px; + margin-right: 1rem; + flex-shrink: 0; + + &.dark { + display: if($is-dark-theme, block, none); + } + + &.light { + display: if($is-dark-theme, none, block); + } + } + + h1 { + margin: 0 1rem 0 0; + } + } + + .formfield { + display: block; + max-width: 400px; + + .name-hint { + font-size: 12px; + } + + .mat-chip-input { + width: 100%; + margin: 0; + } + + .chip { + border-radius: 0.5rem; + height: 40px; + } + + @media only screen and (max-width: 450px) { + max-width: none; + } + } + + .github-content { + .desc { + margin-bottom: 1rem; + } + + .idp-scopes { + padding-bottom: 0.5rem; + + .flex-line { + display: flex; + align-items: flex-start; + max-width: 400px; + + .formfield { + flex: 1; + } + + .scope-add-button { + margin-top: 1.75rem; + } + } + } + } + } +} + +.github-create-actions { + display: flex; + margin-top: 1rem; + + button[mat-raised-button] { + border-radius: 0.5rem; + padding: 0.5rem 4rem; + } +} + +.optional-h-wrapper { + display: flex; + align-items: center; + + h2 { + margin-right: 0.25rem; + } +} diff --git a/console/src/app/modules/providers/provider-github/provider-github.component.spec.ts b/console/src/app/modules/providers/provider-github/provider-github.component.spec.ts new file mode 100644 index 0000000000..08f7b1dbb9 --- /dev/null +++ b/console/src/app/modules/providers/provider-github/provider-github.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { ProviderGithubComponent } from './provider-github.component'; + +describe('ProviderGithubComponent', () => { + let component: ProviderGithubComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ProviderGithubComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ProviderGithubComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/modules/providers/provider-github/provider-github.component.ts b/console/src/app/modules/providers/provider-github/provider-github.component.ts new file mode 100644 index 0000000000..fa2742941a --- /dev/null +++ b/console/src/app/modules/providers/provider-github/provider-github.component.ts @@ -0,0 +1,267 @@ +import { COMMA, ENTER, SPACE } from '@angular/cdk/keycodes'; +import { Location } from '@angular/common'; +import { Component, Injector, Type } from '@angular/core'; +import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms'; +import { MatLegacyChipInputEvent as MatChipInputEvent } from '@angular/material/legacy-chips'; +import { ActivatedRoute } from '@angular/router'; +import { take } from 'rxjs'; +import { + AddGitHubProviderRequest as AdminAddGithubProviderRequest, + GetProviderByIDRequest as AdminGetProviderByIDRequest, + UpdateGitHubProviderRequest as AdminUpdateGithubProviderRequest, +} from 'src/app/proto/generated/zitadel/admin_pb'; +import { Options, Provider } from 'src/app/proto/generated/zitadel/idp_pb'; +import { + AddGitHubProviderRequest as MgmtAddGithubProviderRequest, + GetProviderByIDRequest as MgmtGetProviderByIDRequest, + UpdateGitHubProviderRequest as MgmtUpdateGithubProviderRequest, +} from 'src/app/proto/generated/zitadel/management_pb'; +import { AdminService } from 'src/app/services/admin.service'; +import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service'; +import { ManagementService } from 'src/app/services/mgmt.service'; +import { ToastService } from 'src/app/services/toast.service'; + +import { PolicyComponentServiceType } from '../../policies/policy-component-types.enum'; + +@Component({ + selector: 'cnsl-provider-github', + templateUrl: './provider-github.component.html', + styleUrls: ['./provider-github.component.scss'], +}) +export class ProviderGithubComponent { + public showOptional: boolean = false; + public options: Options = new Options(); + public id: string | null = ''; + public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT; + private service!: ManagementService | AdminService; + + public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE]; + + public form!: FormGroup; + + public loading: boolean = false; + + public provider?: Provider.AsObject; + public updateClientSecret: boolean = false; + + constructor( + private route: ActivatedRoute, + private toast: ToastService, + private injector: Injector, + private _location: Location, + private breadcrumbService: BreadcrumbService, + ) { + this.form = new FormGroup({ + name: new FormControl('', []), + clientId: new FormControl('', [Validators.required]), + clientSecret: new FormControl('', [Validators.required]), + scopesList: new FormControl(['openid', 'profile', 'email'], []), + }); + + this.route.data.pipe(take(1)).subscribe((data) => { + this.serviceType = data.serviceType; + + switch (this.serviceType) { + case PolicyComponentServiceType.MGMT: + this.service = this.injector.get(ManagementService as Type); + + const bread: Breadcrumb = { + type: BreadcrumbType.ORG, + routerLink: ['/org'], + }; + + this.breadcrumbService.setBreadcrumb([bread]); + break; + case PolicyComponentServiceType.ADMIN: + this.service = this.injector.get(AdminService as Type); + + const iamBread = new Breadcrumb({ + type: BreadcrumbType.ORG, + name: 'Instance', + routerLink: ['/instance'], + }); + this.breadcrumbService.setBreadcrumb([iamBread]); + break; + } + + this.id = this.route.snapshot.paramMap.get('id'); + if (this.id) { + this.clientSecret?.setValidators([]); + this.getData(this.id); + } + }); + } + + private getData(id: string): void { + const req = + this.serviceType === PolicyComponentServiceType.ADMIN + ? new AdminGetProviderByIDRequest() + : new MgmtGetProviderByIDRequest(); + req.setId(id); + this.service + .getProviderByID(req) + .then((resp) => { + this.provider = resp.idp; + this.loading = false; + if (this.provider?.config?.github) { + this.form.patchValue(this.provider.config.github); + this.name?.setValue(this.provider.name); + } + }) + .catch((error) => { + this.toast.showError(error); + this.loading = false; + }); + } + + public submitForm(): void { + this.provider ? this.updateGithubProvider() : this.addGithubProvider(); + } + + public addGithubProvider(): void { + if (this.serviceType === PolicyComponentServiceType.MGMT) { + const req = new MgmtAddGithubProviderRequest(); + + req.setName(this.name?.value); + req.setClientId(this.clientId?.value); + req.setClientSecret(this.clientSecret?.value); + req.setScopesList(this.scopesList?.value); + req.setProviderOptions(this.options); + + this.loading = true; + (this.service as ManagementService) + .addGitHubProvider(req) + .then((idp) => { + setTimeout(() => { + this.loading = false; + this.close(); + }, 2000); + }) + .catch((error) => { + this.toast.showError(error); + this.loading = false; + }); + } else if (PolicyComponentServiceType.ADMIN) { + const req = new AdminAddGithubProviderRequest(); + req.setName(this.name?.value); + req.setClientId(this.clientId?.value); + req.setClientSecret(this.clientSecret?.value); + req.setScopesList(this.scopesList?.value); + req.setProviderOptions(this.options); + + this.loading = true; + (this.service as AdminService) + .addGitHubProvider(req) + .then((idp) => { + setTimeout(() => { + this.loading = false; + this.close(); + }, 2000); + }) + .catch((error) => { + this.loading = false; + this.toast.showError(error); + }); + } + } + + public updateGithubProvider(): void { + if (this.provider) { + if (this.serviceType === PolicyComponentServiceType.MGMT) { + const req = new MgmtUpdateGithubProviderRequest(); + req.setId(this.provider.id); + req.setName(this.name?.value); + req.setClientId(this.clientId?.value); + req.setScopesList(this.scopesList?.value); + req.setProviderOptions(this.options); + + if (this.updateClientSecret) { + req.setClientSecret(this.clientSecret?.value); + } + + this.loading = true; + (this.service as ManagementService) + .updateGitHubProvider(req) + .then((idp) => { + setTimeout(() => { + this.loading = false; + this.close(); + }, 2000); + }) + .catch((error) => { + this.toast.showError(error); + this.loading = false; + }); + } else if (PolicyComponentServiceType.ADMIN) { + const req = new AdminUpdateGithubProviderRequest(); + req.setId(this.provider.id); + req.setName(this.name?.value); + req.setClientId(this.clientId?.value); + req.setScopesList(this.scopesList?.value); + req.setProviderOptions(this.options); + + if (this.updateClientSecret) { + req.setClientSecret(this.clientSecret?.value); + } + + this.loading = true; + (this.service as AdminService) + .updateGitHubProvider(req) + .then((idp) => { + setTimeout(() => { + this.loading = false; + this.close(); + }, 2000); + }) + .catch((error) => { + this.loading = false; + this.toast.showError(error); + }); + } + } + } + + public close(): void { + this._location.back(); + } + + public addScope(event: MatChipInputEvent): void { + const input = event.chipInput?.inputElement; + const value = event.value.trim(); + + if (value !== '') { + if (this.scopesList?.value) { + this.scopesList.value.push(value); + if (input) { + input.value = ''; + } + } + } + } + + public removeScope(uri: string): void { + if (this.scopesList?.value) { + const index = this.scopesList.value.indexOf(uri); + + if (index !== undefined && index >= 0) { + this.scopesList.value.splice(index, 1); + } + } + } + + public get name(): AbstractControl | null { + return this.form.get('name'); + } + + public get clientId(): AbstractControl | null { + return this.form.get('clientId'); + } + + public get clientSecret(): AbstractControl | null { + return this.form.get('clientSecret'); + } + + public get scopesList(): AbstractControl | null { + return this.form.get('scopesList'); + } +} diff --git a/console/src/app/modules/providers/provider-github/provider-github.module.ts b/console/src/app/modules/providers/provider-github/provider-github.module.ts new file mode 100644 index 0000000000..8a617b0692 --- /dev/null +++ b/console/src/app/modules/providers/provider-github/provider-github.module.ts @@ -0,0 +1,43 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatIconModule } from '@angular/material/icon'; +import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button'; +import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox'; +import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips'; +import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner'; +import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select'; +import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip'; +import { TranslateModule } from '@ngx-translate/core'; +import { InputModule } from 'src/app/modules/input/input.module'; + +import { CardModule } from '../../card/card.module'; +import { CreateLayoutModule } from '../../create-layout/create-layout.module'; +import { InfoSectionModule } from '../../info-section/info-section.module'; +import { ProviderOptionsModule } from '../../provider-options/provider-options.module'; +import { ProviderGithubRoutingModule } from './provider-github-routing.module'; +import { ProviderGithubComponent } from './provider-github.component'; + +@NgModule({ + declarations: [ProviderGithubComponent], + imports: [ + ProviderGithubRoutingModule, + CommonModule, + FormsModule, + ReactiveFormsModule, + CreateLayoutModule, + InfoSectionModule, + InputModule, + MatButtonModule, + MatSelectModule, + MatIconModule, + MatChipsModule, + CardModule, + MatCheckboxModule, + MatTooltipModule, + TranslateModule, + ProviderOptionsModule, + MatLegacyProgressSpinnerModule, + ], +}) +export default class ProviderGithubModule {} diff --git a/console/src/app/modules/providers/provider-google/provider-google.component.ts b/console/src/app/modules/providers/provider-google/provider-google.component.ts index b24c38159d..5866ab77d2 100644 --- a/console/src/app/modules/providers/provider-google/provider-google.component.ts +++ b/console/src/app/modules/providers/provider-google/provider-google.component.ts @@ -3,7 +3,7 @@ import { Location } from '@angular/common'; import { Component, Injector, Type } from '@angular/core'; import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms'; import { MatLegacyChipInputEvent as MatChipInputEvent } from '@angular/material/legacy-chips'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { take } from 'rxjs'; import { AddGoogleProviderRequest as AdminAddGoogleProviderRequest, @@ -45,7 +45,6 @@ export class ProviderGoogleComponent { public updateClientSecret: boolean = false; constructor( - private router: Router, private route: ActivatedRoute, private toast: ToastService, private injector: Injector, @@ -135,7 +134,7 @@ export class ProviderGoogleComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/org-settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { @@ -156,7 +155,7 @@ export class ProviderGoogleComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { @@ -186,7 +185,7 @@ export class ProviderGoogleComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/org-settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { @@ -211,7 +210,7 @@ export class ProviderGoogleComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { diff --git a/console/src/app/modules/providers/provider-jwt/provider-jwt.component.ts b/console/src/app/modules/providers/provider-jwt/provider-jwt.component.ts index 35a938114b..a6c1d7556e 100644 --- a/console/src/app/modules/providers/provider-jwt/provider-jwt.component.ts +++ b/console/src/app/modules/providers/provider-jwt/provider-jwt.component.ts @@ -2,7 +2,7 @@ import { COMMA, ENTER, SPACE } from '@angular/cdk/keycodes'; import { Location } from '@angular/common'; import { Component, Injector, Type } from '@angular/core'; import { AbstractControl, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { take } from 'rxjs/operators'; import { AddJWTProviderRequest as AdminAddJWTProviderRequest, @@ -42,7 +42,6 @@ export class ProviderJWTComponent { public provider?: Provider.AsObject; constructor( - private router: Router, private route: ActivatedRoute, private toast: ToastService, private injector: Injector, @@ -134,7 +133,7 @@ export class ProviderJWTComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/org-settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { @@ -157,7 +156,7 @@ export class ProviderJWTComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { @@ -185,7 +184,7 @@ export class ProviderJWTComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/org-settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { @@ -208,7 +207,7 @@ export class ProviderJWTComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { diff --git a/console/src/app/modules/providers/provider-oidc/provider-oidc.component.ts b/console/src/app/modules/providers/provider-oidc/provider-oidc.component.ts index ab97bb4bc6..39e8d28e9c 100644 --- a/console/src/app/modules/providers/provider-oidc/provider-oidc.component.ts +++ b/console/src/app/modules/providers/provider-oidc/provider-oidc.component.ts @@ -3,7 +3,7 @@ import { Location } from '@angular/common'; import { Component, Injector, Type } from '@angular/core'; import { AbstractControl, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; import { MatLegacyChipInputEvent as MatChipInputEvent } from '@angular/material/legacy-chips'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { take } from 'rxjs'; import { AddGenericOIDCProviderRequest as AdminAddGenericOIDCProviderRequest, @@ -44,7 +44,6 @@ export class ProviderOIDCComponent { public provider?: Provider.AsObject; constructor( - private router: Router, private route: ActivatedRoute, private toast: ToastService, private injector: Injector, @@ -136,7 +135,7 @@ export class ProviderOIDCComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/org-settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { @@ -157,7 +156,7 @@ export class ProviderOIDCComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { @@ -184,7 +183,7 @@ export class ProviderOIDCComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/org-settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { @@ -206,7 +205,7 @@ export class ProviderOIDCComponent { .then((idp) => { setTimeout(() => { this.loading = false; - this.router.navigate(['/settings'], { queryParams: { id: 'idp' } }); + this.close(); }, 2000); }) .catch((error) => { diff --git a/console/src/app/pages/instance/instance-routing.module.ts b/console/src/app/pages/instance/instance-routing.module.ts index ec302781ef..1ba2a043be 100644 --- a/console/src/app/pages/instance/instance-routing.module.ts +++ b/console/src/app/pages/instance/instance-routing.module.ts @@ -83,6 +83,19 @@ const routes: Routes = [ }, ], }, + { + path: 'github', + children: [ + { + path: 'create', + loadChildren: () => import('src/app/modules/providers/provider-github/provider-github.module'), + }, + { + path: ':id', + loadChildren: () => import('src/app/modules/providers/provider-github/provider-github.module'), + }, + ], + }, ], }, ]; diff --git a/console/src/app/pages/orgs/org-routing.module.ts b/console/src/app/pages/orgs/org-routing.module.ts index 24706df076..d4300276a6 100644 --- a/console/src/app/pages/orgs/org-routing.module.ts +++ b/console/src/app/pages/orgs/org-routing.module.ts @@ -71,6 +71,19 @@ const routes: Routes = [ }, ], }, + { + path: 'github', + children: [ + { + path: 'create', + loadChildren: () => import('src/app/modules/providers/provider-github/provider-github.module'), + }, + { + path: ':id', + loadChildren: () => import('src/app/modules/providers/provider-github/provider-github.module'), + }, + ], + }, ], }, { diff --git a/console/src/app/services/admin.service.ts b/console/src/app/services/admin.service.ts index d6c4d69198..59d4eb2474 100644 --- a/console/src/app/services/admin.service.ts +++ b/console/src/app/services/admin.service.ts @@ -12,6 +12,8 @@ import { AddGenericOAuthProviderResponse, AddGenericOIDCProviderRequest, AddGenericOIDCProviderResponse, + AddGitHubProviderRequest, + AddGitHubProviderResponse, AddGoogleProviderRequest, AddGoogleProviderResponse, AddIAMMemberRequest, @@ -200,6 +202,8 @@ import { UpdateGenericOAuthProviderResponse, UpdateGenericOIDCProviderRequest, UpdateGenericOIDCProviderResponse, + UpdateGitHubProviderRequest, + UpdateGitHubProviderResponse, UpdateGoogleProviderRequest, UpdateGoogleProviderResponse, UpdateIAMMemberRequest, @@ -906,6 +910,14 @@ export class AdminService { return this.grpcService.admin.updateGoogleProvider(req, null).then((resp) => resp.toObject()); } + public addGitHubProvider(req: AddGitHubProviderRequest): Promise { + return this.grpcService.admin.addGitHubProvider(req, null).then((resp) => resp.toObject()); + } + + public updateGitHubProvider(req: UpdateGitHubProviderRequest): Promise { + return this.grpcService.admin.updateGitHubProvider(req, null).then((resp) => resp.toObject()); + } + public addGenericOIDCProvider(req: AddGenericOIDCProviderRequest): Promise { return this.grpcService.admin.addGenericOIDCProvider(req, null).then((resp) => resp.toObject()); } diff --git a/console/src/app/services/mgmt.service.ts b/console/src/app/services/mgmt.service.ts index d8a2a438ec..c06459a6f1 100644 --- a/console/src/app/services/mgmt.service.ts +++ b/console/src/app/services/mgmt.service.ts @@ -33,6 +33,8 @@ import { AddGenericOAuthProviderResponse, AddGenericOIDCProviderRequest, AddGenericOIDCProviderResponse, + AddGitHubProviderRequest, + AddGitHubProviderResponse, AddGoogleProviderRequest, AddGoogleProviderResponse, AddHumanUserRequest, @@ -433,6 +435,8 @@ import { UpdateGenericOAuthProviderResponse, UpdateGenericOIDCProviderRequest, UpdateGenericOIDCProviderResponse, + UpdateGitHubProviderRequest, + UpdateGitHubProviderResponse, UpdateGoogleProviderRequest, UpdateGoogleProviderResponse, UpdateHumanEmailRequest, @@ -865,6 +869,14 @@ export class ManagementService { return this.grpcService.mgmt.updateGoogleProvider(req, null).then((resp) => resp.toObject()); } + public addGitHubProvider(req: AddGitHubProviderRequest): Promise { + return this.grpcService.mgmt.addGitHubProvider(req, null).then((resp) => resp.toObject()); + } + + public updateGitHubProvider(req: UpdateGitHubProviderRequest): Promise { + return this.grpcService.mgmt.updateGitHubProvider(req, null).then((resp) => resp.toObject()); + } + public addGenericOIDCProvider(req: AddGenericOIDCProviderRequest): Promise { return this.grpcService.mgmt.addGenericOIDCProvider(req, null).then((resp) => resp.toObject()); } diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index ffece15de8..1e922debba 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -1629,6 +1629,10 @@ "GOOGLE": { "TITLE": "Google Provider", "DESCRIPTION": "Geben Sie die erforderlichen Daten für Ihren Google-Identitätsprovider ein." + }, + "GITHUB": { + "TITLE": "Github Provider", + "DESCRIPTION": "Geben Sie die erforderlichen Daten für Ihren Github-Identitätsprovider ein." } }, "DETAIL": { diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index 924a24b8ba..6ff14a28e8 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -1634,6 +1634,10 @@ "GOOGLE": { "TITLE": "Google Provider", "DESCRIPTION": "Enter the credentials for your Google Identity Provider" + }, + "GITHUB": { + "TITLE": "Github Provider", + "DESCRIPTION": "Enter the credentials for your Github Identity Provider" } }, "DETAIL": { diff --git a/console/src/assets/i18n/fr.json b/console/src/assets/i18n/fr.json index c1851e7055..bc4a21ffe2 100644 --- a/console/src/assets/i18n/fr.json +++ b/console/src/assets/i18n/fr.json @@ -1633,6 +1633,10 @@ "GOOGLE": { "TITLE": "Fournisseur Google", "DESCRIPTION": "Saisissez les informations d'identification de votre fournisseur d'identité Google" + }, + "GITHUB": { + "TITLE": "Fournisseur Github", + "DESCRIPTION": "Saisissez les informations d'identification de votre fournisseur d'identité Github" } }, "DETAIL": { diff --git a/console/src/assets/i18n/it.json b/console/src/assets/i18n/it.json index 55134f3af7..ae148e99fd 100644 --- a/console/src/assets/i18n/it.json +++ b/console/src/assets/i18n/it.json @@ -1634,6 +1634,10 @@ "GOOGLE": { "TITLE": "Google Provider", "DESCRIPTION": "Inserisci i dati necessari per il tuo Google provider." + }, + "GITHUB": { + "TITLE": "Github Provider", + "DESCRIPTION": "Inserisci i dati necessari per il tuo Github provider." } }, "DETAIL": { diff --git a/console/src/assets/i18n/pl.json b/console/src/assets/i18n/pl.json index 0858d64fdd..9ada33c7f2 100644 --- a/console/src/assets/i18n/pl.json +++ b/console/src/assets/i18n/pl.json @@ -1633,6 +1633,10 @@ "GOOGLE": { "TITLE": "Google Provider", "DESCRIPTION": "Wprowadź dane dla swojego dostawcy tożsamości Google" + }, + "GITHUB": { + "TITLE": "Github Provider", + "DESCRIPTION": "Wprowadź dane dla swojego dostawcy tożsamości Github" } }, "DETAIL": { diff --git a/console/src/assets/i18n/zh.json b/console/src/assets/i18n/zh.json index fdad26a0e2..cbf27fd6c1 100644 --- a/console/src/assets/i18n/zh.json +++ b/console/src/assets/i18n/zh.json @@ -1630,8 +1630,12 @@ "DESCRIPTION": "输入你的JWT供应商所需的数据。" }, "GOOGLE": { - "TITLE": "谷歌供应商", - "DESCRIPTION": "输入你的谷歌身份提供者的凭证" + "TITLE": "Google 身份提供者", + "DESCRIPTION": "输入您的 Google 身份提供商的凭据" + }, + "GITHUB": { + "TITLE": "Github 身份提供者", + "DESCRIPTION": "输入您的 Github 身份提供商的凭据" } }, "DETAIL": { diff --git a/console/src/component-themes.scss b/console/src/component-themes.scss index cf3910986e..eab89c7343 100644 --- a/console/src/component-themes.scss +++ b/console/src/component-themes.scss @@ -25,6 +25,7 @@ @import 'src/app/pages/projects/granted-projects/granted-project-detail/granted-project-detail.component'; @import 'src/app/pages/projects/apps/app-detail/app-detail.component'; @import 'src/app/pages/projects/apps/redirect-uris/redirect-uris.component'; +@import 'src/app/modules/providers/provider-github/provider-github.component'; @import 'src/app/modules/filter-events/filter-events.component'; @import 'src/app/modules/top-view/top-view.component'; @import 'src/app/pages/projects/projects.component'; @@ -89,6 +90,7 @@ @include table-theme($theme); @include detail-layout-theme($theme); @include app-card-theme($theme); + @include provider-github-theme($theme); @include login-policy-mfas-theme($theme); @include changes-theme($theme); @include home-theme($theme);