daemon/db: Make use of IdentityInfo 'EditFlags'.
authorAmarnath Valluri <amarnath.valluri@linux.intel.com>
Mon, 29 Jul 2013 12:12:59 +0000 (15:12 +0300)
committerAmarnath Valluri <amarnath.valluri@linux.intel.com>
Thu, 5 Sep 2013 11:02:21 +0000 (14:02 +0300)
Consider IdentityInfo 'EditFlags' while saving identity to db
and other parts of the code.

src/daemon/db/gsignond-db-credentials-database.c
src/daemon/db/gsignond-db-metadata-database.c
src/daemon/gsignond-identity.c

index 33e0c6c..7189cad 100644 (file)
@@ -27,6 +27,7 @@
 #include "gsignond/gsignond-log.h"
 #include "gsignond/gsignond-credentials.h"
 #include "common/db/gsignond-db-error.h"
+#include "common/gsignond-identity-info-internal.h"
 #include "gsignond-db-credentials-database.h"
 
 #define GSIGNOND_DB_CREDENTIALS_DATABASE_GET_PRIVATE(obj) \
@@ -294,7 +295,10 @@ gsignond_db_credentials_database_load_identity (
 
     identity = gsignond_db_metadata_database_get_identity (
                self->priv->metadata_db, identity_id);
-    if (identity && query_secret &&
+    if (!identity) 
+        return identity;
+
+    if (query_secret &&
        !gsignond_identity_info_get_is_identity_new (identity) &&
         gsignond_db_credentials_database_is_open_secret_storage (self)) {
 
@@ -315,6 +319,8 @@ gsignond_db_credentials_database_load_identity (
             }
         }
     }
+    /* Reseting the edit state to NONE as its newly loaded identity */
+    gsignond_identity_info_reset_edit_flags (identity, IDENTITY_INFO_PROP_NONE);
 
        return identity;
 }
@@ -367,8 +373,12 @@ gsignond_db_credentials_database_update_identity (
     id = gsignond_db_metadata_database_update_identity (self->priv->metadata_db,
                identity);
 
-    if (id != 0 &&
-       gsignond_db_credentials_database_is_open_secret_storage (self)) {
+    if (!id) return 0;
+
+    /* Reseting the edit state to NONE as all the changes are stored in db. */
+    gsignond_identity_info_reset_edit_flags (identity, IDENTITY_INFO_PROP_NONE);
+
+    if (gsignond_db_credentials_database_is_open_secret_storage (self)) {
         GSignondCredentials *creds = NULL;
         gboolean un_sec, pwd_sec;
         const gchar *tmp_str = NULL;
index 29da387..4dacce7 100644 (file)
@@ -31,6 +31,7 @@
 #include "gsignond/gsignond-log.h"
 #include "gsignond/gsignond-config.h"
 #include "common/db/gsignond-db-error.h"
+#include "common/gsignond-identity-info-internal.h"
 #include "gsignond-db-metadata-database.h"
 
 #define GSIGNOND_METADATA_DB_FILENAME   "metadata.db"
@@ -1061,11 +1062,23 @@ gsignond_db_metadata_database_update_identity (
     GHashTableIter method_iter;
     const gchar *method = NULL;
     GSequence *mechanisms = NULL;
+    GSignondIdentityInfoPropFlags edit_flags;
+    gboolean was_new_identity;
 
     g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), 0);
     g_return_val_if_fail (identity != NULL, 0);
     RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), id);
 
+    edit_flags = gsignond_identity_info_get_edit_flags (identity);
+
+    DBG ("Identity EDIT FLAGS : %x", edit_flags);
+    if (edit_flags == IDENTITY_INFO_PROP_NONE) {
+        DBG("No Changes found to update");
+        return gsignond_identity_info_get_id (identity);
+    }
+
+    was_new_identity = gsignond_identity_info_get_is_identity_new (identity);
+
     sql = GSIGNOND_DB_SQL_DATABASE (self);
     if (!gsignond_db_sql_database_start_transaction (sql)) {
         return 0;
@@ -1079,50 +1092,77 @@ gsignond_db_metadata_database_update_identity (
         return 0;
     }
 
-    if (!gsignond_identity_info_get_is_identity_new (identity)) {
-        DBG ("Remove old acl and owner list as identity is not new");
-        /* remove acl */
-        _gsignond_db_metadata_database_exec (self,
-                "DELETE FROM ACL WHERE identity_id = %u;", id);
-
-        /* remove owner */
-        _gsignond_db_metadata_database_exec (self,
-                "DELETE FROM OWNER WHERE identity_id = %u;", id);
-    }
-
-    /* methods */
-    methods = gsignond_identity_info_get_methods (identity);
-    if (!_gsignond_db_metadata_database_insert_methods (self, identity,
-            methods)) {
-        DBG ("Update methods failed");
+    /* realms */
+    if (edit_flags & IDENTITY_INFO_PROP_REALMS) {
+        realms = gsignond_identity_info_get_realms (identity);
+        if (!_gsignond_db_metadata_database_update_realms (self,
+                                        identity, id, realms)) {
+            DBG ("Update realms failed");
+            gsignond_db_sql_database_rollback_transaction (sql);
+            goto finished;
+        }
     }
 
-    /* realms */
-    realms = gsignond_identity_info_get_realms (identity);
-    if (!_gsignond_db_metadata_database_update_realms (self,
-            identity, id, realms)) {
-        DBG ("Update realms failed");
+    /* owner */
+    owner = gsignond_identity_info_get_owner (identity);
+    if (!owner) {
+        WARN("Missing mandatory owner field");
         gsignond_db_sql_database_rollback_transaction (sql);
         goto finished;
     }
 
+    if (edit_flags & IDENTITY_INFO_PROP_OWNER) {
+        if (!was_new_identity) {
+            /* remove owner */
+            _gsignond_db_metadata_database_exec (self,
+                    "DELETE FROM OWNER WHERE identity_id = %u;", id);
+        }
+        if (!_gsignond_db_metadata_database_update_owner (self, identity, owner)){
+            DBG ("Update owner failed");
+            gsignond_db_sql_database_rollback_transaction (sql);
+            goto finished;
+        }
+
+        /* insert owner */
+        _gsignond_db_metadata_database_exec (self,
+                    "INSERT OR REPLACE INTO OWNER "
+                    "(identity_id, secctx_id) "
+                    "VALUES ( %u, "
+                    "( SELECT id FROM SECCTX WHERE sysctx = %Q AND appctx = %Q ));",
+                    id, owner->sys_ctx, owner->app_ctx);
+    }
+
     /* acl */
     acl = gsignond_identity_info_get_access_control_list (identity);
-    if (!_gsignond_db_metadata_database_update_acl (self, identity, acl)) {
-        DBG ("Update acl failed");
+    if (!acl) {
+        WARN("Missing mandatory ACL field");
         gsignond_db_sql_database_rollback_transaction (sql);
         goto finished;
     }
-
-    /* owner */
-    owner = gsignond_identity_info_get_owner (identity);
-    if (!_gsignond_db_metadata_database_update_owner (self, identity, owner)){
-        DBG ("Update owner failed");
-        gsignond_db_sql_database_rollback_transaction (sql);
-        goto finished;
+    if (edit_flags & IDENTITY_INFO_PROP_ACL) {
+        if (!was_new_identity) {
+            /* remove acl */
+            _gsignond_db_metadata_database_exec (self,
+                "DELETE FROM ACL WHERE identity_id = %u;", id);
+        }
+        if (!_gsignond_db_metadata_database_update_acl (self, identity, acl)) {
+            DBG ("Update acl failed");
+            gsignond_db_sql_database_rollback_transaction (sql);
+            goto finished;
+        }
     }
 
+    /* methods */
+    methods = gsignond_identity_info_get_methods (identity);
+    if (edit_flags & IDENTITY_INFO_PROP_METHODS) {
+        if (!_gsignond_db_metadata_database_insert_methods (self, identity,
+                methods)) {
+            DBG ("Update methods failed");
+        }
+    }
 
+    if (edit_flags & IDENTITY_INFO_PROP_ACL ||
+        edit_flags & IDENTITY_INFO_PROP_METHODS) {
     /* ACL insert, this will do basically identity level ACL */
     g_hash_table_iter_init (&method_iter, methods);
     while (g_hash_table_iter_next (&method_iter, (gpointer)&method,
@@ -1197,14 +1237,7 @@ gsignond_db_metadata_database_update_identity (
                     id, ctx->sys_ctx, ctx->app_ctx);
         }
     }
-
-    /* insert owner */
-    _gsignond_db_metadata_database_exec (self,
-                "INSERT OR REPLACE INTO OWNER "
-                "(identity_id, secctx_id) "
-                "VALUES ( %u, "
-                "( SELECT id FROM SECCTX WHERE sysctx = %Q AND appctx = %Q ));",
-                id, owner->sys_ctx, owner->app_ctx);
+    }
 
     if (gsignond_db_sql_database_commit_transaction (sql)) {
         DBG ("Identity updated");
@@ -1260,7 +1293,7 @@ gsignond_db_metadata_database_get_identity (
             identity);
     sqlite3_free (query);
     if (G_UNLIKELY (rows <= 0)) {
-        DBG ("Fetch IDENTITY failed");
+        DBG ("Fetch IDENTITY '%d' failed", identity_id);
         gsignond_identity_info_unref (identity);
         return NULL;
     }
index cb36fa1..3ae327a 100644 (file)
@@ -848,10 +848,11 @@ gsignond_identity_store (GSignondIdentity *identity,
                          const GSignondSecurityContext *ctx,
                          GError **error)
 {
+    GSignondIdentityPrivate *priv = NULL;
     GSignondIdentityInfo *identity_info = NULL;
     gboolean was_new_identity = FALSE;
     GSignondSecurityContextList *contexts = NULL;
-    GSignondSecurityContext *owner = NULL;
+    GSignondIdentityInfoPropFlags flags;
     guint32 id;
 
     if (!(identity && GSIGNOND_IS_IDENTITY (identity))) {
@@ -859,51 +860,73 @@ gsignond_identity_store (GSignondIdentity *identity,
         if (error) *error = gsignond_get_gerror_for_id (GSIGNOND_ERROR_UNKNOWN, "Unknown error");
         return 0;
     }
-    
+
+    priv = identity->priv;
+
     VALIDATE_IDENTITY_WRITE_ACCESS (identity, ctx, 0);
 
-    identity_info = gsignond_dictionary_new_from_variant ((GVariant *)info);
-    /* dont trust 'identity id' passed via 'info' */
-    id = gsignond_identity_info_get_id (identity->priv->info);
-    gsignond_identity_info_set_id (identity_info, id);
+    was_new_identity = gsignond_identity_info_get_is_identity_new (priv->info);
 
-    was_new_identity = gsignond_identity_info_get_is_identity_new (identity_info);
+    identity_info = gsignond_identity_info_new_from_variant ((GVariant *)info);
 
     contexts = gsignond_identity_info_get_access_control_list (identity_info);
-    if (!contexts) {
-        contexts = gsignond_identity_info_get_access_control_list (identity->priv->info);
-        gsignond_identity_info_set_access_control_list (identity_info, contexts);
-    }
-    else {
+    if (contexts) {
         VALIDATE_IDENTITY_WRITE_ACL (identity, ctx, 0);
+        gsignond_security_context_list_free (contexts);
     }
-    gsignond_security_context_list_free (contexts);
    
-    owner = gsignond_identity_info_get_owner (identity_info);
-    if (!owner) {
-        owner = gsignond_identity_info_get_owner (identity->priv->info);
-        gsignond_identity_info_set_owner (identity_info, owner);
+    flags = gsignond_identity_info_get_edit_flags (identity_info);
+
+    if (flags & IDENTITY_INFO_PROP_USERNAME)
+        gsignond_identity_info_set_username (priv->info,
+            gsignond_identity_info_get_username(identity_info));
+    if (flags & IDENTITY_INFO_PROP_USERNAME_IS_SECRET)
+        gsignond_identity_info_set_username_secret (priv->info,
+            gsignond_identity_info_get_is_username_secret (identity_info));
+    if (flags & IDENTITY_INFO_PROP_SECRET)
+        gsignond_identity_info_set_secret (priv->info,
+            gsignond_identity_info_get_secret (identity_info));
+    if (flags & IDENTITY_INFO_PROP_STORE_SECRET)
+        gsignond_identity_info_set_store_secret (priv->info,
+            gsignond_identity_info_get_store_secret (identity_info));
+    if (flags & IDENTITY_INFO_PROP_CAPTION)
+        gsignond_identity_info_set_caption (priv->info,
+            gsignond_identity_info_get_caption (identity_info));
+    if (flags & IDENTITY_INFO_PROP_TYPE)
+        gsignond_identity_info_set_identity_type (priv->info,
+            gsignond_identity_info_get_identity_type (identity_info));
+    if (flags & IDENTITY_INFO_PROP_METHODS) {
+        GHashTable *methods = 
+            gsignond_identity_info_get_methods (identity_info);
+        gsignond_identity_info_set_methods (priv->info, methods);
+        g_hash_table_unref (methods);
+    }
+    if (flags & IDENTITY_INFO_PROP_REALMS) {
+        GSequence *realms = 
+            gsignond_identity_info_get_realms (identity_info);
+        gsignond_identity_info_set_realms (priv->info, realms);
+        g_sequence_free (realms);
     }
-    gsignond_security_context_free (owner);
 
+    /* FIXME : either username/secret changed reset the identity
+     * valdated state to FALSE ???
+     */          
 
-    /* update object cache */
-    if (identity->priv->info)
-        gsignond_identity_info_unref (identity->priv->info);
-    identity->priv->info = identity_info;
+    gsignond_identity_info_unref (identity_info);
 
     /* Ask daemon to store identity info to db */
-    id = gsignond_daemon_store_identity (identity->priv->owner, identity);
+    id = gsignond_daemon_store_identity (priv->owner, identity);
     if (!id) {
         if (error) *error = gsignond_get_gerror_for_id (GSIGNOND_ERROR_STORE_FAILED,
                                                         "Failed to store identity");
+        /*FIXME: Roll-back the local changes */
     }
     else {
         if (was_new_identity) {
             _set_id (identity, id);
-            _StoreCachedTokenCbInfo data = { identity->priv->owner, id };
+            _StoreCachedTokenCbInfo data = { priv->owner, id };
             /* store any cached token data if available at auth sessions */
-            g_hash_table_foreach (identity->priv->auth_sessions, (GHFunc)_store_cached_token_data, (gpointer)&data);
+            g_hash_table_foreach (priv->auth_sessions, (GHFunc)_store_cached_token_data, (gpointer)&data);
         }
 
         g_signal_emit (identity, signals[SIG_INFO_UPDATED], 0, GSIGNOND_IDENTITY_DATA_UPDATED);