Fixed Primary Key of identity table. Was (address) and know is (address, user_id). Added 'virtual' user_id (const string + address) as a side effect, in case user_id isn't given and no user have been created with same address.

doc_update_sequoia
Edouard Tisserant 7 years ago
parent 8339d70b35
commit c3e8184c7e

@ -70,7 +70,43 @@ DYNAMIC_API PEP_STATUS update_identity(
if (!(session && identity && !EMPTYSTR(identity->address)))
return PEP_ILLEGAL_VALUE;
status = get_identity(session, identity->address, &stored_identity);
int _no_user_id = EMPTYSTR(identity->user_id);
if (_no_user_id)
{
free(identity->user_id);
status = get_best_user(session,
identity->address,
&identity->user_id);
// Default user_id, aka Virtual user_id
if (status == PEP_CANNOT_FIND_IDENTITY)
{
identity->user_id = calloc(1, identity->address_size + 5);
if (!identity->user_id)
{
return PEP_OUT_OF_MEMORY;
}
snprintf(identity->user_id, identity->address_size + 5,
"TOFU_%s", identity->address);
}
else if (status != PEP_STATUS_OK)
{
return status;
}
if(identity->user_id)
{
identity->user_id_size = strlen(identity->user_id);
}
}
status = get_identity(session,
identity->address,
identity->user_id,
&stored_identity);
assert(status != PEP_OUT_OF_MEMORY);
if (status == PEP_OUT_OF_MEMORY)
return PEP_OUT_OF_MEMORY;
@ -82,15 +118,6 @@ DYNAMIC_API PEP_STATUS update_identity(
if (status == PEP_OUT_OF_MEMORY)
return PEP_OUT_OF_MEMORY;
if (EMPTYSTR(identity->user_id)) {
free(identity->user_id);
identity->user_id = strndup(stored_identity->user_id, stored_identity->user_id_size);
assert(identity->user_id);
if (identity->user_id == NULL)
return PEP_OUT_OF_MEMORY;
identity->user_id_size = stored_identity->user_id_size;
}
if (EMPTYSTR(identity->username)) {
free(identity->username);
identity->username = strndup(stored_identity->username, stored_identity->username_size);
@ -218,10 +245,15 @@ DYNAMIC_API PEP_STATUS update_identity(
identity->username_size = 9;
}
status = set_identity(session, identity);
assert(status == PEP_STATUS_OK);
if (status != PEP_STATUS_OK) {
return status;
// Identity doesn't get stored if is was just about checking existing
// user by address (i.e. no user id but already stored)
if (!(_no_user_id && stored_identity))
{
status = set_identity(session, identity);
assert(status == PEP_STATUS_OK);
if (status != PEP_STATUS_OK) {
return status;
}
}
}

@ -13,6 +13,7 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
static const char *sql_log;
static const char *sql_trustword;
static const char *sql_get_identity;
static const char *sql_get_best_user;
static const char *sql_set_person;
static const char *sql_set_pgp_keypair;
static const char *sql_set_identity;
@ -140,14 +141,15 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
" comment text\n"
");\n"
"create table if not exists identity (\n"
" address text primary key,\n"
" address text,\n"
" user_id text\n"
" references person (id)\n"
" on delete cascade,\n"
" main_key_id text\n"
" references pgp_keypair (fpr)\n"
" on delete set null,\n"
" comment text\n"
" comment text,\n"
" primary key (address, user_id)\n"
");\n"
"create table if not exists trust (\n"
" user_id text not null\n"
@ -186,13 +188,21 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
sql_log = "insert into log (title, entity, description, comment)"
"values (?1, ?2, ?3, ?4);";
sql_get_identity = "select fpr, identity.user_id, username, comm_type, lang"
sql_get_identity = "select fpr, username, comm_type, lang"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
" join trust on id = trust.user_id"
" and pgp_keypair_fpr = identity.main_key_id"
" where address = ?1 ;";
" where address = ?1 and identity.user_id = ?2;";
sql_get_best_user = "select identity.user_id"
" from identity"
" join trust on trust.user_id = identity.user_id"
" and pgp_keypair_fpr = identity.main_key_id"
" where address = ?1"
" order by comm_type DESC, identity.rowid DESC"
" limit 1;";
sql_trustword = "select id, word from wordlist where lang = lower(?1) "
"and id = ?2 ;";
@ -201,21 +211,21 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
"values (?1, ?2, ?3) ;";
sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
"values (?1) ;";
"values (upper(replace(?1,' ',''))) ;";
sql_set_identity = "insert or replace into identity (address, main_key_id, "
"user_id) values (?1, ?2, ?3) ;";
"user_id) values (?1, upper(replace(?2,' ','')), ?3) ;";
sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
"values (?1, ?2, ?3) ;";
"values (?1, upper(replace(?2,' ','')), ?3) ;";
sql_get_trust = "select user_id, comm_type from trust where user_id = ?1 "
"and pgp_keypair_fpr = ?2 ;";
sql_get_trust = "select comm_type from trust where user_id = ?1 "
"and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = ?1 ;";
sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
sql_mark_as_compromized = "update trust not indexed set comm_type = 15"
" where pgp_keypair_fpr = ?1 ;";
" where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
sql_crashdump = "select timestamp, title, entity, description, comment"
" from log order by timestamp desc limit ?1 ;";
@ -226,13 +236,13 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
// blacklist
sql_blacklist_add = "insert or replace into blacklist_keys (fpr) values (?1) ;"
"delete from identity where main_key_id = ?1 ;"
"delete from pgp_keypair where fpr = ?1 ;";
sql_blacklist_add = "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
"delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
"delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
sql_blacklist_delete = "delete from blacklist_keys where fpr = ?1 ;";
sql_blacklist_delete = "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
sql_blacklist_is_listed = "select count(*) from blacklist_keys where fpr = ?1 ;";
sql_blacklist_is_listed = "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
sql_blacklist_retrieve = "select * from blacklist_keys ;";
}
@ -249,6 +259,10 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
(int)strlen(sql_get_identity), &_session->get_identity, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_get_best_user,
(int)strlen(sql_get_best_user), &_session->get_best_user, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
(int)strlen(sql_set_person), &_session->set_person, NULL);
assert(int_result == SQLITE_OK);
@ -360,6 +374,8 @@ DYNAMIC_API void release(PEP_SESSION session)
sqlite3_finalize(session->trustword);
if (session->get_identity)
sqlite3_finalize(session->get_identity);
if (session->get_best_user)
sqlite3_finalize(session->get_best_user);
if (session->set_person)
sqlite3_finalize(session->set_person);
if (session->set_pgp_keypair)
@ -671,7 +687,9 @@ void free_identity(pEp_identity *identity)
}
DYNAMIC_API PEP_STATUS get_identity(
PEP_SESSION session, const char *address,
PEP_SESSION session,
const char *address,
const char *user_id,
pEp_identity **identity
)
{
@ -689,6 +707,7 @@ DYNAMIC_API PEP_STATUS get_identity(
sqlite3_reset(session->get_identity);
sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
result = sqlite3_step(session->get_identity);
switch (result) {
@ -696,15 +715,15 @@ DYNAMIC_API PEP_STATUS get_identity(
_identity = new_identity(
address,
(const char *) sqlite3_column_text(session->get_identity, 0),
(const char *) sqlite3_column_text(session->get_identity, 1),
(const char *) sqlite3_column_text(session->get_identity, 2)
user_id,
(const char *) sqlite3_column_text(session->get_identity, 1)
);
assert(_identity);
if (_identity == NULL)
return PEP_OUT_OF_MEMORY;
_identity->comm_type = (PEP_comm_type) sqlite3_column_int(session->get_identity, 3);
_lang = (const char *) sqlite3_column_text(session->get_identity, 4);
_identity->comm_type = (PEP_comm_type) sqlite3_column_int(session->get_identity, 2);
_lang = (const char *) sqlite3_column_text(session->get_identity, 3);
if (_lang && _lang[0]) {
assert(_lang[0] >= 'a' && _lang[0] <= 'z');
assert(_lang[1] >= 'a' && _lang[1] <= 'z');
@ -724,6 +743,41 @@ DYNAMIC_API PEP_STATUS get_identity(
return status;
}
DYNAMIC_API PEP_STATUS get_best_user(
PEP_SESSION session,
const char *address,
char **user_id
)
{
PEP_STATUS status = PEP_STATUS_OK;
int result;
assert(session);
assert(address);
assert(user_id);
*user_id = NULL;
if (!(session && address && user_id))
return PEP_ILLEGAL_VALUE;
sqlite3_reset(session->get_best_user);
sqlite3_bind_text(session->get_best_user, 1, address, -1, SQLITE_STATIC);
result = sqlite3_step(session->get_best_user);
switch (result) {
case SQLITE_ROW: {
*user_id = strdup((const char *)sqlite3_column_text(session->get_best_user, 0));
break;
}
default:
status = PEP_CANNOT_FIND_IDENTITY;
}
sqlite3_reset(session->get_best_user);
return status;
}
DYNAMIC_API PEP_STATUS set_identity(
PEP_SESSION session, const pEp_identity *identity
)
@ -868,16 +922,7 @@ DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
result = sqlite3_step(session->get_trust);
switch (result) {
case SQLITE_ROW: {
const char * user_id = (const char *) sqlite3_column_text(session->get_trust, 0);
int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust, 1);
if (strcmp(user_id, identity->user_id) != 0) {
free(identity->user_id);
identity->user_id = strdup(user_id);
assert(identity->user_id);
if (identity->user_id == NULL)
return PEP_OUT_OF_MEMORY;
}
int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust, 0);
identity->comm_type = comm_type;
break;
}

@ -443,10 +443,32 @@ DYNAMIC_API void free_identity(pEp_identity *identity);
// more
DYNAMIC_API PEP_STATUS get_identity(
PEP_SESSION session, const char *address,
PEP_SESSION session,
const char *address,
const char *user_id,
pEp_identity **identity
);
// get_best_user() - get best user_id candidate for a given address
//
// parameters:
// session (in) session handle
// address (in) C string with communication address, UTF-8 encoded
// user_id (out) pointer to user_id string
//
// caveat:
// the address string is being copied; the original string remains in the
// ownership of the caller
// the resulting user_id string goes to the ownership of the
// caller and has to be freed with free() when not in use any
// more
DYNAMIC_API PEP_STATUS get_best_user(
PEP_SESSION session,
const char *address,
char **user_id
);
// set_identity() - set identity information
//

@ -88,6 +88,7 @@ typedef struct _pEpSession {
sqlite3_stmt *log;
sqlite3_stmt *trustword;
sqlite3_stmt *get_identity;
sqlite3_stmt *get_best_user;
sqlite3_stmt *set_person;
sqlite3_stmt *set_pgp_keypair;
sqlite3_stmt *set_identity;

Loading…
Cancel
Save