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

This commit is contained in:
Albert S. 2019-05-03 15:59:29 +02:00
父節點 e87c3a0f4d
當前提交 7630301168
共有 23 個檔案被更改,包括 167 行新增34 行删除

查看文件

@ -74,3 +74,19 @@ QueryOption Handler::queryOption(const Request &r) const
return result; 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);
}

查看文件

@ -18,6 +18,8 @@ class Handler
Session *userSession; Session *userSession;
UrlProvider *urlProvider; UrlProvider *urlProvider;
// TODO: may not to find a better place for this method
Permissions effectivePermissions(std::string page);
QueryOption queryOption(const Request &r) const; QueryOption queryOption(const Request &r) const;
public: public:
@ -29,7 +31,21 @@ class Handler
this->urlProvider = &provider; this->urlProvider = &provider;
this->cache = &cache; 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); void setGeneralVars(TemplatePage &page);
virtual ~Handler() virtual ~Handler()
{ {

查看文件

@ -21,7 +21,7 @@ SOFTWARE.
#include "handlerallcategories.h" #include "handlerallcategories.h"
#include "../urlprovider.h" #include "../urlprovider.h"
#include "../logger.h" #include "../logger.h"
Response HandlerAllCategories::handle(const Request &r) Response HandlerAllCategories::handleRequest(const Request &r)
{ {
auto categoryDao = this->database->createCategoryDao(); auto categoryDao = this->database->createCategoryDao();
QueryOption qo = queryOption(r); QueryOption qo = queryOption(r);
@ -43,3 +43,13 @@ Response HandlerAllCategories::handle(const Request &r)
response.setStatus(200); response.setStatus(200);
return response; 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();
}

查看文件

@ -8,7 +8,9 @@ class HandlerAllCategories : public Handler
public: public:
HandlerAllCategories(); HandlerAllCategories();
using Handler::Handler; 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 #endif // HANDLERALLCATEGORIES_H

查看文件

@ -20,7 +20,7 @@ SOFTWARE.
*/ */
#include "handlerallpages.h" #include "handlerallpages.h"
Response HandlerAllPages::handle(const Request &r) Response HandlerAllPages::handleRequest(const Request &r)
{ {
try try
{ {
@ -46,3 +46,13 @@ Response HandlerAllPages::handle(const Request &r)
return errorResponse("Error", "An unknown error occured"); 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();
}

查看文件

@ -7,7 +7,9 @@ class HandlerAllPages : public Handler
public: public:
HandlerAllPages(); HandlerAllPages();
using Handler::Handler; 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 #endif // HANDLERALLPAGES_H

查看文件

@ -20,7 +20,7 @@ SOFTWARE.
*/ */
#include "handlercategory.h" #include "handlercategory.h"
Response HandlerCategory::handle(const Request &r) Response HandlerCategory::handleRequest(const Request &r)
{ {
try try
{ {
@ -48,3 +48,13 @@ Response HandlerCategory::handle(const Request &r)
return errorResponse("Error", "An unknown error occured"); 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
}

查看文件

@ -7,7 +7,9 @@ class HandlerCategory : public Handler
public: public:
HandlerCategory(); HandlerCategory();
using Handler::Handler; 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 #endif // HANDLERCATEGORY_H

查看文件

@ -20,7 +20,7 @@ SOFTWARE.
*/ */
#include "handlerdefault.h" #include "handlerdefault.h"
Response HandlerDefault::handle(const Request &r) Response HandlerDefault::handleRequest(const Request &r)
{ {
return Response::redirectTemporarily(this->urlProvider->index()); return Response::redirectTemporarily(this->urlProvider->index());
} }
@ -28,3 +28,8 @@ Response HandlerDefault::handle(const Request &r)
HandlerDefault::~HandlerDefault() HandlerDefault::~HandlerDefault()
{ {
} }
bool HandlerDefault::canAccess(const Permissions &perms)
{
return true;
}

查看文件

@ -5,9 +5,10 @@
class HandlerDefault : public Handler class HandlerDefault : public Handler
{ {
public: public:
Response handle(const Request &r) override; Response handleRequest(const Request &r) override;
~HandlerDefault() override; ~HandlerDefault() override;
using Handler::Handler; using Handler::Handler;
bool canAccess(const Permissions &perms) override;
}; };
#endif // HANDLERDEFAULT_H #endif // HANDLERDEFAULT_H

查看文件

@ -23,11 +23,27 @@ SOFTWARE.
#include "../htmllink.h" #include "../htmllink.h"
#include "../logger.h" #include "../logger.h"
#include "../database/exceptions.h" #include "../database/exceptions.h"
Response HandlerHistory::handle(const Request &r) Response HandlerHistory::handleRequest(const Request &r)
{ {
QueryOption qo = queryOption(r); QueryOption qo = queryOption(r);
std::string page = r.get("page"); 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; unsigned int count = 0;
std::vector<Revision> resultList; std::vector<Revision> resultList;
auto revisionDao = this->database->createRevisionDao(); auto revisionDao = this->database->createRevisionDao();
@ -102,3 +118,8 @@ Response HandlerHistory::handle(const Request &r)
response.setStatus(200); response.setStatus(200);
return response; 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
}

查看文件

@ -8,7 +8,8 @@ class HandlerHistory : public Handler
public: public:
HandlerHistory(); HandlerHistory();
using Handler::Handler; using Handler::Handler;
Response handle(const Request &r) override; Response handleRequest(const Request &r) override;
bool canAccess(const Permissions &perms) override;
}; };
#endif // HANDLERHISTORY_H #endif // HANDLERHISTORY_H

查看文件

@ -20,7 +20,12 @@ SOFTWARE.
*/ */
#include "handlerinvalidaction.h" #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"); return errorResponse("Invalid action", "No action defined for this action");
} }
bool HandlerInvalidAction::canAccess(const Permissions &perms)
{
return true;
}

查看文件

@ -5,10 +5,11 @@
class HandlerInvalidAction : public Handler class HandlerInvalidAction : public Handler
{ {
public: public:
Response handle(const Request &r) override; Response handleRequest(const Request &r) override;
~HandlerInvalidAction() override ~HandlerInvalidAction() override
{ {
} }
bool canAccess(const Permissions &perms) override;
using Handler::Handler; using Handler::Handler;
}; };

查看文件

@ -64,7 +64,7 @@ std::vector<char> HandlerLogin::pbkdf5(std::string password, const std::vector<c
return result; return result;
} }
Response HandlerLogin::handle(const Request &r) Response HandlerLogin::handleRequest(const Request &r)
{ {
auto createErrorReesponse = [&]() { auto createErrorReesponse = [&]() {
return errorResponse("Login error", "The supplied credenetials are incorrect"); return errorResponse("Login error", "The supplied credenetials are incorrect");
@ -85,6 +85,10 @@ Response HandlerLogin::handle(const Request &r)
{ {
return createErrorReesponse(); return createErrorReesponse();
} }
if(!user->enabled)
{
return errorResponse("Login failed", "The user account has been disabled");
}
auto hashresult = pbkdf5(password, user.value().salt); auto hashresult = pbkdf5(password, user.value().salt);
// TODO: timing attack // TODO: timing attack
@ -116,3 +120,8 @@ Response HandlerLogin::handle(const Request &r)
result.setBody(loginTemplatePage.render()); result.setBody(loginTemplatePage.render());
return result; return result;
} }
bool HandlerLogin::canAccess(const Permissions &perms)
{
return true;
}

查看文件

@ -12,10 +12,11 @@ class HandlerLogin : public Handler
public: public:
HandlerLogin(); HandlerLogin();
Response handle(const Request &r) override; Response handleRequest(const Request &r) override;
~HandlerLogin() override ~HandlerLogin() override
{ {
} }
bool canAccess(const Permissions &perms) override;
using Handler::Handler; using Handler::Handler;
}; };

查看文件

@ -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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include <optional>
#include "handlerpage.h" #include "handlerpage.h"
Response HandlerPage::handle(const Request &r) Response HandlerPage::handle(const Request &r)

查看文件

@ -21,6 +21,21 @@ SOFTWARE.
#include "handlerpagedelete.h" #include "handlerpagedelete.h"
#include "../database/exceptions.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) Response HandlerPageDelete::handleRequest(PageDao &pageDao, std::string pagename, const Request &r)
{ {
try try

查看文件

@ -4,20 +4,11 @@
class HandlerPageDelete : public HandlerPage class HandlerPageDelete : public HandlerPage
{ {
bool pageMustExist() override bool pageMustExist() override;
{
return true;
}
bool canAccess(std::string page) override bool canAccess(std::string page) override;
{
return this->userSession->user.permissions.canDelete();
}
std::string accessErrorMessage() override std::string accessErrorMessage() override;
{
return "You don't have permission to delete pages";
}
public: public:
Response handleRequest(PageDao &pageDao, std::string pagename, const Request &r) override; Response handleRequest(PageDao &pageDao, std::string pagename, const Request &r) override;

查看文件

@ -26,7 +26,12 @@ SOFTWARE.
bool HandlerPageView::canAccess(std::string page) 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) std::string HandlerPageView::createIndexContent(IParser &parser, std::string content)

查看文件

@ -9,10 +9,7 @@ class HandlerPageView : public HandlerPage
{ {
protected: protected:
bool canAccess(std::string page) override; bool canAccess(std::string page) override;
std::string accessErrorMessage() override std::string accessErrorMessage() override;
{
return "You don't have permission to view this page";
}
std::string createIndexContent(IParser &parser, std::string content); std::string createIndexContent(IParser &parser, std::string content);
public: public:

查看文件

@ -19,7 +19,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include "handlersearch.h" #include "handlersearch.h"
Response HandlerSearch::handle(const Request &r) Response HandlerSearch::handleRequest(const Request &r)
{ {
Response response; Response response;
std::string q = r.get("q"); 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"); 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";
}

查看文件

@ -7,7 +7,9 @@ class HandlerSearch : public Handler
public: public:
HandlerSearch(); HandlerSearch();
using Handler::Handler; 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 #endif // HANDLERSEARCH_H