server.go 2.55 KB
Newer Older
1
2
3
4
5
6
7
package server

import (
	"fmt"
	"io/ioutil"
	"net/http"

8
	"github.com/go-chi/chi"
9
10
11
12
13
14
	"github.com/go-errors/errors"
	"github.com/privacybydesign/irmago"
	"github.com/privacybydesign/irmago/irmaserver"
	"github.com/privacybydesign/irmago/irmaserver/irmarequestor"
)

15
16
17
18
19
type Configuration struct {
	*irmaserver.Configuration
	Port int
}

20
21
var server *http.Server

22
23
24
// Start the server. If successful then it will not return until Stop() is called.
func Start(conf *Configuration) error {
	if err := irmarequestor.Initialize(conf.Configuration); err != nil {
25
26
27
		return err
	}

28
	router := chi.NewRouter()
29

30
31
	// Mount server for irmaclient
	router.Mount("/irma/", irmarequestor.HttpHandlerFunc("/irma/"))
32

33
34
35
36
	// Server routes
	router.Post("/create", handleCreate)
	router.Get("/status/{token}", handleStatus)
	router.Get("/result/{token}", handleResult)
37

38
	// Start server
39
40
41
42
43
44
	server = &http.Server{Addr: fmt.Sprintf(":%d", conf.Port), Handler: router}
	err := server.ListenAndServe()
	if err == http.ErrServerClosed {
		return nil // Server was closed normally
	}
	return err
45
46
47
48
49
50
}

func Stop() {
	server.Close()
}

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
func handleCreate(w http.ResponseWriter, r *http.Request) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		irmaserver.WriteError(w, irmaserver.ErrorInvalidRequest, err.Error())
		return
	}
	request, err := parseRequest(body)
	if err != nil {
		irmaserver.WriteError(w, irmaserver.ErrorInvalidRequest, err.Error())
		return
	}

	qr, _, err := irmarequestor.StartSession(request, nil)
	if err != nil {
		irmaserver.WriteError(w, irmaserver.ErrorInvalidRequest, err.Error())
		return
	}

	irmaserver.WriteJson(w, qr)
}

func handleStatus(w http.ResponseWriter, r *http.Request) {
	res := irmarequestor.GetSessionResult(chi.URLParam(r, "token"))
	if res == nil {
		irmaserver.WriteError(w, irmaserver.ErrorSessionUnknown, "")
		return
	}
	irmaserver.WriteJson(w, res.Status)
}

func handleResult(w http.ResponseWriter, r *http.Request) {
	res := irmarequestor.GetSessionResult(chi.URLParam(r, "token"))
	if res == nil {
		irmaserver.WriteError(w, irmaserver.ErrorSessionUnknown, "")
		return
	}
	irmaserver.WriteJson(w, res)
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
}

func parseRequest(bts []byte) (request irma.SessionRequest, err error) {
	request = &irma.DisclosureRequest{}
	if err = irma.UnmarshalValidate(bts, request); err == nil {
		return request, nil
	}
	request = &irma.SignatureRequest{}
	if err = irma.UnmarshalValidate(bts, request); err == nil {
		return request, nil
	}
	request = &irma.IssuanceRequest{}
	if err = irma.UnmarshalValidate(bts, request); err == nil {
		return request, nil
	}
	return nil, errors.New("Invalid session type")
}