Commit 2e6a103c authored by Pedro Eduardo Trujillo's avatar Pedro Eduardo Trujillo
Browse files

Mejora manejo de peticiones, prueba token oid

Refactoriza lógica de envío de peticiones. Evalúa si la petición debe
llevar credenciales sólo cuando se lance explícitamente, evitando
escuchar (y tener que filtrar) al resto de peticiones de recursos que
realiza la aplicación.

Emplea directamente 'dojo/request/xhr' en lugar del genérico
'dojo/request', ya que siempre se usará este proveedor para lanzar las
peticiones.

Elimina rastros no usados de 'dojo/request' y anidados.

Incorpora soporte inicial para el uso de tokens de acceso alternativo
cuando se consultan servicios asegurados bajo OpenID.

Intercambia asignaciones a null por eliminaciones de entradas. Añade
test para el método 'remove' de la util Credentials.
parent 460b5414
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -72,7 +72,6 @@ var profileObj = {
		map: packagesMap,
		async: true,
		waitSeconds: 5,
		requestProvider: 'dojo/request/registry',
		selectorEngine: 'lite'
	},

@@ -443,7 +442,7 @@ var profileObj = {
				, 'dojo/NodeList-manipulate'
				, 'dojo/NodeList-traverse'
				, 'dojo/request/notify'
				, 'dojo/request/registry'
				, 'dojo/request/xhr'
				, 'dojo/store/Observable'
				, 'dojo/touch'
				, 'dojo/window'
+1 −1
Original line number Diff line number Diff line
@@ -231,7 +231,7 @@ define([
			var data = res.data[0];

			if (!data) {
				Credentials.set('accessToken', null);
				Credentials.remove('accessToken');
				return;
			}

+2 −2
Original line number Diff line number Diff line
@@ -146,8 +146,8 @@ define([

		_setEmptyExternalConfig: function() {

			Credentials.set('externalConfig', null);
			Credentials.set('externalConfigTimestamp', null);
			Credentials.remove('externalConfig');
			Credentials.remove('externalConfigTimestamp');
		},

		_itemAvailable: function(res) {
+81 −58
Original line number Diff line number Diff line
define([
	'src/redmicConfig'
	, 'dojo/_base/declare'
	'dojo/_base/declare'
	, 'dojo/_base/lang'
	, 'dojo/request'
	, 'dojo/request/xhr'
	, 'dojo/request/notify'
	, 'dojo/request/registry'
	, 'src/component/store/RestManager'
	, 'src/redmicConfig'
	, 'src/util/Credentials'
	, './RestManager'
], function(
	redmicConfig
	, declare
	declare
	, lang
	, request
	, notify
	, registry
	, Credentials
	, requestXhr
	, requestNotify
	, RestManager
	, redmicConfig
	, Credentials
) {

	return declare(RestManager, {
		//	summary:
		//		Implementación del módulo RestManager, que provee métodos de comunicación mediante dojo/request.
		//		Implementación del módulo RestManager, que provee métodos de comunicación mediante dojo/request/xhr.
		//	description:
		//		También maneja errores de permisos en peticiones y les añade cabeceras de autentificación.
		//		Importante: el campo 'options' recibido en las peticiones desde otros módulos, sobreescribe directamente
		//		las opciones que se usarán a su vez para realizar la petición HTTP.

		//	_apiUrl: String
		//		Prefijo de rutas hacia el servidor
		//	_filteredUrls: Array
		//		Define las URLs a las que no hay que añadirle caberas de autentificación
		//		Prefijo de rutas hacia el servidor.
		//	_filteredAuthPaths: Array
		//		Define las rutas de URLs a las que no hay que añadirle cabeceras de autenticación.

		constructor: function(args) {

@@ -49,13 +47,16 @@ define([
				handleAs: 'json',

				_apiUrl: redmicConfig.getEnvVariableValue('envApiUrl'),
				_filteredUrls: [
				_filteredAuthPaths: [
					'token',
					'reCaptcha',
					'register',
					'resettingRequest',
					'resettingSetPassword',
					'activateAccount'
				],
				_oidPaths: [
					'acoustic-detection'
				]
			};

@@ -66,8 +67,7 @@ define([

		_prepareRequestHandlers: function() {

			notify('error', lang.hitch(this, this._requestErrorHandler));
			registry.register(lang.hitch(this, this._preRequestHandler), request);
			requestNotify('error', lang.hitch(this, this._requestErrorHandler));
		},

		_getTargetWithEndingSlash: function(target) {
@@ -81,7 +81,66 @@ define([

		_launchRequest: function(url, options) {

			return request(url, options).response;
			const opts = this._getOptionsWithAuthIfNeeded(url, options);

			return requestXhr(url, opts).response;
		},

		_getOptionsWithAuthIfNeeded: function(url, options) {

			if (!this._requestedUrlNeedsAuth(url)) {
				return options;
			}

			const authHeader = this._getAuthHeaderNeededByUrl(url);

			if (!authHeader) {
				return options;
			}

			if (!options.headers) {
				options.headers = {};
			}

			options.headers.Authorization = authHeader;

			return options;
		},

		_requestedUrlNeedsAuth: function(url) {

			const isUrlToApi = url.includes(this._apiUrl);

			if (!isUrlToApi) {
				return false;
			}

			let urlSplitted = url.split('/'),
				lastPathItem = urlSplitted.pop();

			if (!lastPathItem.length) {
				lastPathItem = urlSplitted.pop();
			}

			const lastPathItemWithoutParams = lastPathItem.split('?')[0];

			return !this._filteredAuthPaths.includes(lastPathItemWithoutParams);
		},

		_getAuthHeaderNeededByUrl: function(url) {

			let isOidPath = false;

			for (let i = 0; i < this._oidPaths.length; i++) {
				if (url.includes(this._oidPaths[i])) {
					isOidPath = true;
					break;
				}
			}

			const accessToken = isOidPath ? Credentials.get('oidAccessToken') : Credentials.get('accessToken');

			return accessToken ? `Bearer ${accessToken}` : null;
		},

		_getRequest: function(target, req) {
@@ -236,8 +295,8 @@ define([

		_getSaveRequestTarget: function(target, req) {

			var id = this._getItemIdFromSaveRequest(req),
				targetWithSlash = this._getTargetWithEndingSlash(target);
			const targetWithSlash = this._getTargetWithEndingSlash(target),
				id = this._getItemIdFromSaveRequest(req);

			if (!id) {
				return targetWithSlash;
@@ -411,49 +470,13 @@ define([

			// TODO notificar al usuario que intentó acceder a algo para lo que no tenía permiso (token caducado o con
			// privilegios insuficientes)
			Credentials.set('accessToken', null);
			//Credentials.remove('accessToken');
		},

		_onRequestReachabilityError: function(res) {

			// TODO notificar al usuario que hubo un error de conexión y ofrecerle recargar (para que pueda actuar
			// sobre la página actual antes de recargar)
		},

		_preRequestHandler: function(url, options) {
			//	summary:
			//		Se ejecuta antes de hacer un request y nos permite añadir cabeceras
			//	tags:
			//		private
			//	url:
			//		url del servicio
			//	options:
			//		opciones del request (headers...)

			var urlSplitted = url.split('/'),
				lastUrlItem = urlSplitted.pop();

			if (!lastUrlItem.length) {
				lastUrlItem = urlSplitted.pop();
			}

			var lastUrlItemWithoutParams = lastUrlItem.split('?')[0],
				isFilteredUrlItem = this._filteredUrls.indexOf(lastUrlItemWithoutParams) !== -1,
				isUrlToServer = url.indexOf(this._apiUrl) !== -1,
				urlNeedsAuth = isUrlToServer && !isFilteredUrlItem;

			if (urlNeedsAuth) {
				if (!options.headers) {
					options.headers = {};
				}

				var accessToken = Credentials.get('accessToken');
				if (accessToken) {
					options.headers.Authorization = 'Bearer ' + accessToken;
				}
			}

			return !!options.useXHR;
		}
	});
});
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ define([
					TIMESERIES_DATA: 'timeseriesData'
				},
				target: redmicConfig.services.activity,
				templateTargetChange: redmicConfig.services.activityObservationSeriesStations,
				templateTargetChange: redmicConfig.services.acousticDetectionReceptors,
				_activeRadius: false,
				_showObservationsButtonClass: 'showObservations'
			};
Loading