Commit 7b1d8560 authored by Koen van Ingen's avatar Koen van Ingen
Browse files

Some duplicated code cleanup

parent fd1c52e7
package irmaclient package irmaclient
import ( import (
"fmt" "fmt"
"testing" "github.com/privacybydesign/irmago"
"github.com/credentials/irmago" "testing"
) )
type ManualSessionHandler struct { type ManualSessionHandler struct {
permissionHandler PermissionHandler permissionHandler PermissionHandler
pinHandler PinHandler pinHandler PinHandler
t *testing.T t *testing.T
c chan *irma.SessionError c chan *irma.SessionError
} }
var client *Client var client *Client
...@@ -51,15 +51,15 @@ func TestManualKeyShareSession(t *testing.T) { ...@@ -51,15 +51,15 @@ func TestManualKeyShareSession(t *testing.T) {
} }
} }
func (sh *ManualSessionHandler) Success(irmaAction irma.Action, result string) { func (sh *ManualSessionHandler) Success(irmaAction irma.Action, result string) {
fmt.Println("Result: " + result)
sh.c <- nil sh.c <- nil
} }
func (sh *ManualSessionHandler) UnsatisfiableRequest(irmaAction irma.Action, missingAttributes irma.AttributeDisjunctionList) { sh.t.Fail() } func (sh *ManualSessionHandler) UnsatisfiableRequest(irmaAction irma.Action, missingAttributes irma.AttributeDisjunctionList) {
sh.t.Fail()
}
// Done in irma bridge? // Done in irma bridge?
func (sh *ManualSessionHandler) StatusUpdate(irmaAction irma.Action, status irma.Status) { } func (sh *ManualSessionHandler) StatusUpdate(irmaAction irma.Action, status irma.Status) {}
func (sh *ManualSessionHandler) RequestPin(remainingAttempts int, ph PinHandler) { func (sh *ManualSessionHandler) RequestPin(remainingAttempts int, ph PinHandler) {
ph(true, "12345") ph(true, "12345")
} }
...@@ -70,10 +70,18 @@ func (sh *ManualSessionHandler) RequestSignaturePermission(request irma.Signatur ...@@ -70,10 +70,18 @@ func (sh *ManualSessionHandler) RequestSignaturePermission(request irma.Signatur
// These handlers should not be called, fail test if they are called // These handlers should not be called, fail test if they are called
func (sh *ManualSessionHandler) Cancelled(irmaAction irma.Action) { sh.t.Fail() } func (sh *ManualSessionHandler) Cancelled(irmaAction irma.Action) { sh.t.Fail() }
func (sh *ManualSessionHandler) MissingKeyshareEnrollment(manager irma.SchemeManagerIdentifier) { sh.t.Fail() } func (sh *ManualSessionHandler) MissingKeyshareEnrollment(manager irma.SchemeManagerIdentifier) {
func (sh *ManualSessionHandler) RequestIssuancePermission(request irma.IssuanceRequest, issuerName string, ph PermissionHandler) { sh.t.Fail() } sh.t.Fail()
func (sh *ManualSessionHandler) RequestSchemeManagerPermission(manager *irma.SchemeManager, callback func(proceed bool)) { sh.t.Fail() } }
func (sh *ManualSessionHandler) RequestVerificationPermission(request irma.DisclosureRequest, verifierName string, ph PermissionHandler) { sh.t.Fail() } func (sh *ManualSessionHandler) RequestIssuancePermission(request irma.IssuanceRequest, issuerName string, ph PermissionHandler) {
sh.t.Fail()
}
func (sh *ManualSessionHandler) RequestSchemeManagerPermission(manager *irma.SchemeManager, callback func(proceed bool)) {
sh.t.Fail()
}
func (sh *ManualSessionHandler) RequestVerificationPermission(request irma.DisclosureRequest, verifierName string, ph PermissionHandler) {
sh.t.Fail()
}
func (sh *ManualSessionHandler) Failure(irmaAction irma.Action, err *irma.SessionError) { func (sh *ManualSessionHandler) Failure(irmaAction irma.Action, err *irma.SessionError) {
fmt.Println(err.Err) fmt.Println(err.Err)
sh.t.Fail() sh.t.Fail()
......
package irmaclient package irmaclient
import ( import (
"encoding/json"
"fmt" "fmt"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"encoding/json"
"math/big" "math/big"
...@@ -46,19 +46,23 @@ type SessionDismisser interface { ...@@ -46,19 +46,23 @@ type SessionDismisser interface {
Dismiss() Dismiss()
} }
// baseSession contains methods generic to both manual and interactive sessions
type baseSession interface { type baseSession interface {
sendResponse(message interface{}) getBuilders() (gabi.ProofBuilderList, error)
cancel(action irma.Action) getProof() (interface{}, error)
panicFailure()
checkKeyshareEnrollment() bool
} }
type session struct { type session struct {
baseSession baseSession
Action irma.Action Action irma.Action
Handler Handler Handler Handler
Version irma.Version Version irma.Version
choice *irma.DisclosureChoice choice *irma.DisclosureChoice
client *Client client *Client
downloaded *irma.IrmaIdentifierSet
irmaSession irma.IrmaSession irmaSession irma.IrmaSession
} }
...@@ -68,12 +72,10 @@ type interactiveSession struct { ...@@ -68,12 +72,10 @@ type interactiveSession struct {
ServerURL string ServerURL string
info *irma.SessionInfo info *irma.SessionInfo
jwt irma.RequestorJwt jwt irma.RequestorJwt
transport *irma.HTTPTransport transport *irma.HTTPTransport
choice *irma.DisclosureChoice done bool
downloaded *irma.IrmaIdentifierSet
done bool
} }
// A manualSession is a session started from a request // A manualSession is a session started from a request
...@@ -125,46 +127,96 @@ func calcVersion(qr *irma.Qr) (string, error) { ...@@ -125,46 +127,96 @@ func calcVersion(qr *irma.Qr) (string, error) {
return "", fmt.Errorf("No supported protocol version between %s and %s", qr.ProtocolVersion, qr.ProtocolMaxVersion) return "", fmt.Errorf("No supported protocol version between %s and %s", qr.ProtocolVersion, qr.ProtocolMaxVersion)
} }
func parseSigrequestJSON(sigrequestJSONString string) (*irma.SignatureRequest, error) { func (session *session) getBuilders() (gabi.ProofBuilderList, error) {
sigrequestJSON := []byte(sigrequestJSONString) var builders gabi.ProofBuilderList
sigrequest := &irma.SignatureRequest{} var err error
err := json.Unmarshal(sigrequestJSON, sigrequest)
switch session.Action {
case irma.ActionSigning:
fallthrough
case irma.ActionDisclosing:
builders, err = session.client.ProofBuilders(session.choice)
case irma.ActionIssuing:
builders, err = session.client.IssuanceProofBuilders(session.irmaSession.(*irma.IssuanceRequest))
}
return sigrequest, err return builders, err
} }
// Start a manual session func (session *session) getProof() (interface{}, error) {
func (client *Client) NewManualSession(sigrequestJSONString string, handler Handler) { var message interface{}
sigrequest, err := parseSigrequestJSON(sigrequestJSONString); var err error
if err != nil {
handler.Failure(irma.ActionUnknown, &irma.SessionError{Err: err})
return
}
session := &manualSession{} switch session.Action {
// TODO: for some reason: we can't define these above in constructor? case irma.ActionSigning:
session.Action = irma.ActionSigning// TODO hardcoded for now message, err = session.client.Proofs(session.choice, session.irmaSession, true)
session.Handler = handler case irma.ActionDisclosing:
session.client = client // TODO hardcoded for now message, err = session.client.Proofs(session.choice, session.irmaSession, false)
session.Version = irma.Version("2") // TODO hardcoded for now case irma.ActionIssuing:
session.irmaSession = sigrequest message, err = session.client.IssueCommitments(session.irmaSession.(*irma.IssuanceRequest))
}
session.Handler.StatusUpdate(session.Action, irma.StatusManualStarted) return message, err
}
// Check if we are enrolled into all involved keyshare servers // Check if we are enrolled into all involved keyshare servers
func (session *session) checkKeyshareEnrollment() bool {
for id := range session.irmaSession.Identifiers().SchemeManagers { for id := range session.irmaSession.Identifiers().SchemeManagers {
manager, ok := session.client.Configuration.SchemeManagers[id] manager, ok := session.client.Configuration.SchemeManagers[id]
if !ok { if !ok {
session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorUnknownSchemeManager, Info: id.String()}) session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorUnknownSchemeManager, Info: id.String()})
return return false
} }
distributed := manager.Distributed() distributed := manager.Distributed()
_, enrolled := session.client.keyshareServers[id] _, enrolled := session.client.keyshareServers[id]
if distributed && !enrolled { if distributed && !enrolled {
session.Handler.MissingKeyshareEnrollment(id) session.Handler.MissingKeyshareEnrollment(id)
return return false
} }
} }
return true
}
func (session *session) panicFailure() {
if e := recover(); e != nil {
if session.Handler != nil {
session.Handler.Failure(session.Action, panicToError(e))
}
}
}
func parseSigrequestJSON(sigrequestJSONString string) (*irma.SignatureRequest, error) {
sigrequestJSON := []byte(sigrequestJSONString)
sigrequest := &irma.SignatureRequest{}
err := json.Unmarshal(sigrequestJSON, sigrequest)
return sigrequest, err
}
// Start a manual session
func (client *Client) NewManualSession(sigrequestJSONString string, handler Handler) {
sigrequest, err := parseSigrequestJSON(sigrequestJSONString)
if err != nil {
handler.Failure(irma.ActionUnknown, &irma.SessionError{Err: err})
return
}
session := &manualSession{
session: session{
Action: irma.ActionSigning, // TODO hardcoded for now
Handler: handler,
client: client,
Version: irma.Version("2"), // TODO hardcoded for now
irmaSession: sigrequest,
},
}
session.Handler.StatusUpdate(session.Action, irma.StatusManualStarted)
// Check if we are enrolled into all involved keyshare servers
if !session.checkKeyshareEnrollment() {
return
}
candidates, missing := session.client.CheckSatisfiability(session.irmaSession.ToDisclose()) candidates, missing := session.client.CheckSatisfiability(session.irmaSession.ToDisclose())
if len(missing) > 0 { if len(missing) > 0 {
...@@ -178,59 +230,29 @@ func (client *Client) NewManualSession(sigrequestJSONString string, handler Hand ...@@ -178,59 +230,29 @@ func (client *Client) NewManualSession(sigrequestJSONString string, handler Hand
callback := PermissionHandler(func(proceed bool, choice *irma.DisclosureChoice) { callback := PermissionHandler(func(proceed bool, choice *irma.DisclosureChoice) {
session.choice = choice session.choice = choice
session.irmaSession.SetDisclosureChoice(choice) session.irmaSession.SetDisclosureChoice(choice)
fmt.Println("Starting session.do()") go session.do(proceed)
go session.do(proceed)
}) })
session.Handler.RequestSignaturePermission( session.Handler.RequestSignaturePermission(
*session.irmaSession.(*irma.SignatureRequest), "IRMA Signature App", callback) *session.irmaSession.(*irma.SignatureRequest), "E-mail request", callback)
fmt.Println(session)
} }
func (session *manualSession) do(proceed bool) { func (session *manualSession) do(proceed bool) {
defer func() { defer session.panicFailure()
if e := recover(); e != nil {
if session.Handler != nil {
session.Handler.Failure(session.Action, panicToError(e))
}
}
}()
if !proceed { if !proceed {
session.cancel() session.Handler.Cancelled(session.Action)
return return
} }
session.Handler.StatusUpdate(session.Action, irma.StatusCommunicating)
if !session.irmaSession.Identifiers().Distributed(session.client.Configuration) { if !session.irmaSession.Identifiers().Distributed(session.client.Configuration) {
var message interface{} message, err := session.getProof()
var err error
switch session.Action {
case irma.ActionSigning:
message, err = session.client.Proofs(session.choice, session.irmaSession, true)
case irma.ActionDisclosing:
message, err = session.client.Proofs(session.choice, session.irmaSession, false)
case irma.ActionIssuing:
message, err = session.client.IssueCommitments(session.irmaSession.(*irma.IssuanceRequest))
}
if err != nil { if err != nil {
session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorCrypto, Err: err}) session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorCrypto, Err: err})
return return
} }
session.sendResponse(message) session.sendResponse(message)
} else { } else {
var builders gabi.ProofBuilderList builders, err := session.getBuilders()
var err error
switch session.Action {
case irma.ActionSigning:
fallthrough
case irma.ActionDisclosing:
builders, err = session.client.ProofBuilders(session.choice)
case irma.ActionIssuing:
builders, err = session.client.IssuanceProofBuilders(session.irmaSession.(*irma.IssuanceRequest))
}
if err != nil { if err != nil {
session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorCrypto, Err: err}) session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorCrypto, Err: err})
} }
...@@ -252,13 +274,13 @@ func (client *Client) NewSession(qr *irma.Qr, handler Handler) SessionDismisser ...@@ -252,13 +274,13 @@ func (client *Client) NewSession(qr *irma.Qr, handler Handler) SessionDismisser
session := &interactiveSession{ session := &interactiveSession{
ServerURL: qr.URL, ServerURL: qr.URL,
transport: irma.NewHTTPTransport(qr.URL), transport: irma.NewHTTPTransport(qr.URL),
session: session{
Action: irma.Action(qr.Type),
Handler: handler,
client: client,
},
} }
// TODO: for some reason: we can't define these above in constructor?
session.Action = irma.Action(qr.Type)
session.Handler = handler
session.client = client
if session.Action == irma.ActionSchemeManager { if session.Action == irma.ActionSchemeManager {
go session.managerSession() go session.managerSession()
return session return session
...@@ -295,13 +317,7 @@ func (client *Client) NewSession(qr *irma.Qr, handler Handler) SessionDismisser ...@@ -295,13 +317,7 @@ func (client *Client) NewSession(qr *irma.Qr, handler Handler) SessionDismisser
// 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 *interactiveSession) start() { func (session *interactiveSession) start() {
defer func() { defer session.panicFailure()
if e := recover(); e != nil {
if session.Handler != nil {
session.Handler.Failure(session.Action, panicToError(e))
}
}
}()
session.Handler.StatusUpdate(session.Action, irma.StatusCommunicating) session.Handler.StatusUpdate(session.Action, irma.StatusCommunicating)
...@@ -331,19 +347,8 @@ func (session *interactiveSession) start() { ...@@ -331,19 +347,8 @@ func (session *interactiveSession) start() {
} }
// Check if we are enrolled into all involved keyshare servers // Check if we are enrolled into all involved keyshare servers
for id := range session.irmaSession.Identifiers().SchemeManagers { if !session.checkKeyshareEnrollment() {
manager, ok := session.client.Configuration.SchemeManagers[id] return
if !ok {
session.fail(&irma.SessionError{ErrorType: irma.ErrorUnknownSchemeManager, Info: id.String()})
return
}
distributed := manager.Distributed()
_, enrolled := session.client.keyshareServers[id]
if distributed && !enrolled {
session.delete()
session.Handler.MissingKeyshareEnrollment(id)
return
}
} }
// Download missing credential types/issuers/public keys from the scheme manager // Download missing credential types/issuers/public keys from the scheme manager
...@@ -398,13 +403,7 @@ func (session *interactiveSession) start() { ...@@ -398,13 +403,7 @@ func (session *interactiveSession) start() {
} }
func (session *interactiveSession) do(proceed bool) { func (session *interactiveSession) do(proceed bool) {
defer func() { defer session.panicFailure()
if e := recover(); e != nil {
if session.Handler != nil {
session.Handler.Failure(session.Action, panicToError(e))
}
}
}()
if !proceed { if !proceed {
session.cancel() session.cancel()
...@@ -413,38 +412,17 @@ func (session *interactiveSession) do(proceed bool) { ...@@ -413,38 +412,17 @@ func (session *interactiveSession) do(proceed bool) {
session.Handler.StatusUpdate(session.Action, irma.StatusCommunicating) session.Handler.StatusUpdate(session.Action, irma.StatusCommunicating)
if !session.irmaSession.Identifiers().Distributed(session.client.Configuration) { if !session.irmaSession.Identifiers().Distributed(session.client.Configuration) {
var message interface{} message, err := session.getProof()
var err error
switch session.Action {
case irma.ActionSigning:
message, err = session.client.Proofs(session.choice, session.irmaSession, true)
case irma.ActionDisclosing:
message, err = session.client.Proofs(session.choice, session.irmaSession, false)
case irma.ActionIssuing:
message, err = session.client.IssueCommitments(session.irmaSession.(*irma.IssuanceRequest))
}
if err != nil { if err != nil {
session.fail(&irma.SessionError{ErrorType: irma.ErrorCrypto, Err: err}) session.fail(&irma.SessionError{ErrorType: irma.ErrorCrypto, Err: err})
return return
} }
session.sendResponse(message) session.sendResponse(message)
} else { } else {
var builders gabi.ProofBuilderList builders, err := session.getBuilders()
var err error
switch session.Action {
case irma.ActionSigning:
fallthrough
case irma.ActionDisclosing:
builders, err = session.client.ProofBuilders(session.choice)
case irma.ActionIssuing:
builders, err = session.client.IssuanceProofBuilders(session.irmaSession.(*irma.IssuanceRequest))
}
if err != nil { if err != nil {
session.fail(&irma.SessionError{ErrorType: irma.ErrorCrypto, Err: err}) session.fail(&irma.SessionError{ErrorType: irma.ErrorCrypto, Err: err})
} }
startKeyshareSession( startKeyshareSession(
session, session,
session.Handler, session.Handler,
...@@ -462,7 +440,7 @@ func (session *interactiveSession) KeyshareDone(message interface{}) { ...@@ -462,7 +440,7 @@ func (session *interactiveSession) KeyshareDone(message interface{}) {
} }
func (session *manualSession) KeyshareDone(message interface{}) { func (session *manualSession) KeyshareDone(message interface{}) {
messageJson, err := json.Marshal(message) messageJson, err := json.Marshal(message)
if err != nil { if err != nil {
session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorSerialization, Err: err}) session.Handler.Failure(session.Action, &irma.SessionError{ErrorType: irma.ErrorSerialization, Err: err})
return return
...@@ -508,17 +486,11 @@ func (session *manualSession) KeyshareError(err error) { ...@@ -508,17 +486,11 @@ func (session *manualSession) KeyshareError(err error) {
session.Handler.Failure(session.Action, serr) session.Handler.Failure(session.Action, serr)
} }
func (session *interactiveSession) KeysharePin() { func (session *session) KeysharePin() {
session.Handler.StatusUpdate(session.Action, irma.StatusConnected)
}
func (session *manualSession) KeysharePin() {
session.Handler.StatusUpdate(session.Action, irma.StatusConnected) session.Handler.StatusUpdate(session.Action, irma.StatusConnected)
} }
func (session *interactiveSession) KeysharePinOK() { func (session *session) KeysharePinOK() {
session.Handler.StatusUpdate(session.Action, irma.StatusCommunicating)
}
func (session *manualSession) KeysharePinOK() {
session.Handler.StatusUpdate(session.Action, irma.StatusCommunicating) session.Handler.StatusUpdate(session.Action, irma.StatusCommunicating)
} }
...@@ -665,10 +637,6 @@ func (session *interactiveSession) cancel() { ...@@ -665,10 +637,6 @@ func (session *interactiveSession) cancel() {
} }
} }
func (session *manualSession) cancel() {
session.Handler.Cancelled(session.Action)
}
func (session *interactiveSession) Dismiss() { func (session *interactiveSession) Dismiss() {
session.cancel() session.cancel()
} }
......
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