Commit 3c37d790 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Inform Manager user of new stuff

parent 83e08c7d
...@@ -328,11 +328,18 @@ func (store *ConfigurationStore) AddSchemeManager(manager *SchemeManager) error ...@@ -328,11 +328,18 @@ func (store *ConfigurationStore) AddSchemeManager(manager *SchemeManager) error
return nil return nil
} }
func (store *ConfigurationStore) Download(set *IrmaIdentifierSet) error { func (store *ConfigurationStore) Download(set *IrmaIdentifierSet) (*IrmaIdentifierSet, error) {
var contains bool var contains bool
var err error
downloaded := &IrmaIdentifierSet{
SchemeManagers: map[SchemeManagerIdentifier]struct{}{},
Issuers: map[IssuerIdentifier]struct{}{},
CredentialTypes: map[CredentialTypeIdentifier]struct{}{},
}
for manid := range set.SchemeManagers { for manid := range set.SchemeManagers {
if _, contains = store.SchemeManagers[manid]; !contains { if _, contains = store.SchemeManagers[manid]; !contains {
return errors.Errorf("Unknown scheme manager: %s", manid) return nil, errors.Errorf("Unknown scheme manager: %s", manid)
} }
} }
...@@ -341,20 +348,27 @@ func (store *ConfigurationStore) Download(set *IrmaIdentifierSet) error { ...@@ -341,20 +348,27 @@ func (store *ConfigurationStore) Download(set *IrmaIdentifierSet) error {
if _, contains = store.Issuers[issid]; !contains { if _, contains = store.Issuers[issid]; !contains {
url := store.SchemeManagers[issid.SchemeManagerIdentifier()].URL + "/" + issid.Name() url := store.SchemeManagers[issid.SchemeManagerIdentifier()].URL + "/" + issid.Name()
path := fmt.Sprintf("%s/%s/%s", store.path, issid.SchemeManagerIdentifier().String(), issid.Name()) path := fmt.Sprintf("%s/%s/%s", store.path, issid.SchemeManagerIdentifier().String(), issid.Name())
transport.GetFile(url+"/description.xml", path+"/description.xml") if err = transport.GetFile(url+"/description.xml", path+"/description.xml"); err != nil {
transport.GetFile(url+"/logo.png", path+"/logo.png") return nil, err
}
if transport.GetFile(url+"/logo.png", path+"/logo.png"); err != nil {
return nil, err
}
downloaded.Issuers[issid] = struct{}{}
} }
for issid, list := range set.PublicKeys { for issid, list := range set.PublicKeys {
for _, count := range list { for _, count := range list {
pk, err := store.PublicKey(issid, count) pk, err := store.PublicKey(issid, count)
if err != nil { if err != nil {
return err return nil, err
} }
if pk == nil { if pk == nil {
manager := issid.SchemeManagerIdentifier() manager := issid.SchemeManagerIdentifier()
suffix := fmt.Sprintf("/%s/PublicKeys/%d.xml", issid.Name(), count) suffix := fmt.Sprintf("/%s/PublicKeys/%d.xml", issid.Name(), count)
path := fmt.Sprintf("%s/%s/%s", store.path, manager.String(), suffix) path := fmt.Sprintf("%s/%s/%s", store.path, manager.String(), suffix)
transport.GetFile(store.SchemeManagers[manager].URL+suffix, path) if transport.GetFile(store.SchemeManagers[manager].URL+suffix, path); err != nil {
return nil, err
}
} }
} }
} }
...@@ -365,15 +379,18 @@ func (store *ConfigurationStore) Download(set *IrmaIdentifierSet) error { ...@@ -365,15 +379,18 @@ func (store *ConfigurationStore) Download(set *IrmaIdentifierSet) error {
manager := issuer.SchemeManagerIdentifier() manager := issuer.SchemeManagerIdentifier()
local := fmt.Sprintf("%s/%s/%s/Issues", store.path, manager.Name(), issuer.Name()) local := fmt.Sprintf("%s/%s/%s/Issues", store.path, manager.Name(), issuer.Name())
if err := ensureDirectoryExists(local); err != nil { if err := ensureDirectoryExists(local); err != nil {
return err return nil, err
} }
transport.GetFile( if transport.GetFile(
fmt.Sprintf("%s/%s/Issues/%s/description.xml", fmt.Sprintf("%s/%s/Issues/%s/description.xml",
store.SchemeManagers[manager].URL, issuer.Name(), credid.Name()), store.SchemeManagers[manager].URL, issuer.Name(), credid.Name()),
fmt.Sprintf("%s/%s/description.xml", local, credid.Name()), fmt.Sprintf("%s/%s/description.xml", local, credid.Name()),
) ); err != nil {
return nil, err
}
downloaded.CredentialTypes[credid] = struct{}{}
} }
} }
return store.ParseFolder() return downloaded, store.ParseFolder()
} }
...@@ -161,3 +161,7 @@ func (set *IrmaIdentifierSet) Distributed(store *ConfigurationStore) bool { ...@@ -161,3 +161,7 @@ func (set *IrmaIdentifierSet) Distributed(store *ConfigurationStore) bool {
} }
return false return false
} }
func (set *IrmaIdentifierSet) Empty() bool {
return len(set.SchemeManagers) == 0 && len(set.Issuers) == 0 && len(set.CredentialTypes) == 0 && len(set.PublicKeys) == 0
}
...@@ -29,10 +29,12 @@ func TestMain(m *testing.M) { ...@@ -29,10 +29,12 @@ func TestMain(m *testing.M) {
type IgnoringKeyshareHandler struct{} type IgnoringKeyshareHandler struct{}
func (i *IgnoringKeyshareHandler) StartRegistration(m *SchemeManager, callback func(e, p string)) { func (i *IgnoringKeyshareHandler) UpdateConfigurationStore(new *IrmaIdentifierSet) {}
} func (i *IgnoringKeyshareHandler) UpdateAttributes() {}
func (i *IgnoringKeyshareHandler) RegistrationError(err error) {} func (i *IgnoringKeyshareHandler) RegistrationError(err error) {}
func (i *IgnoringKeyshareHandler) RegistrationSuccess() {} func (i *IgnoringKeyshareHandler) RegistrationSuccess() {}
func (i *IgnoringKeyshareHandler) StartRegistration(m *SchemeManager, callback func(e, p string)) {
}
func parseStorage(t *testing.T) *CredentialManager { func parseStorage(t *testing.T) *CredentialManager {
exists, err := PathExists("testdata/storage/test") exists, err := PathExists("testdata/storage/test")
......
...@@ -95,14 +95,6 @@ type proofPCommitmentMap struct { ...@@ -95,14 +95,6 @@ type proofPCommitmentMap struct {
Commitments map[publicKeyIdentifier]*gabi.ProofPCommitment `json:"c"` Commitments map[publicKeyIdentifier]*gabi.ProofPCommitment `json:"c"`
} }
// KeyshareHandler is used for asking the user for his email address and PIN,
// for registering at a keyshare server.
type KeyshareHandler interface {
StartRegistration(manager *SchemeManager, registrationCallback func(email, pin string))
RegistrationError(err error)
RegistrationSuccess()
}
const ( const (
kssUsernameHeader = "IRMA_Username" kssUsernameHeader = "IRMA_Username"
kssAuthHeader = "IRMA_Authorization" kssAuthHeader = "IRMA_Authorization"
......
...@@ -49,7 +49,22 @@ type CredentialManager struct { ...@@ -49,7 +49,22 @@ type CredentialManager struct {
ConfigurationStore *ConfigurationStore ConfigurationStore *ConfigurationStore
irmaConfigurationPath string irmaConfigurationPath string
androidStoragePath string androidStoragePath string
keyshareHandler KeyshareHandler handler ClientHandler
}
// KeyshareHandler is used for asking the user for his email address and PIN,
// for registering at a keyshare server.
type KeyshareHandler interface {
StartRegistration(manager *SchemeManager, registrationCallback func(email, pin string))
RegistrationError(err error)
RegistrationSuccess()
}
type ClientHandler interface {
KeyshareHandler
UpdateConfigurationStore(new *IrmaIdentifierSet)
UpdateAttributes()
} }
type secretKey struct { type secretKey struct {
...@@ -61,8 +76,8 @@ type secretKey struct { ...@@ -61,8 +76,8 @@ type secretKey struct {
// is the path to a (possibly readonly) folder containing irma_configuration; // is the path to a (possibly readonly) folder containing irma_configuration;
// androidStoragePath is an optional path to the files of the old android app // androidStoragePath is an optional path to the files of the old android app
// (specify "" if you do not want to parse the old android app files), // (specify "" if you do not want to parse the old android app files),
// and keyshareHandler is used for when a registration to a keyshare server needs // and handler is used for informing the user of new stuff, and when a
// to happen. // registration to a keyshare server needs to happen.
// The credential manager returned by this function has been fully deserialized // The credential manager returned by this function has been fully deserialized
// and is ready for use. // and is ready for use.
// //
...@@ -72,7 +87,7 @@ func NewCredentialManager( ...@@ -72,7 +87,7 @@ func NewCredentialManager(
storagePath string, storagePath string,
irmaConfigurationPath string, irmaConfigurationPath string,
androidStoragePath string, androidStoragePath string,
keyshareHandler KeyshareHandler, handler ClientHandler,
) (*CredentialManager, error) { ) (*CredentialManager, error) {
var err error var err error
if err = AssertPathExists(storagePath); err != nil { if err = AssertPathExists(storagePath); err != nil {
...@@ -88,7 +103,7 @@ func NewCredentialManager( ...@@ -88,7 +103,7 @@ func NewCredentialManager(
attributes: make(map[CredentialTypeIdentifier][]*AttributeList), attributes: make(map[CredentialTypeIdentifier][]*AttributeList),
irmaConfigurationPath: irmaConfigurationPath, irmaConfigurationPath: irmaConfigurationPath,
androidStoragePath: androidStoragePath, androidStoragePath: androidStoragePath,
keyshareHandler: keyshareHandler, handler: handler,
} }
cm.ConfigurationStore, err = NewConfigurationStore(storagePath+"/irma_configuration", irmaConfigurationPath) cm.ConfigurationStore, err = NewConfigurationStore(storagePath+"/irma_configuration", irmaConfigurationPath)
...@@ -128,10 +143,7 @@ func NewCredentialManager( ...@@ -128,10 +143,7 @@ func NewCredentialManager(
switch len(unenrolled) { switch len(unenrolled) {
case 0: // nop case 0: // nop
case 1: case 1:
if keyshareHandler == nil { cm.KeyshareEnroll(unenrolled[0], cm.handler)
return nil, errors.New("Keyshare server found but no KeyshareHandler was given")
}
cm.KeyshareEnroll(unenrolled[0], keyshareHandler)
default: default:
return nil, errors.New("Too many keyshare servers") return nil, errors.New("Too many keyshare servers")
} }
......
...@@ -47,6 +47,7 @@ type session struct { ...@@ -47,6 +47,7 @@ type session struct {
transport *HTTPTransport transport *HTTPTransport
choice *DisclosureChoice choice *DisclosureChoice
newmanager *SchemeManager newmanager *SchemeManager
downloaded *IrmaIdentifierSet
} }
// We implement the handler for the keyshare protocol // We implement the handler for the keyshare protocol
...@@ -133,9 +134,20 @@ func (cm *CredentialManager) NewSession(qr *Qr, handler Handler) { ...@@ -133,9 +134,20 @@ func (cm *CredentialManager) NewSession(qr *Qr, handler Handler) {
func (session *session) fail(err *SessionError) { func (session *session) fail(err *SessionError) {
session.transport.Delete() session.transport.Delete()
err.Err = errors.Wrap(err.Err, 0) err.Err = errors.Wrap(err.Err, 0)
if !session.downloaded.Empty() {
session.credManager.handler.UpdateConfigurationStore(session.downloaded)
}
session.Handler.Failure(session.Action, err) session.Handler.Failure(session.Action, err)
} }
func (session *session) cancel() {
session.transport.Delete()
if !session.downloaded.Empty() {
session.credManager.handler.UpdateConfigurationStore(session.downloaded)
}
session.Handler.Cancelled(session.Action)
}
// start retrieves the first message in the IRMA protocol, checks if we can perform // start retrieves the first message in the IRMA protocol, checks if we can perform
// the request, and informs the user of the outcome. // the request, and informs the user of the outcome.
func (session *session) start() { func (session *session) start() {
...@@ -173,7 +185,7 @@ func (session *session) start() { ...@@ -173,7 +185,7 @@ func (session *session) start() {
} }
// Download missing credential types/issuers/public keys from the scheme manager // Download missing credential types/issuers/public keys from the scheme manager
if err = session.credManager.ConfigurationStore.Download(session.irmaSession.Identifiers()); err != nil { if session.downloaded, err = session.credManager.ConfigurationStore.Download(session.irmaSession.Identifiers()); err != nil {
session.Handler.Failure( session.Handler.Failure(
session.Action, session.Action,
&SessionError{ErrorType: ErrorConfigurationStoreDownload, Err: err}, &SessionError{ErrorType: ErrorConfigurationStoreDownload, Err: err},
...@@ -222,8 +234,7 @@ func (session *session) start() { ...@@ -222,8 +234,7 @@ func (session *session) start() {
func (session *session) do(proceed bool) { func (session *session) do(proceed bool) {
if !proceed { if !proceed {
session.transport.Delete() session.cancel()
session.Handler.Cancelled(session.Action)
return return
} }
session.Handler.StatusUpdate(session.Action, StatusCommunicating) session.Handler.StatusUpdate(session.Action, StatusCommunicating)
...@@ -275,8 +286,7 @@ func (session *session) KeyshareDone(message interface{}) { ...@@ -275,8 +286,7 @@ func (session *session) KeyshareDone(message interface{}) {
} }
func (session *session) KeyshareCancelled() { func (session *session) KeyshareCancelled() {
session.transport.Delete() session.cancel()
session.Handler.Cancelled(session.Action)
} }
func (session *session) KeyshareBlocked(duration int) { func (session *session) KeyshareBlocked(duration int) {
...@@ -321,6 +331,12 @@ func (session *session) sendResponse(message interface{}) { ...@@ -321,6 +331,12 @@ func (session *session) sendResponse(message interface{}) {
} }
_ = session.credManager.addLogEntry(log) // TODO err _ = session.credManager.addLogEntry(log) // TODO err
if !session.downloaded.Empty() {
session.credManager.handler.UpdateConfigurationStore(session.downloaded)
}
if session.Action == ActionIssuing {
session.credManager.handler.UpdateAttributes()
}
session.Handler.Success(session.Action) session.Handler.Success(session.Action)
} }
...@@ -332,7 +348,7 @@ func (session *session) managerSession() { ...@@ -332,7 +348,7 @@ func (session *session) managerSession() {
} }
session.Handler.RequestSchemeManagerPermission(manager, func(proceed bool) { session.Handler.RequestSchemeManagerPermission(manager, func(proceed bool) {
if !proceed { if !proceed {
session.Handler.Cancelled(session.Action) session.Handler.Cancelled(session.Action) // No need to DELETE session here
return return
} }
session.newmanager = manager session.newmanager = manager
...@@ -346,12 +362,12 @@ func (session *session) managerSession() { ...@@ -346,12 +362,12 @@ func (session *session) managerSession() {
} }
func (session *session) StartRegistration(manager *SchemeManager, callback func(email, pin string)) { func (session *session) StartRegistration(manager *SchemeManager, callback func(email, pin string)) {
session.credManager.keyshareHandler.StartRegistration(manager, callback) session.credManager.handler.StartRegistration(manager, callback)
} }
func (session *session) RegistrationError(err error) { func (session *session) RegistrationError(err error) {
session.Handler.Failure(session.Action, &SessionError{Err: err}) // TODO session.Handler.Failure(session.Action, &SessionError{Err: err}) // TODO
session.credManager.keyshareHandler.RegistrationError(err) session.credManager.handler.RegistrationError(err)
} }
func (session *session) RegistrationSuccess() { func (session *session) RegistrationSuccess() {
...@@ -359,6 +375,15 @@ func (session *session) RegistrationSuccess() { ...@@ -359,6 +375,15 @@ func (session *session) RegistrationSuccess() {
session.Handler.Failure(session.Action, &SessionError{}) session.Handler.Failure(session.Action, &SessionError{})
return return
} }
session.credManager.handler.UpdateConfigurationStore(
&IrmaIdentifierSet{
SchemeManagers: map[SchemeManagerIdentifier]struct{}{session.newmanager.Identifier(): {}},
Issuers: map[IssuerIdentifier]struct{}{},
CredentialTypes: map[CredentialTypeIdentifier]struct{}{},
},
)
session.Handler.Success(session.Action) session.Handler.Success(session.Action)
session.credManager.keyshareHandler.RegistrationSuccess() if session.newmanager.Distributed() {
session.credManager.handler.RegistrationSuccess()
}
} }
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