Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
IRMA
Github mirrors
irmago
Commits
55e40826
Commit
55e40826
authored
Dec 17, 2018
by
Sietse Ringers
Browse files
Merge branch 'refactor'
parents
a5eb23a3
d9514702
Changes
41
Expand all
Hide whitespace changes
Inline
Side-by-side
Gopkg.lock
View file @
55e40826
...
...
@@ -49,12 +49,6 @@
packages = ["."]
revision = "720887075201f3105c335f837431426d54891b7f"
[[projects]]
branch = "master"
name = "github.com/credentials/safeprime"
packages = ["."]
revision = "424faf641b4987fde58280730486e1035e057abc"
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
...
...
@@ -110,10 +104,14 @@
version = "v1.0"
[[projects]]
branch = "
maste
r"
branch = "
refacto
r"
name = "github.com/mhe/gabi"
packages = ["."]
revision = "4f733a839b2b9234ef7c2610fbc8270bafe250c7"
packages = [
".",
"safeprime"
]
revision = "30dbdc3d708aee39573ef793505e78b6fb949b48"
source = "github.com/privacybydesign/gabi"
[[projects]]
branch = "master"
...
...
@@ -197,6 +195,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "
edc6335a88ff851653a42b9198c2f0f2e7f27502e18a9b48d2641de3b0bd69be
"
inputs-digest = "
463d26f53ec5d07c619bf97f2707460ffa512d6eddc1f8c109972e101981afab
"
solver-name = "gps-cdcl"
solver-version = 1
Gopkg.toml
View file @
55e40826
...
...
@@ -38,8 +38,9 @@
version
=
"1.0.0"
[[constraint]]
branch
=
"
maste
r"
branch
=
"
refacto
r"
name
=
"github.com/mhe/gabi"
source
=
"github.com/privacybydesign/gabi"
[[constraint]]
name
=
"github.com/pkg/errors"
...
...
attributes.go
View file @
55e40826
...
...
@@ -5,13 +5,11 @@ import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"math/big"
"time"
"fmt"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
)
const
(
...
...
@@ -20,24 +18,6 @@ const (
metadataLength
=
1
+
3
+
2
+
2
+
16
)
type
AttributeResult
struct
{
AttributeValue
string
`json:"value"`
// Value of the disclosed attribute
AttributeId
AttributeTypeIdentifier
`json:"id"`
AttributeProofStatus
AttributeProofStatus
`json:"status"`
}
type
AttributeResultList
[]
*
AttributeResult
// AttributeProofStatus is the proof status of a single attribute
type
AttributeProofStatus
string
const
(
PRESENT
=
AttributeProofStatus
(
"PRESENT"
)
// Attribute is disclosed and matches the value
EXTRA
=
AttributeProofStatus
(
"EXTRA"
)
// Attribute is disclosed, but wasn't requested in request
MISSING
=
AttributeProofStatus
(
"MISSING"
)
// Attribute is NOT disclosed, but should be according to request
INVALID_VALUE
=
AttributeProofStatus
(
"INVALID_VALUE"
)
// Attribute is disclosed, but has invalid value according to request
)
var
(
versionField
=
metadataField
{
1
,
0
}
signingDateField
=
metadataField
{
3
,
1
}
...
...
@@ -65,6 +45,7 @@ type AttributeList struct {
*
MetadataAttribute
`json:"-"`
Ints
[]
*
big
.
Int
strings
[]
TranslatedString
attrMap
map
[
AttributeTypeIdentifier
]
TranslatedString
info
*
CredentialInfo
h
string
}
...
...
@@ -96,6 +77,20 @@ func (al *AttributeList) Hash() string {
return
al
.
h
}
func
(
al
*
AttributeList
)
Map
(
conf
*
Configuration
)
map
[
AttributeTypeIdentifier
]
TranslatedString
{
if
al
.
attrMap
==
nil
{
al
.
attrMap
=
make
(
map
[
AttributeTypeIdentifier
]
TranslatedString
)
ctid
:=
al
.
CredentialType
()
.
Identifier
()
strings
:=
al
.
Strings
()
ct
:=
conf
.
CredentialTypes
[
ctid
]
for
i
:=
range
ct
.
AttributeTypes
{
attrid
:=
ct
.
AttributeTypes
[
i
]
.
GetAttributeTypeIdentifier
()
al
.
attrMap
[
attrid
]
=
strings
[
i
]
}
}
return
al
.
attrMap
}
// Strings converts the current instance to human-readable strings.
func
(
al
*
AttributeList
)
Strings
()
[]
TranslatedString
{
if
al
.
strings
==
nil
{
...
...
@@ -105,12 +100,24 @@ func (al *AttributeList) Strings() []TranslatedString {
if
val
==
nil
{
continue
}
al
.
strings
[
i
]
=
map
[
string
]
string
{
"en"
:
*
val
,
"nl"
:
*
val
}
// TODO
al
.
strings
[
i
]
=
translateAttribute
(
val
)
}
}
return
al
.
strings
}
// Localize raw attribute values (to be implemented)
func
translateAttribute
(
attr
*
string
)
TranslatedString
{
if
attr
==
nil
{
return
nil
}
return
map
[
string
]
string
{
""
:
*
attr
,
// raw value
"en"
:
*
attr
,
"nl"
:
*
attr
,
}
}
func
(
al
*
AttributeList
)
decode
(
i
int
)
*
string
{
attr
:=
al
.
Ints
[
i
+
1
]
metadataVersion
:=
al
.
MetadataAttribute
.
Version
()
...
...
@@ -135,7 +142,7 @@ func (al *AttributeList) UntranslatedAttribute(identifier AttributeTypeIdentifie
if
al
.
CredentialType
()
.
Identifier
()
!=
identifier
.
CredentialTypeIdentifier
()
{
return
nil
}
for
i
,
desc
:=
range
al
.
CredentialType
()
.
Attributes
{
for
i
,
desc
:=
range
al
.
CredentialType
()
.
Attribute
Type
s
{
if
desc
.
ID
==
string
(
identifier
.
Name
())
{
return
al
.
decode
(
i
)
}
...
...
@@ -143,12 +150,12 @@ func (al *AttributeList) UntranslatedAttribute(identifier AttributeTypeIdentifie
return
nil
}
// Attribute returns the content of the specified attribute, or
""
if not present in this attribute list.
// Attribute returns the content of the specified attribute, or
nil
if not present in this attribute list.
func
(
al
*
AttributeList
)
Attribute
(
identifier
AttributeTypeIdentifier
)
TranslatedString
{
if
al
.
CredentialType
()
.
Identifier
()
!=
identifier
.
CredentialTypeIdentifier
()
{
return
nil
}
for
i
,
desc
:=
range
al
.
CredentialType
()
.
Attributes
{
for
i
,
desc
:=
range
al
.
CredentialType
()
.
Attribute
Type
s
{
if
desc
.
ID
==
string
(
identifier
.
Name
())
{
return
al
.
Strings
()[
i
]
}
...
...
@@ -334,68 +341,50 @@ type AttributeDisjunction struct {
Values
map
[
AttributeTypeIdentifier
]
*
string
selected
*
AttributeTypeIdentifier
}
// AttributeDisjunction with the disclosed value that is used to satisfy the disjunction
type
DisclosedAttributeDisjunction
struct
{
AttributeDisjunction
DisclosedValue
string
DisclosedId
AttributeTypeIdentifier
ProofStatus
AttributeProofStatus
value
*
string
index
*
int
}
// An AttributeDisjunctionList is a list of AttributeDisjunctions.
type
AttributeDisjunctionList
[]
*
AttributeDisjunction
// Convert disjunction to a DisclosedAttributeDisjunction that contains disclosed attribute+value
func
(
disjunction
*
AttributeDisjunction
)
ToDisclosedAttributeDisjunction
(
ar
*
AttributeResult
)
*
DisclosedAttributeDisjunction
{
return
&
DisclosedAttributeDisjunction
{
AttributeDisjunction
:
*
disjunction
,
DisclosedValue
:
ar
.
AttributeValue
,
DisclosedId
:
ar
.
AttributeId
,
ProofStatus
:
ar
.
AttributeProofStatus
,
}
}
// HasValues indicates if the attributes of this disjunction have values
// that should be satisfied.
func
(
disjunction
*
AttributeDisjunction
)
HasValues
()
bool
{
return
disjunction
.
Values
!=
nil
&&
len
(
disjunction
.
Values
)
!=
0
}
// Satisfied indicates if this disjunction has a valid chosen attribute
// to be disclosed.
func
(
disjunction
*
AttributeDisjunction
)
Satisfied
()
bool
{
if
disjunction
.
selected
==
nil
{
return
false
}
for
_
,
attr
:=
range
disjunction
.
Attributes
{
if
*
disjunction
.
selected
==
attr
{
return
true
// attemptSatisfy tries to match the specified attribute type and value against the current disjunction,
// returning true if the disjunction contains the specified attribute type. Note that if the disjunction
// has required values, then it is only considered satisfied by the specified attribute type and value
// if the required value matches the specified value.
func
(
disjunction
*
AttributeDisjunction
)
attemptSatisfy
(
id
AttributeTypeIdentifier
,
value
*
string
)
bool
{
var
found
bool
for
index
,
attr
:=
range
disjunction
.
Attributes
{
if
attr
==
id
{
found
=
true
disjunction
.
selected
=
&
id
disjunction
.
index
=
&
index
disjunction
.
value
=
value
if
!
disjunction
.
HasValues
()
||
disjunction
.
Values
[
id
]
==
value
{
return
true
}
}
}
return
f
alse
return
f
ound
}
// Check whether specified attributedisjunction satisfy a list of disclosed attributes
// We return true if one of the attributes in the disjunction is satisfied
func
(
disjunction
*
AttributeDisjunction
)
SatisfyDisclosed
(
disclosed
DisclosedCredentialList
,
conf
*
Configuration
)
(
bool
,
*
DisclosedAttributeDisjunction
)
{
var
attributeResult
*
AttributeResult
for
_
,
attr
:=
range
disjunction
.
Attributes
{
requestedValue
:=
disjunction
.
Values
[
attr
]
var
isSatisfied
bool
isSatisfied
,
attributeResult
=
disclosed
.
isAttributeSatisfied
(
attr
,
requestedValue
)
if
isSatisfied
{
return
true
,
disjunction
.
ToDisclosedAttributeDisjunction
(
attributeResult
)
}
// satisfied indicates if this disjunction has a valid attribute type and value selected,
// matching one of the attributes in the disjunction and possibly also the corresponding required value.
func
(
disjunction
*
AttributeDisjunction
)
satisfied
()
bool
{
if
disjunction
.
index
==
nil
{
return
false
}
// Nothing satisfied, attributeResult will contain the last attribute of the original request
// TODO: do we want this?
return
false
,
disjunction
.
ToDisclosedAttributeDisjunction
(
attributeResult
)
attr
:=
disjunction
.
Attributes
[
*
disjunction
.
index
]
return
!
disjunction
.
HasValues
()
||
disjunction
.
value
==
disjunction
.
Values
[
attr
]
return
false
}
// MatchesConfig returns true if all attributes contained in the disjunction are
...
...
@@ -413,10 +402,10 @@ func (disjunction *AttributeDisjunction) MatchesConfig(conf *Configuration) bool
return
true
}
//
S
atisfied indicates whether each contained attribute disjunction has a chosen attribute.
func
(
dl
AttributeDisjunctionList
)
S
atisfied
()
bool
{
//
s
atisfied indicates whether each contained attribute disjunction has a chosen attribute.
func
(
dl
AttributeDisjunctionList
)
s
atisfied
()
bool
{
for
_
,
disjunction
:=
range
dl
{
if
!
disjunction
.
S
atisfied
()
{
if
!
disjunction
.
s
atisfied
()
{
return
false
}
}
...
...
@@ -458,27 +447,6 @@ func (disjunction *AttributeDisjunction) MarshalJSON() ([]byte, error) {
return
json
.
Marshal
(
temp
)
}
// Since we have a custom MarshalJSON for AttributeDisjunction, we also need one for every struct that extends AttributeDisjunction...
func
(
disclosedAttributeDisjunction
*
DisclosedAttributeDisjunction
)
MarshalJSON
()
([]
byte
,
error
)
{
temp
:=
struct
{
Label
string
`json:"label"`
Attributes
[]
AttributeTypeIdentifier
`json:"attributes"`
DisclosedValue
string
`json:"disclosedValue"`
DisclosedId
AttributeTypeIdentifier
`json:"disclosedId"`
ProofStatus
AttributeProofStatus
`json:"proofStatus"`
}{
Label
:
disclosedAttributeDisjunction
.
Label
,
Attributes
:
disclosedAttributeDisjunction
.
Attributes
,
DisclosedValue
:
disclosedAttributeDisjunction
.
DisclosedValue
,
DisclosedId
:
disclosedAttributeDisjunction
.
DisclosedId
,
ProofStatus
:
disclosedAttributeDisjunction
.
ProofStatus
,
}
return
json
.
Marshal
(
temp
)
}
// UnmarshalJSON unmarshals an attribute disjunction from JSON.
func
(
disjunction
*
AttributeDisjunction
)
UnmarshalJSON
(
bytes
[]
byte
)
error
{
if
disjunction
.
Values
==
nil
{
...
...
@@ -531,19 +499,3 @@ func (disjunction *AttributeDisjunction) UnmarshalJSON(bytes []byte) error {
return
nil
}
func
(
al
*
AttributeResultList
)
String
()
string
{
// TODO: pretty print?
str
:=
"Attribute --- Value --- ProofStatus:"
for
_
,
v
:=
range
*
al
{
str
=
str
+
"
\n
"
+
v
.
String
()
}
return
str
}
func
(
ar
*
AttributeResult
)
String
()
string
{
return
fmt
.
Sprintf
(
"%v --- %v --- %v"
,
ar
.
AttributeId
,
ar
.
AttributeValue
,
ar
.
AttributeProofStatus
)
}
credinfo.go
View file @
55e40826
package
irma
import
(
"
math/big
"
"
fmt
"
"strings"
"time"
"github.com/mhe/gabi/big"
)
// CredentialInfo contains all information of an IRMA credential.
type
CredentialInfo
struct
{
CredentialTypeID
CredentialTypeIdentifier
// e.g., "irma-demo.RU.studentCard"
Name
string
// e.g., "studentCard"
IssuerID
IssuerIdentifier
// e.g., "RU"
SchemeManagerID
SchemeManagerIdentifier
// e.g., "irma-demo"
Index
int
// This is the Index-th credential instance of this type
SignedOn
Timestamp
// Unix timestamp
Expires
Timestamp
// Unix timestamp
Attributes
[]
TranslatedString
// Human-readable rendered attributes
Logo
string
// Path to logo on storage
Hash
string
// SHA256 hash over the attributes
ID
string
// e.g., "studentCard"
IssuerID
string
// e.g., "RU"
SchemeManagerID
string
// e.g., "irma-demo"
SignedOn
Timestamp
// Unix timestamp
Expires
Timestamp
// Unix timestamp
Attributes
map
[
AttributeTypeIdentifier
]
TranslatedString
// Human-readable rendered attributes
Hash
string
// SHA256 hash over the attributes
}
// A CredentialInfoList is a list of credentials (implements sort.Interface).
...
...
@@ -34,20 +33,18 @@ func NewCredentialInfo(ints []*big.Int, conf *Configuration) *CredentialInfo {
id
:=
credtype
.
Identifier
()
issid
:=
id
.
IssuerIdentifier
()
return
&
CredentialInfo
{
CredentialTypeID
:
NewCredentialTypeIdentifier
(
id
.
String
()),
Name
:
id
.
Name
(),
IssuerID
:
NewIssuerIdentifier
(
issid
.
Name
()),
SchemeManagerID
:
NewSchemeManagerIdentifier
(
issid
.
SchemeManagerIdentifier
()
.
String
()),
SignedOn
:
Timestamp
(
meta
.
SigningDate
()),
Expires
:
Timestamp
(
meta
.
Expiry
()),
Attributes
:
attrs
.
Strings
(),
Logo
:
credtype
.
Logo
(
conf
),
Hash
:
attrs
.
Hash
(),
ID
:
id
.
Name
(),
IssuerID
:
issid
.
Name
(),
SchemeManagerID
:
issid
.
SchemeManagerIdentifier
()
.
Name
(),
SignedOn
:
Timestamp
(
meta
.
SigningDate
()),
Expires
:
Timestamp
(
meta
.
Expiry
()),
Attributes
:
attrs
.
Map
(
conf
),
Hash
:
attrs
.
Hash
(),
}
}
func
(
ci
CredentialInfo
)
GetCredentialType
(
conf
*
Configuration
)
*
CredentialType
{
return
conf
.
CredentialTypes
[
ci
.
CredentialTypeI
D
]
return
conf
.
CredentialTypes
[
New
CredentialTypeI
dentifier
(
fmt
.
Sprintf
(
"%s.%s.%s"
,
ci
.
SchemeManagerID
,
ci
.
IssuerID
,
ci
.
ID
))
]
}
// Returns true if credential is expired at moment of calling this function
...
...
@@ -68,5 +65,5 @@ func (cl CredentialInfoList) Swap(i, j int) {
// Less implements sort.Interface.
func
(
cl
CredentialInfoList
)
Less
(
i
,
j
int
)
bool
{
// TODO Decide on sorting, and if it depends on a irmago.TranslatedString, allow language choosing
return
strings
.
Compare
(
cl
[
i
]
.
Name
,
cl
[
j
]
.
Name
)
>
0
return
strings
.
Compare
(
cl
[
i
]
.
ID
,
cl
[
j
]
.
ID
)
>
0
}
descriptions.go
View file @
55e40826
...
...
@@ -40,8 +40,7 @@ type Issuer struct {
SchemeManagerID
string
`xml:"SchemeManager"`
ContactAddress
string
ContactEMail
string
URL
string
`xml:"baseURL"`
XMLVersion
int
`xml:"version,attr"`
XMLVersion
int
`xml:"version,attr"`
Valid
bool
`xml:"-"`
}
...
...
@@ -55,27 +54,34 @@ type CredentialType struct {
SchemeManagerID
string
`xml:"SchemeManager"`
IsSingleton
bool
`xml:"ShouldBeSingleton"`
Description
TranslatedString
Attribute
s
[]
Attribute
Description
`xml:"Attributes>Attribute"`
XMLVersion
int
`xml:"version,attr"`
XMLName
xml
.
Name
`xml:"IssueSpecification"`
Attribute
Types
[]
*
Attribute
Type
`xml:"Attributes>Attribute"
json:"-"
`
XMLVersion
int
`xml:"version,attr"`
XMLName
xml
.
Name
`xml:"IssueSpecification"`
Valid
bool
`xml:"-"`
}
// AttributeDescription is a description of an attribute within a credential type.
type
AttributeDescription
struct
{
ID
string
`xml:"id,attr"`
Optional
string
`xml:"optional,attr" json:",omitempty"`
DisplayIndex
*
int
`xml:"displayIndex,attr" json:",omitempty"`
Name
TranslatedString
Description
TranslatedString
// AttributeType is a description of an attribute within a credential type.
type
AttributeType
struct
{
ID
string
`xml:"id,attr"`
Optional
string
`xml:"optional,attr" json:",omitempty"`
Name
TranslatedString
Description
TranslatedString
Index
int
`xml:"-"`
DisplayIndex
*
int
`xml:"displayIndex,attr" json:",omitempty"`
// Taken from containing CredentialType
CredentialTypeID
string
`xml:"-"`
IssuerID
string
`xml:"-"`
SchemeManagerID
string
`xml:"-"`
}
func
(
ad
Attribute
Description
)
GetAttributeTypeIdentifier
(
cred
CredentialTypeIdentifier
)
AttributeTypeIdentifier
{
return
NewAttributeTypeIdentifier
(
cred
.
S
t
rin
g
()
+
"."
+
ad
.
ID
)
func
(
ad
Attribute
Type
)
GetAttributeTypeIdentifier
()
AttributeTypeIdentifier
{
return
NewAttributeTypeIdentifier
(
fmt
.
S
p
rin
tf
(
"%s.%s.%s.%s"
,
ad
.
SchemeManagerID
,
ad
.
IssuerID
,
ad
.
CredentialTypeID
,
ad
.
ID
)
)
}
func
(
ad
Attribute
Description
)
IsOptional
()
bool
{
func
(
ad
Attribute
Type
)
IsOptional
()
bool
{
return
ad
.
Optional
==
"true"
}
...
...
@@ -85,7 +91,7 @@ func (ct *CredentialType) ContainsAttribute(ai AttributeTypeIdentifier) bool {
if
ai
.
CredentialTypeIdentifier
()
.
String
()
!=
ct
.
Identifier
()
.
String
()
{
return
false
}
for
_
,
desc
:=
range
ct
.
Attributes
{
for
_
,
desc
:=
range
ct
.
Attribute
Type
s
{
if
desc
.
ID
==
ai
.
Name
()
{
return
true
}
...
...
@@ -99,7 +105,7 @@ func (ct CredentialType) IndexOf(ai AttributeTypeIdentifier) (int, error) {
if
ai
.
CredentialTypeIdentifier
()
!=
ct
.
Identifier
()
{
return
-
1
,
errors
.
New
(
"Wrong credential type"
)
}
for
i
,
description
:=
range
ct
.
Attributes
{
for
i
,
description
:=
range
ct
.
Attribute
Type
s
{
if
description
.
ID
==
ai
.
Name
()
{
return
i
,
nil
}
...
...
@@ -107,12 +113,12 @@ func (ct CredentialType) IndexOf(ai AttributeTypeIdentifier) (int, error) {
return
-
1
,
errors
.
New
(
"Attribute identifier not found"
)
}
func
(
ct
CredentialType
)
Attribute
Description
(
ai
AttributeTypeIdentifier
)
*
Attribute
Description
{
func
(
ct
CredentialType
)
Attribute
Type
(
ai
AttributeTypeIdentifier
)
*
Attribute
Type
{
i
,
_
:=
ct
.
IndexOf
(
ai
)
if
i
==
-
1
{
return
nil
}
return
&
ct
.
Attributes
[
i
]
return
ct
.
Attribute
Type
s
[
i
]
}
// TranslatedString is a map of translated strings.
...
...
identifiers.go
View file @
55e40826
...
...
@@ -144,12 +144,11 @@ func (id IssuerIdentifier) MarshalText() ([]byte, error) {
return
[]
byte
(
id
.
String
()),
nil
}
// TODO enable this when updating protocol
//// UnmarshalText implements encoding.TextUnmarshaler.
//func (id *IssuerIdentifier) UnmarshalText(text []byte) error {
// *id = NewIssuerIdentifier(string(text))
// return nil
//}
// UnmarshalText implements encoding.TextUnmarshaler.
func
(
id
*
IssuerIdentifier
)
UnmarshalText
(
text
[]
byte
)
error
{
*
id
=
NewIssuerIdentifier
(
string
(
text
))
return
nil
}
// MarshalText implements encoding.TextMarshaler.
func
(
id
CredentialTypeIdentifier
)
MarshalText
()
([]
byte
,
error
)
{
...
...
internal/sessiontest/handlers_test.go
0 → 100644
View file @
55e40826
package
sessiontest
import
(
"encoding/json"
"testing"
"github.com/pkg/errors"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/irmaclient"
)
type
TestClientHandler
struct
{
t
*
testing
.
T
c
chan
error
}
func
(
i
*
TestClientHandler
)
UpdateConfiguration
(
new
*
irma
.
IrmaIdentifierSet
)
{}
func
(
i
*
TestClientHandler
)
UpdateAttributes
()
{}
func
(
i
*
TestClientHandler
)
EnrollmentSuccess
(
manager
irma
.
SchemeManagerIdentifier
)
{
select
{
case
i
.
c
<-
nil
:
// nop
default
:
// nop
}
}
func
(
i
*
TestClientHandler
)
EnrollmentFailure
(
manager
irma
.
SchemeManagerIdentifier
,
err
error
)
{
select
{
case
i
.
c
<-
err
:
// nop
default
:
i
.
t
.
Fatal
(
err
)
}
}
func
(
i
*
TestClientHandler
)
ChangePinSuccess
(
manager
irma
.
SchemeManagerIdentifier
)
{
select
{
case
i
.
c
<-
nil
:
// nop
default
:
// nop
}
}
func
(
i
*
TestClientHandler
)
ChangePinFailure
(
manager
irma
.
SchemeManagerIdentifier
,
err
error
)
{
select
{
case
i
.
c
<-
err
:
//nop
default
:
i
.
t
.
Fatal
(
err
)
}
}
func
(
i
*
TestClientHandler
)
ChangePinIncorrect
(
manager
irma
.
SchemeManagerIdentifier
,
attempts
int
)
{
err
:=
errors
.
New
(
"incorrect pin"
)
select
{
case
i
.
c
<-
err
:
//nop
default
:
i
.
t
.
Fatal
(
err
)
}
}
func
(
i
*
TestClientHandler
)
ChangePinBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
timeout
int
)
{
err
:=
errors
.
New
(
"blocked account"
)
select
{
case
i
.
c
<-
err
:
//nop
default
:
i
.
t
.
Fatal
(
err
)
}
}
type
TestHandler
struct
{
t
*
testing
.
T
c
chan
*
SessionResult
client
*
irmaclient
.
Client
}
func
(
th
TestHandler
)
KeyshareEnrollmentIncomplete
(
manager
irma
.
SchemeManagerIdentifier
)
{
th
.
Failure
(
&
irma
.
SessionError
{
Err
:
errors
.
New
(
"KeyshareEnrollmentIncomplete"
)})
}
func
(
th
TestHandler
)
KeyshareBlocked
(
manager
irma
.
SchemeManagerIdentifier
,
duration
int
)
{
th
.
Failure
(
&
irma
.
SessionError
{
Err
:
errors
.
New
(
"KeyshareBlocked"
)})
}
func
(
th
TestHandler
)
KeyshareEnrollmentMissing
(
manager
irma
.
SchemeManagerIdentifier
)
{
th
.
Failure
(
&
irma
.
SessionError
{
Err
:
errors
.
Errorf
(
"Missing keyshare server %s"
,
manager
.
String
())})
}
func
(
th
TestHandler
)
KeyshareEnrollmentDeleted
(
manager
irma
.
SchemeManagerIdentifier
)
{
th
.
Failure
(
&
irma
.
SessionError
{
Err
:
errors
.
Errorf
(
"Keyshare enrollment deleted for %s"
,
manager
.
String
())})
}
func
(
th
TestHandler
)
StatusUpdate
(
action
irma
.
Action
,
status
irma
.
Status
)
{}
func
(
th
TestHandler
)
Success
(
result
string
)
{
th
.
c
<-
nil
}
func
(
th
TestHandler
)
Cancelled
()
{
th
.
Failure
(
&
irma
.
SessionError
{
Err
:
errors
.
New
(
"Cancelled"
)})
}
func
(
th
TestHandler
)
Failure
(
err
*
irma
.
SessionError
)
{
th
.
t
.
Logf
(
"Session failed: %+v
\n
"
,
*
err
)
select
{
case
th
.
c
<-
&
SessionResult
{
Err
:
err
}
:
default
:
th
.
t
.
Fatal
(
err
)
}
}
func
(
th
TestHandler
)
UnsatisfiableRequest
(
serverName
string
,
missing
irma
.
AttributeDisjunctionList
)
{
th
.
Failure
(
&
irma
.
SessionError
{
ErrorType
:
irma
.
ErrorType
(
"UnsatisfiableRequest"
),
})
}
func
(
th
TestHandler
)
RequestVerificationPermission
(
request
irma
.
DisclosureRequest
,
ServerName
string
,
callback
irmaclient
.
PermissionHandler
)
{
choice
:=
&
irma
.
DisclosureChoice
{
Attributes
:
[]
*
irma
.
AttributeIdentifier
{},
}
var
candidates
[]
*
irma
.
AttributeIdentifier
for
_
,
disjunction
:=
range
request
.
Content
{
candidates
=
th
.
client
.
Candidates
(
disjunction
)
if
len
(
candidates
)
==
0
{
th
.
Failure
(
&
irma
.
SessionError
{
Err
:
errors
.
New
(
"No disclosure candidates found"
)})
}
choice
.
Attributes
=
append
(
choice
.
Attributes
,
candidates
[
0
])
}
callback
(
true
,
choice
)
}
func
(
th
TestHandler
)
RequestIssuancePermission
(
request
irma
.
IssuanceRequest
,
ServerName
string
,
callback
irmaclient
.
PermissionHandler
)
{
dreq
:=
irma
.
DisclosureRequest
{
BaseRequest
:
request
.
BaseRequest
,
Content
:
request
.
Disclose
,
}
th
.
RequestVerificationPermission
(
dreq
,
ServerName
,
callback
)
}
func
(
th
TestHandler
)
RequestSignaturePermission
(
request
irma
.
SignatureRequest
,
ServerName
string
,
callback
irmaclient
.
PermissionHandler
)
{