|
|
@@ -16,19 +16,206 @@
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
|
|
|
|
+#include <string.h>
|
|
|
+#include <json-glib/json-glib.h>
|
|
|
#include "iridium-config.h"
|
|
|
+#include "iridium-crypto.h"
|
|
|
#include "iridium-storage.h"
|
|
|
+#include "iridium-note.h"
|
|
|
|
|
|
struct _IridiumStorage
|
|
|
{
|
|
|
GObject parent_instance;
|
|
|
-
|
|
|
- GList *tags;
|
|
|
- GList *notes;
|
|
|
+ gchar *email;
|
|
|
+ gchar *password;
|
|
|
+ gchar *server;
|
|
|
};
|
|
|
|
|
|
+typedef struct {
|
|
|
+ GFile *file;
|
|
|
+ GFileInputStream *stream;
|
|
|
+ JsonParser *parser;
|
|
|
+ gchar *email;
|
|
|
+ gchar *server;
|
|
|
+ gchar *password;
|
|
|
+} TaskData;
|
|
|
+
|
|
|
G_DEFINE_TYPE (IridiumStorage, iridium_storage, G_TYPE_OBJECT)
|
|
|
|
|
|
+IridiumStorage *
|
|
|
+iridium_storage_new (void)
|
|
|
+{
|
|
|
+ return g_object_new (IRIDIUM_TYPE_STORAGE, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+free_task_data (TaskData *data)
|
|
|
+{
|
|
|
+ g_free (data->email);
|
|
|
+ g_free (data->server);
|
|
|
+ g_free (data->password);
|
|
|
+ g_object_unref (data->parser);
|
|
|
+ g_object_unref (data->stream);
|
|
|
+ g_object_unref (data->file);
|
|
|
+ g_free (data);
|
|
|
+}
|
|
|
+
|
|
|
+static IridiumNote *
|
|
|
+deserialize_note (JsonObject *meta, JsonObject *data)
|
|
|
+{
|
|
|
+ IridiumNote *note;
|
|
|
+ GTimeVal time;
|
|
|
+ GDateTime *last_modified;
|
|
|
+
|
|
|
+ if (!g_time_val_from_iso8601 (json_object_get_string_member (meta, "created_at"), &time)) {
|
|
|
+ g_print ("Problem parsing\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ last_modified = g_date_time_new_from_timeval_local (&time);
|
|
|
+
|
|
|
+ note = iridium_note_new (json_object_get_string_member (data, "title"),
|
|
|
+ json_object_get_string_member (data, "text"),
|
|
|
+ last_modified);
|
|
|
+
|
|
|
+ return note;
|
|
|
+}
|
|
|
+
|
|
|
+static GObject *
|
|
|
+deserialize_item (JsonObject *meta, const gchar *data)
|
|
|
+{
|
|
|
+ JsonObject *root;
|
|
|
+ g_autoptr(JsonParser) parser;
|
|
|
+ const gchar *type;
|
|
|
+ GError *error = NULL;
|
|
|
+
|
|
|
+ parser = json_parser_new_immutable ();
|
|
|
+ json_parser_load_from_data (parser, data, -1, &error);
|
|
|
+ type = json_object_get_string_member (meta, "content_type");
|
|
|
+ root = json_node_get_object (json_parser_get_root (parser));
|
|
|
+
|
|
|
+ if (!g_strcmp0 (type, "Note"))
|
|
|
+ return G_OBJECT (deserialize_note (meta, root));
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+on_json_parsed (GObject *object,
|
|
|
+ GAsyncResult *result,
|
|
|
+ gpointer user_data)
|
|
|
+{
|
|
|
+ GTask *task;
|
|
|
+ TaskData *data;
|
|
|
+ JsonObject *root;
|
|
|
+ JsonArray *array;
|
|
|
+ IridiumAuthParams *params;
|
|
|
+ GList *items = NULL;
|
|
|
+ GError *error = NULL;
|
|
|
+
|
|
|
+ task = G_TASK (user_data);
|
|
|
+ data = g_task_get_task_data (task);
|
|
|
+
|
|
|
+ if (!json_parser_load_from_stream_finish (data->parser, result, &error)) {
|
|
|
+ g_task_return_error (task, error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ root = json_node_get_object (json_parser_get_root (data->parser));
|
|
|
+ array = json_object_get_array_member (root, "items");
|
|
|
+ params = iridium_crypto_auth_params_new ();
|
|
|
+ iridium_crypto_derive_keys (params, data->password);
|
|
|
+
|
|
|
+ for (guint i = 0; i < json_array_get_length (array); i++) {
|
|
|
+ JsonObject *data;
|
|
|
+ GObject *item;
|
|
|
+ const gchar *uuid;
|
|
|
+ const gchar *enc_item_key;
|
|
|
+ const gchar *enc_content;
|
|
|
+ gchar *content;
|
|
|
+
|
|
|
+ data = json_array_get_object_element (array, i);
|
|
|
+ uuid = json_object_get_string_member (data, "uuid");
|
|
|
+ enc_item_key = json_object_get_string_member (data, "enc_item_key");
|
|
|
+
|
|
|
+ if (!g_strcmp0 (enc_item_key, ""))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ enc_content = json_object_get_string_member (data, "content");
|
|
|
+ content = iridium_crypto_decrypt_item (enc_content, params, enc_item_key, uuid);
|
|
|
+
|
|
|
+ if (content) {
|
|
|
+ item = deserialize_item (data, content);
|
|
|
+
|
|
|
+ if (item)
|
|
|
+ items = g_list_append (items, item);
|
|
|
+ }
|
|
|
+
|
|
|
+ g_free (content);
|
|
|
+ }
|
|
|
+
|
|
|
+ iridium_crypto_auth_params_free (params),
|
|
|
+ g_task_return_pointer (task, items, NULL);
|
|
|
+ g_object_unref (task);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+on_json_read (GObject *object,
|
|
|
+ GAsyncResult *result,
|
|
|
+ gpointer user_data)
|
|
|
+{
|
|
|
+ GTask *task;
|
|
|
+ TaskData *data;
|
|
|
+ GError *error = NULL;
|
|
|
+
|
|
|
+ task = G_TASK (user_data);
|
|
|
+ data = g_task_get_task_data (task);
|
|
|
+ data->stream = g_file_read_finish (data->file, result, &error);
|
|
|
+
|
|
|
+ if (data->stream == NULL) {
|
|
|
+ g_task_return_error (task, error);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ data->parser = json_parser_new ();
|
|
|
+ json_parser_load_from_stream_async (data->parser, G_INPUT_STREAM (data->stream),
|
|
|
+ g_task_get_cancellable (task), on_json_parsed, task);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+iridium_storage_sync_local_async (IridiumStorage *storage,
|
|
|
+ const gchar *email,
|
|
|
+ const gchar *server,
|
|
|
+ const gchar *password,
|
|
|
+ GCancellable *cancellable,
|
|
|
+ GAsyncReadyCallback callback,
|
|
|
+ gpointer user_data)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * The main purpose of this is to load dumped and encrypted JSON notes and
|
|
|
+ * store them if something changed.
|
|
|
+ */
|
|
|
+ GTask *task;
|
|
|
+ TaskData *data;
|
|
|
+
|
|
|
+ task = g_task_new (storage, cancellable, callback, user_data);
|
|
|
+ data = g_new0 (TaskData, 1);
|
|
|
+ data->file = g_file_new_for_path ("sn.json");
|
|
|
+ data->email = g_strdup (email);
|
|
|
+ data->server = g_strdup (server);
|
|
|
+ data->password = g_strdup (password);
|
|
|
+
|
|
|
+ g_task_set_task_data (task, data, (GDestroyNotify) free_task_data);
|
|
|
+ g_file_read_async (data->file, G_PRIORITY_DEFAULT, cancellable, on_json_read, task);
|
|
|
+}
|
|
|
+
|
|
|
+GList *
|
|
|
+iridium_storage_sync_local_finish (IridiumStorage *storage,
|
|
|
+ GAsyncResult *result,
|
|
|
+ GError **error)
|
|
|
+{
|
|
|
+ g_return_val_if_fail (g_task_is_valid (result, storage), FALSE);
|
|
|
+ return g_task_propagate_pointer (G_TASK (result), error);
|
|
|
+}
|
|
|
|
|
|
static void
|
|
|
iridium_storage_class_init (IridiumStorageClass *klass)
|
|
|
@@ -38,6 +225,4 @@ iridium_storage_class_init (IridiumStorageClass *klass)
|
|
|
static void
|
|
|
iridium_storage_init (IridiumStorage *self)
|
|
|
{
|
|
|
- self->tags = NULL;
|
|
|
- self->notes = NULL;
|
|
|
}
|