Fix numerous issues around setting the first registered used as an admin.
This commit is contained in:
parent
385524352c
commit
7caf4a0173
159
src/httpd.js.c
159
src/httpd.js.c
@ -1213,6 +1213,94 @@ 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)
|
||||||
|
{
|
||||||
|
JSContext* context = tf_ssb_get_context(ssb);
|
||||||
|
const char* 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);
|
||||||
|
JS_FreeCString(context, code_of_conduct);
|
||||||
|
JS_FreeValue(context, code_of_conduct_value);
|
||||||
|
JS_FreeValue(context, settings_value);
|
||||||
|
tf_free((void*)settings);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _make_administrator_if_first(tf_ssb_t* ssb, const char* account_name_copy, bool may_become_first_admin)
|
||||||
|
{
|
||||||
|
JSContext* context = tf_ssb_get_context(ssb);
|
||||||
|
const char* settings = tf_ssb_db_get_property(ssb, "core", "settings");
|
||||||
|
JSValue settings_value = settings ? JS_ParseJSON(context, settings, strlen(settings), NULL) : JS_UNDEFINED;
|
||||||
|
if (JS_IsUndefined(settings_value))
|
||||||
|
{
|
||||||
|
settings_value = JS_NewObject(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool have_administrator = false;
|
||||||
|
JSValue permissions = JS_GetPropertyStr(context, settings_value, "permissions");
|
||||||
|
|
||||||
|
JSPropertyEnum* ptab = NULL;
|
||||||
|
uint32_t plen = 0;
|
||||||
|
JS_GetOwnPropertyNames(context, &ptab, &plen, permissions, JS_GPN_STRING_MASK);
|
||||||
|
for (int i = 0; i < (int)plen; i++)
|
||||||
|
{
|
||||||
|
JSPropertyDescriptor desc = { 0 };
|
||||||
|
if (JS_GetOwnProperty(context, &desc, permissions, ptab[i].atom) == 1)
|
||||||
|
{
|
||||||
|
int permission_length = tf_util_get_length(context, desc.value);
|
||||||
|
for (int i = 0; i < permission_length; i++)
|
||||||
|
{
|
||||||
|
JSValue entry = JS_GetPropertyUint32(context, desc.value, i);
|
||||||
|
const char* permission = JS_ToCString(context, entry);
|
||||||
|
if (permission && strcmp(permission, "administration") == 0)
|
||||||
|
{
|
||||||
|
have_administrator = true;
|
||||||
|
}
|
||||||
|
JS_FreeCString(context, permission);
|
||||||
|
JS_FreeValue(context, entry);
|
||||||
|
}
|
||||||
|
JS_FreeValue(context, desc.setter);
|
||||||
|
JS_FreeValue(context, desc.getter);
|
||||||
|
JS_FreeValue(context, desc.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < plen; ++i)
|
||||||
|
{
|
||||||
|
JS_FreeAtom(context, ptab[i].atom);
|
||||||
|
}
|
||||||
|
js_free(context, ptab);
|
||||||
|
|
||||||
|
if (!have_administrator && may_become_first_admin)
|
||||||
|
{
|
||||||
|
if (JS_IsUndefined(permissions))
|
||||||
|
{
|
||||||
|
permissions = JS_NewObject(context);
|
||||||
|
JS_SetPropertyStr(context, settings_value, "permissions", JS_DupValue(context, permissions));
|
||||||
|
}
|
||||||
|
JSValue user = JS_GetPropertyStr(context, permissions, account_name_copy);
|
||||||
|
if (JS_IsUndefined(user))
|
||||||
|
{
|
||||||
|
user = JS_NewArray(context);
|
||||||
|
JS_SetPropertyStr(context, permissions, account_name_copy, JS_DupValue(context, user));
|
||||||
|
}
|
||||||
|
JS_SetPropertyUint32(context, user, tf_util_get_length(context, user), JS_NewString(context, "administration"));
|
||||||
|
JS_FreeValue(context, user);
|
||||||
|
|
||||||
|
JSValue settings_json = JS_JSONStringify(context, settings_value, JS_NULL, JS_NULL);
|
||||||
|
const char* settings_string = JS_ToCString(context, settings_json);
|
||||||
|
tf_ssb_db_set_property(ssb, "core", "settings", settings_string);
|
||||||
|
JS_FreeCString(context, settings_string);
|
||||||
|
JS_FreeValue(context, settings_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_FreeValue(context, permissions);
|
||||||
|
JS_FreeValue(context, settings_value);
|
||||||
|
tf_free((void*)settings);
|
||||||
|
return have_administrator;
|
||||||
|
}
|
||||||
|
|
||||||
static void _httpd_endpoint_login(tf_http_request_t* request)
|
static void _httpd_endpoint_login(tf_http_request_t* request)
|
||||||
{
|
{
|
||||||
tf_task_t* task = request->user_data;
|
tf_task_t* task = request->user_data;
|
||||||
@ -1310,6 +1398,8 @@ static void _httpd_endpoint_login(tf_http_request_t* request)
|
|||||||
tf_free(post_form_data);
|
tf_free(post_form_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool have_administrator = _make_administrator_if_first(ssb, account_name_copy, may_become_first_admin);
|
||||||
|
|
||||||
if (session_is_new && _form_data_get(form_data, "return") && !login_error)
|
if (session_is_new && _form_data_get(form_data, "return") && !login_error)
|
||||||
{
|
{
|
||||||
const char* return_url = _form_data_get(form_data, "return");
|
const char* return_url = _form_data_get(form_data, "return");
|
||||||
@ -1334,69 +1424,8 @@ static void _httpd_endpoint_login(tf_http_request_t* request)
|
|||||||
{
|
{
|
||||||
tf_http_request_ref(request);
|
tf_http_request_ref(request);
|
||||||
|
|
||||||
const char* 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);
|
|
||||||
|
|
||||||
bool have_administrator = false;
|
|
||||||
JSValue permissions = JS_GetPropertyStr(context, settings_value, "permissions");
|
|
||||||
|
|
||||||
JSPropertyEnum* ptab = NULL;
|
|
||||||
uint32_t plen = 0;
|
|
||||||
JS_GetOwnPropertyNames(context, &ptab, &plen, permissions, JS_GPN_STRING_MASK);
|
|
||||||
for (int i = 0; i < (int)plen; i++)
|
|
||||||
{
|
|
||||||
JSPropertyDescriptor desc = { 0 };
|
|
||||||
if (JS_GetOwnProperty(context, &desc, permissions, ptab[i].atom) == 1)
|
|
||||||
{
|
|
||||||
int permission_length = tf_util_get_length(context, desc.value);
|
|
||||||
for (int i = 0; i < permission_length; i++)
|
|
||||||
{
|
|
||||||
JSValue entry = JS_GetPropertyUint32(context, desc.value, i);
|
|
||||||
const char* permission = JS_ToCString(context, entry);
|
|
||||||
if (permission && strcmp(permission, "administration") == 0)
|
|
||||||
{
|
|
||||||
have_administrator = true;
|
|
||||||
}
|
|
||||||
JS_FreeCString(context, permission);
|
|
||||||
JS_FreeValue(context, entry);
|
|
||||||
}
|
|
||||||
JS_FreeValue(context, desc.setter);
|
|
||||||
JS_FreeValue(context, desc.getter);
|
|
||||||
JS_FreeValue(context, desc.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (uint32_t i = 0; i < plen; ++i)
|
|
||||||
{
|
|
||||||
JS_FreeAtom(context, ptab[i].atom);
|
|
||||||
}
|
|
||||||
js_free(context, ptab);
|
|
||||||
|
|
||||||
if (!have_administrator && may_become_first_admin)
|
|
||||||
{
|
|
||||||
if (JS_IsUndefined(permissions))
|
|
||||||
{
|
|
||||||
permissions = JS_NewObject(context);
|
|
||||||
JS_SetPropertyStr(context, settings_value, "permissions", permissions);
|
|
||||||
}
|
|
||||||
JSValue user = JS_GetPropertyStr(context, permissions, account_name_copy);
|
|
||||||
if (JS_IsUndefined(user))
|
|
||||||
{
|
|
||||||
user = JS_NewArray(context);
|
|
||||||
JS_SetPropertyStr(context, permissions, account_name_copy, user);
|
|
||||||
}
|
|
||||||
JS_SetPropertyUint32(context, user, tf_util_get_length(context, user), JS_NewString(context, "administration"));
|
|
||||||
|
|
||||||
JSValue settings_json = JS_JSONStringify(context, settings_value, JS_NULL, JS_NULL);
|
|
||||||
const char* settings_string = JS_ToCString(context, settings_json);
|
|
||||||
tf_ssb_db_set_property(ssb, "core", "settings", settings_string);
|
|
||||||
JS_FreeCString(context, settings_string);
|
|
||||||
JS_FreeValue(context, settings_json);
|
|
||||||
}
|
|
||||||
JS_FreeValue(context, permissions);
|
|
||||||
|
|
||||||
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,
|
||||||
@ -1404,14 +1433,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 = tf_strdup(code_of_conduct),
|
.code_of_conduct = code_of_conduct,
|
||||||
.have_administrator = have_administrator,
|
.have_administrator = have_administrator,
|
||||||
};
|
};
|
||||||
|
|
||||||
JS_FreeCString(context, code_of_conduct);
|
|
||||||
JS_FreeValue(context, code_of_conduct_value);
|
|
||||||
JS_FreeValue(context, settings_value);
|
|
||||||
tf_free((void*)settings);
|
|
||||||
tf_file_read(request->user_data, "core/auth.html", _httpd_endpoint_login_file_read_callback, login);
|
tf_file_read(request->user_data, "core/auth.html", _httpd_endpoint_login_file_read_callback, login);
|
||||||
jwt = JS_UNDEFINED;
|
jwt = JS_UNDEFINED;
|
||||||
account_name_copy = NULL;
|
account_name_copy = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user