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

import (
	"time"

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

Tomas's avatar
Tomas committed
12
13
14
// LogSessionInfo is a SessionInfo alias to bypass the custom JSON marshaler
type LogSessionInfo irma.SessionInfo

Sietse Ringers's avatar
Sietse Ringers committed
15
// LogEntry is a log entry of a past event.
Sietse Ringers's avatar
Sietse Ringers committed
16
type LogEntry struct {
Sietse Ringers's avatar
Sietse Ringers committed
17
	// General info
18
	Type        irma.Action
Tomas's avatar
Tomas committed
19
20
21
	Time        irma.Timestamp        // Time at which the session was completed
	SessionInfo *LogSessionInfo       `json:",omitempty"` // Message that started the session
	Version     *irma.ProtocolVersion `json:",omitempty"` // Protocol version that was used in the session
Sietse Ringers's avatar
Sietse Ringers committed
22

Sietse Ringers's avatar
Sietse Ringers committed
23
	// Session type-specific info
Tomas's avatar
Tomas committed
24
25
26
	Removed       map[irma.CredentialTypeIdentifier][]irma.TranslatedString `json:",omitempty"` // In case of credential removal
	SignedMessage []byte                                                    `json:",omitempty"` // In case of signature sessions
	Timestamp     *atum.Timestamp                                           `json:",omitempty"` // In case of signature sessions
Sietse Ringers's avatar
Sietse Ringers committed
27

Tomas's avatar
Tomas committed
28
29
	IssueCommitment *gabi.IssueCommitmentMessage `json:",omitempty"`
	ProofList       gabi.ProofList               `json:",omitempty"`
Sietse Ringers's avatar
Sietse Ringers committed
30
31
}

32
const actionRemoval = irma.Action("removal")
33

Tomas's avatar
Tomas committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// GetDisclosedCredentials gets the list of disclosed credentials for a log entry
func (entry *LogEntry) GetDisclosedCredentials(conf *irma.Configuration) (irma.DisclosedCredentialList, error) {
	if entry.Type == actionRemoval {
		return irma.DisclosedCredentialList{}, nil
	}
	var proofs gabi.ProofList
	if entry.Type == irma.ActionIssuing {
		proofs = entry.IssueCommitment.Proofs
	} else {
		proofs = entry.ProofList
	}
	return irma.ExtractDisclosedCredentials(conf, proofs)
}

// GetIssuedCredentials gets the list of issued credentials for a log entry
func (entry *LogEntry) GetIssuedCredentials(conf *irma.Configuration) (list irma.CredentialInfoList, err error) {
	if entry.Type != irma.ActionIssuing {
		return irma.CredentialInfoList{}, nil
	}
	jwt, err := irma.ParseRequestorJwt(irma.ActionIssuing, entry.SessionInfo.Jwt)
	if err != nil {
		return
	}
57
	ir := jwt.SessionRequest().(*irma.IssuanceRequest)
Tomas's avatar
Tomas committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
	return ir.GetCredentialInfoList(conf, entry.Version)
}

// GetSignedMessage gets the signed for a log entry
func (entry *LogEntry) GetSignedMessage() (abs *irma.IrmaSignedMessage, err error) {
	if entry.Type != irma.ActionSigning {
		return nil, nil
	}
	return &irma.IrmaSignedMessage{
		Signature: entry.ProofList,
		Nonce:     entry.SessionInfo.Nonce,
		Context:   entry.SessionInfo.Context,
		Message:   string(entry.SignedMessage),
		Timestamp: entry.Timestamp,
	}, nil
}

75
func (session *session) createLogEntry(response interface{}) (*LogEntry, error) {
Sietse Ringers's avatar
Sietse Ringers committed
76
77
	entry := &LogEntry{
		Type:        session.Action,
78
		Time:        irma.Timestamp(time.Now()),
Tomas's avatar
Tomas committed
79
80
		Version:     session.Version,
		SessionInfo: (*LogSessionInfo)(session.info),
Sietse Ringers's avatar
Sietse Ringers committed
81
82
83
	}

	switch entry.Type {
Tomas's avatar
Tomas committed
84
85
	case actionRemoval:

86
	case irma.ActionSigning:
Tomas's avatar
Tomas committed
87
		// Get the signed message and timestamp
88
		request := session.request.(*irma.SignatureRequest)
Tomas's avatar
Tomas committed
89
90
91
		entry.SignedMessage = []byte(request.Message)
		entry.Timestamp = request.Timestamp

Sietse Ringers's avatar
Sietse Ringers committed
92
		fallthrough
93
	case irma.ActionDisclosing:
Tomas's avatar
Tomas committed
94
		entry.ProofList = response.(gabi.ProofList)
95
	case irma.ActionIssuing:
Tomas's avatar
Tomas committed
96
		entry.IssueCommitment = response.(*gabi.IssueCommitmentMessage)
Sietse Ringers's avatar
Sietse Ringers committed
97
98
99
100
101
102
103
	default:
		return nil, errors.New("Invalid log type")
	}

	return entry, nil
}

Sietse Ringers's avatar
Sietse Ringers committed
104
105
// Jwt returns the JWT from the requestor that started the IRMA session which the
// current log entry tracks.
106
107
func (entry *LogEntry) Jwt() (irma.RequestorJwt, error) {
	return irma.ParseRequestorJwt(entry.Type, entry.SessionInfo.Jwt)
Sietse Ringers's avatar
Sietse Ringers committed
108
}