mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-12 12:33:07 +00:00
Removed switch statement, changed AuthMethod parsing in authInterceptor to be more generic
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
<div>
|
||||
<img class="mb-4 login-logo" src="assets/images/dspace-logo.png">
|
||||
<h1 class="h3 mb-0 font-weight-normal">{{"login.form.header" | translate}}</h1>
|
||||
<ds-login-container></ds-login-container>
|
||||
<!-- <ds-login-container></ds-login-container>-->
|
||||
<ds-auth-methods></ds-auth-methods>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import {Observable, of as observableOf, throwError as observableThrowError} from 'rxjs';
|
||||
import { Observable, of as observableOf, throwError as observableThrowError } from 'rxjs';
|
||||
|
||||
import {catchError, filter, map, tap} from 'rxjs/operators';
|
||||
import {Injectable, Injector} from '@angular/core';
|
||||
import { catchError, filter, map, tap } from 'rxjs/operators';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import {
|
||||
HttpErrorResponse,
|
||||
HttpEvent,
|
||||
@@ -11,18 +11,18 @@ import {
|
||||
HttpResponse,
|
||||
HttpResponseBase
|
||||
} from '@angular/common/http';
|
||||
import {find} from 'lodash';
|
||||
import { find } from 'lodash';
|
||||
|
||||
import {AppState} from '../../app.reducer';
|
||||
import {AuthService} from './auth.service';
|
||||
import {AuthStatus} from './models/auth-status.model';
|
||||
import {AuthTokenInfo} from './models/auth-token-info.model';
|
||||
import {isNotEmpty, isUndefined, isNotNull} from '../../shared/empty.util';
|
||||
import {RedirectWhenTokenExpiredAction, RefreshTokenAction} from './auth.actions';
|
||||
import {Store} from '@ngrx/store';
|
||||
import {Router} from '@angular/router';
|
||||
import {AuthError} from './models/auth-error.model';
|
||||
import {AuthMethodModel} from './models/auth-method.model';
|
||||
import { AppState } from '../../app.reducer';
|
||||
import { AuthService } from './auth.service';
|
||||
import { AuthStatus } from './models/auth-status.model';
|
||||
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||
import { isNotEmpty, isUndefined, isNotNull } from '../../shared/empty.util';
|
||||
import { RedirectWhenTokenExpiredAction, RefreshTokenAction } from './auth.actions';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Router } from '@angular/router';
|
||||
import { AuthError } from './models/auth-error.model';
|
||||
import { AuthMethodModel } from './models/auth-method.model';
|
||||
|
||||
@Injectable()
|
||||
export class AuthInterceptor implements HttpInterceptor {
|
||||
@@ -59,8 +59,7 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
return http.url && http.url.endsWith('/authn/logout');
|
||||
}
|
||||
|
||||
private parseShibbolethLocation(unparsedLocation: string): string {
|
||||
let parsedLocation = '';
|
||||
private parseLocation(unparsedLocation: string): string {
|
||||
unparsedLocation = unparsedLocation.trim();
|
||||
unparsedLocation = unparsedLocation.replace('location="', '');
|
||||
unparsedLocation = unparsedLocation.replace('"', '');
|
||||
@@ -68,7 +67,7 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
unparsedLocation = unparsedLocation.replace(re, '://');
|
||||
re = /%3A/g
|
||||
unparsedLocation = unparsedLocation.replace(re, ':')
|
||||
parsedLocation = unparsedLocation + '/shibboleth';
|
||||
const parsedLocation = unparsedLocation.trim(); // + '/shibboleth';
|
||||
|
||||
return parsedLocation;
|
||||
}
|
||||
@@ -76,24 +75,32 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
private parseAuthMethodsfromHeaders(headers: HttpHeaders): AuthMethodModel[] {
|
||||
const authMethodModels: AuthMethodModel[] = [];
|
||||
const parts: string[] = headers.get('www-authenticate').split(',');
|
||||
// get the login methods names
|
||||
// get the realms from the header - a realm is a single auth method
|
||||
const completeWWWauthenticateHeader = headers.get('www-authenticate');
|
||||
const regex = /(\w+ (\w+=((".*?")|[^,]*)(, )?)*)/g;
|
||||
const realms = completeWWWauthenticateHeader.match(regex);
|
||||
console.log('realms: ', realms)
|
||||
|
||||
// tslint:disable-next-line:forin
|
||||
for (const i in parts) {
|
||||
const part: string = parts[i].trim();
|
||||
if (part.includes('realm')) {
|
||||
const methodName = part.split(' ')[0];
|
||||
const authMethod: AuthMethodModel = new AuthMethodModel(methodName);
|
||||
// check if the authentication method is shibboleth
|
||||
// if so the next part is the shibboleth location
|
||||
// e.g part i: shibboleth realm="DSpace REST API", part i+1: location="/Shibboleth.sso/Login?target=https://serverUrl"
|
||||
if (methodName.includes('shibboleth')) {
|
||||
// +1: unaray + operator in the next line is necessaray because i is a string, the operator works like parseInt()
|
||||
const location: string = this.parseShibbolethLocation(parts[+i + 1]);
|
||||
authMethod.location = location;
|
||||
}
|
||||
// if other authentication methods deliver data needed for the method to work
|
||||
// it would be checked here e.g. if (methodName.includes('ldap')) { }
|
||||
authMethodModels.push(authMethod);
|
||||
for (const j in realms) {
|
||||
console.log('realm:', realms[j]);
|
||||
|
||||
const splittedRealm = realms[j].split(', ');
|
||||
const methodName = splittedRealm[0].split(' ')[0].trim();
|
||||
console.log('methodName: ', methodName);
|
||||
|
||||
console.log('splittedRealm: ', splittedRealm);
|
||||
let authMethodModel: AuthMethodModel;
|
||||
if (splittedRealm.length === 1) {
|
||||
authMethodModel = new AuthMethodModel(methodName);
|
||||
authMethodModels.push(authMethodModel);
|
||||
} else if (splittedRealm.length > 1) {
|
||||
authMethodModel = new AuthMethodModel(methodName);
|
||||
let location = splittedRealm[1];
|
||||
location = this.parseLocation(location)
|
||||
authMethodModel.location = location;
|
||||
console.log('location: ', location);
|
||||
authMethodModels.push(authMethodModel);
|
||||
}
|
||||
}
|
||||
return authMethodModels;
|
||||
|
@@ -1,12 +1,10 @@
|
||||
import {AuthMethodType} from '../../../shared/log-in/authMethods-type';
|
||||
|
||||
export class AuthMethodModel {
|
||||
authMethodName: string;
|
||||
authMethodType: AuthMethodType;
|
||||
location?: string;
|
||||
authMethodType: AuthMethodType
|
||||
|
||||
constructor(authMethodName: string, location?: string) {
|
||||
this.authMethodName = authMethodName;
|
||||
this.location = location;
|
||||
switch (authMethodName) {
|
||||
case 'ip': {
|
||||
|
@@ -4,7 +4,8 @@
|
||||
<a href="#" id="dropdownLogin" (click)="$event.preventDefault()" ngbDropdownToggle class="px-1">{{ 'nav.login' | translate }}</a>
|
||||
<div id="loginDropdownMenu" [ngClass]="{'pl-3 pr-3': (loading | async)}" ngbDropdownMenu aria-labelledby="dropdownLogin">
|
||||
<!-- <ds-log-in></ds-log-in>-->
|
||||
<ds-login-container></ds-login-container>
|
||||
<!-- <ds-login-container></ds-login-container>-->
|
||||
<ds-auth-methods></ds-auth-methods>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
3
src/app/shared/log-in/authMethods.component.html
Normal file
3
src/app/shared/log-in/authMethods.component.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<ng-container *ngFor="let authMethodModel of (authMethodData | async)">
|
||||
<ds-login-container [authMethodModel]="authMethodModel"></ds-login-container>
|
||||
</ng-container>
|
0
src/app/shared/log-in/authMethods.component.scss
Normal file
0
src/app/shared/log-in/authMethods.component.scss
Normal file
27
src/app/shared/log-in/authMethods.component.ts
Normal file
27
src/app/shared/log-in/authMethods.component.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Component, Injector, Input, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AuthMethodModel } from '../../core/auth/models/auth-method.model';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AuthState } from '../../core/auth/auth.reducer';
|
||||
import { getAuthenticationMethods } from '../../core/auth/selectors';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-auth-methods',
|
||||
templateUrl: './authMethods.component.html',
|
||||
styleUrls: ['./authMethods.component.scss']
|
||||
})
|
||||
export class AuthMethodsComponent implements OnInit {
|
||||
/**
|
||||
* The authentication methods data
|
||||
* @type {AuthMethodModel[]}
|
||||
*/
|
||||
@Input() authMethodData: Observable<AuthMethodModel[]>;
|
||||
|
||||
constructor( private store: Store<AuthState>) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.authMethodData = this.authMethodData = this.store.select(getAuthenticationMethods);
|
||||
}
|
||||
|
||||
}
|
@@ -1,3 +1,2 @@
|
||||
<div *ngFor="let authMethod of authMethodData | async">
|
||||
<ng-container *ngComponentOutlet="getAuthMethodContent(authMethod.authMethodType); injector: objectInjector;"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngComponentOutlet="getAuthMethodContent(); injector: objectInjector;"></ng-container>
|
||||
|
||||
|
@@ -17,11 +17,7 @@ import { AuthMethodType } from '../authMethods-type';
|
||||
})
|
||||
export class LoginContainerComponent implements OnInit {
|
||||
|
||||
/**
|
||||
* The section data
|
||||
* @type {SectionDataObject}
|
||||
*/
|
||||
@Input() authMethodData: Observable<AuthMethodModel[]>;
|
||||
@Input() authMethodModel: AuthMethodModel;
|
||||
|
||||
/**
|
||||
* Injector to inject a section component with the @Input parameters
|
||||
@@ -34,7 +30,7 @@ export class LoginContainerComponent implements OnInit {
|
||||
*
|
||||
* @param {Injector} injector
|
||||
*/
|
||||
constructor(private injector: Injector, private store: Store<AppState>) {
|
||||
constructor(private injector: Injector) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,18 +39,17 @@ export class LoginContainerComponent implements OnInit {
|
||||
ngOnInit() {
|
||||
this.objectInjector = Injector.create({
|
||||
providers: [
|
||||
{provide: 'authMethodProvider', useFactory: () => (this.authMethodData), deps: []},
|
||||
{provide: 'authMethodModelProvider', useFactory: () => (this.authMethodModel), deps: []},
|
||||
],
|
||||
parent: this.injector
|
||||
});
|
||||
|
||||
this.authMethodData = this.store.select(getAuthenticationMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the correct component based on the authMethod's type
|
||||
*/
|
||||
getAuthMethodContent(authMethodType: AuthMethodType): string {
|
||||
return rendersAuthMethodType(authMethodType)
|
||||
getAuthMethodContent(): string {
|
||||
return rendersAuthMethodType(this.authMethodModel.authMethodType)
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<div>
|
||||
<a class="btn btn-lg btn-primary btn-block mt-3" type="submit"
|
||||
[href]="injectedShibbolethUrl"
|
||||
[href]="authMethodModel.location"
|
||||
role="button"
|
||||
>{{"login.shibboleth" | translate}}</a>
|
||||
</div>
|
||||
|
@@ -12,14 +12,17 @@ import { AuthMethodModel } from '../../../../core/auth/models/auth-method.model'
|
||||
@renderAuthMethodFor(AuthMethodType.Shibboleth)
|
||||
export class DynamicShibbolethComponent implements OnInit {
|
||||
|
||||
@Input()authMethodModel: AuthMethodModel;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
constructor(@Inject('authMethodProvider') public injectedObject: AuthMethodModel) {
|
||||
constructor(@Inject('authMethodModelProvider') public injectedAuthMethodModel: AuthMethodModel) {
|
||||
this.authMethodModel = injectedAuthMethodModel;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
console.log('injectedObject', this.injectedObject)
|
||||
console.log('injectedAuthMethodModel', this.injectedAuthMethodModel);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -141,6 +141,7 @@ import {DynamicShibbolethComponent} from './log-in/methods/shibboleth/dynamic-sh
|
||||
// import {LogInComponent} from './log-in/log-in.component';
|
||||
import {LogInPasswordComponent} from './log-in/methods/password/log-in-password.component';
|
||||
import { LoginContainerComponent } from './log-in/container/login-container.component';
|
||||
import { AuthMethodsComponent } from './log-in/authMethods.component';
|
||||
|
||||
const MODULES = [
|
||||
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
||||
@@ -264,7 +265,8 @@ const COMPONENTS = [
|
||||
// LogInComponent,
|
||||
DynamicShibbolethComponent,
|
||||
LogInPasswordComponent,
|
||||
LoginContainerComponent
|
||||
LoginContainerComponent,
|
||||
AuthMethodsComponent
|
||||
];
|
||||
|
||||
const ENTRY_COMPONENTS = [
|
||||
|
Reference in New Issue
Block a user