implemented a new web permission system which utilizes the webnode hierarchy.

This commit is contained in:
Relintai 2022-02-10 16:17:31 +01:00
parent 2266a66a79
commit 02ca1abec9
14 changed files with 183 additions and 13 deletions

View File

@ -5,8 +5,10 @@
#include "http_session.h"
#include "web/http/web_root.h"
#include "session_manager.h"
#include "web/http/web_root.h"
#include "web_permission.h"
Ref<HTTPSession> Request::get_or_create_session() {
if (session.is_valid()) {
@ -18,6 +20,19 @@ Ref<HTTPSession> Request::get_or_create_session() {
return session;
}
bool Request::can_view() const {
return (permissions & WebPermission::WEB_PERMISSION_VIEW) != 0;
}
bool Request::can_create() const {
return (permissions & WebPermission::WEB_PERMISSION_CREATE) != 0;
}
bool Request::can_edit() const {
return (permissions & WebPermission::WEB_PERMISSION_EDIT) != 0;
}
bool Request::can_delete() const {
return (permissions & WebPermission::WEB_PERMISSION_DELETE) != 0;
}
bool Request::has_csrf_token() {
if (!session.is_valid()) {
return false;
@ -153,6 +168,8 @@ void Request::reset() {
connection_closed = false;
_full_path = "";
_status_code = HTTP_STATUS_CODE_200_OK;
// Maybe set NONE or only VIEW as default?
permissions = WebPermission::WEB_PERMISSION_ALL;
head.clear();
body.clear();

View File

@ -4,9 +4,9 @@
#include "core/containers/vector.h"
#include "core/string.h"
#include <vector>
#include <map>
#include <mutex>
#include <vector>
#include "core/object.h"
#include "core/reference.h"
@ -16,6 +16,7 @@
class WebServer;
class Cookie;
class HTTPSession;
class WebPermission;
class Request {
public:
@ -39,7 +40,15 @@ public:
std::map<String, Ref<Reference> > reference_data;
Ref<HTTPSession> get_or_create_session();
Ref<WebPermission> active_permission;
int permissions;
bool can_view() const;
bool can_create() const;
bool can_edit() const;
bool can_delete() const;
bool has_csrf_token();
String get_csrf_token();
void set_csrf_token(const String &value);
@ -86,7 +95,7 @@ public:
String get_url_root_parent(const String &add) const;
String get_url_root(const String &add) const;
String get_url_site(const String &add) const;
virtual void update();
virtual void pool();

View File

@ -4,8 +4,9 @@
#include "http_enums.h"
#include "request.h"
#include "web/http/web_server.h"
#include "core/settings/settings.h"
#include "web/http/web_server.h"
#include "web_permission.h"
#ifdef DATABASES_ENABLED
#include "database/database.h"
@ -64,6 +65,13 @@ void WebNode::set_settings(Settings *settings) {
// todo send event to children when it's implemented?
}
Ref<WebPermission> WebNode::get_web_permission() {
return _web_permission;
}
void WebNode::set_web_permission(const Ref<WebPermission> &wp) {
_web_permission = wp;
}
bool WebNode::get_routing_enabled() {
return _routing_enabled;
}
@ -118,6 +126,12 @@ void WebNode::set_database(Database *db) {
#endif
void WebNode::handle_request_main(Request *request) {
if (_web_permission.is_valid()) {
if (_web_permission->activate(request)) {
return;
}
}
if (!_routing_enabled) {
_handle_request_main(request);
return;

View File

@ -9,6 +9,7 @@
class Request;
class Settings;
class WebServer;
class WebPermission;
#ifdef DATABASES_ENABLED
class DataBase;
@ -29,6 +30,9 @@ public:
Settings *get_settings();
void set_settings(Settings *settings);
Ref<WebPermission> get_web_permission();
void set_web_permission(const Ref<WebPermission> &wp);
virtual bool get_routing_enabled();
virtual void set_routing_enabled(const bool value);
@ -81,6 +85,8 @@ protected:
bool _routing_enabled;
WebNode *_index_node;
std::map<String, WebNode *> _node_route_map;
Ref<WebPermission> _web_permission;
};
#endif

View File

@ -0,0 +1,31 @@
#include "web_permission.h"
#include "request.h"
bool WebPermission::activate(Request *request) {
request->active_permission.reference_ptr(this);
request->permissions = _get_permissions(request);
if (!request->can_view()) {
handle_view_permission_missing(request);
return true;
}
return false;
}
int WebPermission::_get_permissions(Request *request) {
return WEB_PERMISSION_ALL;
}
void WebPermission::handle_view_permission_missing(Request *request) {
request->send_error(HTTP_STATUS_CODE_404_NOT_FOUND);
}
WebPermission::WebPermission() :
Reference() {
}
WebPermission::~WebPermission() {
}

33
web/http/web_permission.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef WEB_PERMISSION_H
#define WEB_PERMISSION_H
#include "core/string.h"
#include "core/reference.h"
class Request;
class WebPermission : public Reference {
RCPP_OBJECT(WebPermission, Reference);
public:
enum WebPermissions {
WEB_PERMISSION_VIEW = 1 << 0,
WEB_PERMISSION_CREATE = 1 << 1,
WEB_PERMISSION_EDIT = 1 << 2,
WEB_PERMISSION_DELETE = 1 << 3,
WEB_PERMISSION_ALL = WEB_PERMISSION_VIEW | WEB_PERMISSION_CREATE | WEB_PERMISSION_EDIT | WEB_PERMISSION_DELETE,
WEB_PERMISSION_NONE = 0,
};
//like in middlewate returns whether it handled the request or not
virtual bool activate(Request *request);
virtual int _get_permissions(Request *request);
virtual void handle_view_permission_missing(Request *request);
WebPermission();
~WebPermission();
};
#endif

View File

@ -9,6 +9,7 @@
#include <iostream>
#include "web_permission.h"
#include <stdio.h>
#include <stdlib.h>
@ -72,13 +73,26 @@ void WebRoot::handle_request_main(Request *request) {
return;
}
if (_web_permission.is_valid()) {
if (_web_permission->activate(request)) {
return;
}
}
// handle files first
if (try_send_wwwroot_file(request)) {
return;
}
// normal routing
WebNode::handle_request_main(request);
if (!_routing_enabled) {
_handle_request_main(request);
return;
}
if (!try_route_request_to_children(request)) {
_handle_request_main(request);
}
}
void WebRoot::handle_error_send_request(Request *request, const int error_code) {

View File

@ -6,11 +6,16 @@
#include "web/http/http_session.h"
#include "web/http/request.h"
#include "web/http/session_manager.h"
#include "web/http/web_permission.h"
#include "admin_node.h"
void AdminPanel::handle_request_main(Request *request) {
//todo check permissions
if (_web_permission.is_valid()) {
if (_web_permission->activate(request)) {
return;
}
}
String seg = request->get_current_path_segment();
@ -32,13 +37,13 @@ void AdminPanel::handle_request_main(Request *request) {
return;
}
//render_menu(request);
// render_menu(request);
render_headers(request);
render_segment_body_top(request);
render_controller_panel(request, c);
render_footer(request);
//request->pop_path();
// request->pop_path();
return;
}
@ -94,9 +99,9 @@ void AdminPanel::render_admin_panel_list(Request *request) {
}
void AdminPanel::render_controller_panel(Request *request, AdminNode *controller) {
//set up headers
// set up headers
controller->admin_handle_request_main(request);
//set up footers
// set up footers
request->compile_and_send_body();
}

View File

@ -1,8 +1,15 @@
#include "folder_serve_node.h"
#include "web/http/request.h"
#include "web/http/web_permission.h"
void FolderServeNode::handle_request_main(Request *request) {
if (_web_permission.is_valid()) {
if (_web_permission->activate(request)) {
return;
}
}
const String &rp = request->get_current_path_segment();
if (rp == "") {

View File

@ -1,13 +1,20 @@
#include "list_page.h"
#include "core/math/math.h"
#include "web/html/html_builder.h"
#include "web/html/utils.h"
#include "core/math/math.h"
#include "web/http/web_permission.h"
#include <tinydir/tinydir.h>
#include <iostream>
void ListPage::handle_request_main(Request *request) {
if (_web_permission.is_valid()) {
if (_web_permission->activate(request)) {
return;
}
}
if (_pages.size() == 0) {
render_menu(request);
request->body += _no_entries_response;

View File

@ -5,8 +5,15 @@
#include "database/query_builder.h"
#include "database/table_builder.h"
#include "database/query_result.h"
#include "web/http/web_permission.h"
void MessagePage::handle_request_main(Request *request) {
if (_web_permission.is_valid()) {
if (_web_permission->activate(request)) {
return;
}
}
Ref<QueryBuilder> b = db->get_query_builder();
b->select("text")->from("message_page")->end_command();

View File

@ -2,10 +2,17 @@
#include "core/os/directory.h"
#include "web/html/utils.h"
#include "web/http/web_permission.h"
#include <iostream>
void PagedArticle::handle_request_main(Request *request) {
if (_web_permission.is_valid()) {
if (_web_permission->activate(request)) {
return;
}
}
const String &rp = request->get_current_path_segment();
if (request->get_remaining_segment_count() > 1 && rp == "files") {

View File

@ -1,10 +1,16 @@
#include "paged_articles_md_index.h"
#include "web/http/request.h"
#include "web/http/web_permission.h"
#include "web/html/html_builder.h"
void PagedArticlesMDIndex::handle_request_main(Request *request) {
if (_web_permission.is_valid()) {
if (_web_permission->activate(request)) {
return;
}
}
const String path = request->get_current_path_segment();
if (request->get_remaining_segment_count() == 0) {

View File

@ -6,6 +6,7 @@
#include "web/http/http_session.h"
#include "web/http/request.h"
#include "web/http/session_manager.h"
#include "web/http/web_permission.h"
#include "database/database.h"
#include "database/database_manager.h"
@ -16,6 +17,12 @@
#include "crypto/hash/sha256.h"
void UserController::handle_request_main(Request *request) {
if (_web_permission.is_valid()) {
if (_web_permission->activate(request)) {
return;
}
}
if (request->session.is_valid()) {
Ref<User> u = request->reference_data["user"];