Let's make (git) history!
This commit is contained in:
79
handlers/handler.cpp
Normal file
79
handlers/handler.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handler.h"
|
||||
|
||||
|
||||
void Handler::setGeneralVars(TemplatePage &page)
|
||||
{
|
||||
if(userSession->loggedIn)
|
||||
{
|
||||
page.setVar("loginstatus", "Logged in as " + userSession->user.login);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.setVar("loginstatus", "not logged in");
|
||||
}
|
||||
page.setVar("csrf_token", utils::toString(this->userSession->csrf_token));
|
||||
}
|
||||
Response Handler::errorResponse(std::string errortitle, std::string errormessage, int status)
|
||||
{
|
||||
TemplatePage &error = this->templ->getPage("error");
|
||||
error.setVar("errortitle", errortitle);
|
||||
error.setVar("errormessage", errormessage);
|
||||
//TODO: log?
|
||||
setGeneralVars(error);
|
||||
return { status, error.render()};
|
||||
}
|
||||
|
||||
QueryOption Handler::queryOption(const Request &r) const
|
||||
{
|
||||
QueryOption result;
|
||||
result.includeInvisible = false;
|
||||
try
|
||||
{
|
||||
result.limit = utils::toUInt(r.get("limit"));
|
||||
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
result.limit = 0;
|
||||
}
|
||||
try
|
||||
{
|
||||
result.offset = utils::toUInt(r.get("offset"));
|
||||
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
result.offset = 0;
|
||||
}
|
||||
std::string order = r.get("sort");
|
||||
if(order == "0")
|
||||
{
|
||||
result.order = ASCENDING;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.order = DESCENDING;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
37
handlers/handler.h
Normal file
37
handlers/handler.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef HANDLER_H
|
||||
#define HANDLER_H
|
||||
|
||||
#include "../response.h"
|
||||
#include "../request.h"
|
||||
#include "../template.h"
|
||||
#include "../database/database.h"
|
||||
#include "../urlprovider.h"
|
||||
#include "../database/queryoption.h"
|
||||
#include "../logger.h"
|
||||
#include "../cache/icache.h"
|
||||
class Handler
|
||||
{
|
||||
protected:
|
||||
ICache *cache;
|
||||
Template *templ;
|
||||
Database *database;
|
||||
Session *userSession;
|
||||
UrlProvider *urlProvider;
|
||||
|
||||
QueryOption queryOption(const Request &r) const;
|
||||
public:
|
||||
Handler(Template &templ, Database &db, Session &userSession, UrlProvider &provider, ICache &cache)
|
||||
{
|
||||
this->templ = &templ;
|
||||
this->database = &db;
|
||||
this->userSession = &userSession;
|
||||
this->urlProvider = &provider;
|
||||
this->cache = &cache;
|
||||
}
|
||||
virtual Response handle(const Request &r) = 0;
|
||||
void setGeneralVars(TemplatePage &page);
|
||||
virtual ~Handler() { }
|
||||
Response errorResponse(std::string errortitle, std::string errormessage, int status = 200);
|
||||
};
|
||||
|
||||
#endif // HANDLER_H
|
44
handlers/handlerallcategories.cpp
Normal file
44
handlers/handlerallcategories.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerallcategories.h"
|
||||
#include "../urlprovider.h"
|
||||
#include "../logger.h"
|
||||
Response HandlerAllCategories::handle(const Request &r)
|
||||
{
|
||||
auto categoryDao = this->database->createCategoryDao();
|
||||
QueryOption qo = queryOption(r);
|
||||
auto resultList = categoryDao->fetchList(qo);
|
||||
if(resultList.size() == 0)
|
||||
{
|
||||
return errorResponse("No categories", "This wiki does not have any categories defined yet or your query options did not yield any results");
|
||||
}
|
||||
TemplatePage &searchPage = this->templ->getPage("allcategories");
|
||||
std::string body = this->templ->renderSearch(resultList, [&](std::string str) {
|
||||
return this->urlProvider->category(str);
|
||||
});
|
||||
searchPage.setVar("categorylist", body);
|
||||
setGeneralVars(searchPage);
|
||||
|
||||
Response response;
|
||||
response.setBody(searchPage.render());
|
||||
response.setStatus(200);
|
||||
return response;
|
||||
}
|
15
handlers/handlerallcategories.h
Normal file
15
handlers/handlerallcategories.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef HANDLERALLCATEGORIES_H
|
||||
#define HANDLERALLCATEGORIES_H
|
||||
|
||||
|
||||
#include "handler.h"
|
||||
|
||||
class HandlerAllCategories : public Handler
|
||||
{
|
||||
public:
|
||||
HandlerAllCategories();
|
||||
using Handler::Handler;
|
||||
Response handle(const Request &r) override;
|
||||
};
|
||||
|
||||
#endif // HANDLERALLCATEGORIES_H
|
51
handlers/handlerallpages.cpp
Normal file
51
handlers/handlerallpages.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerallpages.h"
|
||||
|
||||
|
||||
|
||||
Response HandlerAllPages::handle(const Request &r)
|
||||
{
|
||||
try
|
||||
{
|
||||
Response response;
|
||||
auto pageDao = this->database->createPageDao();
|
||||
QueryOption qo = queryOption(r);
|
||||
auto resultList = pageDao->getPageList(qo);
|
||||
if(resultList.size() == 0)
|
||||
{
|
||||
return errorResponse("No pages", "This wiki does not have any pages yet");
|
||||
}
|
||||
TemplatePage &searchPage = this->templ->getPage("allpages");
|
||||
std::string body = this->templ->renderSearch(resultList);
|
||||
searchPage.setVar("pagelist", body);
|
||||
setGeneralVars(searchPage);
|
||||
response.setBody(searchPage.render());
|
||||
response.setStatus(200);
|
||||
return response;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
Logger::error() << "Error during allpages Handler" << e.what();
|
||||
return errorResponse("Error", "An unknown error occured");
|
||||
}
|
||||
|
||||
}
|
13
handlers/handlerallpages.h
Normal file
13
handlers/handlerallpages.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef HANDLERALLPAGES_H
|
||||
#define HANDLERALLPAGES_H
|
||||
|
||||
#include "handler.h"
|
||||
class HandlerAllPages : public Handler
|
||||
{
|
||||
public:
|
||||
HandlerAllPages();
|
||||
using Handler::Handler;
|
||||
Response handle(const Request &r) override;
|
||||
};
|
||||
|
||||
#endif // HANDLERALLPAGES_H
|
51
handlers/handlercategory.cpp
Normal file
51
handlers/handlercategory.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlercategory.h"
|
||||
|
||||
|
||||
Response HandlerCategory::handle(const Request &r)
|
||||
{
|
||||
try
|
||||
{
|
||||
Response response;
|
||||
std::string categoryname = r.get("category");
|
||||
auto categoryDao = this->database->createCategoryDao();
|
||||
if(! categoryDao->find(categoryname))
|
||||
{
|
||||
return this->errorResponse("No such category", "A category with the provided name does not exist", 404);
|
||||
}
|
||||
QueryOption qo = queryOption(r);
|
||||
auto resultList = categoryDao->fetchMembers(categoryname, qo);
|
||||
TemplatePage &searchPage = this->templ->getPage("show_category");
|
||||
std::string body = this->templ->renderSearch(resultList);
|
||||
searchPage.setVar("pagelist", body);
|
||||
searchPage.setVar("categoryname", categoryname);
|
||||
setGeneralVars(searchPage);
|
||||
response.setBody(searchPage.render());
|
||||
response.setStatus(200);
|
||||
return response;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
Logger::error() << "Error during category Handler" << e.what();
|
||||
return errorResponse("Error", "An unknown error occured");
|
||||
}
|
||||
}
|
13
handlers/handlercategory.h
Normal file
13
handlers/handlercategory.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef HANDLERCATEGORY_H
|
||||
#define HANDLERCATEGORY_H
|
||||
#include "handler.h"
|
||||
|
||||
class HandlerCategory : public Handler
|
||||
{
|
||||
public:
|
||||
HandlerCategory();
|
||||
using Handler::Handler;
|
||||
Response handle(const Request &r) override;
|
||||
};
|
||||
|
||||
#endif // HANDLERCATEGORY_H
|
32
handlers/handlerdefault.cpp
Normal file
32
handlers/handlerdefault.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerdefault.h"
|
||||
|
||||
|
||||
Response HandlerDefault::handle(const Request &r)
|
||||
{
|
||||
return Response::redirectTemporarily(this->urlProvider->index());
|
||||
}
|
||||
|
||||
HandlerDefault::~HandlerDefault()
|
||||
{
|
||||
|
||||
}
|
13
handlers/handlerdefault.h
Normal file
13
handlers/handlerdefault.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef HANDLERDEFAULT_H
|
||||
#define HANDLERDEFAULT_H
|
||||
|
||||
#include "handler.h"
|
||||
class HandlerDefault : public Handler
|
||||
{
|
||||
public:
|
||||
Response handle(const Request &r) override;
|
||||
~HandlerDefault() override;
|
||||
using Handler::Handler;
|
||||
};
|
||||
|
||||
#endif // HANDLERDEFAULT_H
|
101
handlers/handlerfactory.cpp
Normal file
101
handlers/handlerfactory.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerfactory.h"
|
||||
#include "handler.h"
|
||||
#include "handlerdefault.h"
|
||||
#include "handlerpageview.h"
|
||||
#include "handlerinvalidaction.h"
|
||||
#include "handlerlogin.h"
|
||||
#include "handlerpageedit.h"
|
||||
#include "handlersearch.h"
|
||||
#include "handlerallpages.h"
|
||||
#include "handlerallcategories.h"
|
||||
#include "handlercategory.h"
|
||||
#include "handlerhistory.h"
|
||||
#include "handlerpagedelete.h"
|
||||
class Factory
|
||||
{
|
||||
Template &templ;
|
||||
Database &db;
|
||||
Session &userSession;
|
||||
UrlProvider &urlProvider;
|
||||
ICache &cache;
|
||||
public:
|
||||
|
||||
Factory(Template &templ, Database &db, Session &usersession, UrlProvider &urlprovider, ICache &cache) : templ(templ) ,db(db), userSession(usersession), urlProvider(urlprovider), cache(cache) { }
|
||||
|
||||
template<class T>
|
||||
inline std::unique_ptr<T> produce()
|
||||
{
|
||||
return std::make_unique<T>(templ, db, userSession, urlProvider, cache);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<Handler> createHandler(const std::string &action, Template &templ, Database
|
||||
&db, Session &usersession, UrlProvider &urlprovider, ICache &cache)
|
||||
{
|
||||
|
||||
Factory producer(templ, db, usersession, urlprovider, cache);
|
||||
|
||||
if(action == "" || action == "index")
|
||||
{
|
||||
return producer.produce<HandlerDefault>();
|
||||
}
|
||||
if(action == "show")
|
||||
{
|
||||
return producer.produce<HandlerPageView>();
|
||||
}
|
||||
if(action == "edit")
|
||||
{
|
||||
return producer.produce<HandlerPageEdit>();
|
||||
}
|
||||
if(action == "login")
|
||||
{
|
||||
return producer.produce<HandlerLogin>();
|
||||
}
|
||||
if(action == "search")
|
||||
{
|
||||
return producer.produce<HandlerSearch>();
|
||||
}
|
||||
if(action == "delete")
|
||||
{
|
||||
return producer.produce<HandlerPageDelete>();
|
||||
}
|
||||
if(action == "allpages")
|
||||
{
|
||||
return producer.produce<HandlerAllPages>();
|
||||
}
|
||||
if(action == "allcategories")
|
||||
{
|
||||
return producer.produce<HandlerAllCategories>();
|
||||
}
|
||||
if(action == "showcat")
|
||||
{
|
||||
return producer.produce<HandlerCategory>();
|
||||
}
|
||||
if(action == "recent")
|
||||
{
|
||||
return producer.produce<HandlerHistory>();
|
||||
}
|
||||
|
||||
|
||||
return producer.produce<HandlerInvalidAction>();
|
||||
}
|
8
handlers/handlerfactory.h
Normal file
8
handlers/handlerfactory.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef HANDLERFACTORY_H
|
||||
#define HANDLERFACTORY_H
|
||||
#include <memory>
|
||||
#include "handler.h"
|
||||
#include "../template.h"
|
||||
|
||||
std::unique_ptr<Handler> createHandler(const std::string &action, Template &templ, Database &db, Session &usersession, UrlProvider &urlprovider, ICache &cache);
|
||||
#endif // HANDLERFACTORY_H
|
106
handlers/handlerhistory.cpp
Normal file
106
handlers/handlerhistory.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerhistory.h"
|
||||
#include "handler.h"
|
||||
#include "../htmllink.h"
|
||||
#include "../logger.h"
|
||||
#include "../database/exceptions.h"
|
||||
Response HandlerHistory::handle(const Request &r)
|
||||
{
|
||||
QueryOption qo = queryOption(r);
|
||||
std::string page = r.get("page");
|
||||
|
||||
unsigned int count = 0;
|
||||
std::vector<Revision> resultList;
|
||||
auto revisionDao = this->database->createRevisionDao();
|
||||
|
||||
auto makeSortedLink = [&](unsigned int limit, unsigned int offset, unsigned int order)
|
||||
{
|
||||
if(!page.empty())
|
||||
{
|
||||
return this->urlProvider->pageHistorySort(page, limit, offset, order);
|
||||
}
|
||||
return this->urlProvider->recentSorted(limit, offset, order);
|
||||
};
|
||||
std::string templatename = "recentchanges";
|
||||
try
|
||||
{
|
||||
if(!page.empty())
|
||||
{
|
||||
auto pageDao = this->database->createPageDao();
|
||||
if(!pageDao->exists(page))
|
||||
{
|
||||
return errorResponse("No such page", "No such page exists to show history for", 404);
|
||||
}
|
||||
count = revisionDao->countTotalRevisions(page);
|
||||
resultList = revisionDao->getAllRevisionsForPage(page, qo);
|
||||
templatename = "page_history";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
count = revisionDao->countTotalRevisions();
|
||||
if(count == 0)
|
||||
{
|
||||
return errorResponse("No revisions", "This wiki does not have any pages with revisions yet");
|
||||
}
|
||||
resultList = revisionDao->getAllRevisions(qo);
|
||||
}
|
||||
}
|
||||
catch(const DatabaseException &e)
|
||||
{
|
||||
Logger::error() << "DatabaseException in handlerhistory: " << e.what();
|
||||
return errorResponse("Database error", "While trying to fetch revision list, a database error occured");
|
||||
}
|
||||
TemplatePage historyPage = this->templ->getPage(templatename);
|
||||
setGeneralVars(historyPage);
|
||||
|
||||
if( (qo.offset + (unsigned int)resultList.size()) < count)
|
||||
{
|
||||
HtmlLink link;
|
||||
link.href = makeSortedLink(qo.limit, qo.offset + qo.limit, qo.order);
|
||||
link.innervalue = "Next page";
|
||||
|
||||
historyPage.setVar("nextpage", link.render());
|
||||
}
|
||||
|
||||
unsigned int prevoffset = qo.offset - qo.limit;
|
||||
if(prevoffset > count)
|
||||
{
|
||||
prevoffset = 0;
|
||||
}
|
||||
if(qo.offset > 0 && qo.offset < count)
|
||||
{
|
||||
HtmlLink link;
|
||||
link.href = makeSortedLink(qo.limit, prevoffset, qo.order);
|
||||
link.innervalue = "Previous page";
|
||||
|
||||
historyPage.setVar("prevpage", link.render());
|
||||
}
|
||||
|
||||
unsigned int neworder = ( qo.order == DESCENDING ) ? ASCENDING : DESCENDING ;
|
||||
historyPage.setVar("linkrecentsort", makeSortedLink(qo.limit, qo.offset, neworder));
|
||||
historyPage.setVar("revisionlist", this->templ->renderRevisionList(resultList, page.empty()));
|
||||
Response response;
|
||||
response.setBody(historyPage.render());
|
||||
response.setStatus(200);
|
||||
return response;
|
||||
}
|
14
handlers/handlerhistory.h
Normal file
14
handlers/handlerhistory.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef HANDLERHISTORY_H
|
||||
#define HANDLERHISTORY_H
|
||||
#include "handler.h"
|
||||
|
||||
class HandlerHistory : public Handler
|
||||
{
|
||||
|
||||
public:
|
||||
HandlerHistory();
|
||||
using Handler::Handler;
|
||||
Response handle(const Request &r) override;
|
||||
};
|
||||
|
||||
#endif // HANDLERHISTORY_H
|
27
handlers/handlerinvalidaction.cpp
Normal file
27
handlers/handlerinvalidaction.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerinvalidaction.h"
|
||||
|
||||
|
||||
Response HandlerInvalidAction::handle(const Request &r)
|
||||
{
|
||||
return errorResponse("Invalid action", "No action defined for this action");
|
||||
}
|
14
handlers/handlerinvalidaction.h
Normal file
14
handlers/handlerinvalidaction.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef HANDLERINVALIDACTION_H
|
||||
#define HANDLERINVALIDACTION_H
|
||||
#include "handler.h"
|
||||
|
||||
class HandlerInvalidAction : public Handler
|
||||
{
|
||||
public:
|
||||
Response handle(const Request &r) override;
|
||||
~HandlerInvalidAction() override { }
|
||||
using Handler::Handler;
|
||||
};
|
||||
|
||||
|
||||
#endif // HANDLERINVALIDACTION_H
|
123
handlers/handlerlogin.cpp
Normal file
123
handlers/handlerlogin.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include "handlerlogin.h"
|
||||
#include "../logger.h"
|
||||
struct LoginFail
|
||||
{
|
||||
unsigned int count;
|
||||
time_t lastfail;
|
||||
};
|
||||
static std::map<std::string, LoginFail> loginFails;
|
||||
|
||||
//TODO: make configurable
|
||||
bool HandlerLogin::isBanned(std::string ip)
|
||||
{
|
||||
if(utils::hasKey(loginFails, ip))
|
||||
{
|
||||
LoginFail &fl = loginFails[ip];
|
||||
return fl.count > 5 && (time(nullptr) - fl.lastfail) < 1200;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandlerLogin::incFailureCount(std::string ip)
|
||||
{
|
||||
LoginFail &fl = loginFails[ip];
|
||||
fl.count+=1;
|
||||
fl.lastfail = time(nullptr);
|
||||
}
|
||||
|
||||
std::vector<char> HandlerLogin::pbkdf5(std::string password, const std::vector<char> &salt)
|
||||
{
|
||||
unsigned char hash[32];
|
||||
const EVP_MD *sha256 = EVP_sha256();
|
||||
const unsigned char *rawsalt = reinterpret_cast<const unsigned char *>(salt.data());
|
||||
PKCS5_PBKDF2_HMAC(password.c_str(), password.size(), rawsalt, salt.size(), 300000, sha256, sizeof(hash), hash);
|
||||
|
||||
std::vector<char> result;
|
||||
|
||||
for(size_t i = 0; i < sizeof(hash); i++)
|
||||
{
|
||||
|
||||
result.push_back(static_cast<char>(hash[i]));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Response HandlerLogin::handle(const Request &r)
|
||||
{
|
||||
auto createErrorReesponse = [&]() { return errorResponse("Login error", "The supplied credenetials are incorrect"); };
|
||||
|
||||
if(isBanned(r.getIp()))
|
||||
{
|
||||
return errorResponse("Banned", "You have been banned for too many login attempts. Try again later");
|
||||
}
|
||||
if(r.param("submit") == "1")
|
||||
{
|
||||
std::string password = r.post("password");
|
||||
std::string username = r.post("user");
|
||||
|
||||
auto userDao = this->database->createUserDao();
|
||||
std::optional<User> user = userDao->find(username);
|
||||
if(!user)
|
||||
{
|
||||
return createErrorReesponse();
|
||||
}
|
||||
|
||||
auto hashresult = pbkdf5(password, user.value().salt);
|
||||
//TODO: timing attack
|
||||
if(hashresult == user.value().password)
|
||||
{
|
||||
loginFails.erase(r.getIp());
|
||||
Response r = Response::redirectTemporarily(urlProvider->index());
|
||||
*(this->userSession) = Session(user.value());
|
||||
return r;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: only if wanted by config
|
||||
incFailureCount(r.getIp());
|
||||
return createErrorReesponse();
|
||||
}
|
||||
|
||||
|
||||
// auto pbkdf5 = pbkdf5(password, user->)
|
||||
|
||||
|
||||
|
||||
}
|
||||
std::string page = r.get("page");
|
||||
if(page.empty())
|
||||
page = "index";
|
||||
|
||||
TemplatePage &loginTemplatePage = this->templ->getPage("login");
|
||||
setGeneralVars(loginTemplatePage);
|
||||
loginTemplatePage.setVar("loginurl", urlProvider->login(page));
|
||||
Response result;
|
||||
result.setStatus(200);
|
||||
result.setBody(loginTemplatePage.render());
|
||||
return result;
|
||||
}
|
19
handlers/handlerlogin.h
Normal file
19
handlers/handlerlogin.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef HANDLERLOGIN_H
|
||||
#define HANDLERLOGIN_H
|
||||
#include <vector>
|
||||
#include "handler.h"
|
||||
|
||||
class HandlerLogin : public Handler
|
||||
{
|
||||
private:
|
||||
bool isBanned(std::string ip);
|
||||
void incFailureCount(std::string ip);
|
||||
std::vector<char> pbkdf5(std::string password, const std::vector<char> &salt);
|
||||
public:
|
||||
HandlerLogin();
|
||||
Response handle(const Request &r) override;
|
||||
~HandlerLogin() override { }
|
||||
using Handler::Handler;
|
||||
};
|
||||
|
||||
#endif // HANDERLOGIN_H
|
94
handlers/handlerpage.cpp
Normal file
94
handlers/handlerpage.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerpage.h"
|
||||
|
||||
|
||||
Response HandlerPage::handle(const Request &r)
|
||||
{
|
||||
std::string pagename = r.get("page");
|
||||
auto pageDao = this->database->createPageDao();
|
||||
if(pagename.empty())
|
||||
{
|
||||
return errorResponse("No page given", "No page given to request");
|
||||
}
|
||||
|
||||
if(pageMustExist() && !pageDao->exists(pagename))
|
||||
{
|
||||
std::string createlink = this->urlProvider->editPage(pagename);
|
||||
return errorResponse("Page not found", "The requested page was not found. Do you want to <a href=\"" + createlink + "\">create</a> it?", 404);
|
||||
}
|
||||
|
||||
if(!canAccess(pagename))
|
||||
{
|
||||
return errorResponse("Permission denied", accessErrorMessage());
|
||||
}
|
||||
|
||||
return this->handleRequest(*pageDao, pagename, r);
|
||||
}
|
||||
|
||||
std::string HandlerPage::accessErrorMessage()
|
||||
{
|
||||
return "You don't have permission to access this page";
|
||||
}
|
||||
|
||||
bool HandlerPage::pageMustExist()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandlerPage::setPageVars(TemplatePage &page, std::string pagename)
|
||||
{
|
||||
setGeneralVars(page);
|
||||
|
||||
if(!pagename.empty())
|
||||
{
|
||||
std::string headerlinks;
|
||||
TemplatePage &headerlink = this->templ->getPage("_headerlink");
|
||||
auto addHeaderLink = [&headerlinks, &headerlink](std::string href, std::string value)
|
||||
{
|
||||
headerlink.setVar("href", href);
|
||||
headerlink.setVar("value", value);
|
||||
headerlinks += headerlink.render();
|
||||
};
|
||||
Permissions &perms = this->userSession->user.permissions;
|
||||
|
||||
if(perms.canEdit())
|
||||
{
|
||||
addHeaderLink(this->urlProvider->editPage(pagename), "Edit");
|
||||
addHeaderLink(this->urlProvider->pageSettings(pagename), "Page settings");
|
||||
}
|
||||
if(perms.canDelete())
|
||||
{
|
||||
addHeaderLink(this->urlProvider->pageDelete(pagename), "Delete");
|
||||
}
|
||||
if(perms.canSeePageHistory())
|
||||
{
|
||||
addHeaderLink(this->urlProvider->pageHistory(pagename), "Show history");
|
||||
}
|
||||
|
||||
page.setVar("headerlinks", headerlinks);
|
||||
page.setVar("page", pagename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
21
handlers/handlerpage.h
Normal file
21
handlers/handlerpage.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef HANDLERPAGE_H
|
||||
#define HANDLERPAGE_H
|
||||
#include "handler.h"
|
||||
|
||||
class HandlerPage : public Handler
|
||||
{
|
||||
protected:
|
||||
virtual bool canAccess(std::string page) = 0;
|
||||
virtual bool pageMustExist();
|
||||
virtual std::string accessErrorMessage();
|
||||
|
||||
public:
|
||||
Response handle(const Request &r) override;
|
||||
virtual Response handleRequest(PageDao &pageDao, std::string pagename, const Request &r) =0;
|
||||
~HandlerPage() override { }
|
||||
using Handler::Handler;
|
||||
|
||||
void setPageVars(TemplatePage &page, std::string pagename);
|
||||
};
|
||||
|
||||
#endif // HANDLERPAGE_H
|
51
handlers/handlerpagedelete.cpp
Normal file
51
handlers/handlerpagedelete.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerpagedelete.h"
|
||||
#include "../database/exceptions.h"
|
||||
|
||||
Response HandlerPageDelete::handleRequest(PageDao &pageDao, std::string pagename, const Request &r)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if(r.getRequestMethod() == "POST")
|
||||
{
|
||||
pageDao.deletePage(pagename);
|
||||
this->cache->removePrefix("page:"); //TODO: overkill?
|
||||
return Response::redirectTemporarily(this->urlProvider->index());
|
||||
|
||||
|
||||
}
|
||||
TemplatePage delPage = this->templ->getPage("page_deletion");
|
||||
delPage.setVar("deletionurl", this->urlProvider->pageDelete(pagename));
|
||||
setPageVars(delPage, pagename);
|
||||
Response r;
|
||||
r.setBody(delPage.render());
|
||||
return r;
|
||||
}
|
||||
catch(const DatabaseException &e)
|
||||
{
|
||||
Logger::debug() << "Error delete page: " << e.what();
|
||||
return errorResponse("Database error", "A database error occured while trying to delete this page");
|
||||
}
|
||||
|
||||
|
||||
}
|
26
handlers/handlerpagedelete.h
Normal file
26
handlers/handlerpagedelete.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef HANDLERPAGEDELETE_H
|
||||
#define HANDLERPAGEDELETE_H
|
||||
#include "handlerpage.h"
|
||||
|
||||
class HandlerPageDelete : public HandlerPage
|
||||
{
|
||||
bool pageMustExist() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool canAccess(std::string page) override
|
||||
{
|
||||
return this->userSession->user.permissions.canDelete();
|
||||
}
|
||||
|
||||
std::string accessErrorMessage() override
|
||||
{
|
||||
return "You don't have permission to delete pages";
|
||||
}
|
||||
public:
|
||||
Response handleRequest(PageDao &pageDao, std::string pagename, const Request &r) override;
|
||||
using HandlerPage::HandlerPage;
|
||||
};
|
||||
|
||||
#endif // HANDLERPAGEDELETE_H
|
122
handlers/handlerpageedit.cpp
Normal file
122
handlers/handlerpageedit.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerpageedit.h"
|
||||
#include "../database/exceptions.h"
|
||||
#include "../request.h"
|
||||
|
||||
#include "../parser.h"
|
||||
bool HandlerPageEdit::canAccess(std::string page)
|
||||
{
|
||||
return this->userSession->user.permissions.canEdit();
|
||||
}
|
||||
|
||||
bool HandlerPageEdit::pageMustExist()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename, const Request &r)
|
||||
{
|
||||
bool pageexists = pageDao.exists(pagename);
|
||||
if(!pageexists && !this->userSession->user.permissions.canCreate())
|
||||
{
|
||||
return errorResponse("No permission", "You don't have permission to create new pages");
|
||||
}
|
||||
auto revisiondao = this->database->createRevisionDao();
|
||||
auto revision = this->database->createRevisionDao()->getCurrentForPage(pagename);
|
||||
std::string body;
|
||||
|
||||
if(revision)
|
||||
{
|
||||
body = revision->content;
|
||||
}
|
||||
if(r.getRequestMethod() == "POST")
|
||||
{
|
||||
if(r.post("do") == "submit")
|
||||
{
|
||||
std::string newContent = r.post("content");
|
||||
std::string newComment = r.post("comment");
|
||||
|
||||
Revision newRevision;
|
||||
newRevision.author = this->userSession->user.login;
|
||||
newRevision.comment = newComment;
|
||||
newRevision.page = pagename;
|
||||
newRevision.content = newContent;
|
||||
|
||||
|
||||
//TODO: must check, whether categories differ, and perhaps don't allow every user
|
||||
//to set categories
|
||||
Parser parser;
|
||||
std::vector<std::string> cats = parser.extractCategories(newContent);
|
||||
try
|
||||
{
|
||||
this->database->beginTransaction();
|
||||
if(!pageexists)
|
||||
{
|
||||
Page newPage;
|
||||
newPage.current_revision = 0;
|
||||
newPage.listed = true;
|
||||
newPage.name = pagename;
|
||||
pageDao.save(newPage);
|
||||
|
||||
}
|
||||
revisiondao->save(newRevision);
|
||||
pageDao.setCategories(pagename, cats);
|
||||
this->database->commitTransaction();
|
||||
this->cache->removePrefix("page:"); //TODO: overkill?
|
||||
}
|
||||
catch(const DatabaseException &e)
|
||||
{
|
||||
Logger::debug() << "Error saving revision: " << e.what();
|
||||
return errorResponse("Database error", "A database error occured while trying to save this revision");
|
||||
}
|
||||
|
||||
return Response::redirectTemporarily(urlProvider->page(pagename));
|
||||
|
||||
|
||||
}
|
||||
if(r.post("do") == "preview")
|
||||
{
|
||||
std::string newContent = r.post("content");
|
||||
Parser parser;
|
||||
TemplatePage templatePage = this->templ->getPage("page_creation_preview");
|
||||
templatePage.setVar("actionurl", urlProvider->editPage(pagename));
|
||||
templatePage.setVar("preview_content", parser.parse(pageDao, *this->urlProvider, newContent) );
|
||||
templatePage.setVar("content", newContent);
|
||||
setPageVars(templatePage, pagename);
|
||||
|
||||
Response response;
|
||||
response.setBody(templatePage.render());
|
||||
return response;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
TemplatePage &templatePage = this->templ->getPage("page_creation");
|
||||
templatePage.setVar("actionurl", urlProvider->editPage(pagename));
|
||||
templatePage.setVar("content", body);
|
||||
setPageVars(templatePage, pagename);
|
||||
Response response;
|
||||
response.setBody(templatePage.render());
|
||||
return response;
|
||||
|
||||
}
|
20
handlers/handlerpageedit.h
Normal file
20
handlers/handlerpageedit.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef HANDLERPAGEEDI_H
|
||||
#define HANDLERPAGEEDI_H
|
||||
|
||||
#include "handlerpage.h"
|
||||
#include "../page.h"
|
||||
|
||||
|
||||
class HandlerPageEdit : public HandlerPage
|
||||
{
|
||||
protected:
|
||||
bool pageMustExist() override;
|
||||
bool canAccess(std::string page) override;
|
||||
public:
|
||||
Response handleRequest(PageDao &pageDao, std::string pagename, const Request &r) override;
|
||||
|
||||
~HandlerPageEdit() override { }
|
||||
using HandlerPage::HandlerPage;
|
||||
};
|
||||
|
||||
#endif // HANDLERPAGEEDI_H
|
170
handlers/handlerpageview.cpp
Normal file
170
handlers/handlerpageview.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlerpageview.h"
|
||||
#include "../database/exceptions.h"
|
||||
#include "../logger.h"
|
||||
#include "../parser.h"
|
||||
#include "../htmllink.h"
|
||||
|
||||
bool HandlerPageView::canAccess(std::string page)
|
||||
{
|
||||
return this->userSession->user.permissions.canRead();
|
||||
}
|
||||
|
||||
std::string HandlerPageView::createIndexContent(IParser &parser, std::string content)
|
||||
{
|
||||
std::vector<Headline> headlines = parser.extractHeadlines(content);
|
||||
std::string indexcontent = "";
|
||||
unsigned int l = 0;
|
||||
for(const Headline &h : headlines)
|
||||
{
|
||||
if(h.level > l)
|
||||
{
|
||||
indexcontent += "<ul>";
|
||||
}
|
||||
else if(h.level < l)
|
||||
{
|
||||
indexcontent += "</ul>";
|
||||
}
|
||||
l = h.level;
|
||||
HtmlLink link;
|
||||
link.href="#" + h.title;
|
||||
link.innervalue = h.title;
|
||||
link.cssclass = "indexlink";
|
||||
indexcontent += "<li>"+link.render()+"</li>";
|
||||
}
|
||||
indexcontent += "</ul>";
|
||||
return indexcontent;
|
||||
}
|
||||
|
||||
|
||||
Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename, const Request &r)
|
||||
{
|
||||
|
||||
std::string revisionparam = r.get("revision");
|
||||
unsigned int revisionid=0;
|
||||
if(!revisionparam.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
revisionid = utils::toUInt(revisionparam);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
return errorResponse("Error", "Supplied revisionid is misformated");
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Revision> revision;
|
||||
std::string templatepartname;
|
||||
try
|
||||
{
|
||||
if(revisionid > 0 )
|
||||
{
|
||||
revision = this->database->createRevisionDao()->getRevisionForPage(pagename, revisionid);
|
||||
if(!revision)
|
||||
{
|
||||
return errorResponse("Revision not found", "No such revision found");
|
||||
}
|
||||
templatepartname = "page_view_revision";
|
||||
}
|
||||
else
|
||||
{
|
||||
if(! this->userSession->loggedIn)
|
||||
{
|
||||
auto content = this->cache->get("page:foranon:" + pagename);
|
||||
if(content)
|
||||
{
|
||||
Response r;
|
||||
r.setBody(*content);
|
||||
//TODO: etag?
|
||||
return r;
|
||||
}
|
||||
}
|
||||
revision = this->database->createRevisionDao()->getCurrentForPage(pagename);
|
||||
templatepartname = "page_view";
|
||||
}
|
||||
|
||||
}
|
||||
catch(const DatabaseException &e)
|
||||
{
|
||||
Logger::error() << "DatabaseException in handlerpageview: " << e.what();
|
||||
return errorResponse("Database error", "While trying to fetch revision, a database error occured");
|
||||
}
|
||||
|
||||
|
||||
TemplatePage &page = this->templ->getPage(templatepartname);
|
||||
|
||||
Parser parser;
|
||||
Response result;
|
||||
result.setStatus(200);
|
||||
std::string indexcontent;
|
||||
std::string parsedcontent;
|
||||
|
||||
if(revisionid > 0)
|
||||
{
|
||||
indexcontent = createIndexContent(parser, revision->content);
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, revision->content);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string cachekeyindexcontent = "page:indexcontent:" + pagename;
|
||||
std::string cachekeyparsedcontent = "page:parsedcontent:" + pagename;
|
||||
auto cachedindexcontent = this->cache->get(cachekeyindexcontent);
|
||||
auto cachedparsedcontent = this->cache->get(cachekeyparsedcontent);
|
||||
if(cachedindexcontent)
|
||||
{
|
||||
indexcontent = *cachedindexcontent;
|
||||
}
|
||||
else
|
||||
{
|
||||
indexcontent = createIndexContent(parser, revision->content);
|
||||
this->cache->put(cachekeyindexcontent, indexcontent);
|
||||
}
|
||||
if(cachedparsedcontent)
|
||||
{
|
||||
parsedcontent = *cachedparsedcontent;
|
||||
}
|
||||
else
|
||||
{
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, revision->content);
|
||||
this->cache->put(cachekeyparsedcontent, parsedcontent);
|
||||
|
||||
}
|
||||
}
|
||||
page.setVar("content", parsedcontent);
|
||||
page.setVar("index", indexcontent);
|
||||
page.setVar("editedby", revision->author );
|
||||
page.setVar("editedon", utils::toISODate(revision->timestamp));
|
||||
page.setVar("historyurl", this->urlProvider->pageHistory(pagename));
|
||||
page.setVar("revision", revisionparam);
|
||||
setPageVars(page, pagename);
|
||||
std::string body = page.render();
|
||||
if(revisionid == 0 && ! this->userSession->loggedIn)
|
||||
{
|
||||
this->cache->put("page:foranon:" + pagename, body);
|
||||
}
|
||||
result.addHeader("ETAG", std::to_string(revision->revision)+ "+" + std::to_string(this->userSession->loggedIn));
|
||||
result.setBody(body);
|
||||
return result;
|
||||
|
||||
|
||||
}
|
25
handlers/handlerpageview.h
Normal file
25
handlers/handlerpageview.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef HANDLERPAGEVIEW_H
|
||||
#define HANDLERPAGEVIEW_H
|
||||
|
||||
#include "handler.h"
|
||||
#include "handlerpage.h"
|
||||
#include "../page.h"
|
||||
#include "../iparser.h"
|
||||
class HandlerPageView : public HandlerPage
|
||||
{
|
||||
protected:
|
||||
bool canAccess(std::string page) override;
|
||||
std::string accessErrorMessage() override
|
||||
{
|
||||
return "You don't have permission to view this page";
|
||||
}
|
||||
std::string createIndexContent(IParser &parser, std::string content);
|
||||
|
||||
public:
|
||||
Response handleRequest(PageDao &pageDao, std::string pagename, const Request &r) override;
|
||||
~HandlerPageView() override { }
|
||||
using HandlerPage::HandlerPage;
|
||||
};
|
||||
|
||||
|
||||
#endif // HANDLERPAGEVIEW_H
|
63
handlers/handlersearch.cpp
Normal file
63
handlers/handlersearch.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "handlersearch.h"
|
||||
Response HandlerSearch::handle(const Request &r)
|
||||
{
|
||||
Response response;
|
||||
std::string q = r.get("q");
|
||||
if(q.empty())
|
||||
{
|
||||
return errorResponse("Missing search term", "No search term supplied");
|
||||
}
|
||||
|
||||
for(int x : q)
|
||||
{
|
||||
if(!isalnum(x) && !isspace(x))
|
||||
{
|
||||
return errorResponse("Invalid char", "Currently, the search is limited and so only supports alpha numeric characters and spaces");
|
||||
}
|
||||
}
|
||||
auto pageDao = this->database->createPageDao();
|
||||
QueryOption qo = queryOption(r);
|
||||
try
|
||||
{
|
||||
auto resultList = pageDao->search(q, qo);
|
||||
if(resultList.size() == 0)
|
||||
{
|
||||
return errorResponse("No results", "Your search for " + q + " did not yield any results.");
|
||||
}
|
||||
TemplatePage &searchPage = this->templ->getPage("search");
|
||||
std::string body = this->templ->renderSearch(resultList);
|
||||
searchPage.setVar("pagelist", body);
|
||||
searchPage.setVar("searchterm", q);
|
||||
setGeneralVars(searchPage);
|
||||
response.setBody(searchPage.render());
|
||||
response.setStatus(200);
|
||||
return response;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
Logger::error() << "Search failed, q: " << q << "Error: " << e.what();
|
||||
return errorResponse("Technical Error", "The system failed to perform your search");
|
||||
}
|
||||
|
||||
}
|
||||
|
13
handlers/handlersearch.h
Normal file
13
handlers/handlersearch.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef HANDLERSEARCH_H
|
||||
#define HANDLERSEARCH_H
|
||||
#include <vector>
|
||||
#include "handler.h"
|
||||
class HandlerSearch : public Handler
|
||||
{
|
||||
public:
|
||||
HandlerSearch();
|
||||
using Handler::Handler;
|
||||
Response handle(const Request &r) override;
|
||||
};
|
||||
|
||||
#endif // HANDLERSEARCH_H
|
Reference in New Issue
Block a user