diff --git a/handlers/handler.cpp b/handlers/handler.cpp index 8203661..cdd5980 100644 --- a/handlers/handler.cpp +++ b/handlers/handler.cpp @@ -77,3 +77,18 @@ QueryOption Handler::queryOption(const Request &r) const return result; } + +Response Handler::handle(const Request &r) +{ + if(!canAccess(this->userSession->user.permissions)) + { + return errorResponse("Permission denied", accessErrorMessage()); + } + return handleRequest(r); +} + +Permissions Handler::effectivePermissions(std::string page) +{ + return this->database->createPermissionsDao()->find(page, this->userSession->user.login).value_or(this->userSession->user.permissions); +} + diff --git a/handlers/handler.h b/handlers/handler.h index 641cc5c..948984b 100644 --- a/handlers/handler.h +++ b/handlers/handler.h @@ -18,6 +18,8 @@ protected: Session *userSession; UrlProvider *urlProvider; + //TODO: may not to find a better place for this method + Permissions effectivePermissions(std::string page); QueryOption queryOption(const Request &r) const; public: Handler(Template &templ, Database &db, Session &userSession, UrlProvider &provider, ICache &cache) @@ -28,7 +30,19 @@ public: this->urlProvider = &provider; this->cache = &cache; } - virtual Response handle(const Request &r) = 0; + + virtual Response handle(const Request &r); + virtual Response handleRequest(const Request &r) + { + return this->errorResponse("Invalid action", "This action is not implemented yet"); + } + + virtual bool canAccess(const Permissions &perms) { + return false; + } + virtual std::string accessErrorMessage() { + return "No permission for this action"; + } void setGeneralVars(TemplatePage &page); virtual ~Handler() { } Response errorResponse(std::string errortitle, std::string errormessage, int status = 200); diff --git a/handlers/handlerallcategories.cpp b/handlers/handlerallcategories.cpp index 4868889..02201d9 100644 --- a/handlers/handlerallcategories.cpp +++ b/handlers/handlerallcategories.cpp @@ -21,7 +21,7 @@ SOFTWARE. #include "handlerallcategories.h" #include "../urlprovider.h" #include "../logger.h" -Response HandlerAllCategories::handle(const Request &r) +Response HandlerAllCategories::handleRequest(const Request &r) { auto categoryDao = this->database->createCategoryDao(); QueryOption qo = queryOption(r); @@ -42,3 +42,13 @@ Response HandlerAllCategories::handle(const Request &r) response.setStatus(200); return response; } + +std::string HandlerAllCategories::accessErrorMessage() +{ + return "You don't have permission to list all categories"; +} + +bool HandlerAllCategories::canAccess(const Permissions &perms) +{ + return perms.canSeeCategoryList(); +} diff --git a/handlers/handlerallcategories.h b/handlers/handlerallcategories.h index 010f1ba..4d92bea 100644 --- a/handlers/handlerallcategories.h +++ b/handlers/handlerallcategories.h @@ -9,7 +9,9 @@ class HandlerAllCategories : public Handler public: HandlerAllCategories(); using Handler::Handler; - Response handle(const Request &r) override; + Response handleRequest(const Request &r) override; + std::string accessErrorMessage() override; + bool canAccess(const Permissions &perms) override; }; #endif // HANDLERALLCATEGORIES_H diff --git a/handlers/handlerallpages.cpp b/handlers/handlerallpages.cpp index 329ef5f..353c53a 100644 --- a/handlers/handlerallpages.cpp +++ b/handlers/handlerallpages.cpp @@ -20,9 +20,7 @@ SOFTWARE. */ #include "handlerallpages.h" - - -Response HandlerAllPages::handle(const Request &r) +Response HandlerAllPages::handleRequest(const Request &r) { try { @@ -49,3 +47,14 @@ Response HandlerAllPages::handle(const Request &r) } } + +std::string HandlerAllPages::accessErrorMessage() +{ + return "You don't permissions to list all pages"; +} + +bool HandlerAllPages::canAccess(const Permissions &perms) +{ + return perms.canSeePageList(); +} + diff --git a/handlers/handlerallpages.h b/handlers/handlerallpages.h index 1fb9ed5..c667655 100644 --- a/handlers/handlerallpages.h +++ b/handlers/handlerallpages.h @@ -7,7 +7,9 @@ class HandlerAllPages : public Handler public: HandlerAllPages(); using Handler::Handler; - Response handle(const Request &r) override; + Response handleRequest(const Request &r) override; + std::string accessErrorMessage() override; + bool canAccess(const Permissions &perms) override; }; #endif // HANDLERALLPAGES_H diff --git a/handlers/handlercategory.cpp b/handlers/handlercategory.cpp index 8d600af..275bb52 100644 --- a/handlers/handlercategory.cpp +++ b/handlers/handlercategory.cpp @@ -21,7 +21,7 @@ SOFTWARE. #include "handlercategory.h" -Response HandlerCategory::handle(const Request &r) +Response HandlerCategory::handleRequest(const Request &r) { try { @@ -49,3 +49,13 @@ Response HandlerCategory::handle(const Request &r) return errorResponse("Error", "An unknown error occured"); } } + +std::string HandlerCategory::accessErrorMessage() +{ + return "You don't have permission to view categories"; +} + +bool HandlerCategory::canAccess(const Permissions &perms) +{ + return perms.canRead(); //TODO: we may need a more specific permission +} diff --git a/handlers/handlercategory.h b/handlers/handlercategory.h index 8bbf10c..a46e5f6 100644 --- a/handlers/handlercategory.h +++ b/handlers/handlercategory.h @@ -7,7 +7,9 @@ class HandlerCategory : public Handler public: HandlerCategory(); using Handler::Handler; - Response handle(const Request &r) override; + Response handleRequest(const Request &r) override; + std::string accessErrorMessage() override; + bool canAccess(const Permissions &perms) override; }; #endif // HANDLERCATEGORY_H diff --git a/handlers/handlerdefault.cpp b/handlers/handlerdefault.cpp index ec60b2e..9aa121c 100644 --- a/handlers/handlerdefault.cpp +++ b/handlers/handlerdefault.cpp @@ -21,7 +21,7 @@ SOFTWARE. #include "handlerdefault.h" -Response HandlerDefault::handle(const Request &r) +Response HandlerDefault::handleRequest(const Request &r) { return Response::redirectTemporarily(this->urlProvider->index()); } @@ -30,3 +30,8 @@ HandlerDefault::~HandlerDefault() { } + +bool HandlerDefault::canAccess(const Permissions &perms) +{ + return true; +} diff --git a/handlers/handlerdefault.h b/handlers/handlerdefault.h index 15547e2..f90e6b1 100644 --- a/handlers/handlerdefault.h +++ b/handlers/handlerdefault.h @@ -5,9 +5,10 @@ class HandlerDefault : public Handler { public: - Response handle(const Request &r) override; + Response handleRequest(const Request &r) override; ~HandlerDefault() override; using Handler::Handler; + bool canAccess(const Permissions &perms) override; }; #endif // HANDLERDEFAULT_H diff --git a/handlers/handlerhistory.cpp b/handlers/handlerhistory.cpp index a1151ce..893fd69 100644 --- a/handlers/handlerhistory.cpp +++ b/handlers/handlerhistory.cpp @@ -23,11 +23,28 @@ SOFTWARE. #include "../htmllink.h" #include "../logger.h" #include "../database/exceptions.h" -Response HandlerHistory::handle(const Request &r) +Response HandlerHistory::handleRequest(const Request &r) { QueryOption qo = queryOption(r); std::string page = r.get("page"); + if(page.empty()) + { + if(!this->userSession->user.permissions.canSeeGlobalHistory()) + { + return errorResponse("Permission denied", "You can't see the changes history on this wiki", 403); + } + } + else + { + Permissions perms = effectivePermissions(page); + if(!perms.canSeePageHistory()) + { + return errorResponse("Permission denied", "You cannot see the changes history of this page", 403); + } + } + + unsigned int count = 0; std::vector resultList; auto revisionDao = this->database->createRevisionDao(); @@ -104,3 +121,10 @@ Response HandlerHistory::handle(const Request &r) response.setStatus(200); return response; } + + +bool HandlerHistory::canAccess(const Permissions &perms) +{ + return true; //This is a lie but we need to this a little more fine grained here, which we do in the handleRequest +} + diff --git a/handlers/handlerhistory.h b/handlers/handlerhistory.h index fea08a6..60e44db 100644 --- a/handlers/handlerhistory.h +++ b/handlers/handlerhistory.h @@ -8,7 +8,8 @@ class HandlerHistory : public Handler public: HandlerHistory(); using Handler::Handler; - Response handle(const Request &r) override; + Response handleRequest(const Request &r) override; + bool canAccess(const Permissions &perms) override; }; #endif // HANDLERHISTORY_H diff --git a/handlers/handlerinvalidaction.cpp b/handlers/handlerinvalidaction.cpp index 58c1e7c..549b762 100644 --- a/handlers/handlerinvalidaction.cpp +++ b/handlers/handlerinvalidaction.cpp @@ -21,7 +21,12 @@ SOFTWARE. #include "handlerinvalidaction.h" -Response HandlerInvalidAction::handle(const Request &r) +Response HandlerInvalidAction::handleRequest(const Request &r) { return errorResponse("Invalid action", "No action defined for this action"); } + +bool HandlerInvalidAction::canAccess(const Permissions &perms) +{ + return true; +} diff --git a/handlers/handlerinvalidaction.h b/handlers/handlerinvalidaction.h index 37690c4..0b54d52 100644 --- a/handlers/handlerinvalidaction.h +++ b/handlers/handlerinvalidaction.h @@ -5,8 +5,9 @@ class HandlerInvalidAction : public Handler { public: - Response handle(const Request &r) override; + Response handleRequest(const Request &r) override; ~HandlerInvalidAction() override { } + bool canAccess(const Permissions &perms) override; using Handler::Handler; }; diff --git a/handlers/handlerlogin.cpp b/handlers/handlerlogin.cpp index 5c84f9b..50caf14 100644 --- a/handlers/handlerlogin.cpp +++ b/handlers/handlerlogin.cpp @@ -66,7 +66,7 @@ std::vector HandlerLogin::pbkdf5(std::string password, const std::vectorenabled) + { + return errorResponse("Login failed", "The user account has been disabled"); + } auto hashresult = pbkdf5(password, user.value().salt); //TODO: timing attack @@ -121,3 +125,8 @@ Response HandlerLogin::handle(const Request &r) result.setBody(loginTemplatePage.render()); return result; } + +bool HandlerLogin::canAccess(const Permissions &perms) +{ + return true; +} diff --git a/handlers/handlerlogin.h b/handlers/handlerlogin.h index 7ffd250..357a835 100644 --- a/handlers/handlerlogin.h +++ b/handlers/handlerlogin.h @@ -11,8 +11,9 @@ private: std::vector pbkdf5(std::string password, const std::vector &salt); public: HandlerLogin(); - Response handle(const Request &r) override; + Response handleRequest(const Request &r) override; ~HandlerLogin() override { } + bool canAccess(const Permissions &perms) override; using Handler::Handler; }; diff --git a/handlers/handlerpage.cpp b/handlers/handlerpage.cpp index 6f693eb..43dfe41 100644 --- a/handlers/handlerpage.cpp +++ b/handlers/handlerpage.cpp @@ -18,6 +18,7 @@ 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 #include "handlerpage.h" @@ -92,3 +93,5 @@ void HandlerPage::setPageVars(TemplatePage &page, std::string pagename) } + + diff --git a/handlers/handlerpage.h b/handlers/handlerpage.h index 0d6ec20..e908bc8 100644 --- a/handlers/handlerpage.h +++ b/handlers/handlerpage.h @@ -11,7 +11,7 @@ protected: public: Response handle(const Request &r) override; - virtual Response handleRequest(PageDao &pageDao, std::string pagename, const Request &r) =0; + virtual Response handleRequest(PageDao &pageDao, std::string pagename, const Request &r) = 0; ~HandlerPage() override { } using Handler::Handler; diff --git a/handlers/handlerpagedelete.cpp b/handlers/handlerpagedelete.cpp index b429fdd..dcf44b8 100644 --- a/handlers/handlerpagedelete.cpp +++ b/handlers/handlerpagedelete.cpp @@ -21,6 +21,21 @@ SOFTWARE. #include "handlerpagedelete.h" #include "../database/exceptions.h" +bool HandlerPageDelete::pageMustExist() +{ + return true; +} + +bool HandlerPageDelete::canAccess(std::string page) +{ + return effectivePermissions(page).canDelete(); +} + +std::string HandlerPageDelete::accessErrorMessage() +{ + return "You don't have permission to delete pages"; +} + Response HandlerPageDelete::handleRequest(PageDao &pageDao, std::string pagename, const Request &r) { try diff --git a/handlers/handlerpagedelete.h b/handlers/handlerpagedelete.h index d565ba2..55a57e3 100644 --- a/handlers/handlerpagedelete.h +++ b/handlers/handlerpagedelete.h @@ -4,20 +4,11 @@ class HandlerPageDelete : public HandlerPage { - bool pageMustExist() override - { - return true; - } + bool pageMustExist() override; - bool canAccess(std::string page) override - { - return this->userSession->user.permissions.canDelete(); - } + bool canAccess(std::string page) override; - std::string accessErrorMessage() override - { - return "You don't have permission to delete pages"; - } + std::string accessErrorMessage() override; public: Response handleRequest(PageDao &pageDao, std::string pagename, const Request &r) override; using HandlerPage::HandlerPage; diff --git a/handlers/handlerpageview.cpp b/handlers/handlerpageview.cpp index a15177c..128f226 100644 --- a/handlers/handlerpageview.cpp +++ b/handlers/handlerpageview.cpp @@ -26,7 +26,12 @@ SOFTWARE. bool HandlerPageView::canAccess(std::string page) { - return this->userSession->user.permissions.canRead(); + return effectivePermissions(page).canRead(); +} + +std::string HandlerPageView::accessErrorMessage() +{ + return "You don't have permission to view this page"; } std::string HandlerPageView::createIndexContent(IParser &parser, std::string content) diff --git a/handlers/handlerpageview.h b/handlers/handlerpageview.h index fd8485c..e2003f3 100644 --- a/handlers/handlerpageview.h +++ b/handlers/handlerpageview.h @@ -9,10 +9,7 @@ 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 accessErrorMessage() override; std::string createIndexContent(IParser &parser, std::string content); public: diff --git a/handlers/handlersearch.cpp b/handlers/handlersearch.cpp index 2f7df6a..2529695 100644 --- a/handlers/handlersearch.cpp +++ b/handlers/handlersearch.cpp @@ -19,7 +19,7 @@ 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 HandlerSearch::handleRequest(const Request &r) { Response response; std::string q = r.get("q"); @@ -61,3 +61,13 @@ Response HandlerSearch::handle(const Request &r) } +bool HandlerSearch::canAccess(const Permissions &perms) +{ + return perms.canSearch(); +} + +std::string HandlerSearch::accessErrorMessage() +{ + return "You are not allowed to search this wiki"; +} + diff --git a/handlers/handlersearch.h b/handlers/handlersearch.h index 0d166b0..67a993d 100644 --- a/handlers/handlersearch.h +++ b/handlers/handlersearch.h @@ -7,7 +7,9 @@ class HandlerSearch : public Handler public: HandlerSearch(); using Handler::Handler; - Response handle(const Request &r) override; + Response handleRequest(const Request &r) override; + bool canAccess(const Permissions &perms) override; + std::string accessErrorMessage(); }; #endif // HANDLERSEARCH_H