forked from cory/tildefriends
Get the code of conduct and JWT signing key without hitting the database from the main thread.
This commit is contained in:
parent
c259defab5
commit
3fff706848
@ -1066,6 +1066,7 @@ typedef struct _login_request_t
|
|||||||
JSValue jwt;
|
JSValue jwt;
|
||||||
const char* name;
|
const char* name;
|
||||||
const char* error;
|
const char* error;
|
||||||
|
const char* settings;
|
||||||
const char* code_of_conduct;
|
const char* code_of_conduct;
|
||||||
bool have_administrator;
|
bool have_administrator;
|
||||||
bool session_is_new;
|
bool session_is_new;
|
||||||
@ -1260,25 +1261,6 @@ static bool _is_name_valid(const char* name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _visit_auth_identity(const char* identity, void* user_data)
|
|
||||||
{
|
|
||||||
if (!*(char*)user_data)
|
|
||||||
{
|
|
||||||
snprintf((char*)user_data, k_id_base64_len, "%s", identity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool _get_auth_private_key(tf_ssb_t* ssb, uint8_t* out_private_key)
|
|
||||||
{
|
|
||||||
char id[k_id_base64_len] = { 0 };
|
|
||||||
tf_ssb_db_identity_visit(ssb, ":admin", _visit_auth_identity, id);
|
|
||||||
if (*id)
|
|
||||||
{
|
|
||||||
return tf_ssb_db_identity_get_private_key(ssb, ":admin", id, out_private_key, crypto_sign_SECRETKEYBYTES);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
|
static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
|
||||||
{
|
{
|
||||||
if (!name || !*name)
|
if (!name || !*name)
|
||||||
@ -1309,17 +1291,16 @@ static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
|
|||||||
char signature_base64[256] = { 0 };
|
char signature_base64[256] = { 0 };
|
||||||
|
|
||||||
uint8_t private_key[crypto_sign_SECRETKEYBYTES] = { 0 };
|
uint8_t private_key[crypto_sign_SECRETKEYBYTES] = { 0 };
|
||||||
if (_get_auth_private_key(ssb, private_key))
|
tf_ssb_get_private_key(ssb, private_key, sizeof(private_key));
|
||||||
|
|
||||||
|
if (crypto_sign_detached(signature, &signature_length, (const uint8_t*)payload_base64, strlen(payload_base64), private_key) == 0)
|
||||||
{
|
{
|
||||||
if (crypto_sign_detached(signature, &signature_length, (const uint8_t*)payload_base64, strlen(payload_base64), private_key) == 0)
|
sodium_bin2base64(signature_base64, sizeof(signature_base64), signature, sizeof(signature), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
||||||
{
|
size_t size = strlen(header_base64) + 1 + strlen(payload_base64) + 1 + strlen(signature_base64) + 1;
|
||||||
sodium_bin2base64(signature_base64, sizeof(signature_base64), signature, sizeof(signature), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
result = tf_malloc(size);
|
||||||
size_t size = strlen(header_base64) + 1 + strlen(payload_base64) + 1 + strlen(signature_base64) + 1;
|
snprintf(result, size, "%s.%s.%s", header_base64, payload_base64, signature_base64);
|
||||||
result = tf_malloc(size);
|
|
||||||
snprintf(result, size, "%s.%s.%s", header_base64, payload_base64, signature_base64);
|
|
||||||
}
|
|
||||||
sodium_memzero(private_key, sizeof(private_key));
|
|
||||||
}
|
}
|
||||||
|
sodium_memzero(private_key, sizeof(private_key));
|
||||||
|
|
||||||
JS_FreeCString(context, payload_string);
|
JS_FreeCString(context, payload_string);
|
||||||
JS_FreeValue(context, payload_json);
|
JS_FreeValue(context, payload_json);
|
||||||
@ -1335,19 +1316,31 @@ static bool _verify_password(const char* password, const char* hash)
|
|||||||
return out_hash && strcmp(hash, out_hash) == 0;
|
return out_hash && strcmp(hash, out_hash) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* _get_code_of_conduct(tf_ssb_t* ssb)
|
static void _httpd_endpoint_login_get_code_of_conduct_work(tf_ssb_t* ssb, void* user_data)
|
||||||
{
|
{
|
||||||
JSContext* context = tf_ssb_get_context(ssb);
|
login_request_t* login = user_data;
|
||||||
const char* settings = tf_ssb_db_get_property(ssb, "core", "settings");
|
login->settings = tf_ssb_db_get_property(ssb, "core", "settings");
|
||||||
JSValue settings_value = settings ? JS_ParseJSON(context, settings, strlen(settings), NULL) : JS_UNDEFINED;
|
|
||||||
JSValue code_of_conduct_value = JS_GetPropertyStr(context, settings_value, "code_of_conduct");
|
}
|
||||||
const char* code_of_conduct = JS_ToCString(context, code_of_conduct_value);
|
|
||||||
const char* result = tf_strdup(code_of_conduct);
|
static void _httpd_endpoint_login_get_code_of_conduct_after_work(tf_ssb_t* ssb, int status, void* user_data)
|
||||||
JS_FreeCString(context, code_of_conduct);
|
{
|
||||||
JS_FreeValue(context, code_of_conduct_value);
|
login_request_t* login = user_data;
|
||||||
JS_FreeValue(context, settings_value);
|
if (login->settings)
|
||||||
tf_free((void*)settings);
|
{
|
||||||
return result;
|
JSContext* context = tf_ssb_get_context(ssb);
|
||||||
|
JSValue settings_value = JS_ParseJSON(context, login->settings, strlen(login->settings), NULL);
|
||||||
|
JSValue code_of_conduct_value = JS_GetPropertyStr(context, settings_value, "code_of_conduct");
|
||||||
|
const char* code_of_conduct = JS_ToCString(context, code_of_conduct_value);
|
||||||
|
const char* result = tf_strdup(code_of_conduct);
|
||||||
|
JS_FreeCString(context, code_of_conduct);
|
||||||
|
JS_FreeValue(context, code_of_conduct_value);
|
||||||
|
JS_FreeValue(context, settings_value);
|
||||||
|
tf_free((void*)login->settings);
|
||||||
|
login->settings = NULL;
|
||||||
|
login->code_of_conduct = result;
|
||||||
|
}
|
||||||
|
tf_file_read(login->request->user_data, "core/auth.html", _httpd_endpoint_login_file_read_callback, login);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _make_administrator_if_first(tf_ssb_t* ssb, const char* account_name_copy, bool may_become_first_admin)
|
static bool _make_administrator_if_first(tf_ssb_t* ssb, const char* account_name_copy, bool may_become_first_admin)
|
||||||
@ -1547,7 +1540,6 @@ static void _httpd_endpoint_login(tf_http_request_t* request)
|
|||||||
tf_http_request_ref(request);
|
tf_http_request_ref(request);
|
||||||
|
|
||||||
login_request_t* login = tf_malloc(sizeof(login_request_t));
|
login_request_t* login = tf_malloc(sizeof(login_request_t));
|
||||||
const char* code_of_conduct = _get_code_of_conduct(ssb);
|
|
||||||
*login = (login_request_t) {
|
*login = (login_request_t) {
|
||||||
.request = request,
|
.request = request,
|
||||||
.name = account_name_copy,
|
.name = account_name_copy,
|
||||||
@ -1555,11 +1547,10 @@ static void _httpd_endpoint_login(tf_http_request_t* request)
|
|||||||
.error = login_error,
|
.error = login_error,
|
||||||
.session_cookie = send_session,
|
.session_cookie = send_session,
|
||||||
.session_is_new = session_is_new,
|
.session_is_new = session_is_new,
|
||||||
.code_of_conduct = code_of_conduct,
|
|
||||||
.have_administrator = have_administrator,
|
.have_administrator = have_administrator,
|
||||||
};
|
};
|
||||||
|
|
||||||
tf_file_read(request->user_data, "core/auth.html", _httpd_endpoint_login_file_read_callback, login);
|
tf_ssb_run_work(ssb, _httpd_endpoint_login_get_code_of_conduct_work, _httpd_endpoint_login_get_code_of_conduct_after_work, login);
|
||||||
jwt = JS_UNDEFINED;
|
jwt = JS_UNDEFINED;
|
||||||
account_name_copy = NULL;
|
account_name_copy = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1087,6 +1087,8 @@ bool tf_ssb_db_identity_create(tf_ssb_t* ssb, const char* user, uint8_t* out_pub
|
|||||||
if (out_private_key)
|
if (out_private_key)
|
||||||
{
|
{
|
||||||
tf_ssb_id_str_to_bin(out_private_key, private);
|
tf_ssb_id_str_to_bin(out_private_key, private);
|
||||||
|
/* HACK: tf_ssb_id_str_to_bin only produces 32 bytes even though the full private key is 32 + 32. */
|
||||||
|
tf_ssb_id_str_to_bin(out_private_key + crypto_sign_PUBLICKEYBYTES, public);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user