Commit bb5737f4 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Fix and test scheme manager adding and automatic configuration downloading

parent 47dea744
......@@ -24,7 +24,7 @@ import (
// at initialization.
//
// - The attributes of all credentials are stored together, as they all
// immediately need to be available anyway,
// immediately need to be available anyway.
//
// - The secret key (the zeroth attribute of every credential), being the same
// across all credentials, is stored only once in a separate file (storing this
......
......@@ -384,16 +384,31 @@ func TestCredentialRemoval(t *testing.T) {
teardown(t)
}
// Test installing a new scheme manager from a qr, and do a(n issuance) session
// within this manager to test the autmatic downloading of credential definitions,
// issuers, and public keys.
func TestDownloadSchemeManager(t *testing.T) {
client := parseStorage(t)
require.NoError(t, client.Configuration.RemoveSchemeManager(irma.NewSchemeManagerIdentifier("irma-demo")))
url := "https://raw.githubusercontent.com/credentials/irma_configuration/translate/irma-demo"
sm, err := client.Configuration.DownloadSchemeManager(url)
require.NoError(t, err)
require.NotNil(t, sm)
require.NoError(t, client.Configuration.AddSchemeManager(sm))
// Remove irma-demo scheme manager as we need to test adding it
irmademo := irma.NewSchemeManagerIdentifier("irma-demo")
require.Contains(t, client.Configuration.SchemeManagers, irmademo)
require.NoError(t, client.Configuration.RemoveSchemeManager(irmademo))
require.NotContains(t, client.Configuration.SchemeManagers, irmademo)
// Do an add-scheme-manager-session
qr := &irma.Qr{
Type: irma.ActionSchemeManager,
URL: "https://raw.githubusercontent.com/credentials/irma_configuration/translate/irma-demo",
}
c := make(chan *irma.SessionError)
client.NewSession(qr, TestHandler{t, c, client})
if err := <-c; err != nil {
t.Fatal(*err)
}
require.Contains(t, client.Configuration.SchemeManagers, irmademo)
// Do a session to test downloading of cred types, issuers and keys
jwt := getIssuanceJwt("testip", irma.NewAttributeTypeIdentifier("irma-demo.RU.studentCard.studentID"))
sessionHelper(t, jwt, "issue", client)
......
......@@ -112,6 +112,12 @@ func (client *Client) NewSession(qr *irma.Qr, handler Handler) SessionDismisser
transport: irma.NewHTTPTransport(qr.URL),
client: client,
}
if session.Action == irma.ActionSchemeManager {
go session.managerSession()
return session
}
version, err := calcVersion(qr)
if err != nil {
session.fail(&irma.SessionError{ErrorType: irma.ErrorProtocolVersionNotSupported, Err: err})
......@@ -124,7 +130,6 @@ func (client *Client) NewSession(qr *irma.Qr, handler Handler) SessionDismisser
case irma.ActionDisclosing: // nop
case irma.ActionSigning: // nop
case irma.ActionIssuing: // nop
//case irmago.ActionSchemeManager: // nop
case irma.ActionUnknown:
fallthrough
default:
......@@ -154,11 +159,6 @@ func (session *session) start() {
session.Handler.StatusUpdate(session.Action, irma.StatusCommunicating)
if session.Action == irma.ActionSchemeManager {
session.managerSession()
return
}
// Get the first IRMA protocol message and parse it
session.info = &irma.SessionInfo{}
Err := session.transport.Get("jwt", session.info)
......@@ -378,20 +378,34 @@ func (session *session) sendResponse(message interface{}) {
}
func (session *session) managerSession() {
defer func() {
handlePanic(func(err *irma.SessionError) {
if session.Handler != nil {
session.Handler.Failure(session.Action, err)
}
})
}()
// We have to download the scheme manager description.xml here before installing it,
// because we need to show its contents (name, description, website) to the user
// when asking installation permission.
manager, err := session.client.Configuration.DownloadSchemeManager(session.ServerURL)
if err != nil {
session.Handler.Failure(session.Action, &irma.SessionError{Err: err}) // TODO
session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorConfigurationDownload, Err: err})
return
}
session.Handler.RequestSchemeManagerPermission(manager, func(proceed bool) {
if !proceed {
session.Handler.Cancelled(session.Action) // No need to DELETE session here
return
}
if err := session.client.Configuration.AddSchemeManager(manager); err != nil {
session.Handler.Failure(session.Action, &irma.SessionError{})
session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorConfigurationDownload, Err: err})
return
}
// Update state and inform user of success
if manager.Distributed() {
session.client.UnenrolledSchemeManagers = session.client.unenrolledSchemeManagers()
}
......
......@@ -276,6 +276,8 @@ func (conf *Configuration) Copy(source string, parse bool) error {
return nil
}
// DownloadSchemeManager downloads and returns a scheme manager description.xml file
// from the specified URL.
func (conf *Configuration) DownloadSchemeManager(url string) (*SchemeManager, error) {
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
url = "https://" + url
......@@ -316,6 +318,7 @@ func (conf *Configuration) RemoveSchemeManager(id SchemeManagerIdentifier) error
delete(conf.publicKeys, issid)
}
}
delete(conf.SchemeManagers, id)
// Remove from storage
return os.RemoveAll(fmt.Sprintf("%s/%s", conf.path, id.String()))
// or, remove above iterations and call .ParseFolder()?
......@@ -360,7 +363,7 @@ func (conf *Configuration) Download(set *IrmaIdentifierSet) (*IrmaIdentifierSet,
if err = transport.GetFile(url+"/description.xml", path+"/description.xml"); err != nil {
return nil, err
}
if transport.GetFile(url+"/logo.png", path+"/logo.png"); err != nil {
if err = transport.GetFile(url+"/logo.png", path+"/logo.png"); err != nil {
return nil, err
}
downloaded.Issuers[issid] = struct{}{}
......@@ -376,7 +379,7 @@ func (conf *Configuration) Download(set *IrmaIdentifierSet) (*IrmaIdentifierSet,
manager := issid.SchemeManagerIdentifier()
suffix := fmt.Sprintf("/%s/PublicKeys/%d.xml", issid.Name(), count)
path := fmt.Sprintf("%s/%s/%s", conf.path, manager.String(), suffix)
if transport.GetFile(conf.SchemeManagers[manager].URL+suffix, path); err != nil {
if err = transport.GetFile(conf.SchemeManagers[manager].URL+suffix, path); err != nil {
return nil, err
}
}
......@@ -390,13 +393,16 @@ func (conf *Configuration) Download(set *IrmaIdentifierSet) (*IrmaIdentifierSet,
if err := fs.EnsureDirectoryExists(local); err != nil {
return nil, err
}
if transport.GetFile(
fmt.Sprintf("%s/%s/Issues/%s/description.xml",
conf.SchemeManagers[manager].URL, issuer.Name(), credid.Name()),
if err = transport.GetFile(
fmt.Sprintf("%s/%s/Issues/%s/description.xml", conf.SchemeManagers[manager].URL, issuer.Name(), credid.Name()),
fmt.Sprintf("%s/%s/description.xml", local, credid.Name()),
); err != nil {
return nil, err
}
_ = transport.GetFile( // Get logo but ignore errors, it is optional
fmt.Sprintf("%s/%s/Issues/%s/logo.png", conf.SchemeManagers[manager].URL, issuer.Name(), credid.Name()),
fmt.Sprintf("%s/%s/logo.png", local, credid.Name()),
)
downloaded.CredentialTypes[credid] = struct{}{}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment