handle.go 3.44 KB
Newer Older
1
2
3
4
5
6
package backend

import (
	"encoding/json"
	"net/http"
	"runtime/debug"
7
	"time"
8
9
10
11
12
13
14
15

	"github.com/mhe/gabi"
	"github.com/privacybydesign/irmago"
	"github.com/privacybydesign/irmago/irmaserver"
)

var conf *irmaserver.Configuration

16
func (session *session) handleDelete() {
17
	if session.finished() {
18
		return
19
	}
20
21
22
	session.markAlive()
	// TODO const ProofStatusCancelled = irma.ProofStatus("CANCELLED") ?
	session.result = &irmaserver.SessionResult{Token: session.token}
23
	session.setStatus(irmaserver.StatusCancelled)
24
25
}

26
func (session *session) handleGetRequest(min, max *irma.ProtocolVersion) (irma.SessionRequest, *irma.RemoteError) {
27
28
29
30
31
	if session.status != irmaserver.StatusInitialized {
		return nil, getError(irmaserver.ErrorUnexpectedRequest, "Session already started")
	}
	session.markAlive()

32
33
	var err error
	if session.version, err = chooseProtocolVersion(min, max); err != nil {
34
		return nil, session.fail(irmaserver.ErrorProtocolVersion, "")
35
36
	}
	session.request.SetVersion(session.version)
37
38

	session.setStatus(irmaserver.StatusConnected)
39
	return session.request, nil
40
41
}

42
43
func handleGetStatus(session *session) irmaserver.Status {
	return session.status
44
45
}

46
47
48
49
func (session *session) handlePostSignature(signature *irma.SignedMessage) (*irma.ProofStatus, *irma.RemoteError) {
	if session.status != irmaserver.StatusConnected {
		return nil, getError(irmaserver.ErrorUnexpectedRequest, "Session not yet started or already finished")
	}
50
	session.markAlive()
51

52
53
54
	session.result.Signature = signature
	session.result.Disclosed, session.result.Status = signature.Verify(
		conf.IrmaConfiguration, session.request.(*irma.SignatureRequest))
55
56
	session.setStatus(irmaserver.StatusDone)
	return &session.result.Status, nil
57
}
58

59
60
61
62
func (session *session) handlePostProofs(proofs gabi.ProofList) (*irma.ProofStatus, *irma.RemoteError) {
	if session.status != irmaserver.StatusConnected {
		return nil, getError(irmaserver.ErrorUnexpectedRequest, "Session not yet started or already finished")
	}
63
	session.markAlive()
64

65
66
	session.result.Disclosed, session.result.Status = irma.ProofList(proofs).Verify(
		conf.IrmaConfiguration, session.request.(*irma.DisclosureRequest))
67
68
	session.setStatus(irmaserver.StatusDone)
	return &session.result.Status, nil
69
70
}

71
// Session helpers
72

73
74
func (session *session) finished() bool {
	return session.status == irmaserver.StatusDone || session.status == irmaserver.StatusCancelled
75
76
}

77
78
func (session *session) markAlive() {
	session.lastActive = time.Now()
79
80
}

81
82
83
84
func (session *session) setStatus(status irmaserver.Status) {
	session.status = status
}

85
86
func (session *session) fail(err irmaserver.Error, message string) *irma.RemoteError {
	rerr := getError(err, message)
87
	session.setStatus(irmaserver.StatusCancelled)
88
89
90
91
92
93
94
95
96
97
	session.result = &irmaserver.SessionResult{Err: rerr, Token: session.token}
	return rerr
}

// Output helpers

func getError(err irmaserver.Error, message string) *irma.RemoteError {
	stack := string(debug.Stack())
	conf.Logger.Errorf("Error: %d %s %s\n%s", err.Status, err.Type, message, stack)
	return &irma.RemoteError{
98
99
100
101
		Status:      err.Status,
		Description: err.Description,
		ErrorName:   string(err.Type),
		Message:     message,
102
		Stacktrace:  stack,
103
	}
104
}
105

106
107
108
109
110
111
112
113
114
115
116
func responseJson(v interface{}, err *irma.RemoteError) (int, []byte) {
	msg := v
	status := http.StatusOK
	if err != nil {
		msg = err
		status = err.Status
	}
	b, e := json.Marshal(msg)
	if e != nil {
		conf.Logger.Error("Failed to serialize response:", e.Error())
		return http.StatusInternalServerError, nil
117
	}
118
	return status, b
119
}