mirror of
https://gitlab.com/niansa/discordlistforbots.git
synced 2025-03-06 20:49:22 +01:00
Implemented registering bots
This commit is contained in:
parent
72c0ab94a1
commit
1268fbe28b
9 changed files with 168 additions and 28 deletions
|
@ -66,3 +66,8 @@ foreach(file ${files})
|
|||
message("${file}: ${filename}")
|
||||
configure_file("${file}" "./${filename}" COPYONLY)
|
||||
endforeach()
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(format REQUIRED IMPORTED_TARGET fmt)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
PkgConfig::format)
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <fmt/core.h>
|
||||
#include <drogon/drogon.h>
|
||||
#include "../config.h"
|
||||
#include "views.h"
|
||||
|
@ -42,9 +46,27 @@ Bot deserializeBot(orm::Row row) {
|
|||
return thisbot;
|
||||
}
|
||||
|
||||
auto dbErr = [](const orm::DrogonDbException &e) {
|
||||
std::cerr << "Database error:" << e.base().what() << std::endl;
|
||||
};
|
||||
std::string dbEsc(const std::string& src) {
|
||||
std::ostringstream fres;
|
||||
for (const auto &character : src) {
|
||||
if (character == '\'') {
|
||||
fres << "''";
|
||||
} else {
|
||||
fres << character;
|
||||
}
|
||||
}
|
||||
return fres.str();
|
||||
}
|
||||
|
||||
auto dbErr = [](const orm::DrogonDbException &) {};
|
||||
|
||||
void LoginFilter::doFilter(const HttpRequestPtr &req, FilterCallback &&fcb, FilterChainCallback &&fccb) {
|
||||
if (req->session()->isAuthed()) {
|
||||
fccb();
|
||||
} else {
|
||||
authenticate(fcb);
|
||||
}
|
||||
}
|
||||
|
||||
void views::botlist(
|
||||
const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback
|
||||
|
@ -54,9 +76,6 @@ void views::botlist(
|
|||
auto authed = session->isAuthed();
|
||||
auto justMine = req->getPath()=="/bots/@me";
|
||||
auto modView = req->getPath()=="/bots/@unapproved";
|
||||
if (justMine and not authed) {
|
||||
authenticate(callback);
|
||||
}
|
||||
|
||||
std::string q = "SELECT * FROM bots WHERE ";
|
||||
if (justMine) {
|
||||
|
@ -113,10 +132,6 @@ void views::botdetail(
|
|||
void views::botvote(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback,
|
||||
uint64_t bot_id) {
|
||||
auto session = req->session();
|
||||
// Check if user is authenticated
|
||||
if (not session->isAuthed()) {
|
||||
authenticate(callback);
|
||||
}
|
||||
// Check if user is able to vote again
|
||||
auto user_id = session->get<uint64_t>("discord_user_id");
|
||||
auto vote_id = voteID(user_id, bot_id);
|
||||
|
@ -138,6 +153,49 @@ void views::botvote(const HttpRequestPtr& req, std::function<void (const HttpRes
|
|||
}, dbErr);
|
||||
}
|
||||
|
||||
void views::botregister_view(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback
|
||||
) {
|
||||
auto session = req->session();
|
||||
// Display page
|
||||
HttpViewData data;
|
||||
data.insert("owner", session->get<std::string>("discord_user_fullname"));
|
||||
|
||||
callback(HttpResponse::newHttpViewResponse("botregister.csp", data));
|
||||
}
|
||||
void views::botregister_submit(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback
|
||||
) {
|
||||
auto session = req->session();
|
||||
// Get and check parameters
|
||||
auto onError = [callback] (const std::exception& e) {
|
||||
HttpViewData data;
|
||||
data.insert("message", e.what());
|
||||
|
||||
auto resp = HttpResponse::newHttpViewResponse("exception.csp", data);
|
||||
resp->setStatusCode(HttpStatusCode::k500InternalServerError);
|
||||
callback(resp);
|
||||
};
|
||||
try {
|
||||
auto name = req->getParameter("name");
|
||||
auto short_description = req->getParameter("short_description");
|
||||
auto long_description = req->getParameter("long_description");
|
||||
auto avatar_url = req->getParameter("avatar_url");
|
||||
auto support_server = req->getParameter("support_server");
|
||||
auto prefix = req->getParameter("prefix");
|
||||
auto app_id = std::stoul(req->getParameter("app_id"));
|
||||
// Perform database operation
|
||||
db->execSqlAsync(fmt::format("INSERT INTO bots (name, short_description, long_description, avatar_url, owner, support_server, prefix, owner_id, app_id, votes, approved) "
|
||||
"VALUES('{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', 0, 'f')",
|
||||
dbEsc(name), dbEsc(short_description), dbEsc(long_description), dbEsc(avatar_url), session->get<std::string>("discord_user_fullname"), dbEsc(support_server), dbEsc(prefix), session->get<uint64_t>("discord_user_id"), app_id),
|
||||
[app_id, callback] (const orm::Result &) {
|
||||
callback(HttpResponse::newRedirectionResponse(std::to_string(app_id)+"/detail"));
|
||||
}, [onError] (const orm::DrogonDbException &e) {
|
||||
onError(e.base());
|
||||
});
|
||||
} catch (std::exception& e) {
|
||||
onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
void views::discorddeauth(
|
||||
const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback
|
||||
) {
|
||||
|
|
|
@ -10,6 +10,14 @@ struct Bot {
|
|||
bool approved = false;
|
||||
};
|
||||
|
||||
class LoginFilter:public drogon::HttpFilter<LoginFilter>
|
||||
{
|
||||
public:
|
||||
virtual void doFilter(const drogon::HttpRequestPtr &,
|
||||
drogon::FilterCallback &&,
|
||||
drogon::FilterChainCallback &&) override;
|
||||
};
|
||||
|
||||
using namespace drogon;
|
||||
class views: public drogon::HttpController<views> {
|
||||
orm::DbClientPtr db;
|
||||
|
@ -19,15 +27,19 @@ public:
|
|||
void botlist(const HttpRequestPtr&, std::function<void (const HttpResponsePtr &)> &&);
|
||||
void botdetail(const HttpRequestPtr&, std::function<void (const HttpResponsePtr &)> &&, uint64_t);
|
||||
void botvote(const HttpRequestPtr&, std::function<void (const HttpResponsePtr &)> &&, uint64_t);
|
||||
void botregister_view(const HttpRequestPtr&, std::function<void (const HttpResponsePtr &)> &&);
|
||||
void botregister_submit(const HttpRequestPtr&, std::function<void (const HttpResponsePtr &)> &&);
|
||||
void discordauth(const HttpRequestPtr&, std::function<void (const HttpResponsePtr &)> &&, const std::string&);
|
||||
void discorddeauth(const HttpRequestPtr&, std::function<void (const HttpResponsePtr &)> &&);
|
||||
|
||||
METHOD_LIST_BEGIN
|
||||
ADD_METHOD_TO(views::start, "/", Get);
|
||||
ADD_METHOD_TO(views::botlist, "/bots/@all", Get);
|
||||
ADD_METHOD_TO(views::botlist, "/bots/@me", Get);
|
||||
ADD_METHOD_TO(views::botlist, "/bots/@me", Get, "LoginFilter");
|
||||
ADD_METHOD_TO(views::botregister_view, "/bots/register", Get, "LoginFilter");
|
||||
ADD_METHOD_TO(views::botregister_submit, "/bots/register", Post, "LoginFilter");
|
||||
ADD_METHOD_TO(views::botdetail, "/bots/{1}/detail", Get);
|
||||
ADD_METHOD_TO(views::botvote, "/bots/{1}/vote", Get);
|
||||
ADD_METHOD_TO(views::botvote, "/bots/{1}/vote", Get, "LoginFilter");
|
||||
ADD_METHOD_TO(views::discordauth, "/discordauth?code={1}", Get);
|
||||
ADD_METHOD_TO(views::discorddeauth, "/discorddeauth", Get);
|
||||
METHOD_LIST_END
|
||||
|
|
|
@ -15,28 +15,36 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.linkButton {
|
||||
[class*="special-"] {
|
||||
background-color:transparent;
|
||||
border-radius:4px;
|
||||
border:2px solid #ffffff;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
color:#ffffff;
|
||||
font-family:Arial;
|
||||
font-size:15px;
|
||||
text-align:center;
|
||||
padding:9px 23px;
|
||||
text-decoration:none;
|
||||
text-shadow:0px 0px 11px #263666;
|
||||
margin:10px;
|
||||
}
|
||||
.linkButton:hover {
|
||||
|
||||
.special-input {
|
||||
cursor:text;
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
.special-button {
|
||||
cursor:pointer;
|
||||
text-align:center;
|
||||
}
|
||||
.special-button:hover {
|
||||
background-color: #fff;
|
||||
color: #263666;
|
||||
text-shadow: 0px;
|
||||
transform: scale(1.03);
|
||||
}
|
||||
.linkButton:active {
|
||||
.special-button:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
|
@ -48,3 +56,7 @@ body {
|
|||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.maxwidth {
|
||||
width:100%;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
<%inc#include "controllers/views.h" %>
|
||||
<%c++ auto fullname = @@.get<std::string>("fullname");%>
|
||||
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
</div>
|
||||
<div class="actionsWrapper">
|
||||
<div class="actions">
|
||||
<a class="linkButton" href="https://discord.com/oauth2/authorize?client_id={%bot_id%}&permissions=8&scope=applications.commands%20bot">Invite</a>
|
||||
<a class="linkButton" {%(canVote?"href='vote'":"href='#' style='color:grey;'")%}>Vote</a>
|
||||
<a class="special-button" href="https://discord.com/oauth2/authorize?client_id={%bot_id%}&permissions=8&scope=applications.commands%20bot">Invite</a>
|
||||
<a class="special-button" {%(canVote?"href='vote'":"href='#' style='color:grey;'")%}>Vote</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -54,7 +54,7 @@
|
|||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<a class="linkButton" style="margin:0px;" href="https://discord.gg/{%bot.support_server%}">Support Server</a>
|
||||
<a class="special-button" style="margin:0px;" href="https://discord.gg/{%bot.support_server%}">Support Server</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<%inc#include "controllers/views.h" %>
|
||||
<%c++ auto viewHidden = @@.get<bool>("viewHidden");%>
|
||||
<%c++ auto modView = @@.get<bool>("modView");%>
|
||||
<%c++ auto justMine = @@.get<bool>("justMine");%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
@ -16,19 +16,19 @@
|
|||
<p>Find a lot of bots that will be useful to your server</p>
|
||||
<%c++ if (@@.get<bool>("authed")) {%>
|
||||
<%c++ if (justMine) {%>
|
||||
<a class="linkButton" href="@all">All bots</a>
|
||||
<a class="special-button" href="@all">All bots</a>
|
||||
<%c++ } else {%>
|
||||
<a class="linkButton" href="@me">My bots</a>
|
||||
<a class="special-button" href="@me">My bots</a>
|
||||
<%c++ }%>
|
||||
<a class="linkButton" href="/discorddeauth">Logout</a>
|
||||
<a class="special-button" href="register">Register bot</a>
|
||||
<a class="special-button" href="/discorddeauth">Logout</a>
|
||||
<%c++ } else {%>
|
||||
<a class="linkButton" href="/discordauth">Login</a>
|
||||
<a class="special-button" href="/discordauth">Login</a>
|
||||
<%c++ }%>
|
||||
<hr>
|
||||
<br>
|
||||
<%c++ for (const auto& [bot_id, bot] : @@.get<std::map<uint64_t, Bot>>("bots")) {%>
|
||||
<%c++ if (bot.approved == viewHidden) continue;%>
|
||||
<a class="linkButton" href="{%bot_id%}/detail">
|
||||
<a class="special-button" href="{%bot_id%}/detail" {%(bot.approved?"":"style='background-color:red;'")%}>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
|
@ -37,6 +37,9 @@
|
|||
<td style="padding:10px;">
|
||||
<h1 style="line-height:0px;">{%bot.name%}</h1>
|
||||
<p>{%bot.short_description%}</p>
|
||||
<%c++ if (not bot.approved) {%>
|
||||
<i>Not yet approved</i>
|
||||
<%c++ }%>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
31
views/botregister.csp
Normal file
31
views/botregister.csp
Normal file
|
@ -0,0 +1,31 @@
|
|||
<%c++ auto owner = @@.get<std::string>("owner");%>
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/global.css">
|
||||
<title>Registering a bot - DFB</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<form action="register" method="POST">
|
||||
<p class="title text-center">Registering a bot</p>
|
||||
<p>Name</p><input class="special-input maxwidth" name="name" maxlength="10" required autofocus>
|
||||
<p>Owner</p><input class="special-input maxwidth" value="{%owner%}" autocomplete="off" disabled>
|
||||
<p>Avatar URL</p><input type="url" class="special-input maxwidth" name="avatar_url" required>
|
||||
<p>Short description</p><input class="special-input maxwidth" name="short_description" maxlength="36" required>
|
||||
<p>Long description</p><textarea class="special-input maxwidth" name="long_description" style="height:200px;" required></textarea>
|
||||
<p>Prefix</p><input class="special-input maxwidth" name="prefix" maxlength="6" required>
|
||||
<p>Permanent support server invite code</p><input class="special-input maxwidth" name="support_server" maxlength="15" minlength="5" required>
|
||||
<p>Client ID</p><input tyep="number" class="special-input maxwidth" name="app_id" maxlength="19" minlength="17" pattern="^[0-9]+$" required>
|
||||
<br><br><br>
|
||||
<input type="submit" class="special-button" style="margin:0px;" value="Submit">
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
20
views/exception.csp
Normal file
20
views/exception.csp
Normal file
|
@ -0,0 +1,20 @@
|
|||
<%c++ auto message = @@.get<const char *>("message");%>
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/global.css">
|
||||
<title>Exception - DFB</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container text-center">
|
||||
<p class="title text-center">An exception has occured</p>
|
||||
<p>{%message%}</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Add table
Reference in a new issue