ENGINE-463: reconcile usernames, reconcile default names, and about half of merge records ENGINE-463
authorKrista Bennett <krista@pep-project.org>
Tue, 02 Oct 2018 16:37:46 +0200
branchENGINE-463
changeset 2971124bcf396623
parent 2970 7c0ad677fbca
child 2972 4a68c8c4726c
ENGINE-463: reconcile usernames, reconcile default names, and about half of merge records
src/pEpEngine.c
     1.1 --- a/src/pEpEngine.c	Tue Oct 02 15:47:10 2018 +0200
     1.2 +++ b/src/pEpEngine.c	Tue Oct 02 16:37:46 2018 +0200
     1.3 @@ -2992,6 +2992,74 @@
     1.4      return status;
     1.5  }
     1.6  
     1.7 +const char* reconcile_usernames(const char* old_name, const char* new_name, 
     1.8 +                                const char* address) {
     1.9 +    if (EMPTYSTR(old_name)) {
    1.10 +        if (EMPTYSTR(new_name))
    1.11 +            return address;
    1.12 +        else
    1.13 +            return new_name;
    1.14 +    }
    1.15 +    if (EMPTYSTR(new_name))
    1.16 +        return old_name;        
    1.17 +    if (strcmp(new_name, address) == 0)
    1.18 +        return old_name;
    1.19 +    return new_name;        
    1.20 +}
    1.21 +
    1.22 +PEP_STATUS reconcile_default_keys(PEP_SESSION session, pEp_identity* old_ident,
    1.23 +                                  pEp_identity* new_ident) {
    1.24 +    PEP_STATUS status = PEP_STATUS_OK;
    1.25 +                                      
    1.26 +    const char* old_fpr = old_ident->fpr;
    1.27 +    const char* new_fpr = new_ident->fpr;
    1.28 +    if (!old_fpr)
    1.29 +        return status;
    1.30 +
    1.31 +    PEP_comm_type old_ct = old_ident->comm_type;    
    1.32 +    PEP_comm_type new_ct = new_ident->comm_type;
    1.33 +    
    1.34 +    if (!new_fpr) {
    1.35 +        new_ident->fpr = strdup(old_fpr);
    1.36 +        if (!new_ident->fpr)
    1.37 +            status = PEP_OUT_OF_MEMORY;
    1.38 +        else    
    1.39 +            new_ident->comm_type = old_ct;
    1.40 +        return status;
    1.41 +    }        
    1.42 +    
    1.43 +    if (strcmp(old_fpr, new_fpr) == 0) {
    1.44 +        new_ident->comm_type = reconcile_trust(old_ct, new_ct);
    1.45 +        return status;
    1.46 +    }
    1.47 +    
    1.48 +    bool old_confirmed = old_ct & PEP_ct_confirmed;
    1.49 +    bool new_confirmed = new_ct & PEP_ct_confirmed;
    1.50 +    
    1.51 +    if (new_confirmed)
    1.52 +        return status;
    1.53 +    else if (old_confirmed) {
    1.54 +        free(new_ident->fpr);
    1.55 +        new_ident->fpr = strdup(old_fpr);
    1.56 +        if (!new_ident->fpr)
    1.57 +            status = PEP_OUT_OF_MEMORY;
    1.58 +        else    
    1.59 +            new_ident->comm_type = old_ct;
    1.60 +        return status;
    1.61 +    }
    1.62 +    
    1.63 +    if (old_ct > new_ct) {
    1.64 +        free(new_ident->fpr);
    1.65 +        new_ident->fpr = strdup(old_fpr);
    1.66 +        if (!new_ident->fpr)
    1.67 +            status = PEP_OUT_OF_MEMORY;
    1.68 +        else    
    1.69 +            new_ident->comm_type = old_ct;
    1.70 +    }
    1.71 +    return status;
    1.72 +}
    1.73 +
    1.74 +// ONLY CALL THIS IF BOTH IDs ARE IN THE PERSON DB, FOOL! </Mr_T>
    1.75  PEP_STATUS merge_records(PEP_SESSION session, const char* old_uid,
    1.76                           const char* new_uid) {
    1.77      PEP_STATUS status = PEP_STATUS_OK;
    1.78 @@ -3000,7 +3068,74 @@
    1.79      if (status != PEP_STATUS_OK)
    1.80          goto pEp_free;
    1.81          
    1.82 +    pEp_identity* new_ident = NULL;
    1.83 +    identity_list* old_identities = NULL;
    1.84 +    labeled_int_list_t* trust_list = NULL;
    1.85 +    stringlist_t* touched_keys = new_stringlist(NULL);
    1.86 +        
    1.87 +    status = get_identities_by_userid(session, old_uid, &old_identities);
    1.88 +    if (status == PEP_STATUS_OK && old_identities) {
    1.89 +        identity_list* curr_old = old_identities;
    1.90 +        for (; curr_old && curr_old->ident; curr_old = curr_old->next) {
    1.91 +            pEp_identity* old_ident = curr_old->ident;
    1.92 +            const char* address = old_ident->address;
    1.93 +            status = get_identity(session, address, new_uid, &new_ident);
    1.94 +            if (status == PEP_CANNOT_FIND_IDENTITY) {
    1.95 +                // No new identity matching the old one, so we just set one w. new user_id
    1.96 +                free(old_ident->user_id);
    1.97 +                old_ident->user_id = strdup(new_uid);
    1.98 +                if (!old_ident->user_id) {
    1.99 +                    status = PEP_OUT_OF_MEMORY;
   1.100 +                    goto pEp_free;
   1.101 +                }
   1.102 +                status = set_identity(session, old_ident);
   1.103 +                if (status != PEP_STATUS_OK)
   1.104 +                    goto pEp_free;
   1.105 +            }
   1.106 +            else if (status != PEP_STATUS_OK)
   1.107 +                goto pEp_free;
   1.108 +            else {
   1.109 +                // Ok, so we have two idents which might be in conflict. Have to merge them.
   1.110 +                const char* username = reconcile_usernames(old_ident->username,
   1.111 +                                                           new_ident->username,
   1.112 +                                                           address);
   1.113 +                                                           
   1.114 +                if (!new_ident->username || strcmp(username, new_ident->username) != 0) {
   1.115 +                    free(new_ident->username);
   1.116 +                    new_ident->username = strdup(username);
   1.117 +                    if (!new_ident->username) {
   1.118 +                        status = PEP_OUT_OF_MEMORY;
   1.119 +                        goto pEp_free;
   1.120 +                    }
   1.121 +                }
   1.122 +        
   1.123 +                // Reconcile default keys if they differ, trust if they don't
   1.124 +                status = reconcile_default_keys(session, old_ident, new_ident);
   1.125 +                if (status != PEP_STATUS_OK)
   1.126 +                    goto pEp_free;
   1.127 +                    
   1.128 +                // Set the reconciled record
   1.129 +                status = set_identity(session, new_ident);
   1.130 +                if (status != PEP_STATUS_OK)
   1.131 +                    goto pEp_free;
   1.132 +                    
   1.133 +                free_identity(new_ident);
   1.134 +                new_ident = NULL;    
   1.135 +            }
   1.136 +        }
   1.137 +    }
   1.138 +    // otherwise, no need to reconcile identity records. But maybe trust...    
   1.139 +
   1.140 +    // reconcile the default keys if the new id doesn't have one?
   1.141 +    
   1.142 +    // delete the old user
   1.143 +    status = delete_person(session, old_uid);
   1.144 +    
   1.145  pEp_free:
   1.146 +    free_identity(new_ident);
   1.147 +    free_identity_list(old_identities);
   1.148 +    free_labeled_int_list(trust_list);
   1.149 +    free_stringlist(touched_keys);
   1.150      return status;
   1.151  }
   1.152