162 lines
6.2 KiB
C
Executable File
162 lines
6.2 KiB
C
Executable File
#ifndef AUTHMETHODS_H
|
|
#define AUTHMETHODS_H
|
|
|
|
#include <qhttpserverrequest.h>
|
|
#include <qhttpserverresponse.h>
|
|
#include <qcryptographichash.h>
|
|
#include <qjsondocument.h>
|
|
#include <QJsonObject>
|
|
#include <qsqldatabase.h>
|
|
#include <qsqlerror.h>
|
|
#include <qsqlquery.h>
|
|
#include <QUuid>
|
|
#include <QDateTime>
|
|
#include <QDebug>
|
|
|
|
QString hashPassword(const QString &password) {
|
|
return QString(QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Sha256).toHex());
|
|
}
|
|
|
|
QString generateToken() {
|
|
return QUuid::createUuid().toString(QUuid::WithoutBraces);
|
|
}
|
|
|
|
QHttpServerResponse login(const QJsonObject &json) {
|
|
QString username = json["username"].toString();
|
|
QString password = json["password"].toString();
|
|
|
|
QSqlDatabase db = QSqlDatabase::database();
|
|
|
|
QSqlQuery query(db);
|
|
|
|
query.prepare(QString("SELECT id, password FROM public.users WHERE username = '%1'").arg(username));
|
|
|
|
if (!query.exec() || !query.next()) {
|
|
QHttpServerResponse response("Invalid username or password", QHttpServerResponse::StatusCode::Unauthorized);
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE");
|
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
return response;
|
|
}
|
|
|
|
QString hashedPassword = query.value("password").toString();
|
|
|
|
if (hashedPassword != hashPassword(password)) {
|
|
QHttpServerResponse response("Invalid username or password", QHttpServerResponse::StatusCode::Unauthorized);
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE");
|
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
return response;
|
|
}
|
|
|
|
QString token = generateToken();
|
|
int userId = query.value("id").toInt();
|
|
QDateTime expiryDate = QDateTime::currentDateTimeUtc().addSecs(24 * 3600);
|
|
|
|
query.prepare("INSERT INTO public.tokens (user_id, token, expiry_date) VALUES (:user_id, :token, :expiry_date)");
|
|
query.bindValue(":user_id", userId);
|
|
query.bindValue(":token", token);
|
|
query.bindValue(":expiry_date", expiryDate);
|
|
|
|
if (!query.exec()) {
|
|
qDebug() << "Error inserting token";
|
|
QHttpServerResponse response("Token generation failed", QHttpServerResponse::StatusCode::InternalServerError);
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE");
|
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
return response;
|
|
}
|
|
|
|
QJsonObject jsonResponse;
|
|
jsonResponse["token"] = token;
|
|
QByteArray responseBody = QJsonDocument(jsonResponse).toJson();
|
|
|
|
QHttpServerResponse response(responseBody, QHttpServerResponse::StatusCode::Ok);
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE");
|
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
|
|
return response;
|
|
}
|
|
|
|
QHttpServerResponse loginUser(const QHttpServerRequest &request) {
|
|
auto body = request.body();
|
|
QJsonDocument jsonRequest = QJsonDocument::fromJson(body);
|
|
qDebug() << jsonRequest;
|
|
|
|
if (!jsonRequest.isObject()) {
|
|
QHttpServerResponse response("Invalid Request!", QHttpServerResponse::StatusCode::BadRequest);
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE");
|
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
return response;
|
|
}
|
|
|
|
return login(jsonRequest.object());
|
|
}
|
|
|
|
|
|
QHttpServerResponse checkAuth(const QString &token) {
|
|
QSqlDatabase db = QSqlDatabase::database();
|
|
QSqlQuery query(db);
|
|
|
|
query.prepare(QString("SELECT user_id, expiry_date FROM tokens WHERE token = :token"));
|
|
query.bindValue(":token", token);
|
|
|
|
if (!query.exec() || !query.next()) {
|
|
QHttpServerResponse response("Invalid token", QHttpServerResponse::StatusCode::Unauthorized);
|
|
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
return response;
|
|
}
|
|
|
|
QDateTime expiryDate = query.value("expiry_date").toDateTime();
|
|
if (QDateTime::currentDateTimeUtc() > expiryDate) {
|
|
QHttpServerResponse response("Token expired", QHttpServerResponse::StatusCode::Unauthorized);
|
|
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
return response;
|
|
}
|
|
|
|
QJsonObject jsonResponse;
|
|
jsonResponse["status"] = "Authenticated";
|
|
QHttpServerResponse response(QJsonDocument(jsonResponse).toJson(), QHttpServerResponse::StatusCode::Ok);
|
|
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
|
|
return response;
|
|
}
|
|
|
|
QHttpServerResponse authUser(const QHttpServerRequest &request) {
|
|
QList<QPair<QByteArray, QByteArray>> headers = request.headers();
|
|
QString token;
|
|
|
|
for (const auto &header : headers) {
|
|
if (header.first.toLower() == "authorization") {
|
|
QString authHeader = QString::fromUtf8(header.second);
|
|
if (authHeader.startsWith("Bearer ")) {
|
|
token = authHeader.mid(7);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (token.isEmpty()) {
|
|
QHttpServerResponse response("No token provided", QHttpServerResponse::StatusCode::Unauthorized);
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
return response;
|
|
}
|
|
|
|
return checkAuth(token);
|
|
}
|
|
|
|
#endif // AUTHMETHODS_H
|