#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) \
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)) {
}
}
}
+ /* Reseting the edit state to NONE as its newly loaded identity */
+ gsignond_identity_info_reset_edit_flags (identity, IDENTITY_INFO_PROP_NONE);
return 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;
#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"
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;
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,
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");
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;
}
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))) {
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);