Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

A simple authentication mechanism drogon

The encryption is temporary.
I have a quite unreadable error with all the instances execSqlAsync function.

The error is:

In template: invalid operands to binary expression ('std::stringstream' (aka 'basic_stringstream<char>') and 'std::exception') error occurred here in instantiation of function template specialization 'drogon::orm::Field::as<std::exception>' requested here in instantiation of function template specialization 'drogon::orm::internal::CallbackHolder<(lambda at /Users/<br>
41:13)>::makeValue<std::exception>' requested here in instantiation of function template specialization 'drogon::orm::internal::CallbackHolder<(lambda at /Users/
<br>
41:13)>::run<1UL>' requested here in instantiation of function template specialization 'drogon::orm::internal::CallbackHolder<(lambda at <br>
41:13)>::run<true>' requested here in instantiation of member function 'drogon::orm::internal::CallbackHolder<(lambda at /Users/<br>
41:13)>::execCallback' requested here in instantiation of function template specialization 'drogon::orm::internal::CallbackHolder<(lambda at /Users/<br>
41:13)>::CallbackHolder<(lambda at patr... in instantiation of function template specialization 'drogon::orm::internal::SqlBinder::operator>><(lambda at 
<br>
 server/AuthController.cpp:41:13), drogon::orm::internal::FunctionTraits<(lambda at /U... in instantiation of function template specialization 'drogon::orm::DbClient::execSqlAsync<(lambda at <br> server/AuthController.cpp:35:13), (lambda at /<br> server/A... candidate template ignored: deduced conflicting types for parameter '_CharT' ('char' vs. 'std::exception') candidate template ignored: could not match 'uniform_int_distribution<_IT>' against 'std::exception' candidate template ignored: could not match '_CharT[_Np]' against 'std::exception' candidate template ignored: could not match 'unsigned char[_Np]' against 'std::exception' candidate template ignored: could not match 'signed char[_Np]' against 'std::exception' candidate template ignored: could not match 'basic_string<_CharT, _Traits, _Allocator>' against 'std::exception' candidate template ignored: could not match 'bitset<_Size>' against 'std::exception' candidate template ignored: requirement 'integral_constant<bool, false>::value' was not satisfied [with _Stream = std::stringstream &, _Tp = std::exception &] candidate template ignored: could not match '__iom_t7<_MoneyT>' against 'std::exception' candidate template ignored: could not match '__iom_t9<_CharT>' against 'std::exception'

And here is the code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#include "AuthController.h"
#include <drogon/drogon.h>
#include <drogon/orm/DbClient.h>
#include <algorithm>

using namespace drogon;
using namespace drogon::orm;

// Simple Caesar Cipher function
std::string caesarCipher(const std::string& text, int shift) {
    std::string result = text;
    std::transform(result.begin(), result.end(), result.begin(),
                   [shift](char c) -> char {
                       if (c >= 'a' && c <= 'z')
                           return 'a' + (c - 'a' + shift) % 26;
                       else if (c >= 'A' && c <= 'Z')
                           return 'A' + (c - 'A' + shift) % 26;
                       else
                           return c;
                   });
    return result;
}

void AuthController::signup(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) {
    auto json = req->getJsonObject();
    std::string username = json->get("username", "").asString();
    std::string password = json->get("password", "").asString();

    // Encrypt the password using Caesar cipher
    std::string encryptedPassword = caesarCipher(password, 3);

    auto client = drogon::app().getDbClient().get();
    client->execSqlAsync(
            "INSERT INTO users (username, password_hash) VALUES ($1, $2)",
            [callback](const Result &result) {
                auto response = HttpResponse::newHttpResponse();
                response->setStatusCode(HttpStatusCode::k200OK);
                response->setBody("Signup successful");
                callback(response);
            },
            [callback](const std::exception &e) {  // Correct exception handling
                auto response = HttpResponse::newHttpResponse();
                response->setStatusCode(HttpStatusCode::k500InternalServerError);
                response->setBody(e.what());
                callback(response);
            },
            username, encryptedPassword);
}

void AuthController::login(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) {
    auto json = req->getJsonObject();
    std::string username = json->get("username", "").asString();
    std::string password = json->get("password", "").asString();

    auto client = drogon::app().getDbClient();
    client.get()->execSqlAsync(
            "SELECT password_hash FROM users WHERE username = $1",
            [password, callback](const Result &result) {
                std::shared_ptr<HttpResponse> response;
                if (!result.empty()) {
                    std::string storedHash = result[0]["password_hash"].as<std::string>();
                    std::string decryptedPassword = caesarCipher(storedHash, -3);
                    if (decryptedPassword == password) {
                        response = HttpResponse::newHttpResponse();
                        response->setStatusCode(k200OK);
                        response->setBody("Login successful");
                    } else {
                        response = HttpResponse::newHttpResponse();
                        response->setStatusCode(k401Unauthorized);
                        response->setBody("Login failed");
                    }
                } else {
                    response = HttpResponse::newHttpResponse();
                    response->setStatusCode(k401Unauthorized);
                    response->setBody("User not found");
                }
                callback(response);
            },
            [callback](const std::exception &e) {
                auto resp = HttpResponse::newHttpResponse();
                resp->setStatusCode(k500InternalServerError);
                resp->setBody(e.what());
                callback(resp);
            },
            username);
}

>Solution :

Remember to post link to library you are using.

After I was able to google this library and inspecting documentation solution is clear:

ENG 08 1 Database DbClient · drogonframework/drogon Wiki · GitHub

After the execution of sql is successful, the execution result is wrapped by the Result class and passed to the user through the result callback function; if there is any exception in the sql execution, the exception callback function is executed, and the user can obtain the exception information from the DrogonDbException object.

Let us give an example:

clientPtr->execSqlAsync("select * from users where org_name=$1",
                            [](const drogon::orm::Result &result) {
                                std::cout << result.size() << " rows selected!" << std::endl;
                                int i = 0;
                                for (auto row : result)
                                {
                                    std::cout << i++ << ": user name is " << row["user_name"].as<std::string>() << std::endl;
                                }
                            },
                            [](const DrogonDbException &e) {
                                std::cerr << "error:" << e.base().what() << std::endl;
                            },
                            "default");

so you should your code this way:

            [callback](const DrogonDbException &e) {  // Correct exception handling
                auto response = HttpResponse::newHttpResponse();
                response->setStatusCode(HttpStatusCode::k500InternalServerError);
                response->setBody(e.base().what());
                callback(response);
            },
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading