Skip to content
GitLab
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
0ceea884
Commit
0ceea884
authored
Feb 10, 2019
by
Sietse Ringers
Browse files
Add irma request subcommand
parent
72c6e2bc
Changes
3
Hide whitespace changes
Inline
Side-by-side
irma/cmd/request.go
0 → 100644
View file @
0ceea884
package
cmd
import
(
"encoding/json"
"fmt"
"net/http"
"os"
"strconv"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/go-errors/errors"
"github.com/mdp/qrterminal"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/fs"
"github.com/privacybydesign/irmago/server"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
// requestCmd represents the request command
var
requestCmd
=
&
cobra
.
Command
{
Use
:
"request"
,
Short
:
"Generate an IRMA session request"
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
request
,
_
,
err
:=
configureRequest
(
cmd
)
if
err
!=
nil
{
die
(
""
,
err
)
}
flags
:=
cmd
.
Flags
()
authmethod
,
_
:=
flags
.
GetString
(
"authmethod"
)
var
output
string
if
authmethod
==
"none"
||
authmethod
==
"token"
{
output
=
prettyprint
(
request
)
}
else
{
key
,
_
:=
flags
.
GetString
(
"key"
)
name
,
_
:=
flags
.
GetString
(
"name"
)
if
output
,
err
=
signRequest
(
request
,
name
,
authmethod
,
key
);
err
!=
nil
{
die
(
"Failed to sign request"
,
err
)
}
}
fmt
.
Println
(
output
)
},
}
func
signRequest
(
request
irma
.
RequestorRequest
,
name
,
authmethod
,
key
string
)
(
string
,
error
)
{
var
(
err
error
sk
interface
{}
jwtalg
jwt
.
SigningMethod
bts
[]
byte
)
// If the key refers to an existing file, use contents of the file as key
if
bts
,
err
=
fs
.
ReadKey
(
""
,
key
);
err
!=
nil
{
bts
=
[]
byte
(
key
)
}
switch
authmethod
{
case
"hmac"
:
jwtalg
=
jwt
.
SigningMethodHS256
if
sk
,
err
=
fs
.
Base64Decode
(
bts
);
err
!=
nil
{
return
""
,
err
}
case
"rsa"
:
jwtalg
=
jwt
.
SigningMethodRS256
if
sk
,
err
=
jwt
.
ParseRSAPrivateKeyFromPEM
(
bts
);
err
!=
nil
{
return
""
,
err
}
default
:
return
""
,
errors
.
Errorf
(
"Unsupported signing algorithm: '%s'"
,
authmethod
)
}
return
irma
.
SignRequestorRequest
(
request
,
jwtalg
,
sk
,
name
)
}
func
configureRequest
(
cmd
*
cobra
.
Command
)
(
irma
.
RequestorRequest
,
*
irma
.
Configuration
,
error
)
{
irmaconfigPath
,
err
:=
cmd
.
Flags
()
.
GetString
(
"schemes-path"
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
irmaconfig
,
err
:=
irma
.
NewConfiguration
(
irmaconfigPath
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
if
err
=
irmaconfig
.
ParseFolder
();
err
!=
nil
{
return
nil
,
nil
,
err
}
if
len
(
irmaconfig
.
SchemeManagers
)
==
0
{
if
err
=
irmaconfig
.
DownloadDefaultSchemes
();
err
!=
nil
{
return
nil
,
nil
,
err
}
}
request
,
err
:=
constructSessionRequest
(
cmd
,
irmaconfig
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
return
request
,
irmaconfig
,
nil
}
// Helper functions
// poll recursively polls the session status until a status different from initialStatus is received.
func
poll
(
initialStatus
server
.
Status
,
transport
*
irma
.
HTTPTransport
,
statuschan
chan
server
.
Status
)
{
// First we wait
<-
time
.
NewTimer
(
pollInterval
)
.
C
// Get session status
var
status
string
if
err
:=
transport
.
Get
(
"status"
,
&
status
);
err
!=
nil
{
_
=
server
.
LogFatal
(
err
)
}
status
=
strings
.
Trim
(
status
,
`"`
)
// If the status has not yet changed, schedule another poll
if
server
.
Status
(
status
)
==
initialStatus
{
go
poll
(
initialStatus
,
transport
,
statuschan
)
}
else
{
logger
.
Trace
(
"Stopped polling, new status "
,
status
)
statuschan
<-
server
.
Status
(
status
)
}
}
func
constructSessionRequest
(
cmd
*
cobra
.
Command
,
conf
*
irma
.
Configuration
)
(
irma
.
RequestorRequest
,
error
)
{
disclose
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"disclose"
)
issue
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"issue"
)
sign
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"sign"
)
message
,
_
:=
cmd
.
Flags
()
.
GetString
(
"message"
)
jsonrequest
,
_
:=
cmd
.
Flags
()
.
GetString
(
"request"
)
if
len
(
disclose
)
==
0
&&
len
(
issue
)
==
0
&&
len
(
sign
)
==
0
&&
message
==
""
{
if
jsonrequest
==
""
{
return
nil
,
errors
.
New
(
"Provide either a complete session request using --request or construct one using the other flags"
)
}
request
,
err
:=
server
.
ParseSessionRequest
(
jsonrequest
)
if
err
!=
nil
{
return
nil
,
err
}
return
request
,
nil
}
if
jsonrequest
!=
""
{
return
nil
,
errors
.
New
(
"Provide either a complete session request using --request or construct one using the other flags"
)
}
if
len
(
sign
)
!=
0
{
if
len
(
disclose
)
!=
0
{
return
nil
,
errors
.
New
(
"cannot combine disclosure and signature sessions, use either --disclose or --sign"
)
}
if
len
(
issue
)
!=
0
{
return
nil
,
errors
.
New
(
"cannot combine issuance and signature sessions, use either --issue or --sign"
)
}
if
message
==
""
{
return
nil
,
errors
.
New
(
"signature sessions require a message to be signed using --message"
)
}
}
var
request
irma
.
RequestorRequest
if
len
(
disclose
)
!=
0
{
disjunctions
,
err
:=
parseDisjunctions
(
disclose
,
conf
)
if
err
!=
nil
{
return
nil
,
err
}
request
=
&
irma
.
ServiceProviderRequest
{
Request
:
&
irma
.
DisclosureRequest
{
BaseRequest
:
irma
.
BaseRequest
{
Type
:
irma
.
ActionDisclosing
},
Content
:
disjunctions
,
},
}
}
if
len
(
sign
)
!=
0
{
disjunctions
,
err
:=
parseDisjunctions
(
sign
,
conf
)
if
err
!=
nil
{
return
nil
,
err
}
request
=
&
irma
.
SignatureRequestorRequest
{
Request
:
&
irma
.
SignatureRequest
{
DisclosureRequest
:
irma
.
DisclosureRequest
{
BaseRequest
:
irma
.
BaseRequest
{
Type
:
irma
.
ActionSigning
},
Content
:
disjunctions
,
},
Message
:
message
,
},
}
}
if
len
(
issue
)
!=
0
{
creds
,
err
:=
parseCredentials
(
issue
,
conf
)
if
err
!=
nil
{
return
nil
,
err
}
disjunctions
,
err
:=
parseDisjunctions
(
disclose
,
conf
)
if
err
!=
nil
{
return
nil
,
err
}
request
=
&
irma
.
IdentityProviderRequest
{
Request
:
&
irma
.
IssuanceRequest
{
BaseRequest
:
irma
.
BaseRequest
{
Type
:
irma
.
ActionIssuing
,
},
Credentials
:
creds
,
Disclose
:
disjunctions
,
},
}
}
return
request
,
nil
}
func
parseCredentials
(
credentialsStr
[]
string
,
conf
*
irma
.
Configuration
)
([]
*
irma
.
CredentialRequest
,
error
)
{
list
:=
make
([]
*
irma
.
CredentialRequest
,
0
,
len
(
credentialsStr
))
for
_
,
credStr
:=
range
credentialsStr
{
parts
:=
strings
.
Split
(
credStr
,
"="
)
if
len
(
parts
)
!=
2
{
return
nil
,
errors
.
New
(
"--issue argument must contain exactly 1 = sign"
)
}
credIdStr
,
attrsStr
:=
parts
[
0
],
parts
[
1
]
credtype
:=
conf
.
CredentialTypes
[
irma
.
NewCredentialTypeIdentifier
(
credIdStr
)]
if
credtype
==
nil
{
return
nil
,
errors
.
New
(
"unknown credential type: "
+
credIdStr
)
}
attrsSlice
:=
strings
.
Split
(
attrsStr
,
","
)
if
len
(
attrsSlice
)
!=
len
(
credtype
.
AttributeTypes
)
{
return
nil
,
errors
.
Errorf
(
"%d attributes required but %d provided for %s"
,
len
(
credtype
.
AttributeTypes
),
len
(
attrsSlice
),
credIdStr
)
}
attrs
:=
make
(
map
[
string
]
string
,
len
(
attrsSlice
))
for
i
,
typ
:=
range
credtype
.
AttributeTypes
{
attrs
[
typ
.
ID
]
=
attrsSlice
[
i
]
}
list
=
append
(
list
,
&
irma
.
CredentialRequest
{
CredentialTypeID
:
irma
.
NewCredentialTypeIdentifier
(
credIdStr
),
Attributes
:
attrs
,
})
}
return
list
,
nil
}
func
parseDisjunctions
(
disjunctionsStr
[]
string
,
conf
*
irma
.
Configuration
)
(
irma
.
AttributeDisjunctionList
,
error
)
{
list
:=
make
(
irma
.
AttributeDisjunctionList
,
0
,
len
(
disjunctionsStr
))
for
_
,
disjunctionStr
:=
range
disjunctionsStr
{
disjunction
:=
&
irma
.
AttributeDisjunction
{}
attrids
:=
strings
.
Split
(
disjunctionStr
,
","
)
for
_
,
attridStr
:=
range
attrids
{
attrid
:=
irma
.
NewAttributeTypeIdentifier
(
attridStr
)
if
conf
.
AttributeTypes
[
attrid
]
==
nil
{
return
nil
,
errors
.
New
(
"unknown attribute: "
+
attridStr
)
}
disjunction
.
Attributes
=
append
(
disjunction
.
Attributes
,
attrid
)
}
disjunction
.
Label
=
disjunction
.
Attributes
[
0
]
.
Name
()
list
=
append
(
list
,
disjunction
)
}
return
list
,
nil
}
func
startServer
(
port
int
)
{
mux
:=
http
.
NewServeMux
()
mux
.
HandleFunc
(
"/"
,
irmaServer
.
HandlerFunc
())
httpServer
=
&
http
.
Server
{
Addr
:
":"
+
strconv
.
Itoa
(
port
),
Handler
:
mux
}
go
func
()
{
err
:=
httpServer
.
ListenAndServe
()
if
err
!=
nil
&&
err
!=
http
.
ErrServerClosed
{
die
(
"Failed to start server"
,
err
)
}
}()
}
func
printQr
(
qr
*
irma
.
Qr
,
noqr
bool
)
error
{
qrBts
,
err
:=
json
.
Marshal
(
qr
)
if
err
!=
nil
{
return
err
}
if
noqr
{
fmt
.
Println
(
string
(
qrBts
))
}
else
{
qrterminal
.
GenerateWithConfig
(
string
(
qrBts
),
qrterminal
.
Config
{
Level
:
qrterminal
.
L
,
Writer
:
os
.
Stdout
,
BlackChar
:
qrterminal
.
BLACK
,
WhiteChar
:
qrterminal
.
WHITE
,
})
}
return
nil
}
func
printSessionResult
(
result
*
server
.
SessionResult
)
{
fmt
.
Println
(
"Session result:"
)
fmt
.
Println
(
prettyprint
(
result
))
}
func
init
()
{
RootCmd
.
AddCommand
(
requestCmd
)
flags
:=
requestCmd
.
Flags
()
flags
.
SortFlags
=
false
addRequestFlags
(
flags
)
}
func
addRequestFlags
(
flags
*
pflag
.
FlagSet
)
{
flags
.
StringP
(
"schemes-path"
,
"s"
,
server
.
DefaultSchemesPath
(),
"path to irma_configuration"
)
flags
.
StringP
(
"authmethod"
,
"a"
,
"none"
,
"Authentication method to server (none, token, rsa, hmac)"
)
flags
.
String
(
"key"
,
""
,
"Key to sign request with"
)
flags
.
String
(
"name"
,
""
,
"Requestor name"
)
flags
.
StringArray
(
"disclose"
,
nil
,
"Add an attribute disjunction (comma-separated)"
)
flags
.
StringArray
(
"issue"
,
nil
,
"Add a credential to issue"
)
flags
.
StringArray
(
"sign"
,
nil
,
"Add an attribute disjunction to signature session"
)
flags
.
String
(
"message"
,
""
,
"Message to sign in signature session"
)
}
irma/cmd/session.go
View file @
0ceea884
package
cmd
import
(
"encoding/json"
"fmt"
"net/http"
"os"
"strconv"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/go-errors/errors"
"github.com/mdp/qrterminal"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/fs"
"github.com/privacybydesign/irmago/server"
"github.com/privacybydesign/irmago/server/irmaserver"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/x-cray/logrus-prefixed-formatter"
)
const
pollInterval
=
1000
*
time
.
Millisecond
...
...
@@ -49,7 +45,7 @@ irma session --server http://localhost:48680 --authmethod token --key mytoken --
flags
:=
cmd
.
Flags
()
if
serverurl
==
""
{
port
,
_
:=
flags
.
GetInt
(
"port"
)
privatekeysPath
,
_
:=
flags
.
GetString
(
"priv
ate
keys"
)
privatekeysPath
,
_
:=
flags
.
GetString
(
"privkeys"
)
result
,
err
=
libraryRequest
(
request
,
irmaconfig
,
port
,
privatekeysPath
,
noqr
)
}
else
{
authmethod
,
_
:=
flags
.
GetString
(
"authmethod"
)
...
...
@@ -146,7 +142,6 @@ func serverRequest(
func
postRequest
(
serverurl
string
,
request
irma
.
RequestorRequest
,
name
,
authmethod
,
key
string
)
(
*
irma
.
Qr
,
*
irma
.
HTTPTransport
,
error
)
{
var
(
err
error
sk
interface
{}
qr
=
&
irma
.
Qr
{}
transport
=
irma
.
NewHTTPTransport
(
serverurl
)
)
...
...
@@ -158,29 +153,8 @@ func postRequest(serverurl string, request irma.RequestorRequest, name, authmeth
transport
.
SetHeader
(
"Authentication"
,
key
)
err
=
transport
.
Post
(
"session"
,
qr
,
request
)
case
"hmac"
,
"rsa"
:
var
(
jwtalg
jwt
.
SigningMethod
jwtstr
string
bts
[]
byte
)
// If the key refers to an existing file, use contents of the file as key
if
bts
,
err
=
fs
.
ReadKey
(
""
,
key
);
err
!=
nil
{
bts
=
[]
byte
(
key
)
}
if
authmethod
==
"hmac"
{
jwtalg
=
jwt
.
SigningMethodHS256
if
sk
,
err
=
fs
.
Base64Decode
(
bts
);
err
!=
nil
{
return
nil
,
nil
,
err
}
}
if
authmethod
==
"rsa"
{
jwtalg
=
jwt
.
SigningMethodRS256
if
sk
,
err
=
jwt
.
ParseRSAPrivateKeyFromPEM
(
bts
);
err
!=
nil
{
return
nil
,
nil
,
err
}
}
if
jwtstr
,
err
=
irma
.
SignRequestorRequest
(
request
,
jwtalg
,
sk
,
name
);
err
!=
nil
{
jwtstr
,
err
:=
signRequest
(
request
,
name
,
authmethod
,
key
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
logger
.
Debug
(
"Session request JWT: "
,
jwtstr
)
...
...
@@ -215,230 +189,13 @@ func configureServer(port int, privatekeysPath string, irmaconfig *irma.Configur
}
func
configure
(
cmd
*
cobra
.
Command
)
(
irma
.
RequestorRequest
,
*
irma
.
Configuration
,
error
)
{
irmaconfigPath
,
err
:=
cmd
.
Flags
()
.
GetString
(
"irmaconf"
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
irmaconfig
,
err
:=
irma
.
NewConfiguration
(
irmaconfigPath
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
if
err
=
irmaconfig
.
ParseFolder
();
err
!=
nil
{
return
nil
,
nil
,
err
}
if
len
(
irmaconfig
.
SchemeManagers
)
==
0
{
if
err
=
irmaconfig
.
DownloadDefaultSchemes
();
err
!=
nil
{
return
nil
,
nil
,
err
}
}
verbosity
,
_
:=
cmd
.
Flags
()
.
GetCount
(
"verbose"
)
logger
=
logrus
.
New
()
logger
.
Level
=
server
.
Verbosity
(
verbosity
)
logger
.
Formatter
=
&
logrus
.
TextFormatter
{
FullTimestamp
:
true
}
logger
.
Formatter
=
&
prefixed
.
TextFormatter
{
FullTimestamp
:
true
}
irma
.
Logger
=
logger
request
,
err
:=
constructSessionRequest
(
cmd
,
irmaconfig
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
logger
.
Debugf
(
"Session request: %s"
,
prettyprint
(
request
))
return
request
,
irmaconfig
,
nil
}
// Helper functions
// poll recursively polls the session status until a status different from initialStatus is received.
func
poll
(
initialStatus
server
.
Status
,
transport
*
irma
.
HTTPTransport
,
statuschan
chan
server
.
Status
)
{
// First we wait
<-
time
.
NewTimer
(
pollInterval
)
.
C
// Get session status
var
status
string
if
err
:=
transport
.
Get
(
"status"
,
&
status
);
err
!=
nil
{
_
=
server
.
LogFatal
(
err
)
}
status
=
strings
.
Trim
(
status
,
`"`
)
// If the status has not yet changed, schedule another poll
if
server
.
Status
(
status
)
==
initialStatus
{
go
poll
(
initialStatus
,
transport
,
statuschan
)
}
else
{
logger
.
Trace
(
"Stopped polling, new status "
,
status
)
statuschan
<-
server
.
Status
(
status
)
}
}
func
constructSessionRequest
(
cmd
*
cobra
.
Command
,
conf
*
irma
.
Configuration
)
(
irma
.
RequestorRequest
,
error
)
{
disclose
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"disclose"
)
issue
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"issue"
)
sign
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"sign"
)
message
,
_
:=
cmd
.
Flags
()
.
GetString
(
"message"
)
jsonrequest
,
_
:=
cmd
.
Flags
()
.
GetString
(
"request"
)
if
len
(
disclose
)
==
0
&&
len
(
issue
)
==
0
&&
len
(
sign
)
==
0
&&
message
==
""
{
if
jsonrequest
==
""
{
return
nil
,
errors
.
New
(
"Provide either a complete session request using --request or construct one using the other flags"
)
}
request
,
err
:=
server
.
ParseSessionRequest
(
jsonrequest
)
if
err
!=
nil
{
return
nil
,
err
}
return
request
,
nil
}
if
jsonrequest
!=
""
{
return
nil
,
errors
.
New
(
"Provide either a complete session request using --request or construct one using the other flags"
)
}
if
len
(
sign
)
!=
0
{
if
len
(
disclose
)
!=
0
{
return
nil
,
errors
.
New
(
"cannot combine disclosure and signature sessions, use either --disclose or --sign"
)
}
if
len
(
issue
)
!=
0
{
return
nil
,
errors
.
New
(
"cannot combine issuance and signature sessions, use either --issue or --sign"
)
}
if
message
==
""
{
return
nil
,
errors
.
New
(
"signature sessions require a message to be signed using --message"
)
}
}
var
request
irma
.
RequestorRequest
if
len
(
disclose
)
!=
0
{
disjunctions
,
err
:=
parseDisjunctions
(
disclose
,
conf
)
if
err
!=
nil
{
return
nil
,
err
}
request
=
&
irma
.
ServiceProviderRequest
{
Request
:
&
irma
.
DisclosureRequest
{
BaseRequest
:
irma
.
BaseRequest
{
Type
:
irma
.
ActionDisclosing
},
Content
:
disjunctions
,
},
}
}
if
len
(
sign
)
!=
0
{
disjunctions
,
err
:=
parseDisjunctions
(
sign
,
conf
)
if
err
!=
nil
{
return
nil
,
err
}
request
=
&
irma
.
SignatureRequestorRequest
{
Request
:
&
irma
.
SignatureRequest
{
DisclosureRequest
:
irma
.
DisclosureRequest
{
BaseRequest
:
irma
.
BaseRequest
{
Type
:
irma
.
ActionSigning
},
Content
:
disjunctions
,
},
Message
:
message
,
},
}
}
if
len
(
issue
)
!=
0
{
creds
,
err
:=
parseCredentials
(
issue
,
conf
)
if
err
!=
nil
{
return
nil
,
err
}
disjunctions
,
err
:=
parseDisjunctions
(
disclose
,
conf
)
if
err
!=
nil
{
return
nil
,
err
}
request
=
&
irma
.
IdentityProviderRequest
{
Request
:
&
irma
.
IssuanceRequest
{
BaseRequest
:
irma
.
BaseRequest
{
Type
:
irma
.
ActionIssuing
,
},
Credentials
:
creds
,
Disclose
:
disjunctions
,
},
}
}
return
request
,
nil
}
func
parseCredentials
(
credentialsStr
[]
string
,
conf
*
irma
.
Configuration
)
([]
*
irma
.
CredentialRequest
,
error
)
{
list
:=
make
([]
*
irma
.
CredentialRequest
,
0
,
len
(
credentialsStr
))
for
_
,
credStr
:=
range
credentialsStr
{
parts
:=
strings
.
Split
(
credStr
,
"="
)
if
len
(
parts
)
!=
2
{
return
nil
,
errors
.
New
(
"--issue argument must contain exactly 1 = sign"
)
}
credIdStr
,
attrsStr
:=
parts
[
0
],
parts
[
1
]
credtype
:=
conf
.
CredentialTypes
[
irma
.
NewCredentialTypeIdentifier
(
credIdStr
)]
if
credtype
==
nil
{
return
nil
,
errors
.
New
(
"unknown credential type: "
+
credIdStr
)
}
attrsSlice
:=
strings
.
Split
(
attrsStr
,
","
)
if
len
(
attrsSlice
)
!=
len
(
credtype
.
AttributeTypes
)
{
return
nil
,
errors
.
Errorf
(
"%d attributes required but %d provided for %s"
,
len
(
credtype
.
AttributeTypes
),
len
(
attrsSlice
),
credIdStr
)
}
attrs
:=
make
(
map
[
string
]
string
,
len
(
attrsSlice
))
for
i
,
typ
:=
range
credtype
.
AttributeTypes
{
attrs
[
typ
.
ID
]
=
attrsSlice
[
i
]
}
list
=
append
(
list
,
&
irma
.
CredentialRequest
{
CredentialTypeID
:
irma
.
NewCredentialTypeIdentifier
(
credIdStr
),
Attributes
:
attrs
,
})
}
return
list
,
nil
}
func
parseDisjunctions
(
disjunctionsStr
[]
string
,
conf
*
irma
.
Configuration
)
(
irma
.
AttributeDisjunctionList
,
error
)
{
list
:=
make
(
irma
.
AttributeDisjunctionList
,
0
,
len
(
disjunctionsStr
))
for
_
,
disjunctionStr
:=
range
disjunctionsStr
{
disjunction
:=
&
irma
.
AttributeDisjunction
{}
attrids
:=
strings
.
Split
(
disjunctionStr
,
","
)
for
_
,
attridStr
:=
range
attrids
{
attrid
:=
irma
.
NewAttributeTypeIdentifier
(
attridStr
)
if
conf
.
AttributeTypes
[
attrid
]
==
nil
{
return
nil
,
errors
.
New
(
"unknown attribute: "
+
attridStr
)
}
disjunction
.
Attributes
=
append
(
disjunction
.
Attributes
,
attrid
)
}
disjunction
.
Label
=
disjunction
.
Attributes
[
0
]
.
Name
()
list
=
append
(
list
,
disjunction
)
}
return
list
,
nil
}
func
startServer
(
port
int
)
{
mux
:=
http
.
NewServeMux
()
mux
.
HandleFunc
(
"/"
,
irmaServer
.
HandlerFunc
())
httpServer
=
&
http
.
Server
{
Addr
:
":"
+
strconv
.
Itoa
(
port
),
Handler
:
mux
}
go
func
()
{
err
:=
httpServer
.
ListenAndServe
()
if
err
!=
nil
&&
err
!=
http
.
ErrServerClosed
{
die
(
"Failed to start server"
,
err
)
}
}()
}
func
printQr
(
qr
*
irma
.
Qr
,
noqr
bool
)
error
{
qrBts
,
err
:=
json
.
Marshal
(
qr
)
if
err
!=
nil
{
return
err
}
if
noqr
{
fmt
.
Println
(
string
(
qrBts
))
}
else
{
qrterminal
.
GenerateWithConfig
(
string
(
qrBts
),
qrterminal
.
Config
{
Level
:
qrterminal
.
L
,
Writer
:
os
.
Stdout
,
BlackChar
:
qrterminal
.
BLACK
,
WhiteChar
:
qrterminal
.
WHITE
,
})
}
return
nil
}