handlers: permisison check for all pages + retrieve user-specific permissions for pages (if any)

Este commit está contenido en:
Albert S. 2019-05-03 15:59:29 +02:00
padre 9c0dfd170e
commit 7d1cae24a9
Se han modificado 24 ficheros con 171 adiciones y 37 borrados

Ver fichero

@ -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);
}

Ver fichero

@ -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);

Ver fichero

@ -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();
}

Ver fichero

@ -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

Ver fichero

@ -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();
}

Ver fichero

@ -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

Ver fichero

@ -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
}

Ver fichero

@ -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

Ver fichero

@ -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;
}

Ver fichero

@ -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

Ver fichero

@ -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<Revision> 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
}

Ver fichero

@ -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

Ver fichero

@ -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;
}

Ver fichero

@ -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;
};

Ver fichero

@ -66,7 +66,7 @@ std::vector<char> HandlerLogin::pbkdf5(std::string password, const std::vector<c
}
Response HandlerLogin::handle(const Request &r)
Response HandlerLogin::handleRequest(const Request &r)
{
auto createErrorReesponse = [&]() { return errorResponse("Login error", "The supplied credenetials are incorrect"); };
@ -85,6 +85,10 @@ Response HandlerLogin::handle(const Request &r)
{
return createErrorReesponse();
}
if(!user->enabled)
{
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;
}

Ver fichero

@ -11,8 +11,9 @@ private:
std::vector<char> pbkdf5(std::string password, const std::vector<char> &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;
};

Ver fichero

@ -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 <optional>
#include "handlerpage.h"
@ -92,3 +93,5 @@ void HandlerPage::setPageVars(TemplatePage &page, std::string pagename)
}

Ver fichero

@ -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;

Ver fichero

@ -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

Ver fichero

@ -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;

Ver fichero

@ -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)

Ver fichero

@ -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:

Ver fichero

@ -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";
}

Ver fichero

@ -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