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
return nil
}
func (store *ConfigurationStore) Download(set *IrmaIdentifierSet) error {
func (store *ConfigurationStore) Download(set *IrmaIdentifierSet) (*IrmaIdentifierSet, error) {
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 {
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 {
if _, contains = store.Issuers[issid]; !contains {
url := store.SchemeManagers[issid.SchemeManagerIdentifier()].URL + "/" + issid.Name()
path := fmt.Sprintf("%s/%s/%s", store.path, issid.SchemeManagerIdentifier().String(), issid.Name())
transport.GetFile(url+"/description.xml", path+"/description.xml")
transport.GetFile(url+"/logo.png", path+"/logo.png")
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 {
return nil, err
}
downloaded.Issuers[issid] = struct{}{}
}
for issid, list := range set.PublicKeys {
for _, count := range list {
pk, err := store.PublicKey(issid, count)
if err != nil {
return err
return nil, err
}
if pk == nil {
manager := issid.SchemeManagerIdentifier()
suffix := fmt.Sprintf("/%s/PublicKeys/%d.xml", issid.Name(), count)
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 {
manager := issuer.SchemeManagerIdentifier()
local := fmt.Sprintf("%s/%s/%s/Issues", store.path, manager.Name(), issuer.Name())
if err := ensureDirectoryExists(local); err != nil {
return err
return nil, err
}
transport.GetFile(
if transport.GetFile(
fmt.Sprintf("%s/%s/Issues/%s/description.xml",
store.SchemeManagers[manager].URL, issuer.Name(), 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 {
}
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) {
type IgnoringKeyshareHandler struct{}
func (i *IgnoringKeyshareHandler) UpdateConfigurationStore(new *IrmaIdentifierSet) {}
func (i *IgnoringKeyshareHandler) UpdateAttributes() {}
func (i *IgnoringKeyshareHandler) RegistrationError(err error) {}
func (i *IgnoringKeyshareHandler) RegistrationSuccess() {}
func (i *IgnoringKeyshareHandler) StartRegistration(m *SchemeManager, callback func(e, p string)) {
}
func (i *IgnoringKeyshareHandler) RegistrationError(err error) {}
func (i *IgnoringKeyshareHandler) RegistrationSuccess() {}
func parseStorage(t *testing.T) *CredentialManager {
exists, err := PathExists("testdata/storage/test")
......
......@@ -95,14 +95,6 @@ type proofPCommitmentMap struct {
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 (
kssUsernameHeader = "IRMA_Username"
kssAuthHeader = "IRMA_Authorization"
......
......@@ -49,7 +49,22 @@ type CredentialManager struct {
ConfigurationStore *ConfigurationStore
irmaConfigurationPath 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 {
......@@ -61,8 +76,8 @@ type secretKey struct {
// is the path to a (possibly readonly) folder containing irma_configuration;
// 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),
// and keyshareHandler is used for when a registration to a keyshare server needs
// to happen.
// and handler is used for informing the user of new stuff, and when a
// registration to a keyshare server needs to happen.
// The credential manager returned by this function has been fully deserialized
// and is ready for use.
//
......@@ -72,7 +87,7 @@ func NewCredentialManager(
storagePath string,
irmaConfigurationPath string,
androidStoragePath string,
keyshareHandler KeyshareHandler,
handler ClientHandler,
) (*CredentialManager, error) {
var err error
if err = AssertPathExists(storagePath); err != nil {
......@@ -88,7 +103,7 @@ func NewCredentialManager(
attributes: make(map[CredentialTypeIdentifier][]*AttributeList),
irmaConfigurationPath: irmaConfigurationPath,
androidStoragePath: androidStoragePath,
keyshareHandler: keyshareHandler,
handler: handler,
}
cm.ConfigurationStore, err = NewConfigurationStore(storagePath+"/irma_configuration", irmaConfigurationPath)
......@@ -128,10 +143,7 @@ func NewCredentialManager(
switch len(unenrolled) {
case 0: // nop
case 1:
if keyshareHandler == nil {
return nil, errors.New("Keyshare server found but no KeyshareHandler was given")
}
cm.KeyshareEnroll(unenrolled[0], keyshareHandler)
cm.KeyshareEnroll(unenrolled[0], cm.handler)
default:
return nil, errors.New("Too many keyshare servers")
}
......
......@@ -47,6 +47,7 @@ type session struct {
transport *HTTPTransport
choice *DisclosureChoice
newmanager *SchemeManager
downloaded *IrmaIdentifierSet
}
// We implement the handler for the keyshare protocol
......@@ -133,9 +134,20 @@ func (cm *CredentialManager) NewSession(qr *Qr, handler Handler) {
func (session *session) fail(err *SessionError) {
session.transport.Delete()
err.Err = errors.Wrap(err.Err, 0)
if !session.downloaded.Empty() {
session.credManager.handler.UpdateConfigurationStore(session.downloaded)
}
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
// the request, and informs the user of the outcome.
func (session *session) start() {
......@@ -173,7 +185,7 @@ func (session *session) start() {
}
// 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.Action,
&SessionError{ErrorType: ErrorConfigurationStoreDownload, Err: err},
......@@ -222,8 +234,7 @@ func (session *session) start() {
func (session *session) do(proceed bool) {
if !proceed {
session.transport.Delete()
session.Handler.Cancelled(session.Action)
session.cancel()
return
}
session.Handler.StatusUpdate(session.Action, StatusCommunicating)
......@@ -275,8 +286,7 @@ func (session *session) KeyshareDone(message interface{}) {
}
func (session *session) KeyshareCancelled() {
session.transport.Delete()
session.Handler.Cancelled(session.Action)
session.cancel()
}
func (session *session) KeyshareBlocked(duration int) {
......@@ -321,6 +331,12 @@ func (session *session) sendResponse(message interface{}) {
}
_ = 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)
}
......@@ -332,7 +348,7 @@ func (session *session) managerSession() {
}
session.Handler.RequestSchemeManagerPermission(manager, func(proceed bool) {
if !proceed {
session.Handler.Cancelled(session.Action)
session.Handler.Cancelled(session.Action) // No need to DELETE session here
return
}
session.newmanager = manager
......@@ -346,12 +362,12 @@ func (session *session) managerSession() {
}
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) {
session.Handler.Failure(session.Action, &SessionError{Err: err}) // TODO
session.credManager.keyshareHandler.RegistrationError(err)
session.credManager.handler.RegistrationError(err)
}
func (session *session) RegistrationSuccess() {
......@@ -359,6 +375,15 @@ func (session *session) RegistrationSuccess() {
session.Handler.Failure(session.Action, &SessionError{})
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.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