From 2f634b0141ccafa928951c6deebbc90a1980b92c Mon Sep 17 00:00:00 2001 From: Ivar Derksen Date: Thu, 31 Oct 2019 14:40:22 +0100 Subject: [PATCH] Feat: replace cred when refreshing non-singleton credential --- attributes.go | 16 ++++++++++++++++ internal/sessiontest/session_test.go | 14 ++++++++++++++ irmaclient/client.go | 15 ++++++++++++--- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/attributes.go b/attributes.go index bb0c678..26d7109 100644 --- a/attributes.go +++ b/attributes.go @@ -63,6 +63,22 @@ func (al *AttributeList) Info() *CredentialInfo { return al.info } +// EqualsExceptMetadata checks whether two AttributeLists have the same attribute values. +// The attribute containing the metadata information is skipped in this check. +func (al *AttributeList) EqualsExceptMetadata(ol *AttributeList) bool { + if len(al.Ints) != len(ol.Ints) { + return false + } + + // Check whether value of all attributes, except for metadata attribute, is equal + for i := 1; i < len(al.Ints); i++ { + if al.Ints[i].Cmp(ol.Ints[i]) != 0 { + return false + } + } + return true +} + func (al *AttributeList) Hash() string { if al.h == "" { bytes := []byte{} diff --git a/internal/sessiontest/session_test.go b/internal/sessiontest/session_test.go index 79f029d..bb1ad35 100644 --- a/internal/sessiontest/session_test.go +++ b/internal/sessiontest/session_test.go @@ -96,6 +96,20 @@ func TestIssuanceOptionalSetAttributes(t *testing.T) { sessionHelper(t, req, "issue", nil) } +func TestIssuanceSameAttributesNotSingleton(t *testing.T) { + client, _ := parseStorage(t) + defer test.ClearTestStorage(t) + + prevLen := len(client.CredentialInfoList()) + + req := getIssuanceRequest(true) + sessionHelper(t, req, "issue", client) + + req = getIssuanceRequest(false) + sessionHelper(t, req, "issue", client) + require.Equal(t, prevLen+1, len(client.CredentialInfoList())) +} + func TestLargeAttribute(t *testing.T) { client, _ := parseStorage(t) defer test.ClearTestStorage(t) diff --git a/irmaclient/client.go b/irmaclient/client.go index efc9f95..6673668 100644 --- a/irmaclient/client.go +++ b/irmaclient/client.go @@ -217,9 +217,18 @@ func (client *Client) addCredential(cred *credential, storeAttributes bool) (err } // If this is a singleton credential type, ensure we have at most one by removing any previous instance - if !id.Empty() && cred.CredentialType().IsSingleton { - for len(client.attrs(id)) != 0 { - client.remove(id, 0, false) + // If a credential already exists with exactly the same attribute values (except metadata), delete the previous credential + if !id.Empty() { + if cred.CredentialType().IsSingleton { + for len(client.attrs(id)) != 0 { + _ = client.remove(id, 0, false) + } + } + + for i := len(client.attrs(id)) - 1; i >= 0; i-- { // Go backwards through array because remove manipulates it + if client.attrs(id)[i].EqualsExceptMetadata(cred.AttributeList()) { + _ = client.remove(id, i, false) + } } } -- GitLab