-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed the header names bug, and started working on the demo site
- Loading branch information
1 parent
f5df92a
commit fbd0d3f
Showing
67 changed files
with
275,622 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -143,3 +143,4 @@ _deps | |
|
||
# End of https://www.gitignore.io/api/c++,cmake,clion | ||
|
||
.vs/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
|
||
# Created by https://www.gitignore.io/api/c++,cmake,clion | ||
# Edit at https://www.gitignore.io/?templates=c++,cmake,clion | ||
|
||
### C++ ### | ||
# Prerequisites | ||
*.d | ||
|
||
# Compiled Object files | ||
*.slo | ||
*.lo | ||
*.o | ||
*.obj | ||
|
||
# Precompiled Headers | ||
*.gch | ||
*.pch | ||
|
||
# Compiled Dynamic libraries | ||
*.so | ||
*.dylib | ||
*.dll | ||
|
||
# Fortran module files | ||
*.mod | ||
*.smod | ||
|
||
# Compiled Static libraries | ||
*.lai | ||
*.la | ||
*.a | ||
*.lib | ||
|
||
# Executables | ||
*.exe | ||
*.out | ||
*.app | ||
|
||
### CLion ### | ||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm | ||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
|
||
# User-specific stuff | ||
.idea/**/workspace.xml | ||
.idea/**/tasks.xml | ||
.idea/**/usage.statistics.xml | ||
.idea/**/dictionaries | ||
.idea/**/shelf | ||
|
||
# Generated files | ||
.idea/**/contentModel.xml | ||
|
||
# Sensitive or high-churn files | ||
.idea/**/dataSources/ | ||
.idea/**/dataSources.ids | ||
.idea/**/dataSources.local.xml | ||
.idea/**/sqlDataSources.xml | ||
.idea/**/dynamic.xml | ||
.idea/**/uiDesigner.xml | ||
.idea/**/dbnavigator.xml | ||
|
||
# Gradle | ||
.idea/**/gradle.xml | ||
.idea/**/libraries | ||
.idea/** | ||
# Gradle and Maven with auto-import | ||
# When using Gradle or Maven with auto-import, you should exclude module files, | ||
# since they will be recreated, and may cause churn. Uncomment if using | ||
# auto-import. | ||
# .idea/modules.xml | ||
# .idea/*.iml | ||
# .idea/modules | ||
# *.iml | ||
# *.ipr | ||
|
||
# CMake | ||
cmake-build-*/ | ||
|
||
# Mongo Explorer plugin | ||
.idea/**/mongoSettings.xml | ||
|
||
# File-based project format | ||
*.iws | ||
|
||
# IntelliJ | ||
out/ | ||
|
||
# mpeltonen/sbt-idea plugin | ||
.idea_modules/ | ||
|
||
# JIRA plugin | ||
atlassian-ide-plugin.xml | ||
|
||
# Cursive Clojure plugin | ||
.idea/replstate.xml | ||
|
||
# Crashlytics plugin (for Android Studio and IntelliJ) | ||
com_crashlytics_export_strings.xml | ||
crashlytics.properties | ||
crashlytics-build.properties | ||
fabric.properties | ||
|
||
# Editor-based Rest Client | ||
.idea/httpRequests | ||
|
||
# Android studio 3.1+ serialized cache file | ||
.idea/caches/build_file_checksums.ser | ||
|
||
### CLion Patch ### | ||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 | ||
|
||
# *.iml | ||
# modules.xml | ||
# .idea/misc.xml | ||
# *.ipr | ||
|
||
# Sonarlint plugin | ||
.idea/**/sonarlint/ | ||
|
||
# SonarQube Plugin | ||
.idea/**/sonarIssues.xml | ||
|
||
# Markdown Navigator plugin | ||
.idea/**/markdown-navigator.xml | ||
.idea/**/markdown-navigator/ | ||
|
||
### CMake ### | ||
CMakeLists.txt.user | ||
CMakeCache.txt | ||
CMakeFiles | ||
CMakeScripts | ||
Testing | ||
Makefile | ||
cmake_install.cmake | ||
install_manifest.txt | ||
compile_commands.json | ||
CTestTestfile.cmake | ||
_deps | ||
|
||
### CMake Patch ### | ||
# External projects | ||
*-prefix/ | ||
|
||
# End of https://www.gitignore.io/api/c++,cmake,clion | ||
|
||
.vs/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,185 @@ | ||
#include <chttp/CHttp.h> | ||
#include <iostream> | ||
#include <chttp/CHttp.h> | ||
#include <SQLiteCpp/SQLiteCpp.h> | ||
#include <json.hpp> | ||
|
||
|
||
struct blogPostJSON { | ||
int id{}; | ||
std::string title; | ||
std::string body; | ||
}; | ||
|
||
void to_json(nlohmann::json& j, const blogPostJSON& p) { | ||
j = nlohmann::json{{"title", p.title}, {"body", p.body}, {"id", p.id}}; | ||
} | ||
|
||
void from_json(const nlohmann::json& j, blogPostJSON& p) { | ||
j.at("id").get_to(p.id); | ||
j.at("title").get_to(p.title); | ||
j.at("body").get_to(p.body); | ||
} | ||
|
||
void CreateTables(SQLite::Database &db) { | ||
db.exec("CREATE TABLE IF NOT EXISTS users(id integer primary key, username char(20), password text)"); | ||
db.exec("CREATE TABLE IF NOT EXISTS posts(id integer primary key, publisher_id integer,post_title text, post_content TEXT, foreign key(publisher_id) references users(id))"); | ||
} | ||
|
||
void Signup(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) { | ||
// if(req->) TODO write a function to return one header | ||
nlohmann::json body = nlohmann::json::parse(dynamic_cast<PostRequest *>(req.get())->GetBody()); | ||
std::string username = body["username"].get<std::string>(); | ||
std::string password = body["password"].get<std::string>(); | ||
nlohmann::json responseBody; | ||
try { | ||
SQLite::Database db("exampleBlogDB.db"); | ||
SQLite::Statement insertNewUser(db, "insert into users(username, password) values (?,?)"); | ||
insertNewUser.bind(1, username); | ||
insertNewUser.bind(2, password); | ||
while (insertNewUser.executeStep()) { | ||
responseBody["id"] = db.getLastInsertRowid(); | ||
} | ||
resp->AddCookie("Auth", responseBody.dump()); | ||
} catch (std::exception &e) { | ||
responseBody["error"] = "Unable to create a new user!"; | ||
resp->SetStatus(Unauthorized); | ||
} | ||
resp->Header("Content-Type", "application/json"); | ||
resp->Raw(responseBody.dump()); | ||
} | ||
|
||
void form(std::shared_ptr<HttpRequest> rq, std::shared_ptr<HttpResponse> rs) { | ||
auto b = ((PostRequest *)rq.get())->GetBody(); | ||
auto ct = rq->GetHeaders()["Content-Type"]; | ||
MultipartField mp(b, ct); | ||
auto data = mp.getData(); | ||
std::string res = std::string(data.begin(), data.end()) + " to you too"; | ||
rs->Raw(std::vector<char>(res.begin(), res.end())); | ||
void usersMe(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) { | ||
resp->Header("Content-Type", "application/json"); | ||
CookieJar jar(req->GetHeaders()["cookie"]); | ||
resp->Raw(jar.GetCookieValue("Auth")); | ||
} | ||
|
||
void Logout(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) { | ||
resp->RemoveCookie("Auth"); | ||
resp->Raw("ok"); | ||
} | ||
|
||
void Login(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) { | ||
nlohmann::json body = nlohmann::json::parse(dynamic_cast<PostRequest *>(req.get())->GetBody()); | ||
nlohmann::json responseBody; | ||
responseBody["error"] = "Invalid credentials"; | ||
resp->SetStatus(Unauthorized); | ||
std::string username = body["username"].get<std::string>(); | ||
std::string password = body["password"].get<std::string>(); | ||
|
||
try { | ||
SQLite::Database db("exampleBlogDB.db"); | ||
SQLite::Statement stmt(db, "select id from users where username = ? and password = ?"); | ||
stmt.bind(1, username); | ||
stmt.bind(2, password); | ||
while (stmt.executeStep()) { | ||
if (responseBody.contains("error")) { | ||
responseBody.clear(); | ||
} | ||
responseBody["UID"] = std::stoi(stmt.getColumn("id")); | ||
} | ||
if (!responseBody.contains("error")) { | ||
resp->SetStatus(OK); | ||
resp->AddCookie("Auth", responseBody.dump()); | ||
} | ||
} catch (...) { | ||
resp->SetStatus(Internal_Server_Error); | ||
responseBody["error"] = "Something went wrong"; | ||
} | ||
resp->Header("Content-Type", "application/json"); | ||
resp->Raw(responseBody.dump()); | ||
} | ||
|
||
void CreatePost(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) { | ||
CookieJar cookies(req->GetHeaders()["cookie"]); | ||
nlohmann::json respBody; | ||
if (cookies.IsInJar("Auth")) { | ||
try { | ||
nlohmann::json cookieBody = nlohmann::json::parse(cookies.GetCookieValue("Auth")); | ||
SQLite::Database db("exampleBlogDB.db", SQLite::OPEN_READWRITE); | ||
SQLite::Statement isUser(db, "select count(*) as count from users where id=?"); | ||
bool isLoggedIn = false; | ||
int tmp = cookieBody["UID"].get<int>(); | ||
isUser.bind(1, tmp); | ||
while (isUser.executeStep()) { | ||
tmp = isUser.getColumn("count"); | ||
if (tmp != 0) { | ||
isLoggedIn = true; | ||
} | ||
} | ||
if (isLoggedIn) { | ||
SQLite::Statement insertPost(db, | ||
"insert into posts(publisher_id, post_title, post_content) values (?,?,?)"); | ||
tmp = cookieBody["UID"].get<int>(); | ||
insertPost.bind(1, tmp); | ||
nlohmann::json requestBody = nlohmann::json::parse(dynamic_cast<PostRequest *>(req.get())->GetBody()); | ||
std::string requestTmp = requestBody["title"].get<std::string>(); | ||
insertPost.bind(2, requestTmp); | ||
requestTmp = requestBody["body"].get<std::string>(); | ||
insertPost.bind(3, requestTmp); | ||
insertPost.exec(); | ||
respBody["id"] = db.getLastInsertRowid(); | ||
} else { | ||
respBody["error"] = "You are not allowed to do that"; | ||
resp->SetStatus(Unauthorized); | ||
} | ||
} catch (std::exception &e) { | ||
std::cerr << e.what() << std::endl; | ||
respBody["error"] = "Something went wrong!"; | ||
resp->SetStatus(Internal_Server_Error); | ||
} | ||
} else { | ||
respBody["error"] = "You are not allowed to do that"; | ||
resp->SetStatus(Unauthorized); | ||
} | ||
resp->Header("Content-Type", "application/json"); | ||
resp->Raw(respBody.dump()); | ||
} | ||
|
||
void AllPosts(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp){ | ||
nlohmann::json responseBody; | ||
try{ | ||
SQLite::Database db("exampleBlogDB.db"); | ||
SQLite::Statement allPosts(db, "select posts.post_content, posts.post_title, posts.id, users.username from posts join users on publisher_id=users.id"); | ||
nlohmann::json postsJSON = nlohmann::json::array(); | ||
blogPostJSON postTmp; | ||
std::string titleTmp; | ||
std::vector<blogPostJSON> posts; | ||
while(allPosts.executeStep()){ | ||
postTmp.body = allPosts.getColumn(0).getString(); | ||
titleTmp = allPosts.getColumn(1).getString(); | ||
titleTmp += " - " + allPosts.getColumn(3).getString(); | ||
postTmp.title = titleTmp; | ||
postTmp.id = allPosts.getColumn(2).getInt(); | ||
posts.push_back(postTmp); | ||
} | ||
postsJSON = nlohmann::json(posts); | ||
responseBody["posts"] = postsJSON; | ||
}catch(std::exception &e){ | ||
std::cerr << e.what() << std::endl; | ||
resp->SetStatus(Not_Found); | ||
responseBody["error"] = "Unable to fetch posts"; | ||
} | ||
resp->Header("Content-Type", "application/json"); | ||
resp->Raw(responseBody.dump()); | ||
} | ||
|
||
|
||
int main(int argc, char **argv) { | ||
int port = 8080; | ||
Server app; | ||
app.Post("/form", form, {}); | ||
app.ServeStaticFolder("/", "/home/themiper/chttp/examples/public/"); | ||
app.Run(port); | ||
int port = 8081; | ||
if (argc == 2) { | ||
port = std::stoi(argv[1]); | ||
} | ||
{ | ||
SQLite::Database dbHandler("exampleBlogDB.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); | ||
CreateTables(dbHandler); | ||
} | ||
Server server; | ||
server.Post("/api/v1/signup", Signup, {}); | ||
server.Post("/api/v1/login", Login, {}); | ||
server.Post("/api/v1/newPost", CreatePost, {}); | ||
server.Get("/api/v1/users/me", usersMe, {}); | ||
server.Get("/api/v1/logout", Logout, {}); | ||
server.Get("/api/v1/posts", AllPosts, {}); | ||
server.Run(port); | ||
} |
Oops, something went wrong.