import Exceptions = require("../../Exceptions"); import objectPath = require("object-path"); import BluebirdPromise = require("bluebird"); import express = require("express"); import { AccessController } from "../../access_control/AccessController"; import { Regulator } from "../../regulation/Regulator"; import { GroupsAndEmails } from "../../ldap/IClient"; import Endpoint = require("../../../../../shared/api"); import ErrorReplies = require("../../ErrorReplies"); import AuthenticationSessionHandler = require("../../AuthenticationSession"); import Constants = require("../../../../../shared/constants"); import { DomainExtractor } from "../../utils/DomainExtractor"; import UserMessages = require("../../../../../shared/UserMessages"); import { AuthenticationMethodCalculator } from "../../AuthenticationMethodCalculator"; import { ServerVariables } from "../../ServerVariables"; import { AuthenticationSession } from "../../../../types/AuthenticationSession"; export default function (vars: ServerVariables) { return function (req: express.Request, res: express.Response) : BluebirdPromise<void> { const username: string = req.body.username; const password: string = req.body.password; let authSession: AuthenticationSession; return BluebirdPromise.resolve() .then(function () { if (!username || !password) { return BluebirdPromise.reject(new Error("No username or password.")); } vars.logger.info(req, "Starting authentication of user \"%s\"", username); return AuthenticationSessionHandler.get(req, vars.logger); }) .then(function (_authSession) { authSession = _authSession; return vars.regulator.regulate(username); }) .then(function () { vars.logger.info(req, "No regulation applied."); return vars.ldapAuthenticator.authenticate(username, password); }) .then(function (groupsAndEmails: GroupsAndEmails) { vars.logger.info(req, "LDAP binding successful. Retrieved information about user are %s", JSON.stringify(groupsAndEmails)); authSession.userid = username; authSession.first_factor = true; const redirectUrl = req.query[Constants.REDIRECT_QUERY_PARAM] !== "undefined" // Fuck, don't know why it is a string! ? req.query[Constants.REDIRECT_QUERY_PARAM] : undefined; const emails: string[] = groupsAndEmails.emails; const groups: string[] = groupsAndEmails.groups; const redirectHost: string = DomainExtractor.fromUrl(redirectUrl); const authMethod = new AuthenticationMethodCalculator(vars.config.authentication_methods) .compute(redirectHost); vars.logger.debug(req, "Authentication method for \"%s\" is \"%s\"", redirectHost, authMethod); if (!emails || emails.length <= 0) { const errMessage = "No emails found. The user should have at least one email address to reset password."; vars.logger.error(req, "%s", errMessage); return BluebirdPromise.reject(new Error(errMessage)); } authSession.email = emails[0]; authSession.groups = groups; vars.logger.debug(req, "Mark successful authentication to regulator."); vars.regulator.mark(username, true); if (authMethod == "basic_auth") { res.send({ redirect: redirectUrl }); vars.logger.debug(req, "Redirect to '%s'", redirectUrl); } else if (authMethod == "two_factor") { let newRedirectUrl = Endpoint.SECOND_FACTOR_GET; if (redirectUrl) { newRedirectUrl += "?" + Constants.REDIRECT_QUERY_PARAM + "=" + encodeURIComponent(redirectUrl); } vars.logger.debug(req, "Redirect to '%s'", newRedirectUrl, typeof redirectUrl); res.send({ redirect: newRedirectUrl }); } else { return BluebirdPromise.reject(new Error("Unknown authentication method for this domain.")); } return BluebirdPromise.resolve(); }) .catch(Exceptions.LdapBindError, function (err: Error) { vars.regulator.mark(username, false); return ErrorReplies.replyWithError200(req, res, vars.logger, UserMessages.OPERATION_FAILED)(err); }) .catch(ErrorReplies.replyWithError200(req, res, vars.logger, UserMessages.OPERATION_FAILED)); }; }