From 763030116882ebf343879d36ee2b84bd80516815 Mon Sep 17 00:00:00 2001 From: Albert S Date: Fri, 3 May 2019 15:59:29 +0200 Subject: [PATCH] handlers: permisison check for all pages + retrieve user-specific permissions for pages (if any) --- handlers/handler.cpp | 16 ++++++++++++++++ handlers/handler.h | 18 +++++++++++++++++- handlers/handlerallcategories.cpp | 12 +++++++++++- handlers/handlerallcategories.h | 4 +++- handlers/handlerallpages.cpp | 12 +++++++++++- handlers/handlerallpages.h | 4 +++- handlers/handlercategory.cpp | 12 +++++++++++- handlers/handlercategory.h | 4 +++- handlers/handlerdefault.cpp | 7 ++++++- handlers/handlerdefault.h | 3 ++- handlers/handlerhistory.cpp | 23 ++++++++++++++++++++++- handlers/handlerhistory.h | 3 ++- handlers/handlerinvalidaction.cpp | 7 ++++++- handlers/handlerinvalidaction.h | 3 ++- handlers/handlerlogin.cpp | 11 ++++++++++- handlers/handlerlogin.h | 3 ++- handlers/handlerpage.cpp | 1 + handlers/handlerpagedelete.cpp | 15 +++++++++++++++ handlers/handlerpagedelete.h | 15 +++------------ handlers/handlerpageview.cpp | 7 ++++++- handlers/handlerpageview.h | 5 +---- handlers/handlersearch.cpp | 12 +++++++++++- handlers/handlersearch.h | 4 +++- 23 files changed, 167 insertions(+), 34 deletions(-) diff --git a/handlers/handler.cpp b/handlers/handler.cpp index dbc1f4a..2111f48 100644 --- a/handlers/handler.cpp +++ b/handlers/handler.cpp @@ -74,3 +74,19 @@ 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 611d692..929c430 100644 --- a/handlers/handler.h +++ b/handlers/handler.h @@ -18,6 +18,8 @@ class Handler 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: @@ -29,7 +31,21 @@ class Handler 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() { diff --git a/handlers/handlerallcategories.cpp b/handlers/handlerallcategories.cpp index efe3b86..b00a0d4 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); @@ -43,3 +43,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 0835977..84880b4 100644 --- a/handlers/handlerallcategories.h +++ b/handlers/handlerallcategories.h @@ -8,7 +8,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 26c2609..2ac6373 100644 --- a/handlers/handlerallpages.cpp +++ b/handlers/handlerallpages.cpp @@ -20,7 +20,7 @@ SOFTWARE. */ #include "handlerallpages.h" -Response HandlerAllPages::handle(const Request &r) +Response HandlerAllPages::handleRequest(const Request &r) { try { @@ -46,3 +46,13 @@ Response HandlerAllPages::handle(const Request &r) return errorResponse("Error", "An unknown error occured"); } } + +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 cd68c26..68703aa 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 961f97d..99844dc 100644 --- a/handlers/handlercategory.cpp +++ b/handlers/handlercategory.cpp @@ -20,7 +20,7 @@ SOFTWARE. */ #include "handlercategory.h" -Response HandlerCategory::handle(const Request &r) +Response HandlerCategory::handleRequest(const Request &r) { try { @@ -48,3 +48,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 5370004..3d55c86 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 af53ebf..ac55c25 100644 --- a/handlers/handlerdefault.cpp +++ b/handlers/handlerdefault.cpp @@ -20,7 +20,7 @@ SOFTWARE. */ #include "handlerdefault.h" -Response HandlerDefault::handle(const Request &r) +Response HandlerDefault::handleRequest(const Request &r) { return Response::redirectTemporarily(this->urlProvider->index()); } @@ -28,3 +28,8 @@ Response HandlerDefault::handle(const Request &r) HandlerDefault::~HandlerDefault() { } + +bool HandlerDefault::canAccess(const Permissions &perms) +{ + return true; +} diff --git a/handlers/handlerdefault.h b/handlers/handlerdefault.h index 3cb2ab6..32f6ccc 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 2bd5f70..703a6d1 100644 --- a/handlers/handlerhistory.cpp +++ b/handlers/handlerhistory.cpp @@ -23,11 +23,27 @@ 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(); @@ -102,3 +118,8 @@ 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 2988688..794b07d 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 281cf1d..a96880b 100644 --- a/handlers/handlerinvalidaction.cpp +++ b/handlers/handlerinvalidaction.cpp @@ -20,7 +20,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 b278724..eca9c14 100644 --- a/handlers/handlerinvalidaction.h +++ b/handlers/handlerinvalidaction.h @@ -5,10 +5,11 @@ 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 bc7e2c9..9770fd2 100644 --- a/handlers/handlerlogin.cpp +++ b/handlers/handlerlogin.cpp @@ -64,7 +64,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 @@ -116,3 +120,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 7772dd6..5e3c029 100644 --- a/handlers/handlerlogin.h +++ b/handlers/handlerlogin.h @@ -12,10 +12,11 @@ class HandlerLogin : public Handler 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 8604e2b..2eead55 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" Response HandlerPage::handle(const Request &r) diff --git a/handlers/handlerpagedelete.cpp b/handlers/handlerpagedelete.cpp index 23fcd96..2498f0e 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 2d5e664..2718fb4 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; diff --git a/handlers/handlerpageview.cpp b/handlers/handlerpageview.cpp index 018089e..d0e63b9 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 8a970c1..a28f902 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 e0bbf3e..4dbcc4d 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) return errorResponse("Technical Error", "The system failed to perform your search"); } } + +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 43048d0..4107abc 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