Skip to content

Commit

Permalink
Merge pull request #362 from privacybydesign/remove-scheme-fix
Browse files Browse the repository at this point in the history
Fix/Feat: RemoveScheme not deleting demo schemes and requestor schemes
  • Loading branch information
ivard authored Nov 30, 2023
2 parents bc07cec + 43d11cd commit 5024f30
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
### Added
- `RemoveRequestorScheme` function in `irmaclient` to remove a requestor scheme from the `irma_configuration` directory

### Fixed
- HTTP cookies not stored in `irmaclient` when received from a `Set-Cookie` header
- Invalid hostname specified in MX record bypasses e-mail address revalidation
- Background revocation tasks not stopped when closing an `irmaclient`
- `RemoveScheme` function in `irmaclient` not deleting issuer schemes without a keyshare server ([#260](https://github.com/privacybydesign/irmago/issues/260))

### Internal
- Fixed issue with expired `irma-demo.MijnOverheid` key in testdata
Expand Down
33 changes: 22 additions & 11 deletions irmaclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1356,7 +1356,10 @@ func (client *Client) keyshareChangePinWorker(managerID irma.SchemeManagerIdenti

// KeyshareRemove unenrolls the keyshare server of the specified scheme manager and removes all associated credentials.
func (client *Client) KeyshareRemove(manager irma.SchemeManagerIdentifier) error {
return client.keyshareRemoveMultiple([]irma.SchemeManagerIdentifier{manager}, false)
if _, contains := client.keyshareServers[manager]; !contains {
return errors.New("can't uninstall unknown keyshare server")
}
return client.stripStorage([]irma.SchemeManagerIdentifier{manager}, false)
}

// KeyshareRemoveAll removes all keyshare server registrations and associated credentials.
Expand All @@ -1365,16 +1368,11 @@ func (client *Client) KeyshareRemoveAll() error {
for schemeID := range client.keyshareServers {
managers = append(managers, schemeID)
}
return client.keyshareRemoveMultiple(managers, false)
return client.stripStorage(managers, false)
}

func (client *Client) keyshareRemoveMultiple(schemeIDs []irma.SchemeManagerIdentifier, removeLogs bool) error {
for _, schemeID := range schemeIDs {
if _, contains := client.keyshareServers[schemeID]; !contains {
return errors.New("can't uninstall unknown keyshare server")
}
}

// stripStorage removes all credentials and optionally removes all logs of the specified schemes from storage.
func (client *Client) stripStorage(schemeIDs []irma.SchemeManagerIdentifier, removeLogs bool) error {
client.credMutex.Lock()
defer client.credMutex.Unlock()

Expand Down Expand Up @@ -1542,14 +1540,14 @@ func (client *Client) ConfigurationUpdated(downloaded *irma.IrmaIdentifierSet) e
return nil
}

// RemoveScheme removes the given scheme and all credentials and log entries related to it.
// RemoveScheme removes the given scheme manager and all credentials and log entries related to it.
func (client *Client) RemoveScheme(schemeID irma.SchemeManagerIdentifier) error {
scheme, ok := client.Configuration.SchemeManagers[schemeID]
if !ok {
return errors.New("unknown scheme manager")
}

err := client.keyshareRemoveMultiple([]irma.SchemeManagerIdentifier{schemeID}, true)
err := client.stripStorage([]irma.SchemeManagerIdentifier{schemeID}, true)
if err != nil {
return err
}
Expand All @@ -1560,6 +1558,19 @@ func (client *Client) RemoveScheme(schemeID irma.SchemeManagerIdentifier) error
return client.Configuration.ParseFolder()
}

// RemoveRequestorScheme removes the given requestor scheme and all requestors and issue wizards related to it.
func (client *Client) RemoveRequestorScheme(schemeID irma.RequestorSchemeIdentifier) error {
scheme, ok := client.Configuration.RequestorSchemes[schemeID]
if !ok {
return errors.New("unknown requestor scheme")
}
err := client.Configuration.DangerousDeleteScheme(scheme)
if err != nil {
return err
}
return client.Configuration.ParseFolder()
}

func (cc *credCandidate) Present() bool {
return cc.Hash != ""
}
Expand Down
46 changes: 46 additions & 0 deletions irmaclient/irmaclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"testing"

Expand Down Expand Up @@ -298,6 +299,51 @@ func TestCredentialRemoval(t *testing.T) {
require.Nil(t, cred)
}

func TestRemoveSchemes(t *testing.T) {
client, handler := parseStorage(t)
defer test.ClearTestStorage(t, client, handler.storage)

// Unset configuration assets to enable removal of schemes
var err error
client.Configuration, err = irma.NewConfiguration(
client.Configuration.Path,
irma.ConfigurationOptions{IgnorePrivateKeys: true},
)
require.NoError(t, err)
err = client.Configuration.ParseFolder()
require.NoError(t, err)

// Remove demo scheme
irmaDemoSchemeID := irma.NewSchemeManagerIdentifier("irma-demo")
err = client.RemoveScheme(irmaDemoSchemeID)
require.NoError(t, err)
require.NotContains(t, client.Configuration.SchemeManagers, irmaDemoSchemeID)

// Remove test scheme
testSchemeID := irma.NewSchemeManagerIdentifier("test")
err = client.RemoveScheme(testSchemeID)
require.NoError(t, err)
require.NotContains(t, client.Configuration.SchemeManagers, testSchemeID)

// Remove nonexistent scheme
err = client.RemoveScheme(irma.NewSchemeManagerIdentifier("nonexistent"))
require.Error(t, err)

// Remove requestor scheme
testRequestorsSchemeID := irma.NewRequestorSchemeIdentifier("test-requestors")
err = client.RemoveRequestorScheme(testRequestorsSchemeID)
require.NoError(t, err)
require.NotContains(t, client.Configuration.RequestorSchemes, testRequestorsSchemeID)
require.NotContains(t, client.Configuration.Requestors, testRequestorsSchemeID)
for wizardID := range client.Configuration.IssueWizards {
require.False(t, strings.HasPrefix(wizardID.String(), testRequestorsSchemeID.String()))
}

// Remove nonexistent requestor scheme
err = client.RemoveRequestorScheme(irma.NewRequestorSchemeIdentifier("nonexistent"))
require.Error(t, err)
}

func TestWrongSchemeManager(t *testing.T) {
client, handler := parseStorage(t)
defer test.ClearTestStorage(t, client, handler.storage)
Expand Down

0 comments on commit 5024f30

Please sign in to comment.