forked from cory/tildefriends
Move some DB things out of httpd.
This commit is contained in:
143
src/ssb.db.c
143
src/ssb.db.c
@ -6,6 +6,7 @@
|
||||
#include "trace.h"
|
||||
#include "util.js.h"
|
||||
|
||||
#include "ow-crypt.h"
|
||||
#include "sodium/crypto_hash_sha256.h"
|
||||
#include "sodium/crypto_sign.h"
|
||||
#include "sqlite3.h"
|
||||
@ -1592,3 +1593,145 @@ void tf_ssb_db_forget_stored_connection(tf_ssb_t* ssb, const char* address, int
|
||||
}
|
||||
tf_ssb_release_db_writer(ssb, db);
|
||||
}
|
||||
|
||||
bool tf_ssb_db_get_account_password_hash(tf_ssb_t* ssb, const char* name, char* out_password, size_t password_size)
|
||||
{
|
||||
bool result = false;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
sqlite3_stmt* statement = NULL;
|
||||
if (sqlite3_prepare(db, "SELECT value ->> '$.password' FROM properties WHERE id = 'auth' AND key = 'user:' || ?", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
snprintf(out_password, password_size, "%s", (const char*)sqlite3_column_text(statement, 0));
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool tf_ssb_db_set_account_password(tf_ssb_t* ssb, const char* name, const char* password)
|
||||
{
|
||||
JSContext* context = tf_ssb_get_context(ssb);
|
||||
bool result = false;
|
||||
static const int k_salt_length = 12;
|
||||
|
||||
char buffer[16];
|
||||
size_t bytes = uv_random(tf_ssb_get_loop(ssb), &(uv_random_t) { 0 }, buffer, sizeof(buffer), 0, NULL) == 0 ? sizeof(buffer) : 0;
|
||||
char output[7 + 22 + 1];
|
||||
char* salt = crypt_gensalt_rn("$2b$", k_salt_length, buffer, bytes, output, sizeof(output));
|
||||
char hash_output[7 + 22 + 31 + 1];
|
||||
char* hash = crypt_rn(password, salt, hash_output, sizeof(hash_output));
|
||||
|
||||
JSValue user_entry = JS_NewObject(context);
|
||||
JS_SetPropertyStr(context, user_entry, "password", JS_NewString(context, hash));
|
||||
JSValue user_json = JS_JSONStringify(context, user_entry, JS_NULL, JS_NULL);
|
||||
size_t user_length = 0;
|
||||
const char* user_string = JS_ToCStringLen(context, &user_length, user_json);
|
||||
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(ssb);
|
||||
sqlite3_stmt* statement = NULL;
|
||||
if (sqlite3_prepare(db, "INSERT OR REPLACE INTO properties (id, key, value) VALUES ('auth', 'user:' || ?, ?)", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, user_string, user_length, NULL) == SQLITE_OK)
|
||||
{
|
||||
result = sqlite3_step(statement) == SQLITE_DONE;
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
tf_ssb_release_db_writer(ssb, db);
|
||||
|
||||
JS_FreeCString(context, user_string);
|
||||
JS_FreeValue(context, user_json);
|
||||
JS_FreeValue(context, user_entry);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool tf_ssb_db_register_account(tf_ssb_t* ssb, const char* name, const char* password)
|
||||
{
|
||||
bool result = false;
|
||||
JSContext* context = tf_ssb_get_context(ssb);
|
||||
JSValue users_array = JS_UNDEFINED;
|
||||
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(ssb);
|
||||
sqlite3_stmt* statement = NULL;
|
||||
if (sqlite3_prepare(db, "SELECT value FROM properties WHERE id = 'auth' AND key = 'users'", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
users_array = JS_ParseJSON(context, (const char*)sqlite3_column_text(statement, 0), sqlite3_column_bytes(statement, 0), NULL);
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
if (JS_IsUndefined(users_array))
|
||||
{
|
||||
users_array = JS_NewArray(context);
|
||||
}
|
||||
int length = tf_util_get_length(context, users_array);
|
||||
JS_SetPropertyUint32(context, users_array, length, JS_NewString(context, name));
|
||||
|
||||
JSValue json = JS_JSONStringify(context, users_array, JS_NULL, JS_NULL);
|
||||
JS_FreeValue(context, users_array);
|
||||
size_t value_length = 0;
|
||||
const char* value = JS_ToCStringLen(context, &value_length, json);
|
||||
if (sqlite3_prepare(db, "INSERT OR REPLACE INTO properties (id, key, value) VALUES ('auth', 'users', ?)", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, value, value_length, NULL) == SQLITE_OK)
|
||||
{
|
||||
result = sqlite3_step(statement) == SQLITE_DONE;
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
JS_FreeCString(context, value);
|
||||
JS_FreeValue(context, json);
|
||||
tf_ssb_release_db_writer(ssb, db);
|
||||
|
||||
result = result && tf_ssb_db_set_account_password(ssb, name, password);
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* tf_ssb_db_get_property(tf_ssb_t* ssb, const char* id, const char* key)
|
||||
{
|
||||
char* result = NULL;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
sqlite3_stmt* statement = NULL;
|
||||
if (sqlite3_prepare(db, "SELECT value FROM properties WHERE id = ? AND key = ?", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, key, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
size_t length = sqlite3_column_bytes(statement, 0);
|
||||
result = tf_malloc(length + 1);
|
||||
memcpy(result, sqlite3_column_text(statement, 0), length);
|
||||
result[length] = '\0';
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool tf_ssb_db_set_property(tf_ssb_t* ssb, const char* id, const char* key, const char* value)
|
||||
{
|
||||
bool result = false;
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(ssb);
|
||||
sqlite3_stmt* statement = NULL;
|
||||
if (sqlite3_prepare(db, "INSERT OR REPLACE INTO properties (id, key, value) VALUES (?, ?, ?)", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, key, -1, NULL) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 3, value, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
result = sqlite3_step(statement) == SQLITE_DONE;
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
tf_ssb_release_db_writer(ssb, db);
|
||||
return result;
|
||||
}
|
||||
|
Reference in New Issue
Block a user