handlers_test.go 6.87 KB
Newer Older
1
package sessiontest
2
3
4

import (
	"encoding/json"
5
	"math/rand"
6
	"testing"
7
	"time"
8
9
10

	"github.com/pkg/errors"
	"github.com/privacybydesign/irmago"
11
	"github.com/privacybydesign/irmago/irmaclient"
12
	"github.com/stretchr/testify/require"
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
)

type TestClientHandler struct {
	t *testing.T
	c chan error
}

func (i *TestClientHandler) UpdateConfiguration(new *irma.IrmaIdentifierSet) {}
func (i *TestClientHandler) UpdateAttributes()                               {}
func (i *TestClientHandler) EnrollmentSuccess(manager irma.SchemeManagerIdentifier) {
	select {
	case i.c <- nil: // nop
	default: // nop
	}
}
func (i *TestClientHandler) EnrollmentFailure(manager irma.SchemeManagerIdentifier, err error) {
	select {
	case i.c <- err: // nop
	default:
		i.t.Fatal(err)
	}
}
func (i *TestClientHandler) ChangePinSuccess(manager irma.SchemeManagerIdentifier) {
	select {
	case i.c <- nil: // nop
	default: // nop
	}
}
func (i *TestClientHandler) ChangePinFailure(manager irma.SchemeManagerIdentifier, err error) {
	select {
	case i.c <- err: //nop
	default:
		i.t.Fatal(err)
	}
}
func (i *TestClientHandler) ChangePinIncorrect(manager irma.SchemeManagerIdentifier, attempts int) {
	err := errors.New("incorrect pin")
	select {
	case i.c <- err: //nop
	default:
		i.t.Fatal(err)
	}
}
func (i *TestClientHandler) ChangePinBlocked(manager irma.SchemeManagerIdentifier, timeout int) {
	err := errors.New("blocked account")
	select {
	case i.c <- err: //nop
	default:
		i.t.Fatal(err)
	}
}

type TestHandler struct {
66
67
68
69
	t                  *testing.T
	c                  chan *SessionResult
	client             *irmaclient.Client
	expectedServerName irma.TranslatedString
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
}

func (th TestHandler) KeyshareEnrollmentIncomplete(manager irma.SchemeManagerIdentifier) {
	th.Failure(&irma.SessionError{Err: errors.New("KeyshareEnrollmentIncomplete")})
}
func (th TestHandler) KeyshareBlocked(manager irma.SchemeManagerIdentifier, duration int) {
	th.Failure(&irma.SessionError{Err: errors.New("KeyshareBlocked")})
}
func (th TestHandler) KeyshareEnrollmentMissing(manager irma.SchemeManagerIdentifier) {
	th.Failure(&irma.SessionError{Err: errors.Errorf("Missing keyshare server %s", manager.String())})
}
func (th TestHandler) KeyshareEnrollmentDeleted(manager irma.SchemeManagerIdentifier) {
	th.Failure(&irma.SessionError{Err: errors.Errorf("Keyshare enrollment deleted for %s", manager.String())})
}
func (th TestHandler) StatusUpdate(action irma.Action, status irma.Status) {}
func (th TestHandler) Success(result string) {
	th.c <- nil
}
func (th TestHandler) Cancelled() {
	th.Failure(&irma.SessionError{Err: errors.New("Cancelled")})
}
func (th TestHandler) Failure(err *irma.SessionError) {
	th.t.Logf("Session failed: %+v\n", *err)
	select {
	case th.c <- &SessionResult{Err: err}:
	default:
		th.t.Fatal(err)
	}
}
99
func (th TestHandler) UnsatisfiableRequest(request irma.SessionRequest, serverName irma.TranslatedString, missing irmaclient.MissingAttributes) {
100
101
102
103
	th.Failure(&irma.SessionError{
		ErrorType: irma.ErrorType("UnsatisfiableRequest"),
	})
}
104
105
106
107
func (th TestHandler) RequestVerificationPermission(request *irma.DisclosureRequest, candidates [][][]*irma.AttributeIdentifier, ServerName irma.TranslatedString, callback irmaclient.PermissionHandler) {
	var choice irma.DisclosureChoice
	for _, cand := range candidates {
		choice.Attributes = append(choice.Attributes, cand[0])
108
	}
109
110
111
	if len(th.expectedServerName) != 0 {
		require.Equal(th.t, th.expectedServerName, ServerName)
	}
112
	callback(true, &choice)
113
}
114
func (th TestHandler) RequestIssuancePermission(request *irma.IssuanceRequest, candidates [][][]*irma.AttributeIdentifier, ServerName irma.TranslatedString, callback irmaclient.PermissionHandler) {
115
	th.RequestVerificationPermission(&request.DisclosureRequest, candidates, ServerName, callback)
116
}
117
func (th TestHandler) RequestSignaturePermission(request *irma.SignatureRequest, candidates [][][]*irma.AttributeIdentifier, ServerName irma.TranslatedString, callback irmaclient.PermissionHandler) {
118
	th.RequestVerificationPermission(&request.DisclosureRequest, candidates, ServerName, callback)
119
120
121
122
}
func (th TestHandler) RequestSchemeManagerPermission(manager *irma.SchemeManager, callback func(proceed bool)) {
	callback(true)
}
123
func (th TestHandler) RequestPin(remainingAttempts int, callback irmaclient.PinHandler) {
124
125
126
127
	callback(true, "12345")
}

type SessionResult struct {
128
129
130
	Err              error
	SignatureResult  *irma.SignedMessage
	DisclosureResult *irma.Disclosure
131
132
133
134
135
136
137
138
139
140
141
142
143
	Missing          irmaclient.MissingAttributes
}

type UnsatisfiableTestHandler struct {
	TestHandler
}

func (th UnsatisfiableTestHandler) UnsatisfiableRequest(request irma.SessionRequest, serverName irma.TranslatedString, missing irmaclient.MissingAttributes) {
	th.c <- &SessionResult{Missing: missing}
}

func (th UnsatisfiableTestHandler) Success(result string) {
	th.Failure(&irma.SessionError{ErrorType: irma.ErrorType("Unsatisfiable request succeeded")})
144
145
}

146
147
148
// ManualTestHandler embeds a TestHandler to inherit its methods.
// Below we overwrite the methods that require behaviour specific to manual settings.
type ManualTestHandler struct {
149
	TestHandler
150
151
152
153
154
	action irma.Action
}

func (th *ManualTestHandler) StatusUpdate(action irma.Action, status irma.Status) {
	th.action = action
155
156
}

157
func (th *ManualTestHandler) Success(result string) {
158
159
160
161
162
	if len(result) == 0 {
		th.c <- nil
		return
	}

163
164
165
166
167
168
169
	var err error
	retval := &SessionResult{}
	switch th.action {
	case irma.ActionSigning:
		retval.SignatureResult = &irma.SignedMessage{}
		err = json.Unmarshal([]byte(result), retval.SignatureResult)
	case irma.ActionDisclosing:
170
171
		retval.DisclosureResult = &irma.Disclosure{}
		err = json.Unmarshal([]byte(result), retval.DisclosureResult)
172
173
	}
	if err != nil {
174
175
176
177
178
179
180
		th.Failure(&irma.SessionError{
			Err:       err,
			ErrorType: irma.ErrorSerialization,
		})
		return
	}

181
	th.c <- retval
182
}
183
func (th *ManualTestHandler) RequestSignaturePermission(request *irma.SignatureRequest, candidates [][][]*irma.AttributeIdentifier, requesterName irma.TranslatedString, ph irmaclient.PermissionHandler) {
184
	th.RequestVerificationPermission(&request.DisclosureRequest, candidates, requesterName, ph)
185
}
186
func (th *ManualTestHandler) RequestIssuancePermission(request *irma.IssuanceRequest, candidates [][][]*irma.AttributeIdentifier, issuerName irma.TranslatedString, ph irmaclient.PermissionHandler) {
187
188
189
190
	ph(true, nil)
}

// These handlers should not be called, fail test if they are called
191
func (th *ManualTestHandler) RequestSchemeManagerPermission(manager *irma.SchemeManager, callback func(proceed bool)) {
192
193
	th.Failure(&irma.SessionError{Err: errors.New("Unexpected session type")})
}
194
func (th *ManualTestHandler) RequestVerificationPermission(request *irma.DisclosureRequest, candidates [][][]*irma.AttributeIdentifier, verifierName irma.TranslatedString, ph irmaclient.PermissionHandler) {
195
	var choice irma.DisclosureChoice
196
	for _, cand := range candidates {
197
		choice.Attributes = append(choice.Attributes, cand[0])
198
	}
199
	ph(true, &choice)
200
}
201
202
203
204

func init() {
	rand.Seed(time.Now().UnixNano())
}