<%
/*
 * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. 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.
 */

var uri = request.getRequestURI();
var uriMatcher = new URIMatcher(String(uri));

var log = new Log("api/user-api.jag");

var constants = require("/app/modules/constants.js");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var utility = require("/app/modules/utility.js")["utility"];
var apiWrapperUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
var util = require("/app/modules/oauth/token-handler-utils.js")["utils"];

var responseProcessor = require("utils").response;

var result;

if (uriMatcher.match("/{context}/api/user/authenticate")) {
    var username = request.getParameter("username");
    var password = request.getParameter("password");
    //Check if a username and password is provided
    if ((!username) || (!password)) {
        response = responseProcessor.buildErrorResponse(response, 400, 'Username and Password must be provided');
    } else {
        try {
            userModule.login(username, password, function (user) {
                if (log.isDebugEnabled()) {
                    log.debug("User Logged In : " + user);
                }
                apiWrapperUtil.setupTokenPairByPasswordGrantType(username, password);
            }, function () {
                response = responseProcessor.buildSuccessResponse(response, 200, {'sessionId': session.getId()});
            });
        } catch (e) {
            log.error("Exception occurred while a user tried to login to MDM", e);
            response = responseProcessor.buildErrorResponse(response, 401, 'username/password is incorrect');
        }
    }
} else if (uriMatcher.match("/{context}/api/user/login/")) {
    username = request.getParameter("username");
    password = request.getParameter("password");
    username = util.decode(username);
    password = util.decode(password);
    try {
        userModule.login(username, password, function (user) {
            if (log.isDebugEnabled()) {
                log.debug("User Logged In : " + user);
            }

            apiWrapperUtil.setupTokenPairByPasswordGrantType(username, password);
            var permissions = userModule.getUIPermissions();
            if (permissions.VIEW_DASHBOARD) {
                response.sendRedirect(devicemgtProps["appContext"]);
            } else {
                response.sendRedirect(devicemgtProps["appContext"] + "devices");
            }
        }, function () {
            response.sendRedirect(devicemgtProps.appContext + "login?#auth-failed");
        });
    } catch (e) {
        log.error("Exception occurred while a user tried to login to MDM", e);
        response.sendRedirect(devicemgtProps.appContext + "login?#error");
    }
} else if (uriMatcher.match("/{context}/api/user/logout/")) {
    userModule.logout(function () {
        response.sendRedirect(devicemgtProps.appContext + "login");
    });
} else if (uriMatcher.match("/{context}/api/user/devices/")) {
    /*
     @Deprecated
     */
    if (userModule.isAuthorized("/permission/admin/device-mgt/user/devices/list")) {
        carbonUser = session.get(constants.USER_SESSION_KEY);
        result = deviceModule.listDevicesForUser(carbonUser.username);
    } else {
        response.sendError(403);
    }
} else if (uriMatcher.match("/{context}/api/user/{username}/invite")) {
    /*
     @Deprecated
     */
    if (userModule.isAuthorized("/permission/admin/device-mgt/user/invite")) {
        elements = uriMatcher.elements();
        username = elements.username;
        userModule.inviteUser(username);
    } else {
        response.sendError(403);
    }
} else if (uriMatcher.match("/{context}/api/user/add")) {
    /*
     @Deprecated
     */
    if (userModule.isAuthorized("/permission/admin/device-mgt/user/add")) {
        addUserFormData = request.getContent();
        username = addUserFormData.username;
        firstname = addUserFormData.firstname;
        lastname = addUserFormData.lastname;
        emailAddress = addUserFormData.emailAddress;

        if (!addUserFormData.userRoles) {
            userRoles = null;
        } else {
            userRoles = String(addUserFormData.userRoles).split(",");
        }
        if (username.length < devicemgtProps.userValidationConfig.usernameLength) {
            log.error("Username Must be between 1 and " + devicemgtProps.userValidationConfig.usernameLength + " characters long");
            result = "Username Must be between 1 and " + devicemgtProps.userValidationConfig.usernameLength + " characters long";
        } else {
            try {
                result = userModule.addUser(username, firstname, lastname, emailAddress, userRoles);
            } catch (e) {
                log.error("Exception occurred while trying to add a user to MDM User Store", e);
                // http status code 400 refers to - Bad request.
                result = 400;
            }
        }
    } else {
        // http status code 403 refers to - forbidden.
        result = 403;
    }
} else if (uriMatcher.match("/{context}/api/user/register")) {

    addUserFormData = request.getContent();
    username = addUserFormData.username;
    firstname = addUserFormData.firstname;
    lastname = addUserFormData.lastname;
    emailAddress = addUserFormData.emailAddress;
    password = addUserFormData.password;
    userRoles = ["internal/devicemgt-user"];

    try {
        result = userModule.registerUser(username, firstname, lastname, emailAddress, password,
            userRoles);
    } catch (e) {
        log.error("Exception occurred while trying to registering a new user to DC User Store", e);
        // http status code 400 refers to - Bad request.
        result = 400;
    }

} else if (uriMatcher.match("/{context}/api/user/{username}/remove")) {
    /*
     @Deprecated
     */
    if (userModule.isAuthorized("/permission/admin/device-mgt/user/remove")) {
        elements = uriMatcher.elements();
        username = elements.username;
        try {
            result = userModule.removeUser(username);
        } catch (e) {
            log.error("Exception occurred while trying to remove a user from MDM User Store", e);
            // http status code 400 refers to - Bad request.
            result = 400;
        }
    } else {
        // http status code 403 refers to - forbidden.
        result = 403;
    }
} else if (uriMatcher.match("/{context}/api/user/all")) {
    result = userModule.getUsers();
} else if (uriMatcher.match("/{context}/api/user/environment-loaded")) {
    try {
        var carbonUser = session.get(constants.USER_SESSION_KEY);
        if (!carbonUser) {
            response.sendRedirect("/devicemgt/login?#login-required");
            exit();
        }
        utility.startTenantFlow(carbonUser);
        var APIManagementProviderService = utility.getAPIManagementProviderService();
        var isLoaded = APIManagementProviderService.isTierLoaded();
        result = {"isLoaded": isLoaded};
        if (isLoaded) {
            var samlToken = session.get(constants.SAML_TOKEN_KEY);
            if (samlToken) {
                apiWrapperUtil.setupTokenPairByJWTGrantType(carbonUser.username + '@' + carbonUser.domain, samlToken);
            }
        }
        response.contentType = 'application/json';
    } finally {
        utility.endTenantFlow();
    }
}

// returning the result.
if (result) {
    print(result);
}
%>
