From 5eda6884585eda2f8493dcb101ae2ed255ea29d1 Mon Sep 17 00:00:00 2001
From: sinanmohd <sinan@sinanmohd.com>
Date: Wed, 1 May 2024 11:07:30 +0530
Subject: npassd/service/ReadAlias: init

---
 src/npassd/collection.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++---
 src/npassd/service.c    | 46 ++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+), 5 deletions(-)

(limited to 'src')

diff --git a/src/npassd/collection.c b/src/npassd/collection.c
index a190b79..4bf6ca7 100644
--- a/src/npassd/collection.c
+++ b/src/npassd/collection.c
@@ -18,8 +18,8 @@ static int collection_alloc(sd_bus *bus, struct collection **p,
 			    const char *root, const char *alias,
 			    const char *label, uint64_t created,
 			    uint64_t modified);
-static int collection_db_read(sd_bus *bus, struct sqlite3 *db,
-			      struct collection **p, const char *alias);
+static int collection_db_root_read(sd_bus *bus, struct sqlite3 *db,
+				   struct collection **p, const char *alias);
 static int collection_db_write(struct sqlite3 *db, struct collection *c);
 
 static int handle_create_item(__attribute__((unused)) sd_bus_message *msg,
@@ -55,8 +55,8 @@ void collection_free(struct collection *c)
 	free(c);
 }
 
-static int collection_db_read(sd_bus *bus, struct sqlite3 *db,
-			      struct collection **p, const char *root)
+static int collection_db_root_read(sd_bus *bus, struct sqlite3 *db,
+				   struct collection **p, const char *root)
 {
 	const char *query, *alias, *label;
 	uint64_t created, modified;
@@ -96,6 +96,60 @@ static int collection_db_read(sd_bus *bus, struct sqlite3 *db,
 	created = sqlite3_column_int64(stmt, 2);
 	modified = sqlite3_column_int64(stmt, 3);
 
+	if (alias == NULL || label == NULL || created == 0 || modified == 0) {
+		print_err("%s", "Found null value in column");
+		ret = -EINVAL;
+		goto out_stmt_finalize;
+	}
+
+	ret = collection_alloc(bus, p, root, alias, label, created, modified);
+
+out_stmt_finalize:
+	sqlite3_finalize(stmt);
+	return ret;
+}
+
+int collection_db_alias_read(sd_bus *bus, struct sqlite3 *db,
+			     struct collection **p, const char *alias)
+{
+	const char *query, *root, *label;
+	uint64_t created, modified;
+	sqlite3_stmt *stmt;
+	int ret;
+
+	query = "SELECT root, label, created, modified "
+		"FROM collections "
+		"WHERE collections.alias = ? ";
+
+	ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
+	if (ret != SQLITE_OK) {
+		print_err("%s", "Failed to prepare sql");
+		return -EPERM;
+	}
+
+	ret = sqlite3_bind_text(stmt, 1, alias, -1, NULL);
+	if (ret != SQLITE_OK) {
+		print_err("%s", "Failed to bind sql");
+		ret = -EPERM;
+		goto out_stmt_finalize;
+	}
+
+	ret = sqlite3_step(stmt);
+	if (ret == SQLITE_DONE) {
+		ret = -ENOENT;
+		goto out_stmt_finalize;
+	}
+	if (ret != SQLITE_ROW) {
+		print_err("%s", "Failed to step sql");
+		ret = -EPERM;
+		goto out_stmt_finalize;
+	}
+
+	root = (char *)sqlite3_column_text(stmt, 0);
+	label = (char *)sqlite3_column_text(stmt, 1);
+	created = sqlite3_column_int64(stmt, 2);
+	modified = sqlite3_column_int64(stmt, 3);
+
 	if (root == NULL || label == NULL || created == 0 || modified == 0) {
 		print_err("%s", "Found null value in column");
 		ret = -EINVAL;
@@ -261,6 +315,23 @@ static int collection_alloc(sd_bus *bus, struct collection **p,
 	return 0;
 }
 
+int collection_alias_search(struct collection_dlist *collections,
+			    const char *alias, struct collection **collection)
+{
+	struct collection *c;
+	int ret;
+
+	LIST_FOREACH (c, collections, dlist) {
+		ret = strcmp(c->alias, alias);
+		if (ret == 0) {
+			*collection = c;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
 int collection_root_make(const char *label, const char *alias, char **root)
 {
 	int ret;
@@ -286,7 +357,7 @@ int collection_new(sd_bus *bus, struct sqlite3 *db, struct collection **p,
 	uint64_t epoch;
 	int ret;
 
-	ret = collection_db_read(bus, db, p, root);
+	ret = collection_db_root_read(bus, db, p, root);
 	if (ret != -ENOENT)
 		return ret;
 
diff --git a/src/npassd/service.c b/src/npassd/service.c
index f69ac22..5996ddc 100644
--- a/src/npassd/service.c
+++ b/src/npassd/service.c
@@ -15,6 +15,8 @@ static int handle_search_items(sd_bus_message *msg, void *data,
 			       sd_bus_error *ret_error);
 static int handle_create_collection(sd_bus_message *msg, void *data,
 				    sd_bus_error *ret_error);
+static int handle_read_alias(sd_bus_message *msg, void *data,
+			     sd_bus_error *ret_error);
 
 static const sd_bus_vtable service_vtable[] = {
 	SD_BUS_VTABLE_START(0),
@@ -24,6 +26,8 @@ static const sd_bus_vtable service_vtable[] = {
 		      SD_BUS_VTABLE_UNPRIVILEGED),
 	SD_BUS_METHOD("CreateCollection", "a{sv}s", "oo",
 		      handle_create_collection, SD_BUS_VTABLE_UNPRIVILEGED),
+	SD_BUS_METHOD("ReadAlias", "s", "o", handle_read_alias,
+		      SD_BUS_VTABLE_UNPRIVILEGED),
 	SD_BUS_VTABLE_END,
 };
 
@@ -112,6 +116,48 @@ static int handle_create_collection(sd_bus_message *msg, void *data,
 	return ret;
 }
 
+static int handle_read_alias(sd_bus_message *msg, void *data,
+			     __attribute__((unused)) sd_bus_error *ret_error)
+{
+	struct service *service = data;
+	struct collection *collection;
+	const char *alias;
+	int ret;
+
+	ret = sd_bus_message_read(msg, "s", &alias);
+	if (ret < 0) {
+		print_err("%s", strerror(-ret));
+		return ret;
+	}
+
+	ret = collection_alias_search(&service->collections, alias,
+				      &collection);
+	if (ret >= 0) {
+		ret = sd_bus_reply_method_return(msg, "o", collection->path);
+		if (ret < 0)
+			print_err("%s", strerror(-ret));
+		return ret;
+	}
+
+	ret = collection_db_alias_read(service->bus, service->db, &collection,
+				       alias);
+	if (ret < 0) {
+		ret = sd_bus_reply_method_return(msg, "o", "/");
+		if (ret < 0)
+			print_err("%s", strerror(-ret));
+		return ret;
+	}
+
+	ret = sd_bus_reply_method_return(msg, "o", collection->path);
+	if (ret < 0) {
+		print_err("%s", strerror(-ret));
+		return ret;
+	}
+
+	LIST_INSERT_HEAD(&service->collections, collection, dlist);
+	return ret;
+}
+
 static int handle_open_session(sd_bus_message *msg, void *data,
 			       sd_bus_error *ret_error)
 {
-- 
cgit v1.2.3