Skip to content

Commit

Permalink
feat(auth): Provide a config to setup a key value based on regex value (
Browse files Browse the repository at this point in the history
#926)

* chore(*): lib update

* chore(*): lib update to ol 6.8

* chore(*) update eslint

* wip

* chore(*): tslint to eslint

* refactor(*): eslint rule async pipe negation

* refactor(*): eslint rules 2 space and eqeqeq === vs ==

* chore(*): eslint rule unused imports

* chore(*): eslint fix with current rules

* chore(*): eslint rule max len

* chore(github action): add the lint before the build.

* lint

* feat(auth): provide a config to setup a key value based on regex values (domain). Each intercepted layer will have the key added to the url.

* feat(layer-service): add the authInterceptor for tile layer

* feat(image-layer): add a step to the custom loader to add a key used as auth.

* feat(vector-layer): add a step to the custom loader to add a key used as auth.

* feat(vectortile-layer): add a step to the custom loader to add a key used as auth.

* feat(tile-layer): add a step to the custom loader to add a key used as auth.

* wip
  • Loading branch information
pelord authored Nov 15, 2021
1 parent 1e51e39 commit b9bc82e
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 21 deletions.
40 changes: 39 additions & 1 deletion packages/auth/src/lib/shared/auth.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Md5 } from 'ts-md5';

import { ConfigService } from '@igo2/core';
import { TokenService } from './token.service';
import { WithCredentialsOptions } from './auth.interface';
import { AuthByKeyOptions, WithCredentialsOptions } from './auth.interface';

@Injectable({
providedIn: 'root'
Expand All @@ -29,6 +29,10 @@ export class AuthInterceptor implements HttpInterceptor {
return this.config.getConfig('auth.hostsWithCredentials') || [];
}

private get hostsWithAuthByKey(): AuthByKeyOptions[] {
return this.config.getConfig('auth.hostsByKey') || [];
}

constructor(
private config: ConfigService,
private tokenService: TokenService,
Expand All @@ -41,6 +45,12 @@ export class AuthInterceptor implements HttpInterceptor {
): Observable<HttpEvent<any>> {
const withCredentials = this.handleHostsWithCredentials(originalReq.url);
let req = originalReq.clone();
const hostWithKey = this.handleHostsAuthByKey(originalReq.url);
if (hostWithKey) {
req = req.clone({
params: req.params.set(hostWithKey.key, hostWithKey.value)
});
}
if (withCredentials) {
req = originalReq.clone({
withCredentials
Expand Down Expand Up @@ -102,6 +112,22 @@ export class AuthInterceptor implements HttpInterceptor {
return true;
}

alterUrlWithKeyAuth(url: string): string {
const hostWithKey = this.handleHostsAuthByKey(url);
let interceptedUrl = url;
if (hostWithKey) {
const urlDecomposed = interceptedUrl.split(/[?&]/);
let urlWithKeyAdded = urlDecomposed.shift();
const paramsToKeep = urlDecomposed.filter(p => p.length !== 0);
paramsToKeep.push(`${hostWithKey.key}=${hostWithKey.value}`);
if (paramsToKeep.length) {
urlWithKeyAdded += '?' + paramsToKeep.join('&');
}
return urlWithKeyAdded;
}
return;
}

private handleHostsWithCredentials(reqUrl: string) {
let withCredentials = false;
for (const hostWithCredentials of this.hostsWithCredentials) {
Expand All @@ -114,6 +140,18 @@ export class AuthInterceptor implements HttpInterceptor {
return withCredentials;
}

private handleHostsAuthByKey(reqUrl: string): {key: string, value: string} {
let hostWithKey;
for (const hostWithAuthByKey of this.hostsWithAuthByKey) {
const domainRegex = new RegExp(hostWithAuthByKey.domainRegFilters);
if (domainRegex.test(reqUrl)) {
hostWithKey = {key : hostWithAuthByKey.keyProperty, value: hostWithAuthByKey.keyValue};
break;
}
}
return hostWithKey;
}

refreshToken() {
const jwt = this.tokenService.decode();
const currentTime = new Date().getTime() / 1000;
Expand Down
7 changes: 7 additions & 0 deletions packages/auth/src/lib/shared/auth.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ export interface AuthOptions {
trustHosts?: string[];
profilsGuard?: string[];
hostsWithCredentials?: WithCredentialsOptions[];
hostsByKey?: AuthByKeyOptions[];
}
export interface AuthByKeyOptions {
domainRegFilters?: string;
keyProperty?: string;
keyValue?: string;

}
export interface WithCredentialsOptions {
withCredentials?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/geo/src/lib/layer/shared/layer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export class LayerService {
}

private createTileLayer(layerOptions: TileLayerOptions): TileLayer {
return new TileLayer(layerOptions, this.messageService);
return new TileLayer(layerOptions, this.messageService, this.authInterceptor);
}

private createVectorLayer(layerOptions: VectorLayerOptions): VectorLayer {
Expand Down
13 changes: 9 additions & 4 deletions packages/geo/src/lib/layer/shared/layers/image-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,19 @@ export class ImageLayer extends Layer {
super.setMap(map);
}

private customLoader(tile, src, interceptor, messageService, languageService) {
private customLoader(tile, src: string, interceptor: AuthInterceptor, messageService: MessageService, languageService: LanguageService) {
const xhr = new XMLHttpRequest();
xhr.open('GET', src);

const intercepted = interceptor.interceptXhr(xhr, src);
const alteredUrlWithKeyAuth = interceptor.alterUrlWithKeyAuth(src);
let url = src;
if (alteredUrlWithKeyAuth) {
url = alteredUrlWithKeyAuth;
}
xhr.open('GET', url);
const intercepted = interceptor.interceptXhr(xhr, url);
if (!intercepted) {
xhr.abort();
tile.getImage().src = src;
tile.getImage().src = url;
return;
}

Expand Down
30 changes: 27 additions & 3 deletions packages/geo/src/lib/layer/shared/layers/tile-layer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import olLayerTile from 'ol/layer/Tile';
import olSourceTile from 'ol/source/Tile';
import Tile from 'ol/Tile';

import { TileWatcher } from '../../utils';
import { IgoMap } from '../../../map';
Expand All @@ -15,6 +16,7 @@ import { Layer } from './layer';
import { TileLayerOptions } from './tile-layer.interface';

import { MessageService } from '@igo2/core';
import { AuthInterceptor } from '@igo2/auth';
export class TileLayer extends Layer {
public dataSource:
| OSMDataSource
Expand All @@ -30,7 +32,8 @@ export class TileLayer extends Layer {

constructor(
options: TileLayerOptions,
public messageService?: MessageService) {
public messageService?: MessageService,
public authInterceptor?: AuthInterceptor) {
super(options, messageService);

this.watcher = new TileWatcher(this);
Expand All @@ -39,10 +42,31 @@ export class TileLayer extends Layer {

protected createOlLayer(): olLayerTile<olSourceTile> {
const olOptions = Object.assign({}, this.options, {
source: this.options.source.ol as olSourceTile
source: this.options.source.ol
});
const tileLayer = new olLayerTile(olOptions);
const tileSource = tileLayer.getSource();
tileSource.setTileLoadFunction((tile: Tile, url: string) => {
this.customLoader(tile, url, this.authInterceptor);
});

return tileLayer;
}

return new olLayerTile(olOptions);
/**
* Custom loader for tile layer.
* @internal
* @param tile the current tile
* @param url the url string or function to retrieve the data
*/
customLoader(tile, url: string, interceptor: AuthInterceptor ) {

const alteredUrlWithKeyAuth = interceptor.alterUrlWithKeyAuth(url);
let modifiedUrl = url;
if (alteredUrlWithKeyAuth) {
modifiedUrl = alteredUrlWithKeyAuth;
}
tile.getImage().src = modifiedUrl;
}

public setMap(map: IgoMap | undefined) {
Expand Down
27 changes: 18 additions & 9 deletions packages/geo/src/lib/layer/shared/layers/vector-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,14 @@ export class VectorLayer extends Layer {
success, failure) {

const xhr = new XMLHttpRequest();
xhr.open('GET', url);
const alteredUrlWithKeyAuth = interceptor.alterUrlWithKeyAuth(url);
let modifiedUrl = url;
if (alteredUrlWithKeyAuth) {
modifiedUrl = alteredUrlWithKeyAuth;
}
xhr.open('GET', modifiedUrl);
if (interceptor) {
interceptor.interceptXhr(xhr, url);
interceptor.interceptXhr(xhr, modifiedUrl);
}
const onError = () => {
vectorSource.removeLoadedExtent(extent);
Expand Down Expand Up @@ -363,18 +368,22 @@ export class VectorLayer extends Layer {
failure
) {
const xhr = new XMLHttpRequest();
xhr.open(
'GET',
typeof url === 'function'
? url = url(extent, resolution, projection)
: url
);
let modifiedUrl = url;
if (typeof url !== 'function') {
const alteredUrlWithKeyAuth = interceptor.alterUrlWithKeyAuth(url);
if (alteredUrlWithKeyAuth) {
modifiedUrl = alteredUrlWithKeyAuth;
}
} else {
modifiedUrl = url(extent, resolution, projection);
}
xhr.open( 'GET', modifiedUrl);
const format = vectorSource.getFormat();
if (format.getType() === FormatType.ARRAY_BUFFER) {
xhr.responseType = 'arraybuffer';
}
if (interceptor) {
interceptor.interceptXhr(xhr, url);
interceptor.interceptXhr(xhr, modifiedUrl);
}

const onError = () => {
Expand Down
15 changes: 12 additions & 3 deletions packages/geo/src/lib/layer/shared/layers/vectortile-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class VectorTileLayer extends Layer {
const vectorTile = new olLayerVectorTile(olOptions);
const vectorTileSource = vectorTile.getSource() as olSourceVectorTile;

vectorTileSource.setTileLoadFunction((tile: VectorTile, url) => {
vectorTileSource.setTileLoadFunction((tile: VectorTile, url: string) => {
const loader = this.customLoader(url, tile.getFormat(), this.authInterceptor, tile.onLoad.bind(tile));
if (loader) {
tile.setLoader(loader);
Expand All @@ -58,9 +58,18 @@ export class VectorTileLayer extends Layer {
customLoader(url, format, interceptor, success, failure?) {
return ((extent, resolution, projection) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', typeof url === 'function' ? url = url(extent, resolution, projection) : url);
let modifiedUrl = url;
if (typeof url !== 'function') {
const alteredUrlWithKeyAuth = interceptor.alterUrlWithKeyAuth(url);
if (alteredUrlWithKeyAuth) {
modifiedUrl = alteredUrlWithKeyAuth;
}
} else {
modifiedUrl = url(extent, resolution, projection);
}
xhr.open( 'GET', modifiedUrl);
if (interceptor) {
interceptor.interceptXhr(xhr, url);
interceptor.interceptXhr(xhr, modifiedUrl);
}

if (format.getType() === 'arraybuffer') {
Expand Down

0 comments on commit b9bc82e

Please sign in to comment.