forked from DSpace/dspace-angular
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'w2p-111801_CSRF-bugfix-7.6' into w2p-111801_CSRF-bugfix…
…-main
- Loading branch information
Showing
13 changed files
with
228 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { BrowserXSRFService } from './browser-xsrf.service'; | ||
import { HttpClient } from '@angular/common/http'; | ||
import { RESTURLCombiner } from '../url-combiner/rest-url-combiner'; | ||
import { TestBed } from '@angular/core/testing'; | ||
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; | ||
|
||
describe(`BrowserXSRFService`, () => { | ||
let service: BrowserXSRFService; | ||
let httpClient: HttpClient; | ||
let httpTestingController: HttpTestingController; | ||
|
||
const endpointURL = new RESTURLCombiner('/security/csrf').toString(); | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [ HttpClientTestingModule ], | ||
providers: [ BrowserXSRFService ] | ||
}); | ||
httpClient = TestBed.inject(HttpClient); | ||
httpTestingController = TestBed.inject(HttpTestingController); | ||
service = TestBed.inject(BrowserXSRFService); | ||
}); | ||
|
||
describe(`initXSRFToken`, () => { | ||
it(`should perform a POST to the csrf endpoint`, () => { | ||
service.initXSRFToken(httpClient)(); | ||
|
||
const req = httpTestingController.expectOne({ | ||
url: endpointURL, | ||
method: 'POST' | ||
}); | ||
|
||
req.flush({}); | ||
httpTestingController.verify(); | ||
}); | ||
|
||
describe(`when the POST succeeds`, () => { | ||
it(`should set tokenInitialized$ to true`, () => { | ||
service.initXSRFToken(httpClient)(); | ||
|
||
const req = httpTestingController.expectOne(endpointURL); | ||
|
||
req.flush({}); | ||
httpTestingController.verify(); | ||
|
||
expect(service.tokenInitialized$.getValue()).toBeTrue(); | ||
}); | ||
}); | ||
|
||
describe(`when the POST fails`, () => { | ||
it(`should set tokenInitialized$ to true`, () => { | ||
service.initXSRFToken(httpClient)(); | ||
|
||
const req = httpTestingController.expectOne(endpointURL); | ||
|
||
req.error(new ErrorEvent('415')); | ||
httpTestingController.verify(); | ||
|
||
expect(service.tokenInitialized$.getValue()).toBeTrue(); | ||
}); | ||
}); | ||
|
||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { HttpClient } from '@angular/common/http'; | ||
import { Injectable } from '@angular/core'; | ||
import { RESTURLCombiner } from '../url-combiner/rest-url-combiner'; | ||
import { take, catchError } from 'rxjs/operators'; | ||
import { of as observableOf } from 'rxjs'; | ||
import { XSRFService } from './xsrf.service'; | ||
|
||
@Injectable() | ||
export class BrowserXSRFService extends XSRFService { | ||
initXSRFToken(httpClient: HttpClient): () => Promise<any> { | ||
return () => new Promise((resolve) => { | ||
httpClient.post(new RESTURLCombiner('/security/csrf').toString(), undefined).pipe( | ||
// errors are to be expected if the token and the cookie don't match, that's what we're | ||
// trying to fix for future requests, so just emit any observable to end up in the | ||
// subscribe | ||
catchError(() => observableOf(null)), | ||
take(1), | ||
).subscribe(() => { | ||
this.tokenInitialized$.next(true); | ||
}); | ||
|
||
// return immediately, the rest of the app doesn't need to wait for this to finish | ||
resolve(undefined); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { ServerXSRFService } from './server-xsrf.service'; | ||
import { HttpClient } from '@angular/common/http'; | ||
|
||
describe(`ServerXSRFService`, () => { | ||
let service: ServerXSRFService; | ||
let httpClient: HttpClient; | ||
|
||
beforeEach(() => { | ||
httpClient = jasmine.createSpyObj(['post', 'get', 'request']); | ||
service = new ServerXSRFService(); | ||
}); | ||
|
||
describe(`initXSRFToken`, () => { | ||
it(`shouldn't perform any requests`, (done: DoneFn) => { | ||
service.initXSRFToken(httpClient)().then(() => { | ||
for (const prop in httpClient) { | ||
if (httpClient.hasOwnProperty(prop)) { | ||
expect(httpClient[prop]).not.toHaveBeenCalled(); | ||
} | ||
} | ||
done(); | ||
}); | ||
}); | ||
|
||
it(`should leave tokenInitialized$ on false`, (done: DoneFn) => { | ||
service.initXSRFToken(httpClient)().then(() => { | ||
expect(service.tokenInitialized$.getValue()).toBeFalse(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { HttpClient } from '@angular/common/http'; | ||
import { Injectable } from '@angular/core'; | ||
import { XSRFService } from './xsrf.service'; | ||
|
||
@Injectable() | ||
export class ServerXSRFService extends XSRFService { | ||
initXSRFToken(httpClient: HttpClient): () => Promise<any> { | ||
return () => new Promise((resolve) => { | ||
// return immediately, and keep tokenInitialized$ false. The server side can make only GET | ||
// requests, since it can never get a valid XSRF cookie | ||
resolve(undefined); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { XSRFService } from './xsrf.service'; | ||
import { HttpClient } from '@angular/common/http'; | ||
|
||
class XSRFServiceImpl extends XSRFService { | ||
initXSRFToken(httpClient: HttpClient): () => Promise<any> { | ||
return () => null; | ||
} | ||
} | ||
|
||
describe(`XSRFService`, () => { | ||
let service: XSRFService; | ||
|
||
beforeEach(() => { | ||
service = new XSRFServiceImpl(); | ||
}); | ||
|
||
it(`should start with tokenInitialized$.hasValue() === false`, () => { | ||
expect(service.tokenInitialized$.getValue()).toBeFalse(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { HttpClient } from '@angular/common/http'; | ||
import { Injectable } from '@angular/core'; | ||
import { BehaviorSubject } from 'rxjs'; | ||
|
||
@Injectable() | ||
export abstract class XSRFService { | ||
public tokenInitialized$: BehaviorSubject<boolean> = new BehaviorSubject(false); | ||
|
||
abstract initXSRFToken(httpClient: HttpClient): () => Promise<any>; | ||
} |
Oops, something went wrong.