handlers_test.go 6.41 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(serverName irma.TranslatedString, missing map[int]map[int]irma.AttributeCon) {
100
101
102
103
	th.Failure(&irma.SessionError{
		ErrorType: irma.ErrorType("UnsatisfiableRequest"),
	})
}
104
func (th TestHandler) RequestVerificationPermission(request *irma.DisclosureRequest, ServerName irma.TranslatedString, callback irmaclient.PermissionHandler) {
105
	choice := &irma.DisclosureChoice{
106
		Attributes: [][]*irma.AttributeIdentifier{},
107
	}
108
109
110
	var candidates [][]*irma.AttributeIdentifier
	for _, disjunction := range request.Disclose {
		candidates, _ = th.client.Candidates(disjunction)
111
112
113
		if len(candidates) == 0 {
			th.Failure(&irma.SessionError{Err: errors.New("No disclosure candidates found")})
		}
114
		choice.Attributes = append(choice.Attributes, candidates[rand.Intn(len(candidates))])
115
	}
116
117
118
	if len(th.expectedServerName) != 0 {
		require.Equal(th.t, th.expectedServerName, ServerName)
	}
119
120
	callback(true, choice)
}
121
122
func (th TestHandler) RequestIssuancePermission(request *irma.IssuanceRequest, ServerName irma.TranslatedString, callback irmaclient.PermissionHandler) {
	th.RequestVerificationPermission(request.DisclosureRequest, ServerName, callback)
123
}
124
func (th TestHandler) RequestSignaturePermission(request *irma.SignatureRequest, ServerName irma.TranslatedString, callback irmaclient.PermissionHandler) {
125
126
127
128
129
	th.RequestVerificationPermission(request.DisclosureRequest, ServerName, callback)
}
func (th TestHandler) RequestSchemeManagerPermission(manager *irma.SchemeManager, callback func(proceed bool)) {
	callback(true)
}
130
func (th TestHandler) RequestPin(remainingAttempts int, callback irmaclient.PinHandler) {
131
132
133
134
	callback(true, "12345")
}

type SessionResult struct {
135
136
137
	Err              error
	SignatureResult  *irma.SignedMessage
	DisclosureResult *irma.Disclosure
138
139
}

140
141
142
// ManualTestHandler embeds a TestHandler to inherit its methods.
// Below we overwrite the methods that require behaviour specific to manual settings.
type ManualTestHandler struct {
143
	TestHandler
144
145
146
147
148
	action irma.Action
}

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

151
func (th *ManualTestHandler) Success(result string) {
152
153
154
155
156
	if len(result) == 0 {
		th.c <- nil
		return
	}

157
158
159
160
161
162
163
	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:
164
165
		retval.DisclosureResult = &irma.Disclosure{}
		err = json.Unmarshal([]byte(result), retval.DisclosureResult)
166
167
	}
	if err != nil {
168
169
170
171
172
173
174
		th.Failure(&irma.SessionError{
			Err:       err,
			ErrorType: irma.ErrorSerialization,
		})
		return
	}

175
	th.c <- retval
176
}
177
func (th *ManualTestHandler) RequestSignaturePermission(request *irma.SignatureRequest, requesterName irma.TranslatedString, ph irmaclient.PermissionHandler) {
178
	th.RequestVerificationPermission(request.DisclosureRequest, requesterName, ph)
179
}
180
func (th *ManualTestHandler) RequestIssuancePermission(request *irma.IssuanceRequest, issuerName irma.TranslatedString, ph irmaclient.PermissionHandler) {
181
182
183
184
	ph(true, nil)
}

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

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