js: Move storePermission to C.

This commit is contained in:
Cory McWilliams 2024-10-16 20:36:53 -04:00
parent 68817feeec
commit 36cc9398c7
2 changed files with 110 additions and 44 deletions

View File

@ -387,9 +387,9 @@ async function getProcessBlob(blobId, key, options) {
} else if (process.app) { } else if (process.app) {
return process.app return process.app
.makeFunction(['requestPermission'])(permission) .makeFunction(['requestPermission'])(permission)
.then(function (value) { .then(async function (value) {
if (value == 'allow') { if (value == 'allow') {
storePermission( await ssb.setUserPermission(
user, user,
options.packageOwner, options.packageOwner,
options.packageName, options.packageName,
@ -401,7 +401,7 @@ async function getProcessBlob(blobId, key, options) {
} else if (value == 'allow once') { } else if (value == 'allow once') {
return true; return true;
} else if (value == 'deny') { } else if (value == 'deny') {
storePermission( await ssb.setUserPermission(
user, user,
options.packageOwner, options.packageOwner,
options.packageName, options.packageName,
@ -748,7 +748,7 @@ async function getProcessBlob(blobId, key, options) {
}; };
process.resetPermission = async function resetPermission(permission) { process.resetPermission = async function resetPermission(permission) {
let user = process?.credentials?.session?.name; let user = process?.credentials?.session?.name;
storePermission( await ssb.setUserPermission(
user, user,
options?.packageOwner, options?.packageOwner,
options?.packageName, options?.packageName,
@ -1245,44 +1245,4 @@ loadSettings()
exit(1); exit(1);
}); });
/**
* TODOC
* @param {*} user
* @param {*} packageOwner
* @param {*} packageName
* @param {*} permission
* @param {*} allow
*/
async function storePermission(user, packageOwner, packageName, permission, allow) {
let settings = await loadSettings();
if (!settings.userPermissions) {
settings.userPermissions = {};
}
if (!settings.userPermissions[user]) {
settings.userPermissions[user] = {};
}
if (!settings.userPermissions[user][packageOwner]) {
settings.userPermissions[user][packageOwner] = {};
}
if (!settings.userPermissions[user][packageOwner][packageName]) {
settings.userPermissions[user][packageOwner][packageName] = {};
}
if (
settings.userPermissions[user][packageOwner][packageName][
permission
] !== allow
) {
if (allow === undefined) {
delete settings.userPermissions[user][packageOwner][packageName][
permission
];
} else {
settings.userPermissions[user][packageOwner][packageName][
permission
] = allow;
}
return setGlobalSettings(settings);
}
}
export {invoke, getProcessBlob}; export {invoke, getProcessBlob};

View File

@ -2394,6 +2394,111 @@ static JSValue _tf_ssb_sync(JSContext* context, JSValueConst this_val, int argc,
return JS_UNDEFINED; return JS_UNDEFINED;
} }
typedef struct _set_user_permission_t
{
tf_ssb_t* ssb;
JSContext* context;
const char* user;
const char* package_owner;
const char* package_name;
const char* permission;
bool allow;
bool result;
JSValue promise[2];
} set_user_permission_t;
static void _tf_ssb_set_user_permission_work(tf_ssb_t* ssb, void* user_data)
{
set_user_permission_t* work = user_data;
JSMallocFunctions funcs = { 0 };
tf_get_js_malloc_functions(&funcs);
JSRuntime* runtime = JS_NewRuntime2(&funcs, NULL);
JSContext* context = JS_NewContext(runtime);
/* XXX: Do this with one DB writer. */
const char* settings = tf_ssb_db_get_property(ssb, "core", "settings");
if (settings)
{
JSValue settings_value = JS_ParseJSON(context, settings, strlen(settings), NULL);
JSValue user_permissions = JS_GetPropertyStr(context, settings_value, "userPermissions");
if (JS_IsUndefined(user_permissions))
{
user_permissions = JS_NewObject(context);
JS_SetPropertyStr(context, settings_value, "userPermissions", JS_DupValue(context, user_permissions));
}
JSValue user = JS_GetPropertyStr(context, user_permissions, work->user);
if (JS_IsUndefined(user))
{
user = JS_NewObject(context);
JS_SetPropertyStr(context, user_permissions, work->user, JS_DupValue(context, user));
}
JSValue package_owner = JS_GetPropertyStr(context, user, work->package_owner);
if (JS_IsUndefined(package_owner))
{
package_owner = JS_NewObject(context);
JS_SetPropertyStr(context, user, work->package_owner, JS_DupValue(context, package_owner));
}
JSValue package_name = JS_GetPropertyStr(context, package_owner, work->package_name);
if (JS_IsUndefined(package_name))
{
package_name = JS_NewObject(context);
JS_SetPropertyStr(context, package_owner, work->package_name, package_name);
}
JSValue permission = JS_GetPropertyStr(context, package_name, work->permission);
if (JS_ToBool(context, permission) != work->allow)
{
JS_SetPropertyStr(context, package_name, work->permission, JS_NewBool(context, work->allow));
JSValue settings_json = JS_JSONStringify(context, settings_value, JS_NULL, JS_NULL);
const char* settings_string = JS_ToCString(context, settings_json);
work->result = tf_ssb_db_set_property(ssb, "core", "settings", settings_string);
JS_FreeCString(context, settings_string);
JS_FreeValue(context, settings_json);
}
else
{
work->result = true;
}
}
JS_FreeContext(context);
JS_FreeRuntime(runtime);
}
static void _tf_ssb_set_user_permission_after_work(tf_ssb_t* ssb, int status, void* user_data)
{
set_user_permission_t* work = user_data;
JSContext* context = work->context;
JS_FreeCString(context, work->user);
JS_FreeCString(context, work->package_owner);
JS_FreeCString(context, work->package_name);
JS_FreeCString(context, work->permission);
JSValue error = JS_Call(context, work->result ? work->promise[0] : work->promise[0], JS_UNDEFINED, 0, NULL);
tf_util_report_error(context, error);
JS_FreeValue(context, error);
JS_FreeValue(context, work->promise[0]);
JS_FreeValue(context, work->promise[1]);
tf_free(work);
}
static JSValue _tf_ssb_set_user_permission(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
set_user_permission_t* set = tf_malloc(sizeof(set_user_permission_t));
*set = (set_user_permission_t)
{
.ssb = JS_GetOpaque(this_val, _tf_ssb_classId),
.context = context,
.user = JS_ToCString(context, argv[0]),
.package_owner = JS_ToCString(context, argv[1]),
.package_name = JS_ToCString(context, argv[2]),
.permission = JS_ToCString(context, argv[3]),
.allow = JS_ToBool(context, argv[4]),
};
JSValue result = JS_NewPromiseCapability(context, set->promise);
tf_ssb_run_work(set->ssb, _tf_ssb_set_user_permission_work, _tf_ssb_set_user_permission_after_work, set);
return result;
}
void tf_ssb_register(JSContext* context, tf_ssb_t* ssb) void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
{ {
JS_NewClassID(&_tf_ssb_classId); JS_NewClassID(&_tf_ssb_classId);
@ -2420,6 +2525,7 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
JS_SetPropertyStr(context, object, "getPrivateKey", JS_NewCFunction(context, _tf_ssb_getPrivateKey, "getPrivateKey", 2)); JS_SetPropertyStr(context, object, "getPrivateKey", JS_NewCFunction(context, _tf_ssb_getPrivateKey, "getPrivateKey", 2));
JS_SetPropertyStr(context, object, "privateMessageEncrypt", JS_NewCFunction(context, _tf_ssb_private_message_encrypt, "privateMessageEncrypt", 4)); JS_SetPropertyStr(context, object, "privateMessageEncrypt", JS_NewCFunction(context, _tf_ssb_private_message_encrypt, "privateMessageEncrypt", 4));
JS_SetPropertyStr(context, object, "privateMessageDecrypt", JS_NewCFunction(context, _tf_ssb_private_message_decrypt, "privateMessageDecrypt", 3)); JS_SetPropertyStr(context, object, "privateMessageDecrypt", JS_NewCFunction(context, _tf_ssb_private_message_decrypt, "privateMessageDecrypt", 3));
JS_SetPropertyStr(context, object, "setUserPermission", JS_NewCFunction(context, _tf_ssb_set_user_permission, "setUserPermission", 5));
/* Write. */ /* Write. */
JS_SetPropertyStr(context, object, "appendMessageWithIdentity", JS_NewCFunction(context, _tf_ssb_appendMessageWithIdentity, "appendMessageWithIdentity", 3)); JS_SetPropertyStr(context, object, "appendMessageWithIdentity", JS_NewCFunction(context, _tf_ssb_appendMessageWithIdentity, "appendMessageWithIdentity", 3));