Compare commits

...

6 Commits

21 changed files with 205 additions and 57 deletions

30
cache/nocache.h vendored Normal file
View File

@ -0,0 +1,30 @@
#include "icache.h"
class NoCache : public ICache
{
public:
NoCache(std::string p)
{
}
virtual std::optional<std::string> get(std::string_view key) const
{
return {};
}
virtual void put(std::string_view key, std::string val)
{
return;
}
virtual void remove(std::string_view key)
{
return;
}
virtual void removePrefix(std::string_view prefix)
{
return;
}
virtual void clear()
{
return;
}
};

View File

@ -13,7 +13,7 @@
#include "permissionsdao.h" #include "permissionsdao.h"
class Database class Database
{ {
private: protected:
std::string connnectionstring; std::string connnectionstring;
public: public:

View File

@ -54,7 +54,7 @@ void SessionDaoSqlite::fillSession(int userid, Session &sess)
{ {
if(userid > -1) if(userid > -1)
{ {
UserDaoSqlite userDao{this->db}; UserDaoSqlite userDao{*this->db};
auto u = userDao.find(userid); auto u = userDao.find(userid);
if(u) if(u)
{ {

View File

@ -18,23 +18,43 @@ 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include <atomic>
#include "sqlite.h" #include "sqlite.h"
#include "../logger.h"
#include "pagedaosqlite.h" #include "pagedaosqlite.h"
#include "revisiondaosqlite.h" #include "revisiondaosqlite.h"
#include "sessiondaosqlite.h" #include "sessiondaosqlite.h"
#include "sqlite_modern_cpp.h"
#include "userdaosqlite.h" #include "userdaosqlite.h"
#include "categorydaosqlite.h" #include "categorydaosqlite.h"
#include "exceptions.h"
#include "permissionsdaosqlite.h" #include "permissionsdaosqlite.h"
thread_local sqlite::database *Sqlite::db = nullptr;
std::atomic<int> instances = 0;
Sqlite::Sqlite(std::string path) : Database(path) Sqlite::Sqlite(std::string path) : Database(path)
{ {
this->db = std::make_shared<sqlite::database>(path); instances++;
if(instances.load() > 1)
*db << "PRAGMA journal_mode=WAL;"; {
std::cerr << "temporal (yeah, right) HACK... only one instance allowed" << std::endl;
abort();
}
} }
std::mutex dbmutex;
sqlite::database &Sqlite::database() const
{
if(Sqlite::db == nullptr)
{
sqlite::sqlite_config config;
config.flags = config.flags | sqlite::OpenFlags::FULLMUTEX;
std::lock_guard<std::mutex> dbguard(dbmutex);
Sqlite::db = new sqlite::database(this->connnectionstring, config);
*Sqlite::db << "PRAGMA journal_mode=WAL;";
*Sqlite::db << "PRAGMA busy_timeout=10000;";
}
return *Sqlite::db;
}
std::unique_ptr<RevisionDao> Sqlite::createRevisionDao() const std::unique_ptr<RevisionDao> Sqlite::createRevisionDao() const
{ {
return create<RevisionDaoSqlite>(); return create<RevisionDaoSqlite>();
@ -67,27 +87,20 @@ std::unique_ptr<PermissionsDao> Sqlite::createPermissionsDao() const
void Sqlite::beginTransaction() void Sqlite::beginTransaction()
{ {
if(!inTransaction) *db << "begin;";
{
*db << "begin;";
inTransaction = true;
}
} }
void Sqlite::rollbackTransaction() void Sqlite::rollbackTransaction()
{ {
if(inTransaction) *db << "rollback;";
{
*db << "rollback;";
inTransaction = false;
}
} }
void Sqlite::commitTransaction() void Sqlite::commitTransaction()
{ {
if(inTransaction) *db << "commit;";
{ }
*db << "commit;";
inTransaction = false; Sqlite::~Sqlite()
} {
delete this->db;
} }

View File

@ -8,14 +8,15 @@
class Sqlite : public Database class Sqlite : public Database
{ {
private: private:
bool inTransaction = false; static thread_local sqlite::database *db;
std::shared_ptr<sqlite::database> db;
template <class T> std::unique_ptr<T> create() const template <class T> std::unique_ptr<T> create() const
{ {
return std::make_unique<T>(db); return std::make_unique<T>(database());
} }
sqlite::database &database() const;
public: public:
Sqlite(std::string path); Sqlite(std::string path);
std::unique_ptr<PageDao> createPageDao() const; std::unique_ptr<PageDao> createPageDao() const;
@ -27,6 +28,7 @@ class Sqlite : public Database
void beginTransaction(); void beginTransaction();
void commitTransaction(); void commitTransaction();
void rollbackTransaction(); void rollbackTransaction();
virtual ~Sqlite();
}; };
#endif // SQLITE_H #endif // SQLITE_H

View File

@ -12,20 +12,20 @@
class SqliteDao class SqliteDao
{ {
protected: protected:
std::shared_ptr<sqlite::database> db; sqlite::database *db = nullptr;
public: public:
SqliteDao() SqliteDao()
{ {
} }
SqliteDao(std::shared_ptr<sqlite::database> db) SqliteDao(sqlite::database &db)
{ {
this->db = db; this->db = &db;
} }
void setDb(std::shared_ptr<sqlite::database> db) void setDb(sqlite::database &db)
{ {
this->db = db; this->db = &db;
} }
inline void throwFrom(const sqlite::sqlite_exception &e) const inline void throwFrom(const sqlite::sqlite_exception &e) const

View File

@ -1,8 +1,9 @@
#include "dynamiccontent.h" #include "dynamiccontent.h"
DynamicContent::DynamicContent(Template &templ, Database &database, UrlProvider &provider) DynamicContent::DynamicContent(Template &templ, Database &database, UrlProvider &provider, Session &session)
{ {
this->templ = &templ; this->templ = &templ;
this->database = &database; this->database = &database;
this->urlProvider = &provider; this->urlProvider = &provider;
this->userSession = &session;
} }

View File

@ -10,11 +10,12 @@ class DynamicContent
Template *templ; Template *templ;
Database *database; Database *database;
UrlProvider *urlProvider; UrlProvider *urlProvider;
Session *userSession;
std::string argument; std::string argument;
public: public:
DynamicContent(Template &templ, Database &database, UrlProvider &urlProvider); DynamicContent(Template &templ, Database &database, UrlProvider &urlProvider, Session &session);
virtual std::string render() = 0; virtual std::string render() = 0;
virtual void setArgument(std::string argument) virtual void setArgument(std::string argument)
{ {

View File

@ -9,18 +9,20 @@ private:
Template *templ; Template *templ;
Database *db; Database *db;
UrlProvider *urlProvider; UrlProvider *urlProvider;
Session *session;
public: public:
DynamicContentFactory(Template &templ, Database &db, UrlProvider &urlProvider) DynamicContentFactory(Template &templ, Database &db, UrlProvider &urlProvider, Session &session)
{ {
this->templ = &templ; this->templ = &templ;
this->db = &db; this->db = &db;
this->urlProvider = &urlProvider; this->urlProvider = &urlProvider;
this->session = &session;
} }
template <class T> inline std::shared_ptr<T> createDynamicContent() template <class T> inline std::shared_ptr<T> createDynamicContent()
{ {
return std::make_shared<T>(*this->templ, *this->db, *this->urlProvider); return std::make_shared<T>(*this->templ, *this->db, *this->urlProvider, *this->session);
} }

View File

@ -6,14 +6,21 @@ std::string DynamicContentPostList::render()
auto categoryDao = this->database->createCategoryDao(); auto categoryDao = this->database->createCategoryDao();
auto pageDao = this->database->createPageDao(); auto pageDao = this->database->createPageDao();
auto revisionDao = this->database->createRevisionDao(); auto revisionDao = this->database->createRevisionDao();
auto permissionDao = this->database->createPermissionsDao();
QueryOption option; QueryOption option;
option.includeInvisible = false; option.includeInvisible = false;
auto members = categoryDao->fetchMembers(this->argument, option); auto members = categoryDao->fetchMembers(this->argument, option);
std::vector<std::pair<std::string, time_t>> pageList; std::vector<std::pair<std::string, time_t>> pageList;
for(const Page &member : members) for(const Page &member : members)
{ {
auto revision = revisionDao->getRevisionForPage(member.name, 1); Permissions perms = permissionDao->find(member.name, this->userSession->user.login)
pageList.push_back({member.name, revision->timestamp}); .value_or(this->userSession->user.permissions);
if(perms.canRead()) /* TODO: Maybe add canList() */
{
auto revision = revisionDao->getRevisionForPage(member.name, 1);
pageList.push_back({member.name, revision->timestamp});
}
} }
std::sort(pageList.begin(), pageList.end(), std::sort(pageList.begin(), pageList.end(),
[](std::pair<std::string, time_t> &a, std::pair<std::string, time_t> &b) { return a.second > b.second; }); [](std::pair<std::string, time_t> &a, std::pair<std::string, time_t> &b) { return a.second > b.second; });

View File

@ -98,7 +98,10 @@ Response Handler::handle(const Request &r)
Permissions Handler::effectivePermissions(std::string page) Permissions Handler::effectivePermissions(std::string page)
{ {
return this->database->createPermissionsDao() Permissions &userPerms = this->userSession->user.permissions;
->find(page, this->userSession->user.login) if(userPerms.isAdmin())
.value_or(this->userSession->user.permissions); {
return userPerms;
}
return this->database->createPermissionsDao()->find(page, this->userSession->user.login).value_or(userPerms);
} }

View File

@ -1,19 +1,19 @@
#include "handlerfeedgenerator.h" #include "handlerfeedgenerator.h"
#include "../parser.h"
#include "../revisionrenderer.h" #include "../revisionrenderer.h"
std::vector<HandlerFeedGenerator::EntryRevisionPair> HandlerFeedGenerator::fetchEntries( std::vector<HandlerFeedGenerator::EntryRevisionPair> HandlerFeedGenerator::fetchEntries(
std::vector<std::string> categories) std::vector<std::string> categories)
{ {
auto revisionDao = this->database->createRevisionDao(); auto revisionDao = this->database->createRevisionDao();
auto pageDao = this->database->createPageDao(); auto pageDao = this->database->createPageDao();
auto permissionDao = this->database->createPermissionsDao();
std::vector<EntryRevisionPair> result; std::vector<EntryRevisionPair> result;
QueryOption option; QueryOption option;
option.includeInvisible = false; option.includeInvisible = false;
// option.limit = 20; // option.limit = 20;
auto comppage = [](const Page &a, const Page &b) { return a.name < b.name; }; auto comppage = [](const Page &a, const Page &b) { return a.name < b.name; };
std::set<Page, decltype(comppage)> members (comppage); std::set<Page, decltype(comppage)> members(comppage);
if(categories.empty()) if(categories.empty())
{ {
auto pages = pageDao->getPageList(option); auto pages = pageDao->getPageList(option);
@ -34,8 +34,13 @@ std::vector<HandlerFeedGenerator::EntryRevisionPair> HandlerFeedGenerator::fetch
} }
for(const Page &member : members) for(const Page &member : members)
{ {
auto revision = revisionDao->getRevisionForPage(member.name, 1).value(); Permissions perms = permissionDao->find(member.name, this->userSession->user.login)
result.push_back({member, revision}); .value_or(this->userSession->user.permissions);
if(perms.canRead())
{
auto revision = revisionDao->getRevisionForPage(member.name, 1).value();
result.push_back({member, revision});
}
} }
std::sort(result.begin(), result.end(), std::sort(result.begin(), result.end(),
[](EntryRevisionPair &a, EntryRevisionPair &b) { return a.second.timestamp > b.second.timestamp; }); [](EntryRevisionPair &a, EntryRevisionPair &b) { return a.second.timestamp > b.second.timestamp; });
@ -68,7 +73,7 @@ std::string HandlerFeedGenerator::generateAtom(const std::vector<HandlerFeedGene
subtitle = "All pages"; subtitle = "All pages";
} }
RevisionRenderer revisionRenderer { *this->templ, *this->database, *this->urlProvider }; RevisionRenderer revisionRenderer{*this->templ, *this->database, *this->urlProvider, *this->userSession};
for(const EntryRevisionPair &entry : entries) for(const EntryRevisionPair &entry : entries)
{ {

View File

@ -24,6 +24,7 @@ SOFTWARE.
#include "../parser.h" #include "../parser.h"
#include "../revisionrenderer.h" #include "../revisionrenderer.h"
bool HandlerPageEdit::canAccess([[maybe_unused]] std::string page) bool HandlerPageEdit::canAccess([[maybe_unused]] std::string page)
{ {
return effectivePermissions(page).canEdit(); return effectivePermissions(page).canEdit();
@ -56,7 +57,8 @@ Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename,
{ {
if(!effectivePermissions(from).canRead()) if(!effectivePermissions(from).canRead())
{ {
return this->errorResponse("Permission denied", "No access permissions, so you can't use this page as a template"); return this->errorResponse("Permission denied",
"No access permissions, so you can't use this page as a template");
} }
body = revisiondao->getCurrentForPage(from)->content; body = revisiondao->getCurrentForPage(from)->content;
} }
@ -77,6 +79,7 @@ Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename,
std::string visiblecmd = parser.extractCommand("visible", newContent); std::string visiblecmd = parser.extractCommand("visible", newContent);
std::string rename = parser.extractCommand("rename", newContent); std::string rename = parser.extractCommand("rename", newContent);
std::string customtitle = parser.extractCommand("pagetitle", newContent); std::string customtitle = parser.extractCommand("pagetitle", newContent);
std::vector<std::string> perms = parser.extractCommands("permissions", newContent);
Page page; Page page;
std::optional<Page> currentPage = pageDao.find(pagename); std::optional<Page> currentPage = pageDao.find(pagename);
if(currentPage) if(currentPage)
@ -91,6 +94,33 @@ Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename,
} }
pagename = rename; pagename = rename;
} }
for(const std::string &perm : perms)
{
auto splitted = utils::split(perm, '|');
if(splitted.size() != 2)
{
return this->errorResponse("Invalid command", "permissions command is misformated");
}
auto permissionDao = this->database->createPermissionsDao();
auto currentPermission = permissionDao->find(pagename, splitted[0]);
Permissions newPermissions = Permissions{splitted[1]};
if(!currentPermission || newPermissions != currentPermission.value())
{
if(this->userSession->user.permissions.canSetPagePerms())
{
permissionDao->save(pagename, splitted[0], newPermissions);
}
else
{
this->database->rollbackTransaction();
return errorResponse("Invalid permissions",
"You don't have permission to change page permissions");
}
}
}
page.current_revision = current_revision; page.current_revision = current_revision;
page.listed = !(visiblecmd == "0"); page.listed = !(visiblecmd == "0");
page.name = pagename; page.name = pagename;
@ -115,6 +145,7 @@ Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename,
} }
catch(const DatabaseException &e) catch(const DatabaseException &e)
{ {
this->database->rollbackTransaction();
Logger::debug() << "Error saving revision: " << e.what(); Logger::debug() << "Error saving revision: " << e.what();
return errorResponse("Database error", "A database error occured while trying to save this revision"); return errorResponse("Database error", "A database error occured while trying to save this revision");
} }
@ -129,7 +160,7 @@ Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename,
TemplatePage templatePage = this->templ->getPage("page_creation_preview"); TemplatePage templatePage = this->templ->getPage("page_creation_preview");
templatePage.setVar("actionurl", urlProvider->editPage(pagename)); templatePage.setVar("actionurl", urlProvider->editPage(pagename));
RevisionRenderer revisionRenderer { *this->templ, *this->database, *this->urlProvider }; RevisionRenderer revisionRenderer{*this->templ, *this->database, *this->urlProvider, *this->userSession};
templatePage.setVar("preview_content", revisionRenderer.renderContent(newContent)); templatePage.setVar("preview_content", revisionRenderer.renderContent(newContent));
templatePage.setVar("content", newContent); templatePage.setVar("content", newContent);

View File

@ -138,8 +138,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename,
Response result; Response result;
result.setStatus(200); result.setStatus(200);
RevisionRenderer revisionRenderer { *this->templ, *this->database, *this->urlProvider }; RevisionRenderer revisionRenderer{*this->templ, *this->database, *this->urlProvider, *this->userSession};
std::string customtitle = parser.extractCommand("pagetitle", revision->content); std::string customtitle = parser.extractCommand("pagetitle", revision->content);
std::string parsedcontent = revisionRenderer.renderContent(revision.value(), customtitle); std::string parsedcontent = revisionRenderer.renderContent(revision.value(), customtitle);

View File

@ -16,6 +16,8 @@ class IParser
public: public:
virtual std::string extractCommand(std::string cmdname, const std::string &content) const = 0; virtual std::string extractCommand(std::string cmdname, const std::string &content) const = 0;
virtual std::vector<std::string> extractCommands(std::string cmdname, const std::string &content) const = 0;
virtual std::vector<Headline> extractHeadlines(const std::string &content) const = 0; virtual std::vector<Headline> extractHeadlines(const std::string &content) const = 0;
virtual inline std::string parse(const PageDao &pagedao, UrlProvider &provider, const std::string &content) const virtual inline std::string parse(const PageDao &pagedao, UrlProvider &provider, const std::string &content) const
{ {

View File

@ -82,6 +82,28 @@ std::string Parser::extractCommand(std::string cmdname, const std::string &conte
} }
return ""; return "";
} }
std::vector<std::string> Parser::extractCommands(std::string cmdname, const std::string &content) const
{
std::vector<std::string> result;
std::string cmd = "[cmd:" + cmdname + "]";
std::string cmdend = "[/cmd:" + cmdname + "]";
std::string_view view = content;
size_t pos = 0;
while((pos = view.find(cmd)) != std::string::npos)
{
view.remove_prefix(pos);
view.remove_prefix(cmd.size());
if((pos = view.find(cmdend)) != std::string::npos)
{
result.emplace_back(view.substr(0, pos));
}
}
return result;
}
std::string Parser::processLink(const PageDao &pageDao, UrlProvider &urlProvider, std::smatch &match) const std::string Parser::processLink(const PageDao &pageDao, UrlProvider &urlProvider, std::smatch &match) const
{ {
std::string linktag = match.str(1); std::string linktag = match.str(1);
@ -148,7 +170,7 @@ std::string Parser::parse(const PageDao &pagedao, UrlProvider &provider, const s
std::string result; std::string result;
// we don't care about commands, but we nevertheless replace them with empty strings // we don't care about commands, but we nevertheless replace them with empty strings
std::regex tagfinder( std::regex tagfinder(
R"(\[(b|i|u|s|li||ul|ol|code|blockquote|img|link|wikilink|h\d|cmd:visible|cmd:rename|cmd:redirect|cmd:pagetitle|cmd:allowinclude|category|dynamic:postlist|dynamic:includepage|dynamic:getvar|dynamic:setvar)*?\]((\s|\S)*?)\[/\1])"); R"(\[(b|i|u|s|li||ul|ol|code|blockquote|img|link|wikilink|h\d|cmd:visible|cmd:rename|cmd:redirect|cmd:pagetitle|cmd:allowinclude|cmd:permissions|category|dynamic:postlist|dynamic:includepage|dynamic:getvar|dynamic:setvar)*?\]((\s|\S)*?)\[/\1])");
result = utils::regex_callback_replacer( result = utils::regex_callback_replacer(
tagfinder, content, tagfinder, content,
[&](std::smatch &match) [&](std::smatch &match)
@ -180,7 +202,7 @@ std::string Parser::parse(const PageDao &pagedao, UrlProvider &provider, const s
} }
if(tag == "code" || tag == "blockquote") if(tag == "code" || tag == "blockquote")
{ {
return "<pre><" + tag + ">"+ utils::strreplace(content, "\r\n", "\n") + "</"+tag+"></pre>"; return "<pre><" + tag + ">" + utils::strreplace(content, "\r\n", "\n") + "</" + tag + "></pre>";
} }
return callback(tag, content); return callback(tag, content);
}); });

View File

@ -9,7 +9,8 @@ class Parser : public IParser
std::string processImage(std::smatch &match) const; std::string processImage(std::smatch &match) const;
public: public:
std::string extractCommand(std::string cmdname, const std::string &content) const; std::string extractCommand(std::string cmdname, const std::string &content) const override;
std::vector<std::string> extractCommands(std::string cmdname, const std::string &content) const override;
std::vector<Headline> extractHeadlines(const std::string &content) const override; std::vector<Headline> extractHeadlines(const std::string &content) const override;
std::vector<std::string> extractCategories(const std::string &content) const override; std::vector<std::string> extractCategories(const std::string &content) const override;
using IParser::parse; using IParser::parse;

View File

@ -20,7 +20,8 @@ SOFTWARE.
*/ */
#include "permissions.h" #include "permissions.h"
static const std::map<std::string, int> permmap = {{"can_read", PERM_CAN_READ}, static const std::map<std::string, int> permmap = {{"can_nothing", PERM_CAN_NOTHING},
{"can_read", PERM_CAN_READ},
{"can_edit", PERM_CAN_EDIT}, {"can_edit", PERM_CAN_EDIT},
{"can_page_history", PERM_CAN_PAGE_HISTORY}, {"can_page_history", PERM_CAN_PAGE_HISTORY},
{"can_global_history", PERM_CAN_GLOBAL_HISTORY}, {"can_global_history", PERM_CAN_GLOBAL_HISTORY},
@ -29,7 +30,8 @@ static const std::map<std::string, int> permmap = {{"can_read", PERM_CAN_READ},
{"can_create", PERM_CAN_CREATE}, {"can_create", PERM_CAN_CREATE},
{"can_see_category_list", PERM_CAN_SEE_CATEGORY_LIST}, {"can_see_category_list", PERM_CAN_SEE_CATEGORY_LIST},
{"can_see_links_here", PERM_CAN_SEE_LINKS_HERE}, {"can_see_links_here", PERM_CAN_SEE_LINKS_HERE},
{"can_search", PERM_CAN_SEARCH}}; {"can_search", PERM_CAN_SEARCH},
{"can_set_page_perms", PERM_CAN_SET_PAGE_PERMS}};
Permissions::Permissions(int permissions) Permissions::Permissions(int permissions)
{ {

View File

@ -1,6 +1,7 @@
#ifndef PERMISSIONS_H #ifndef PERMISSIONS_H
#define PERMISSIONS_H #define PERMISSIONS_H
#define PERM_CAN_NOTHING 0
#define PERM_CAN_READ 1 << 0 #define PERM_CAN_READ 1 << 0
#define PERM_CAN_EDIT 1 << 1 #define PERM_CAN_EDIT 1 << 1
#define PERM_CAN_PAGE_HISTORY 1 << 2 #define PERM_CAN_PAGE_HISTORY 1 << 2
@ -11,6 +12,8 @@
#define PERM_CAN_SEE_CATEGORY_LIST 1 << 7 #define PERM_CAN_SEE_CATEGORY_LIST 1 << 7
#define PERM_CAN_SEE_LINKS_HERE 1 << 8 #define PERM_CAN_SEE_LINKS_HERE 1 << 8
#define PERM_CAN_SEARCH 1 << 9 #define PERM_CAN_SEARCH 1 << 9
#define PERM_CAN_SET_PAGE_PERMS 1 << 10
#define PERM_IS_ADMIN (1L<<31)-1
#include <string> #include <string>
#include <map> #include <map>
@ -54,10 +57,16 @@ class Permissions
return this->permissions; return this->permissions;
} }
bool canNothing() const
{
return this->permissions == PERM_CAN_NOTHING;
}
bool canRead() const bool canRead() const
{ {
return this->permissions & PERM_CAN_READ; return this->permissions & PERM_CAN_READ;
} }
bool canEdit() const bool canEdit() const
{ {
return this->permissions & PERM_CAN_EDIT; return this->permissions & PERM_CAN_EDIT;
@ -95,12 +104,27 @@ class Permissions
return this->permissions & PERM_CAN_SEE_PAGE_LIST; return this->permissions & PERM_CAN_SEE_PAGE_LIST;
} }
bool canSetPagePerms() const
{
return this->permissions & PERM_CAN_SET_PAGE_PERMS;
}
bool isAdmin() const
{
return this->permissions == PERM_IS_ADMIN;
}
std::string toString() const std::string toString() const
{ {
return Permissions::toString(this->permissions); return Permissions::toString(this->permissions);
} }
static std::string toString(int perms); static std::string toString(int perms);
bool operator==(const Permissions &o) const
{
return this->permissions == o.permissions;
}
}; };
#endif // PERMISSIONS_H #endif // PERMISSIONS_H

View File

@ -37,6 +37,7 @@ SOFTWARE.
#include "urlprovider.h" #include "urlprovider.h"
#include "requestworker.h" #include "requestworker.h"
#include "cache/fscache.h" #include "cache/fscache.h"
#include "cache/nocache.h"
#include "sandbox/sandboxfactory.h" #include "sandbox/sandboxfactory.h"
#include "cli.h" #include "cli.h"
#include "cliconsole.h" #include "cliconsole.h"
@ -68,9 +69,11 @@ static struct option long_options[] = {{"cli", no_argument, 0, 'c'}, {"version",
std::unique_ptr<ICache> createCache(const ConfigVariableResolver &resolver) std::unique_ptr<ICache> createCache(const ConfigVariableResolver &resolver)
{ {
std::string path = resolver.getConfig("cache_fs_dir"); std::string path = resolver.getConfig("cache_fs_dir");
if(path == "")
{
return std::make_unique<NoCache>(path);
}
return std::make_unique<FsCache>(path); return std::make_unique<FsCache>(path);
} }

View File

@ -17,7 +17,7 @@ private:
Parser parser; Parser parser;
public: public:
RevisionRenderer(Template &templ, Database &db, UrlProvider &urlProvider) :dynamicContentFactory(templ, db, urlProvider) RevisionRenderer(Template &templ, Database &db, UrlProvider &urlProvider, Session &session) :dynamicContentFactory(templ, db, urlProvider, session)
{ {
this->db = &db; this->db = &db;
this->urlProvider = &urlProvider; this->urlProvider = &urlProvider;