<commit_before>/**
 * Copyright (c) 2014 "Fronteer LTD"
 * Grasshopper Event Engine
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var passport = require('passport');
var util = require('util');

var GrassHopper = require('gh-core');
var log = require('gh-core/lib/logger').logger('gh-auth');

var AuthenticationUtil = require('./util');
var ShibbolethAPI = require('./api.shibboleth');

/**
 * @REST logout
 *
 * Log out
 *
 * @Server      admin,app
 * @Method      POST
 * @Path        /auth/logout
 * @Return      {void}
 */
var logout = function(req, res) {
    // Kill the user session
    req.logout();

    // Redirect the user to the main landing page
    return res.redirect('/');
};

GrassHopper.globalAdminRouter.on('post', '/api/auth/logout', logout);
GrassHopper.appRouter.on('post', '/api/auth/logout', logout);


//////////////////////////
// Local authentication //
//////////////////////////

/**
 * @REST localLogin
 *
 * Log in using local authentication
 *
 * @Server      admin,app
 * @Method      POST
 * @Path        /auth/login
 * @FormParam   {string}            password                <PASSWORD>
 * @FormParam   {string}            username                The username for the user
 * @Return      {User}                                      The logged in user
 */
var localLogin = function(req, res, next) {
    passport.authenticate('local', function(err, authInfo) {
        if (err) {
            return next(err);
        } else if (!authInfo || !authInfo.user) {
            return res.status(401).end();
        }

        // Create the user session
        req.logIn(authInfo, function(err) {
            if (err) {
                return next(err);
            }

            return res.status(200).send(req.user);
        });
    })(req, res, next);
};

GrassHopper.globalAdminRouter.on('post', '/api/auth/login', localLogin);
GrassHopper.appRouter.on('post', '/api/auth/login', localLogin);

/**
 * @REST changePassword
 *
 * Change a user's local password
 *
 * @Server      admin,app
 * @Method      POST
 * @Path        /users/{id}/password
 * @PathParam   {string}            id                      The id of user for which to change the local password
 * @FormParam   {string}            newPassword             The new password for the user
 * @FormParam   {string}            [oldPassword]           The previous password for the user. This is only required when the current user is not an administrator
 * @Return      {void}
 */
var changePassword = function(req, res) {
    res.sendStatus(501);
};

GrassHopper.globalAdminRouter.on('post', '/api/users/:id/password', changePassword);
GrassHopper.appRouter.on('post', '/api/users/:id/password', changePassword);


///////////////////////////////
// Shibboleth authentication //
///////////////////////////////

/**
 * @REST shibbolethLogin
 *
 * Log in using Shibboleth authentication
 *
 * @Server      app
 * @Method      POST
 * @Path        /auth/shibboleth
 * @Return      {void}
 */
GrassHopper.appRouter.on('post', '/api/auth/shibboleth', function(req, res) {
    if (!ShibbolethAPI.isEnabled(req.ctx.app.id)) {
        return res.status(400).send('Shibboleth authentication is not enabled for this application');
    }

    // Get the URL to which the user should be redirected and store it in a cookie,
    // so we can retrieve it once the user returns from the identity provider
    var redirectUrl = AuthenticationUtil.validateRedirectUrl(req.param('redirectUrl'));
    res.cookie('redirectUrl', redirectUrl, {'signed': true});

    // Redirect the user to our SP host
    var serviceProviderUrl = ShibbolethAPI.getServiceProviderUrl(req.ctx.app.id);
    res.redirect(serviceProviderUrl);
});

/**
 * @REST redirectToIdentityProvider
 *
 * Redirect the user to the configured identity provider
 *
 * @Api         private
 * @Server      app
 * @Method      GET
 * @Path        /auth/shibboleth/sp
 * @QueryParam  {string}            [app]                   The id of the app on which the user wants to authenticate
 * @QueryParam  {string}            [signature]             The signature for the app id
 * @QueryParam  {number}            [expires]               The timestamp (ISO 8601) at which the signature expires
 * @Return      {void}
 */
GrassHopper.appRouter.on('get', '/api/auth/shibboleth/sp', function(req, res, next) {
    if (ShibbolethAPI.getSPHost() !== req.hostname) {
        return res.status(501).send('This endpoint is not enabled on a regular app');
    }

    var appId = req.query.app;
    var signature = req.query.signature;
    var expires = req.query.expires;

    // Validate the parameters
    ShibbolethAPI.validateInitiateParameters(appId, signature, expires, function(err, app) {
        if (err) {
            return res.status(err.code).send(err.msg);
        }

        // Keep track of the application from which the user originated
        res.cookie('shibboleth', appId, {'signed': true});

        // Get the generic error handler
        var errorHandler = AuthenticationUtil.handlePassportError(req, res, next);

        // Get the URL to which the user should be redirected and store it in a cookie,
        // so we can retrieve it once the user returns from the external authentication source
        var redirectUrl = AuthenticationUtil.validateRedirectUrl(req.param('redirectUrl'));
        res.cookie('redirectUrl', redirectUrl, {'signed': true});<commit_msg>Fixed deprecation warning + removed unused bit of logic from Shibboleth REST layer<commit_after>/**
 * Copyright (c) 2014 "Fronteer LTD"
 * Grasshopper Event Engine
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var passport = require('passport');
var util = require('util');

var GrassHopper = require('gh-core');
var log = require('gh-core/lib/logger').logger('gh-auth');

var AuthenticationUtil = require('./util');
var ShibbolethAPI = require('./api.shibboleth');

/**
 * @REST logout
 *
 * Log out
 *
 * @Server      admin,app
 * @Method      POST
 * @Path        /auth/logout
 * @Return      {void}
 */
var logout = function(req, res) {
    // Kill the user session
    req.logout();

    // Redirect the user to the main landing page
    return res.redirect('/');
};

GrassHopper.globalAdminRouter.on('post', '/api/auth/logout', logout);
GrassHopper.appRouter.on('post', '/api/auth/logout', logout);


//////////////////////////
// Local authentication //
//////////////////////////

/**
 * @REST localLogin
 *
 * Log in using local authentication
 *
 * @Server      admin,app
 * @Method      POST
 * @Path        /auth/login
 * @FormParam   {string}            password                The password for the user
 * @FormParam   {string}            username                The username for the user
 * @Return      {User}                                      The logged in user
 */
var localLogin = function(req, res, next) {
    passport.authenticate('local', function(err, authInfo) {
        if (err) {
            return next(err);
        } else if (!authInfo || !authInfo.user) {
            return res.status(401).end();
        }

        // Create the user session
        req.logIn(authInfo, function(err) {
            if (err) {
                return next(err);
            }

            return res.status(200).send(req.user);
        });
    })(req, res, next);
};

GrassHopper.globalAdminRouter.on('post', '/api/auth/login', localLogin);
GrassHopper.appRouter.on('post', '/api/auth/login', localLogin);

/**
 * @REST changePassword
 *
 * Change a user's local password
 *
 * @Server      admin,app
 * @Method      POST
 * @Path        /users/{id}/password
 * @PathParam   {string}            id                      The id of user for which to change the local password
 * @FormParam   {string}            newPassword             The new password for the user
 * @FormParam   {string}            [oldPassword]           The previous password for the user. This is only required when the current user is not an administrator
 * @Return      {void}
 */
var changePassword = function(req, res) {
    res.sendStatus(501);
};

GrassHopper.globalAdminRouter.on('post', '/api/users/:id/password', changePassword);
GrassHopper.appRouter.on('post', '/api/users/:id/password', changePassword);


///////////////////////////////
// Shibboleth authentication //
///////////////////////////////

/**
 * @REST shibbolethLogin
 *
 * Log in using Shibboleth authentication
 *
 * @Server      app
 * @Method      POST
 * @Path        /auth/shibboleth
 * @Return      {void}
 */
GrassHopper.appRouter.on('post', '/api/auth/shibboleth', function(req, res) {
    if (!ShibbolethAPI.isEnabled(req.ctx.app.id)) {
        return res.status(400).send('Shibboleth authentication is not enabled for this application');
    }

    // Get the URL to which the user should be redirected and store it in a cookie,
    // so we can retrieve it once the user returns from the identity provider
    var redirectUrl = AuthenticationUtil.validateRedirectUrl(req.body.redirectUrl);
    res.cookie('redirectUrl', redirectUrl, {'signed': true});

    // Redirect the user to our SP host
    var serviceProviderUrl = ShibbolethAPI.getServiceProviderUrl(req.ctx.app.id);
    res.redirect(serviceProviderUrl);
});

/**
 * @REST redirectToIdentityProvider
 *
 * Redirect the user to the configured identity provider
 *
 * @Api         private
 * @Server      app
 * @Method      GET
 * @Path        /auth/shibboleth/sp
 * @QueryParam  {string}            [app]                   The id of the app on which the user wants to authenticate
 * @QueryParam  {string}            [signature]             The signature for the app id
 * @QueryParam  {number}            [expires]               The timestamp (ISO 8601) at which the signature expires
 * @Return      {void}
 */
GrassHopper.appRouter.on('get', '/api/auth/shibboleth/sp', function(req, res, next) {
    if (ShibbolethAPI.getSPHost() !== req.hostname) {
        return res.status(501).send('This endpoint is not enabled on a regular app');
    }

    var appId = req.query.app;
    var signature = req.query.signature;
    var expires = req.query.expires;

    // Validate the parameters
    ShibbolethAPI.validateInitiateParameters(appId, signature, expires, function(err, app) {
        if (err) {
            return res.status(err.code).send(err.msg);
        }

        // Keep track of the application from which the user originated
        res.cookie('shibboleth', appId, {'signed': true});

        // Get the generic error handler
        var errorHandler = AuthenticationUtil.handlePassportError(req, res, next);
{'fraction_non_alphanumeric': 0.13068469991546913, 'fraction_numerical': 0.0040574809805579036, 'mean_word_length': 2.4332559489262913, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4114682', 'n_tokens_mistral': 3400, 'n_tokens_neox': 3272, 'n_words': 1063}