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}}
</a>
</button>

View File

@@ -1,7 +1,6 @@
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Store, StoreModule } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core';
@@ -14,13 +13,21 @@ import { AppState } from '../../../../app.reducer';
import { AuthMethod } from '../../../../core/auth/models/auth.method';
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
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 fixture: ComponentFixture<LogInShibbolethComponent>;
let page: Page;
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 = {
authenticated: false,
@@ -44,9 +51,10 @@ describe('LogInShibbolethComponent', () => {
],
providers: [
{ provide: AuthService, useClass: AuthServiceStub },
{ provide: 'authMethodProvider',
useValue: new AuthMethod(AuthMethodType.Shibboleth, 'dspace.test/shibboleth')
}
{ provide: 'authMethodProvider', useValue: new AuthMethod(AuthMethodType.Shibboleth, location) },
{ provide: NativeWindowService, useFactory: NativeWindowMockFactory },
{ provide: Router, useValue: new RouterStub() },
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA
@@ -68,16 +76,42 @@ describe('LogInShibbolethComponent', () => {
// get test component from the fixture
component = fixture.componentInstance;
componentAsAny = component;
// create page
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();
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 { 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({
selector: 'ds-log-in-shibboleth',
@@ -46,10 +49,14 @@ export class LogInShibbolethComponent implements OnInit {
/**
* @constructor
* @param {AuthMethod} injectedAuthMethodModel
* @param {NativeWindowRef} _window
* @param {RouteService} route
* @param {Store<State>} store
*/
constructor(
@Inject('authMethodProvider') public injectedAuthMethodModel: AuthMethod,
@Inject(NativeWindowService) protected _window: NativeWindowRef,
private route: RouteService,
private store: Store<CoreState>
) {
this.authMethod = injectedAuthMethodModel;
@@ -63,7 +70,26 @@ export class LogInShibbolethComponent implements OnInit {
this.loading = this.store.pipe(select(isAuthenticationLoading));
// 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();
}