<commit_before>/*
 * httpServer.cpp
 *   Code to handle the REST API
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * Permission to use, modify and distribute is granted via the
 *  GNU Affero General Public License v3 or later
 *
 *  Copyright (C) 2007-2021 <NAME>, <NAME>
 *     Contributions by <NAME>, <NAME>
 *  Based on Mordor (C) <NAME>, <NAME>, <NAME>
 *
 */

#include <thread>

#include <crow.h>
#include <nlohmann/json.hpp>
#include <fmt/format.h>
#include <jwt-cpp/jwt.h>

#include "config.hpp"
#include "httpServer.hpp"
#include "server.hpp"
#include "version.hpp"
#include "quests.hpp"
#include "proto.hpp"                // for lowercize
#include "mudObjects/players.hpp"   // for Player
#include "xml.hpp"                  // for loadPlayer

using json = nlohmann::json;

bool Server::initHttpServer() {
    httpServer = new HttpServer(8080);
    return true;
}

void Server::cleanupHttpServer() {
    delete httpServer;
}


HttpServer::HttpServer(int pPort) {
    app.signal_clear();
    port = pPort;

    CROW_ROUTE(app, "/version").methods("GET"_method)
        ([](const crow::request& req){
            json j;
            j["status"] = 200;  
            j["version"] = VERSION;
            j["lastCompiled"] = fmt::format("{} {}", __DATE__, __TIME__);
            return to_string(j);
        });

    CROW_ROUTE(app, "/authtest").methods("GET"_method)
    .CROW_MIDDLEWARES(app, AuthMiddleware)
        ([](const crow::request& req){
            json j;
            j["status"] = 200;  
            j["version"] = VERSION;
            j["lastCompiled"] = fmt::format("{} {}", __DATE__, __TIME__);
            return to_string(j);
        });

    CROW_ROUTE(app, "/login").methods("POST"_method)
        ([](const crow::request& req){
            json j;
            auto body = crow::json::load(req.body);
            std::string name = std::string(body["name"]);
            std::string pw = std::string(body["pw"]);
            lowercize(name, 1);

            if (!body) {
                return crow::response(crow::status::BAD_REQUEST);
            }

            Player *player = nullptr;
            if (!loadPlayer(name, &player)) {
                return crow::response(crow::status::NOT_FOUND);
            }

            if (!player->isPassword(pw)) {
                return crow::response(crow::status::UNAUTHORIZED);
            }

            j["token"] = jwt::create()
                .set_issuer("realms")
                .set_payload_claim("id", jwt::claim(player->getId()))
                .sign(jwt::algorithm::hs256{"not a real secret, replace me"});
            return crow::response(to_string(j));
        });

    CROW_ROUTE(app, "/zones/<string>/quests/<int>").methods("GET"_method)
            ([](const crow::request& req, std::string zone, int Id){
                auto questId = CatRef(zone, (short)Id);
                auto quest = gConfig->getQuest(questId);
                if(quest == nullptr) {
                    json j;
                    j["status"] = 404;
                    j["message"] = "quest not found";
                    return to_string(j);
                }

                json questOverview = json(*quest);
                return to_string(questOverview);
            });

    CROW_ROUTE(app, "/zones/<string>/quests").methods("GET"_method)
            ([](const crow::request& req, std::string zone){
                return "not implemented";
            });
}
<commit_msg>Don't leak the player<commit_after>/*
 * httpServer.cpp
 *   Code to handle the REST API
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * Permission to use, modify and distribute is granted via the
 *  GNU Affero General Public License v3 or later
 *
 *  Copyright (C) 2007-2021 <NAME>, <NAME>
 *     Contributions by <NAME>, <NAME>
 *  Based on Mordor (C) <NAME>, <NAME>, <NAME>
 *
 */

#include <thread>

#include <crow.h>
#include <nlohmann/json.hpp>
#include <fmt/format.h>
#include <jwt-cpp/jwt.h>

#include "config.hpp"
#include "httpServer.hpp"
#include "server.hpp"
#include "version.hpp"
#include "quests.hpp"
#include "proto.hpp"                // for lowercize
#include "mudObjects/players.hpp"   // for Player
#include "xml.hpp"                  // for loadPlayer

using json = nlohmann::json;

bool Server::initHttpServer() {
    httpServer = new HttpServer(8080);
    return true;
}

void Server::cleanupHttpServer() {
    delete httpServer;
}


HttpServer::HttpServer(int pPort) {
    app.signal_clear();
    port = pPort;

    CROW_ROUTE(app, "/version").methods("GET"_method)
        ([](const crow::request& req){
            json j;
            j["status"] = 200;  
            j["version"] = VERSION;
            j["lastCompiled"] = fmt::format("{} {}", __DATE__, __TIME__);
            return to_string(j);
        });

    CROW_ROUTE(app, "/authtest").methods("GET"_method)
    .CROW_MIDDLEWARES(app, AuthMiddleware)
        ([](const crow::request& req){
            json j;
            j["status"] = 200;  
            j["version"] = VERSION;
            j["lastCompiled"] = fmt::format("{} {}", __DATE__, __TIME__);
            return to_string(j);
        });

    CROW_ROUTE(app, "/login").methods("POST"_method)
        ([](const crow::request& req){
            json body = json::parse(req.body);

            std::string name = body["name"];
            std::string pw = body["pw"];
            lowercize(name, 1);
            bool offline = false, valid=false;

            // TODO: Thread Saftey
            Player *player = gServer->findPlayer(name);
            if(!player) {
                if (!loadPlayer(name, &player)) {
                    return crow::response(crow::status::NOT_FOUND);
                }
                offline = true;
            }

            json j;
            if (player->isPassword(pw)) {
                valid = true;
                j["token"] = jwt::create()
                        .set_issuer("realms")
                        .set_payload_claim("id", jwt::claim(player->getId()))
                        .sign(jwt::algorithm::hs256{"not a real secret, replace me"});
            }

            if(offline)
                free_crt(player, false);

            if(!valid)
                return crow::response(crow::status::UNAUTHORIZED);

            return crow::response(to_string(j));
        });

    CROW_ROUTE(app, "/zones/<string>/quests/<int>").methods("GET"_method)
            ([](const crow::request& req, std::string zone, int Id){
                auto questId = CatRef(zone, (short)Id);
                auto quest = gConfig->getQuest(questId);
                if(quest == nullptr) {
                    json j;
                    j["status"] = 404;
                    j["message"] = "quest not found";
                    return to_string(j);
                }

                json questOverview = json(*quest);
                return to_string(questOverview);
            });

    CROW_ROUTE(app, "/zones/<string>/quests").methods("GET"_method)
            ([](const crow::request& req, std::string zone){
                return "not implemented";
            });
}

{'fraction_non_alphanumeric': 0.15836612837562764, 'fraction_numerical': 0.007056588410910571, 'mean_word_length': 1.8867998433215825, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6305500', 'n_tokens_mistral': 2379, 'n_tokens_neox': 2248, 'n_words': 453}