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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 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
	}
	ir := jwt.IrmaSession().(*irma.IssuanceRequest)
	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
88
89
90
91
		// Get the signed message and timestamp
		request := session.irmaSession.(*irma.SignatureRequest)
		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
}