main_test.go 7.13 KB
Newer Older
1
2
3
package sessiontest

import (
4
5
6
	"encoding/base64"
	"encoding/json"
	"io/ioutil"
7
8
	"os"
	"path/filepath"
9
	"reflect"
10
	"testing"
11
	"time"
12

13
14
	jwt "github.com/dgrijalva/jwt-go"
	irma "github.com/privacybydesign/irmago"
15
16
	"github.com/privacybydesign/irmago/internal/test"
	"github.com/privacybydesign/irmago/irmaclient"
17
18
	"github.com/privacybydesign/irmago/server"
	"github.com/sirupsen/logrus"
19
20
21
	"github.com/stretchr/testify/require"
)

22
23
func init() {
	irma.ForceHttps = false
24
	irma.Logger.SetLevel(logrus.WarnLevel)
25
26
}

27
28
29
func TestMain(m *testing.M) {
	// Create HTTP server for scheme managers
	test.StartSchemeManagerHttpServer()
30
	defer test.StopSchemeManagerHttpServer()
31
32

	test.CreateTestStorage(nil)
33
	defer test.ClearTestStorage(nil)
34

35
	os.Exit(m.Run())
36
37
}

38
func parseStorage(t *testing.T) (*irmaclient.Client, *TestClientHandler) {
39
	test.SetupTestStorage(t)
40
	handler := &TestClientHandler{t: t, c: make(chan error)}
41
42
43
44
	path := test.FindTestdataFolder(t)
	client, err := irmaclient.New(
		filepath.Join(path, "storage", "test"),
		filepath.Join(path, "irma_configuration"),
45
		handler,
46
47
	)
	require.NoError(t, err)
48
	return client, handler
49
}
50
51

func getDisclosureRequest(id irma.AttributeTypeIdentifier) *irma.DisclosureRequest {
52
	return irma.NewDisclosureRequest(id)
53
54
55
}

func getSigningRequest(id irma.AttributeTypeIdentifier) *irma.SignatureRequest {
56
	return irma.NewSignatureRequest("test", id)
57
58
59
60
61
62
63
64
}

func getIssuanceRequest(defaultValidity bool) *irma.IssuanceRequest {
	temp := irma.Timestamp(irma.FloorToEpochBoundary(time.Now().AddDate(1, 0, 0)))
	var expiry *irma.Timestamp
	if !defaultValidity {
		expiry = &temp
	}
65
66
67
68
69
70
71
72
73
	return irma.NewIssuanceRequest([]*irma.CredentialRequest{
		{
			Validity:         expiry,
			CredentialTypeID: irma.NewCredentialTypeIdentifier("irma-demo.RU.studentCard"),
			Attributes: map[string]string{
				"university":        "Radboud",
				"studentCardNumber": "31415927",
				"studentID":         "s1234567",
				"level":             "42",
74
75
			},
		},
76
	})
77
78
79
80
}

func getNameIssuanceRequest() *irma.IssuanceRequest {
	expiry := irma.Timestamp(irma.NewMetadataAttribute(0).Expiry())
81
82
83
84
85
86
87
88
	return irma.NewIssuanceRequest([]*irma.CredentialRequest{
		{
			Validity:         &expiry,
			CredentialTypeID: irma.NewCredentialTypeIdentifier("irma-demo.MijnOverheid.fullName"),
			Attributes: map[string]string{
				"firstnames": "Johan Pieter",
				"firstname":  "Johan",
				"familyname": "Stuivezand",
89
90
			},
		},
91
	})
92
93
94
95
96
97
98
99
100
101
102

}

func getSpecialIssuanceRequest(defaultValidity bool, attribute string) *irma.IssuanceRequest {
	request := getIssuanceRequest(defaultValidity)
	request.Credentials[0].Attributes["studentCardNumber"] = attribute
	return request
}

func getCombinedIssuanceRequest(id irma.AttributeTypeIdentifier) *irma.IssuanceRequest {
	request := getIssuanceRequest(false)
103
	request.AddSingle(id, nil, nil)
104
105
106
	return request
}

107
108
109
110
111
112
113
114
115
116
117
118
func getMultipleIssuanceRequest() *irma.IssuanceRequest {
	request := getIssuanceRequest(false)
	request.Credentials = append(request.Credentials, &irma.CredentialRequest{
		Validity:         request.Credentials[0].Validity,
		CredentialTypeID: irma.NewCredentialTypeIdentifier("irma-demo.MijnOverheid.root"),
		Attributes: map[string]string{
			"BSN": "299792458",
		},
	})
	return request
}

119
120
121
var TestType = "irmaserver-jwt"

func startSession(t *testing.T, request irma.SessionRequest, sessiontype string) *irma.Qr {
122
123
	var (
		qr     *irma.Qr = new(irma.Qr)
124
		sesPkg server.SessionPackage
125
126
		err    error
	)
127
128
129
130

	switch TestType {
	case "apiserver":
		url := "http://localhost:8088/irma_api_server/api/v2/" + sessiontype
131
		err = irma.NewHTTPTransport(url).Post("", qr, getJwt(t, request, sessiontype, jwt.SigningMethodNone))
132
133
134
		qr.URL = url + "/" + qr.URL
	case "irmaserver-jwt":
		url := "http://localhost:48682"
135
136
		err = irma.NewHTTPTransport(url).Post("session", &sesPkg, getJwt(t, request, sessiontype, jwt.SigningMethodRS256))
		qr = sesPkg.SessionPtr
137
138
	case "irmaserver-hmac-jwt":
		url := "http://localhost:48682"
139
140
		err = irma.NewHTTPTransport(url).Post("session", &sesPkg, getJwt(t, request, sessiontype, jwt.SigningMethodHS256))
		qr = sesPkg.SessionPtr
141
142
	case "irmaserver":
		url := "http://localhost:48682"
143
144
		err = irma.NewHTTPTransport(url).Post("session", &sesPkg, request)
		qr = sesPkg.SessionPtr
145
146
147
148
149
	default:
		t.Fatal("Invalid TestType")
	}

	require.NoError(t, err)
150
	return qr
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
}

func getJwt(t *testing.T, request irma.SessionRequest, sessiontype string, alg jwt.SigningMethod) string {
	var jwtcontents irma.RequestorJwt
	var kid string
	switch sessiontype {
	case "issue":
		kid = "testip"
		jwtcontents = irma.NewIdentityProviderJwt("testip", request.(*irma.IssuanceRequest))
	case "verification":
		kid = "testsp"
		jwtcontents = irma.NewServiceProviderJwt("testsp", request.(*irma.DisclosureRequest))
	case "signature":
		kid = "testsigclient"
		jwtcontents = irma.NewSignatureRequestorJwt("testsigclient", request.(*irma.SignatureRequest))
	}

	var j string
	var err error

	switch alg {
	case jwt.SigningMethodRS256:
		skbts, err := ioutil.ReadFile(filepath.Join(test.FindTestdataFolder(t), "jwtkeys", "requestor1-sk.pem"))
		require.NoError(t, err)
		sk, err := jwt.ParseRSAPrivateKeyFromPEM(skbts)
		require.NoError(t, err)
		tok := jwt.NewWithClaims(jwt.SigningMethodRS256, jwtcontents)
		tok.Header["kid"] = "requestor1"
		j, err = tok.SignedString(sk)
Sietse Ringers's avatar
Sietse Ringers committed
180
		require.NoError(t, err)
181
182
183
184
185
186
	case jwt.SigningMethodHS256:
		tok := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtcontents)
		tok.Header["kid"] = "requestor3"
		bts, err := base64.StdEncoding.DecodeString(JwtServerConfiguration.Requestors["requestor3"].AuthenticationKey)
		require.NoError(t, err)
		j, err = tok.SignedString(bts)
Sietse Ringers's avatar
Sietse Ringers committed
187
		require.NoError(t, err)
188
189
190
191
	case jwt.SigningMethodNone:
		tok := jwt.NewWithClaims(jwt.SigningMethodNone, jwtcontents)
		tok.Header["kid"] = kid
		j, err = tok.SignedString(jwt.UnsafeAllowNoneSignatureType)
Sietse Ringers's avatar
Sietse Ringers committed
192
		require.NoError(t, err)
193
194
195
196
197
198
199
	}

	return j
}

func sessionHelper(t *testing.T, request irma.SessionRequest, sessiontype string, client *irmaclient.Client) {
	if client == nil {
200
		client, _ = parseStorage(t)
201
202
203
204
205
206
207
208
209
210
211
		defer test.ClearTestStorage(t)
	}

	if TestType == "irmaserver" || TestType == "irmaserver-jwt" || TestType == "irmaserver-hmac-jwt" {
		StartRequestorServer(JwtServerConfiguration)
		defer StopRequestorServer()
	}

	qr := startSession(t, request, sessiontype)

	c := make(chan *SessionResult)
212
	h := &TestHandler{t: t, c: c, client: client, expectedServerName: expectedServerName(t, request, client.Configuration)}
213
214
215
216
217
218
219
220
	qrjson, err := json.Marshal(qr)
	require.NoError(t, err)
	client.NewSession(string(qrjson), h)

	if result := <-c; result != nil {
		require.NoError(t, result.Err)
	}
}
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

func expectedServerName(t *testing.T, request irma.SessionRequest, conf *irma.Configuration) irma.TranslatedString {
	localhost := "localhost"
	host := irma.NewTranslatedString(&localhost)

	ir, ok := request.(*irma.IssuanceRequest)
	if !ok {
		return host
	}

	// In issuance sessions, the server name is expected to be:
	// - the name of the issuer, if there is just one issuer
	// - the hostname as usual otherwise

	var name irma.TranslatedString
	for _, credreq := range ir.Credentials {
		n := conf.Issuers[credreq.CredentialTypeID.IssuerIdentifier()].Name
		if !reflect.DeepEqual(name, n) {
			if len(name) != 0 {
				return host
			}
			name = n
		}
	}

	return name
}