Change the redirect url using the current page url on shibboleth authentication

This commit is contained in:
Giuseppe Digilio
2020-02-07 13:09:55 +01:00
parent cc4b7b215e
commit 0452a9a8cd
4 changed files with 93 additions and 12 deletions

View File

@@ -1,6 +1,6 @@
<a class="btn btn-lg btn-primary btn-block mt-2 text-white" [href]="location" role="button"> <button class="btn btn-lg btn-primary btn-block mt-2 text-white" (click)="redirectToShibboleth()" role="button">
{{"login.form.shibboleth" | translate}} {{"login.form.shibboleth" | translate}}
</a> </button>

View File

@@ -1,7 +1,6 @@
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Store, StoreModule } from '@ngrx/store'; import { Store, StoreModule } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
@@ -14,13 +13,21 @@ import { AppState } from '../../../../app.reducer';
import { AuthMethod } from '../../../../core/auth/models/auth.method'; import { AuthMethod } from '../../../../core/auth/models/auth.method';
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
import { LogInShibbolethComponent } from './log-in-shibboleth.component'; import { LogInShibbolethComponent } from './log-in-shibboleth.component';
import { NativeWindowService } from '../../../../core/services/window.service';
import { RouterStub } from '../../../testing/router-stub';
import { ActivatedRouteStub } from '../../../testing/active-router-stub';
import { NativeWindowMockFactory } from '../../../mocks/mock-native-window-ref';
describe('LogInShibbolethComponent', () => { fdescribe('LogInShibbolethComponent', () => {
let component: LogInShibbolethComponent; let component: LogInShibbolethComponent;
let fixture: ComponentFixture<LogInShibbolethComponent>; let fixture: ComponentFixture<LogInShibbolethComponent>;
let page: Page; let page: Page;
let user: EPerson; let user: EPerson;
let componentAsAny: any;
let setHrefSpy;
const shibbolethBaseUrl = 'dspace-rest.test/shibboleth?redirectUrl=';
const location = shibbolethBaseUrl + 'http://dspace-angular.test/home';
const authState = { const authState = {
authenticated: false, authenticated: false,
@@ -44,9 +51,10 @@ describe('LogInShibbolethComponent', () => {
], ],
providers: [ providers: [
{ provide: AuthService, useClass: AuthServiceStub }, { provide: AuthService, useClass: AuthServiceStub },
{ provide: 'authMethodProvider', { provide: 'authMethodProvider', useValue: new AuthMethod(AuthMethodType.Shibboleth, location) },
useValue: new AuthMethod(AuthMethodType.Shibboleth, 'dspace.test/shibboleth') { provide: NativeWindowService, useFactory: NativeWindowMockFactory },
} { provide: Router, useValue: new RouterStub() },
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
], ],
schemas: [ schemas: [
CUSTOM_ELEMENTS_SCHEMA CUSTOM_ELEMENTS_SCHEMA
@@ -68,16 +76,42 @@ describe('LogInShibbolethComponent', () => {
// get test component from the fixture // get test component from the fixture
component = fixture.componentInstance; component = fixture.componentInstance;
componentAsAny = component;
// create page // create page
page = new Page(component, fixture); page = new Page(component, fixture);
setHrefSpy = spyOnProperty(componentAsAny._window.nativeWindow.location, 'href', 'set').and.callThrough();
})); }));
it('should display a link with properly href', () => { it('should set the properly a new redirectUrl', () => {
const currentUrl = 'http://dspace-angular.test/collections/12345';
componentAsAny._window.nativeWindow.location.href = currentUrl;
fixture.detectChanges(); fixture.detectChanges();
const link = fixture.debugElement.query(By.css('a'));
expect(link.nativeElement.getAttribute('href')).toBe('dspace.test/shibboleth'); expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
component.redirectToShibboleth();
expect(setHrefSpy).toHaveBeenCalledWith(shibbolethBaseUrl + currentUrl)
});
it('should not set a new redirectUrl', () => {
const currentUrl = 'http://dspace-angular.test/home';
componentAsAny._window.nativeWindow.location.href = currentUrl;
fixture.detectChanges();
expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
component.redirectToShibboleth();
expect(setHrefSpy).toHaveBeenCalledWith(shibbolethBaseUrl + currentUrl)
}); });
}); });

View File

@@ -9,6 +9,9 @@ import { AuthMethod } from '../../../../core/auth/models/auth.method';
import { CoreState } from '../../../../core/core.reducers'; import { CoreState } from '../../../../core/core.reducers';
import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors'; import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors';
import { RouteService } from '../../../../core/services/route.service';
import { NativeWindowRef, NativeWindowService } from '../../../../core/services/window.service';
import { isNotNull } from '../../../empty.util';
@Component({ @Component({
selector: 'ds-log-in-shibboleth', selector: 'ds-log-in-shibboleth',
@@ -46,10 +49,14 @@ export class LogInShibbolethComponent implements OnInit {
/** /**
* @constructor * @constructor
* @param {AuthMethod} injectedAuthMethodModel * @param {AuthMethod} injectedAuthMethodModel
* @param {NativeWindowRef} _window
* @param {RouteService} route
* @param {Store<State>} store * @param {Store<State>} store
*/ */
constructor( constructor(
@Inject('authMethodProvider') public injectedAuthMethodModel: AuthMethod, @Inject('authMethodProvider') public injectedAuthMethodModel: AuthMethod,
@Inject(NativeWindowService) protected _window: NativeWindowRef,
private route: RouteService,
private store: Store<CoreState> private store: Store<CoreState>
) { ) {
this.authMethod = injectedAuthMethodModel; this.authMethod = injectedAuthMethodModel;
@@ -63,7 +70,26 @@ export class LogInShibbolethComponent implements OnInit {
this.loading = this.store.pipe(select(isAuthenticationLoading)); this.loading = this.store.pipe(select(isAuthenticationLoading));
// set location // set location
this.location = this.injectedAuthMethodModel.location this.location = decodeURIComponent(this.injectedAuthMethodModel.location);
}
redirectToShibboleth() {
let newLocationUrl = this.location;
const currentUrl = this._window.nativeWindow.location.href;
const myRegexp = /\?redirectUrl=(.*)/g;
const match = myRegexp.exec(this.location);
const redirectUrl = (match && match[1]) ? match[1] : null;
// Check whether the current page is different from the redirect url received from rest
if (isNotNull(redirectUrl) && redirectUrl !== currentUrl) {
// change the redirect url with the current page url
const newRedirectUrl = `?redirectUrl=${currentUrl}`;
newLocationUrl = this.location.replace(/\?redirectUrl=(.*)/g, newRedirectUrl);
}
// redirect to shibboleth authentication url
this._window.nativeWindow.location.href = newLocationUrl;
} }
} }

View File

@@ -0,0 +1,21 @@
export const MockWindow = {
location: {
_href: '',
set href(url: string) {
this._href = url;
},
get href() {
return this._href;
}
}
};
export class NativeWindowRefMock {
get nativeWindow(): any {
return MockWindow;
}
}
export function NativeWindowMockFactory() {
return new NativeWindowRefMock();
}