logs.go 4.24 KB
Newer Older
1
package irmaclient
Sietse Ringers's avatar
Sietse Ringers committed
2
3

import (
Sietse Ringers's avatar
Sietse Ringers committed
4
5
6
	"encoding/json"
	"time"

Tomas's avatar
Tomas committed
7
	"github.com/bwesterb/go-atum"
Sietse Ringers's avatar
Sietse Ringers committed
8
	"github.com/go-errors/errors"
9
	"github.com/privacybydesign/irmago"
Sietse Ringers's avatar
Sietse Ringers committed
10
11
)

Sietse Ringers's avatar
Sietse Ringers committed
12
// LogEntry is a log entry of a past event.
Sietse Ringers's avatar
Sietse Ringers committed
13
type LogEntry struct {
Sietse Ringers's avatar
Sietse Ringers committed
14
	// General info
15
16
	Type irma.Action
	Time irma.Timestamp // Time at which the session was completed
Sietse Ringers's avatar
Sietse Ringers committed
17

18
19
	// Credential removal
	Removed map[irma.CredentialTypeIdentifier][]irma.TranslatedString `json:",omitempty"`
Sietse Ringers's avatar
Sietse Ringers committed
20

21
22
23
24
	// Signature sessions
	SignedMessage          []byte          `json:",omitempty"`
	Timestamp              *atum.Timestamp `json:",omitempty"`
	SignedMessageLDContext string          `json:",omitempty"`
Sietse Ringers's avatar
Sietse Ringers committed
25

26
	// Issuance sessions
27
	IssueCommitment *irma.IssueCommitmentMessage `json:",omitempty"`
28
29
30
31
32
33

	// All session types
	Version    *irma.ProtocolVersion `json:",omitempty"`
	Disclosure *irma.Disclosure      `json:",omitempty"`
	Request    json.RawMessage       `json:",omitempty"` // Message that started the session
	request    irma.SessionRequest   // cached parsed version of Request; get with LogEntry.SessionRequest()
Sietse Ringers's avatar
Sietse Ringers committed
34
35
}

36
const actionRemoval = irma.Action("removal")
37

Sietse Ringers's avatar
Sietse Ringers committed
38
func (entry *LogEntry) SessionRequest() (irma.SessionRequest, error) {
39
40
41
42
43
44
45
46
47
48
49
50
51
	if entry.request != nil {
		return entry.request, nil
	}

	switch entry.Type {
	case irma.ActionDisclosing:
		entry.request = &irma.DisclosureRequest{}
	case irma.ActionSigning:
		entry.request = &irma.SignatureRequest{}
	case irma.ActionIssuing:
		entry.request = &irma.IssuanceRequest{}
	default:
		return nil, nil
Sietse Ringers's avatar
Sietse Ringers committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
	}

	err := json.Unmarshal([]byte(entry.Request), entry.request)
	if err != nil {
		return nil, err
	}

	return entry.request, nil
}

func (entry *LogEntry) setSessionRequest() error {
	bts, err := json.Marshal(entry.request)
	if err != nil {
		return err
	}
	entry.Request = json.RawMessage(bts)
	return nil
}

Tomas's avatar
Tomas committed
71
// GetDisclosedCredentials gets the list of disclosed credentials for a log entry
72
func (entry *LogEntry) GetDisclosedCredentials(conf *irma.Configuration) ([][]*irma.DisclosedAttribute, error) {
Sietse Ringers's avatar
Sietse Ringers committed
73
	if entry.Type == actionRemoval {
74
		return [][]*irma.DisclosedAttribute{}, nil
Sietse Ringers's avatar
Sietse Ringers committed
75
76
77
78
79
80
	}

	request, err := entry.SessionRequest()
	if err != nil {
		return nil, err
	}
81
	var disclosure *irma.Disclosure
82
	disjunctions := request.Disclosure()
Sietse Ringers's avatar
Sietse Ringers committed
83
	if entry.Type == irma.ActionIssuing {
84
		disclosure = entry.IssueCommitment.Disclosure()
Sietse Ringers's avatar
Sietse Ringers committed
85
	} else {
86
		disclosure = entry.Disclosure
Sietse Ringers's avatar
Sietse Ringers committed
87
	}
88
	_, attrs, err := disclosure.DisclosedAttributes(conf, disjunctions.Disclose)
Sietse Ringers's avatar
Sietse Ringers committed
89
	return attrs, err
Tomas's avatar
Tomas committed
90
91
92
93
}

// GetIssuedCredentials gets the list of issued credentials for a log entry
func (entry *LogEntry) GetIssuedCredentials(conf *irma.Configuration) (list irma.CredentialInfoList, err error) {
Sietse Ringers's avatar
Sietse Ringers committed
94
95
96
97
98
99
100
101
	if entry.Type != irma.ActionIssuing {
		return irma.CredentialInfoList{}, nil
	}
	request, err := entry.SessionRequest()
	if err != nil {
		return nil, err
	}
	return request.(*irma.IssuanceRequest).GetCredentialInfoList(conf, entry.Version)
Tomas's avatar
Tomas committed
102
103
104
}

// GetSignedMessage gets the signed for a log entry
105
func (entry *LogEntry) GetSignedMessage() (abs *irma.SignedMessage, err error) {
Sietse Ringers's avatar
Sietse Ringers committed
106
107
108
109
110
111
112
113
114
	if entry.Type != irma.ActionSigning {
		return nil, nil
	}
	request, err := entry.SessionRequest()
	if err != nil {
		return nil, err
	}
	sigrequest := request.(*irma.SignatureRequest)
	return &irma.SignedMessage{
115
		LDContext: entry.SignedMessageLDContext,
116
		Signature: entry.Disclosure.Proofs,
Sietse Ringers's avatar
Sietse Ringers committed
117
		Nonce:     sigrequest.Nonce,
118
		Context:   sigrequest.GetContext(),
Sietse Ringers's avatar
Sietse Ringers committed
119
120
121
		Message:   string(entry.SignedMessage),
		Timestamp: entry.Timestamp,
	}, nil
Tomas's avatar
Tomas committed
122
123
}

124
func (session *session) createLogEntry(response interface{}) (*LogEntry, error) {
Sietse Ringers's avatar
Sietse Ringers committed
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
	entry := &LogEntry{
		Type:    session.Action,
		Time:    irma.Timestamp(time.Now()),
		Version: session.Version,
		request: session.request,
	}

	if err := entry.setSessionRequest(); err != nil {
		return nil, err
	}

	switch entry.Type {
	case actionRemoval:

	case irma.ActionSigning:
		// Get the signed message and timestamp
141
		entry.SignedMessage = []byte(session.request.(*irma.SignatureRequest).Message)
142
		entry.Timestamp = session.timestamp
143
		entry.SignedMessageLDContext = irma.LDContextSignedMessage
Sietse Ringers's avatar
Sietse Ringers committed
144
145
146

		fallthrough
	case irma.ActionDisclosing:
147
		entry.Disclosure = response.(*irma.Disclosure)
Sietse Ringers's avatar
Sietse Ringers committed
148
	case irma.ActionIssuing:
149
		entry.IssueCommitment = response.(*irma.IssueCommitmentMessage)
Sietse Ringers's avatar
Sietse Ringers committed
150
151
152
153
154
	default:
		return nil, errors.New("Invalid log type")
	}

	return entry, nil
Sietse Ringers's avatar
Sietse Ringers committed
155
}