aboutsummaryrefslogtreecommitdiff
path: root/solr-8.3.1/server/solr-webapp/webapp/js/angular/controllers/login.js
diff options
context:
space:
mode:
authorserver <brownptcdash@gmail.com>2019-12-10 18:12:37 -0500
committerserver <brownptcdash@gmail.com>2019-12-10 18:12:37 -0500
commit7478e610d99d1f2fb383ecbfa0b70d72eae27f81 (patch)
tree59486701838067351f00580315c05690f36a39ce /solr-8.3.1/server/solr-webapp/webapp/js/angular/controllers/login.js
parent096718ee546afbd7568bf8ec9e23dca0556d814d (diff)
solr changes
Diffstat (limited to 'solr-8.3.1/server/solr-webapp/webapp/js/angular/controllers/login.js')
-rw-r--r--solr-8.3.1/server/solr-webapp/webapp/js/angular/controllers/login.js317
1 files changed, 317 insertions, 0 deletions
diff --git a/solr-8.3.1/server/solr-webapp/webapp/js/angular/controllers/login.js b/solr-8.3.1/server/solr-webapp/webapp/js/angular/controllers/login.js
new file mode 100644
index 000000000..8127c6fda
--- /dev/null
+++ b/solr-8.3.1/server/solr-webapp/webapp/js/angular/controllers/login.js
@@ -0,0 +1,317 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+solrAdminApp.controller('LoginController',
+ ['$scope', '$routeParams', '$rootScope', '$location', '$window', 'AuthenticationService', 'Constants',
+ function ($scope, $routeParams, $rootScope, $location, $window, AuthenticationService, Constants) {
+ $scope.resetMenu("login", Constants.IS_ROOT_PAGE);
+ $scope.subPath = $routeParams.route;
+ $rootScope.exceptions = {};
+
+ // Session variables set in app.js 401 interceptor
+ var wwwAuthHeader = sessionStorage.getItem("auth.wwwAuthHeader");
+ var authScheme = sessionStorage.getItem("auth.scheme");
+ if (wwwAuthHeader) {
+ // Parse www-authenticate header
+ var wwwHeader = wwwAuthHeader.match(/(\w+)(\s+)?(.*)/);
+ authScheme = "unknown";
+ var authParams = {};
+ if (wwwHeader && wwwHeader.length >= 1)
+ authScheme = wwwHeader[1];
+ if (wwwHeader && wwwHeader.length >= 3)
+ authParams = www_auth_parse_params(wwwHeader[3]);
+ if (typeof authParams === 'string' || authParams instanceof String) {
+ $scope.authParamsError = authParams;
+ } else {
+ $scope.authParamsError = undefined;
+ }
+ var realm = authParams['realm'];
+ sessionStorage.setItem("auth.realm", realm);
+ if (authScheme === 'Basic' || authScheme === 'xBasic') {
+ authScheme = 'Basic';
+ }
+ sessionStorage.setItem("auth.scheme", authScheme);
+ }
+
+ var supportedSchemes = ['Basic', 'Bearer', 'Negotiate'];
+ $scope.authSchemeSupported = supportedSchemes.includes(authScheme);
+
+ if (authScheme === 'Bearer') {
+ // Check for OpenId redirect response
+ var errorText = "";
+ $scope.isCallback = false;
+ if ($scope.subPath === 'callback') {
+ $scope.isCallback = true;
+ var hash = $location.hash();
+ var hp = AuthenticationService.decodeHashParams(hash);
+ var expectedState = sessionStorage.getItem("auth.stateRandom") + "_" + sessionStorage.getItem("auth.location");
+ sessionStorage.setItem("auth.state", "error");
+ if (hp['access_token'] && hp['token_type'] && hp['state']) {
+ // Validate state
+ if (hp['state'] !== expectedState) {
+ $scope.error = "Problem with auth callback";
+ console.log("Expected state param " + expectedState + " but got " + hp['state']);
+ errorText += "Invalid values in state parameter. ";
+ }
+ // Validate token type
+ if (hp['token_type'].toLowerCase() !== "bearer") {
+ console.log("Expected token_type param 'bearer', but got " + hp['token_type']);
+ errorText += "Invalid values in token_type parameter. ";
+ }
+ // Unpack ID token and validate nonce, get username
+ if (hp['id_token']) {
+ var idToken = hp['id_token'].split(".");
+ if (idToken.length === 3) {
+ var payload = AuthenticationService.decodeJwtPart(idToken[1]);
+ if (!payload['nonce'] || payload['nonce'] !== sessionStorage.getItem("auth.nonce")) {
+ errorText += "Invalid 'nonce' value, possible attack detected. Please log in again. ";
+ }
+
+ if (errorText === "") {
+ sessionStorage.setItem("auth.username", payload['sub']);
+ sessionStorage.setItem("auth.header", "Bearer " + hp['access_token']);
+ sessionStorage.removeItem("auth.statusText");
+ sessionStorage.removeItem("auth.stateRandom");
+ sessionStorage.removeItem("auth.wwwAuthHeader");
+ console.log("User " + payload['sub'] + " is logged in");
+ var redirectTo = sessionStorage.getItem("auth.location");
+ console.log("Redirecting to stored location " + redirectTo);
+ sessionStorage.setItem("auth.state", "authenticated");
+ sessionStorage.removeItem("http401");
+ $location.path(redirectTo).hash("");
+ }
+ } else {
+ console.log("Expected JWT compact id_token param but got " + idToken);
+ errorText += "Invalid values in id_token parameter. ";
+ }
+ } else {
+ console.log("Callback was missing the id_token parameter, could not validate nonce.");
+ errorText += "Callback was missing the id_token parameter, could not validate nonce. ";
+ }
+ if (hp['access_token'].split(".").length !== 3) {
+ console.log("Expected JWT compact access_token param but got " + hp['access_token']);
+ errorText += "Invalid values in access_token parameter. ";
+ }
+ if (errorText !== "") {
+ $scope.error = "Problems with OpenID callback";
+ $scope.errorDescription = errorText;
+ $scope.http401 = "true";
+ }
+ // End callback processing
+ } else if (hp['error']) {
+ // The callback had errors
+ console.log("Error received from idp: " + hp['error']);
+ var errorDescriptions = {};
+ errorDescriptions['invalid_request'] = "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.";
+ errorDescriptions['unauthorized_client'] = "The client is not authorized to request an access token using this method.";
+ errorDescriptions['access_denied'] = "The resource owner or authorization server denied the request.";
+ errorDescriptions['unsupported_response_type'] = "The authorization server does not support obtaining an access token using this method.";
+ errorDescriptions['invalid_scope'] = "The requested scope is invalid, unknown, or malformed.";
+ errorDescriptions['server_error'] = "The authorization server encountered an unexpected condition that prevented it from fulfilling the request.";
+ errorDescriptions['temporarily_unavailable'] = "The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.";
+ $scope.error = "Callback from Id Provider contained error. ";
+ if (hp['error_description']) {
+ $scope.errorDescription = decodeURIComponent(hp['error_description']);
+ } else {
+ $scope.errorDescription = errorDescriptions[hp['error']];
+ }
+ if (hp['error_uri']) {
+ $scope.errorDescription += " More information at " + hp['error_uri'] + ". ";
+ }
+ if (hp['state'] !== expectedState) {
+ $scope.errorDescription += "The state parameter returned from ID Provider did not match the one we sent.";
+ }
+ sessionStorage.setItem("auth.state", "error");
+ }
+ }
+ }
+
+ if (errorText === "" && !$scope.error && authParams) {
+ $scope.error = authParams['error'];
+ $scope.errorDescription = authParams['error_description'];
+ $scope.authData = AuthenticationService.getAuthDataHeader();
+ }
+
+ $scope.authScheme = sessionStorage.getItem("auth.scheme");
+ $scope.authRealm = sessionStorage.getItem("auth.realm");
+ $scope.wwwAuthHeader = sessionStorage.getItem("auth.wwwAuthHeader");
+ $scope.statusText = sessionStorage.getItem("auth.statusText");
+ $scope.authLocation = sessionStorage.getItem("auth.location");
+ $scope.authLoggedinUser = sessionStorage.getItem("auth.username");
+ $scope.authHeader = sessionStorage.getItem("auth.header");
+
+ $scope.login = function () {
+ AuthenticationService.SetCredentials($scope.username, $scope.password);
+ $location.path($scope.authLocation); // Redirect to the location that caused the login prompt
+ };
+
+ $scope.logout = function() {
+ // reset login status
+ AuthenticationService.ClearCredentials();
+ $location.path("/");
+ };
+
+ $scope.jwtLogin = function () {
+ var stateRandom = Math.random().toString(36).substr(2);
+ sessionStorage.setItem("auth.stateRandom", stateRandom);
+ var authState = stateRandom + "_" + sessionStorage.getItem("auth.location");
+ var authNonce = Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2);
+ sessionStorage.setItem("auth.nonce", authNonce);
+ var params = {
+ "response_type" : "id_token token",
+ "client_id" : $scope.authData['client_id'],
+ "redirect_uri" : $window.location.href.split('#')[0],
+ "scope" : "openid " + $scope.authData['scope'],
+ "state" : authState,
+ "nonce" : authNonce
+ };
+
+ var endpointBaseUrl = $scope.authData['authorizationEndpoint'];
+ var loc = endpointBaseUrl + "?" + paramsToString(params);
+ console.log("Redirecting to " + loc);
+ sessionStorage.setItem("auth.state", "expectCallback");
+ $window.location.href = loc;
+
+ function paramsToString(params) {
+ var arr = [];
+ for (var p in params) {
+ if( params.hasOwnProperty(p) ) {
+ arr.push(p + "=" + encodeURIComponent(params[p]));
+ }
+ }
+ return arr.join("&");
+ }
+ };
+
+ $scope.jwtIsLoginNode = function() {
+ var redirect = $scope.authData ? $scope.authData['redirect_uris'] : undefined;
+ if (redirect && Array.isArray(redirect) && redirect.length > 0) {
+ var isLoginNode = false;
+ redirect.forEach(function(uri) { // Check that current node URL is among the configured callback URIs
+ if ($window.location.href.startsWith(uri)) isLoginNode = true;
+ });
+ return isLoginNode;
+ } else {
+ return true; // no redirect UIRs configured, all nodes are potential login nodes
+ }
+ };
+
+ $scope.jwtFindLoginNode = function() {
+ var redirect = $scope.authData ? $scope.authData['redirect_uris'] : undefined;
+ if (redirect && Array.isArray(redirect) && redirect.length > 0) {
+ var loginNode = redirect[0];
+ redirect.forEach(function(uri) { // if current node is in list, return its callback uri
+ if ($window.location.href.startsWith(uri)) loginNode = uri;
+ });
+ return loginNode;
+ } else {
+ return $window.location.href.split('#')[0]; // Return base url of current URL as the url to use
+ }
+ };
+
+ // Redirect to login node if this is not a valid one
+ $scope.jwtGotoLoginNode = function() {
+ if (!$scope.jwtIsLoginNode()) {
+ $window.location.href = $scope.jwtFindLoginNode();
+ }
+ };
+
+ $scope.jwtLogout = function() {
+ // reset login status
+ AuthenticationService.ClearCredentials();
+ $location.path("/");
+ };
+
+ $scope.isLoggedIn = function() {
+ return (sessionStorage.getItem("auth.username") !== null);
+ };
+ }]);
+
+// This function is copied and adapted from MIT-licensed https://github.com/randymized/www-authenticate/blob/master/lib/parsers.js
+www_auth_parse_params= function (header) {
+ // This parser will definitely fail if there is more than one challenge
+ var params = {};
+ var tok, last_tok, _i, _len, key, value;
+ var state= 0; //0: token,
+ var m= header.split(/([",=])/);
+ for (_i = 0, _len = m.length; _i < _len; _i++) {
+ last_tok= tok;
+ tok = m[_i];
+ if (!tok.length) continue;
+ switch (state) {
+ case 0: // token
+ key= tok.trim();
+ state= 1; // expect equals
+ continue;
+ case 1: // expect equals
+ if ('=' != tok) return 'Equal sign was expected after '+key;
+ state= 2;
+ continue;
+ case 2: // expect value
+ if ('"' == tok) {
+ value= '';
+ state= 3; // expect quoted
+ continue;
+ }
+ else {
+ params[key]= value= tok.trim();
+ state= 9; // expect comma or end
+ continue;
+ }
+ case 3: // handling quoted string
+ if ('"' == tok) {
+ state= 8; // end quoted
+ continue;
+ }
+ else {
+ value+= tok;
+ state= 3; // continue accumulating quoted string
+ continue;
+ }
+ case 8: // end quote encountered
+ if ('"' == tok) {
+ // double quoted
+ value+= '"';
+ state= 3; // back to quoted string
+ continue;
+ }
+ if (',' == tok) {
+ params[key]= value;
+ state= 0;
+ continue;
+ }
+ else {
+ return 'Unexpected token ('+tok+') after '+value+'"';
+ }
+ continue;
+ case 9: // expect commma
+ if (',' != tok) return 'Comma expected after '+value;
+ state= 0;
+ continue;
+ }
+ }
+ switch (state) { // terminal state
+ case 0: // Empty or ignoring terminal comma
+ case 9: // Expecting comma or end of header
+ return params;
+ case 8: // Last token was end quote
+ params[key]= value;
+ return params;
+ default:
+ return 'Unexpected end of www-authenticate value.';
+ }
+};