Core support for csrf tokens.

This commit is contained in:
Relintai 2022-01-09 14:51:04 +01:00
parent a119251e09
commit 3c8d2eaed9
6 changed files with 112 additions and 65 deletions

View File

@ -1,6 +1,8 @@
#include "html_builder.h" #include "html_builder.h"
#include "core/string.h" #include "core/string.h"
#include "core/http/request.h"
HTMLTag *HTMLTag::str(const String &str) { HTMLTag *HTMLTag::str(const String &str) {
result += " " + str; result += " " + str;
@ -2491,6 +2493,13 @@ HTMLTag *HTMLBuilder::form_post(const String &action, const String &cls, const S
return t; return t;
} }
HTMLBuilder *HTMLBuilder::form_post(const String &action, Request *request, const String &cls, const String &id) {
form_post(action, cls, id);
csrf_token(request);
return this;
}
HTMLTag *HTMLBuilder::input_button() { HTMLTag *HTMLBuilder::input_button() {
write_tag(); write_tag();
@ -3223,6 +3232,20 @@ HTMLTag *HTMLBuilder::input_hidden(const String& name, const String& value) {
return t; return t;
} }
HTMLBuilder *HTMLBuilder::csrf_token(const String &token) {
if (token == "") {
//don't waste html characters if it's an empty string anyway
return this;
}
input_hidden("csrf_token", token);
return this;
}
HTMLBuilder *HTMLBuilder::csrf_token(Request *request) {
return csrf_token(request->get_csrf_token());
}
void HTMLBuilder::f() { void HTMLBuilder::f() {
write_tag(); write_tag();
} }

View File

@ -453,6 +453,8 @@ public:
HTMLTag *form_post(); HTMLTag *form_post();
HTMLTag *form_get(const String &action, const String &cls = "", const String &id = ""); HTMLTag *form_get(const String &action, const String &cls = "", const String &id = "");
HTMLTag *form_post(const String &action, const String &cls = "", const String &id = ""); HTMLTag *form_post(const String &action, const String &cls = "", const String &id = "");
//will add a csrf token from request
HTMLBuilder *form_post(const String &action, Request *request, const String &cls = "", const String &id = "");
HTMLTag *input_button(); HTMLTag *input_button();
HTMLTag *input_checkbox(); HTMLTag *input_checkbox();
@ -502,6 +504,9 @@ public:
HTMLTag *input_week(const String &name, const String &cls = "", const String &id = "", const String &vmin = "", const String &vmax = ""); HTMLTag *input_week(const String &name, const String &cls = "", const String &id = "", const String &vmin = "", const String &vmax = "");
HTMLTag *input_hidden(const String &name, const String &value); HTMLTag *input_hidden(const String &name, const String &value);
HTMLBuilder *csrf_token(const String &token);
HTMLBuilder *csrf_token(Request *request);
void f(); void f();
// write // write

View File

@ -22,6 +22,9 @@ bool HTTPSession::has(const String &key) {
Variant HTTPSession::get(const String &key) { Variant HTTPSession::get(const String &key) {
return _data[key]; return _data[key];
} }
const Variant &HTTPSession::get_const(const String &key) {
return _data[key];
}
Object *HTTPSession::get_object(const String &key) { Object *HTTPSession::get_object(const String &key) {
// don't lock here // don't lock here

View File

@ -19,6 +19,7 @@ public:
bool has(const String &key); bool has(const String &key);
Variant get(const String &key); Variant get(const String &key);
const Variant &get_const(const String &key);
Object *get_object(const String &key); Object *get_object(const String &key);
Ref<Reference> get_reference(const String &key); Ref<Reference> get_reference(const String &key);
int get_int(const String &key); int get_int(const String &key);

View File

@ -18,6 +18,20 @@ Ref<HTTPSession> Request::get_or_create_session() {
return session; return session;
} }
String Request::get_csrf_token() {
if (!session.is_valid()) {
return "";
}
const Variant &val = session->get_const("csrf_token");
if (val.is_simple_type()) {
return val.to_string();
}
return "";
}
const String Request::get_cookie(const String &key) { const String Request::get_cookie(const String &key) {
static String str(0); static String str(0);
return str; return str;

View File

@ -39,6 +39,7 @@ public:
std::map<String, Ref<Reference> > reference_data; std::map<String, Ref<Reference> > reference_data;
Ref<HTTPSession> get_or_create_session(); Ref<HTTPSession> get_or_create_session();
String get_csrf_token();
virtual const String get_cookie(const String &key); virtual const String get_cookie(const String &key);
virtual void add_cookie(const ::Cookie &cookie); virtual void add_cookie(const ::Cookie &cookie);