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
91166ae1
Commit
91166ae1
authored
Dec 19, 2018
by
Sietse Ringers
Browse files
Document server and library api
parent
b77e2db6
Changes
6
Hide whitespace changes
Inline
Side-by-side
server/api.go
View file @
91166ae1
...
...
@@ -13,16 +13,26 @@ import (
var
Logger
*
logrus
.
Logger
=
logrus
.
StandardLogger
()
// Configuration contains configuration for the irmarequestor library and irmaserver.
type
Configuration
struct
{
IrmaConfigurationPath
string
`json:"irmaconf" mapstructure:"irmaconf"`
IssuerPrivateKeysPath
string
`json:"privatekeys" mapstructure:"privatekeys"`
CachePath
string
`json:"cachepath" mapstructure:"cachepath"`
Url
string
`json:"url" mapstructure:"url"`
Logger
*
logrus
.
Logger
`json:"-"`
IssuerPrivateKeys
map
[
irma
.
IssuerIdentifier
]
*
gabi
.
PrivateKey
`json:"-"`
IrmaConfiguration
*
irma
.
Configuration
`json:"-"`
// irma_configuration. If not given, this will be popupated using IrmaConfigurationPath.
IrmaConfiguration
*
irma
.
Configuration
`json:"-"`
// Path to schemes to parse (only used if IrmaConfiguration is not given)
IrmaConfigurationPath
string
`json:"irmaconf" mapstructure:"irmaconf"`
// Path to writable dir to write cache to (only used if IrmaConfiguration is not give)
CachePath
string
`json:"cachepath" mapstructure:"cachepath"`
// Path to issuer private keys to parse
IssuerPrivateKeysPath
string
`json:"privatekeys" mapstructure:"privatekeys"`
// Issuer private keys
IssuerPrivateKeys
map
[
irma
.
IssuerIdentifier
]
*
gabi
.
PrivateKey
`json:"-"`
// URL at which the IRMA app can reach this server during sessions
URL
string
`json:"url" mapstructure:"url"`
// Logging
Logger
*
logrus
.
Logger
`json:"-"`
}
// SessionResult contains session information such as the session status, type, possible errors,
// and disclosed attributes or attribute-based signature if appropriate to the session type.
type
SessionResult
struct
{
Token
string
Status
Status
...
...
@@ -44,6 +54,7 @@ const (
StatusTimeout
Status
=
"TIMEOUT"
// Session timed out
)
// RemoteError converts an error and an explaining message to an *irma.RemoteError.
func
RemoteError
(
err
Error
,
message
string
)
*
irma
.
RemoteError
{
stack
:=
string
(
debug
.
Stack
())
Logger
.
Errorf
(
"Error: %d %s %s
\n
%s"
,
err
.
Status
,
err
.
Type
,
message
,
stack
)
...
...
@@ -56,6 +67,8 @@ func RemoteError(err Error, message string) *irma.RemoteError {
}
}
// JsonResponse JSON-marshals the specified object or error
// and returns it along with a suitable HTTP status code
func
JsonResponse
(
v
interface
{},
err
*
irma
.
RemoteError
)
(
int
,
[]
byte
)
{
msg
:=
v
status
:=
http
.
StatusOK
...
...
@@ -71,14 +84,17 @@ func JsonResponse(v interface{}, err *irma.RemoteError) (int, []byte) {
return
status
,
b
}
// WriteError writes the specified error and explaining message as JSON to the http.ResponseWriter.
func
WriteError
(
w
http
.
ResponseWriter
,
err
Error
,
msg
string
)
{
WriteResponse
(
w
,
nil
,
RemoteError
(
err
,
msg
))
}
// WriteJson writes the specified object as JSON to the http.ResponseWriter.
func
WriteJson
(
w
http
.
ResponseWriter
,
object
interface
{})
{
WriteResponse
(
w
,
object
,
nil
)
}
// WriteResponse writes the specified object or error as JSON to the http.ResponseWriter.
func
WriteResponse
(
w
http
.
ResponseWriter
,
object
interface
{},
rerr
*
irma
.
RemoteError
)
{
status
,
bts
:=
JsonResponse
(
object
,
rerr
)
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
...
...
@@ -86,12 +102,16 @@ func WriteResponse(w http.ResponseWriter, object interface{}, rerr *irma.RemoteE
w
.
Write
(
bts
)
}
// WriteString writes the specified string to the http.ResponseWriter.
func
WriteString
(
w
http
.
ResponseWriter
,
str
string
)
{
w
.
Header
()
.
Set
(
"Content-Type"
,
"text/plain"
)
w
.
WriteHeader
(
http
.
StatusOK
)
w
.
Write
([]
byte
(
str
))
}
// ParseSessionRequest tries to parse the specified bytes as an
// disclosure request, a signature request, and an issuance request, in that order.
// Returns an error if none of the attempts work.
func
ParseSessionRequest
(
bts
[]
byte
)
(
request
irma
.
SessionRequest
,
err
error
)
{
request
=
&
irma
.
DisclosureRequest
{}
if
err
=
irma
.
UnmarshalValidate
(
bts
,
request
);
err
==
nil
{
...
...
server/backend/api.go
View file @
91166ae1
...
...
@@ -93,9 +93,9 @@ func Initialize(configuration *server.Configuration) error {
}
}
if
conf
.
U
rl
!=
""
{
if
!
strings
.
HasSuffix
(
conf
.
U
rl
,
"/"
)
{
conf
.
U
rl
=
conf
.
U
rl
+
"/"
if
conf
.
U
RL
!=
""
{
if
!
strings
.
HasSuffix
(
conf
.
U
RL
,
"/"
)
{
conf
.
U
RL
=
conf
.
U
RL
+
"/"
}
}
else
{
conf
.
Logger
.
Warn
(
"No url parameter specified in configuration; unless an url is elsewhere prepended in the QR, the IRMA client will not be able to connect"
)
...
...
@@ -128,7 +128,7 @@ func StartSession(request irma.SessionRequest) (*irma.Qr, string, error) {
conf
.
Logger
.
Infof
(
"%s session started, token %s"
,
action
,
session
.
token
)
return
&
irma
.
Qr
{
Type
:
action
,
URL
:
conf
.
U
rl
+
session
.
token
,
URL
:
conf
.
U
RL
+
session
.
token
,
},
session
.
token
,
nil
}
...
...
server/errors.go
View file @
91166ae1
package
server
// Error represents an error that occured during an IRMA sessions.
type
Error
struct
{
Type
ErrorType
`json:"error"`
Status
int
`json:"status"`
...
...
server/irmarequestor/main.go
View file @
91166ae1
...
...
@@ -9,14 +9,20 @@ import (
"github.com/privacybydesign/irmago/server/backend"
)
// SessionHandler is a function that can handle a session result
// once an IRMA session has completed.
type
SessionHandler
func
(
*
server
.
SessionResult
)
var
handlers
=
make
(
map
[
string
]
SessionHandler
)
// Initialize sets configuration.
func
Initialize
(
configuration
*
server
.
Configuration
)
error
{
return
backend
.
Initialize
(
configuration
)
}
// StartSession starts an IRMA session, running the handler on completion, if specified.
// The session token (the second return parameter) can be used in GetSessionResult()
// and CancelSession().
func
StartSession
(
request
irma
.
SessionRequest
,
handler
SessionHandler
)
(
*
irma
.
Qr
,
string
,
error
)
{
qr
,
token
,
err
:=
backend
.
StartSession
(
request
)
if
err
!=
nil
{
...
...
@@ -28,17 +34,28 @@ func StartSession(request irma.SessionRequest, handler SessionHandler) (*irma.Qr
return
qr
,
token
,
nil
}
// GetSessionResult retrieves the result of the specified IRMA session.
func
GetSessionResult
(
token
string
)
*
server
.
SessionResult
{
return
backend
.
GetSessionResult
(
token
)
}
// CancelSession cancels the specified IRMA session.
func
CancelSession
(
token
string
)
error
{
return
backend
.
CancelSession
(
token
)
}
func
HttpHandlerFunc
(
prefix
string
)
http
.
HandlerFunc
{
if
len
(
prefix
)
!=
0
&&
prefix
[
0
]
!=
'/'
{
prefix
=
"/"
+
prefix
// HttpHandlerFunc returns a http.HandlerFunc that handles the IRMA protocol
// with IRMA apps. Initialize() must be called before this.
//
// Example usage:
// http.HandleFunc("/irma/", irmarequestor.HttpHandlerFunc("/irma/"))
//
// The IRMA app can then perform IRMA sessions at https://example.com/irma.
// Note that the two strings must be equal, i.e. you must pass the pattern at which
// you register the handler.
func
HttpHandlerFunc
(
pattern
string
)
http
.
HandlerFunc
{
if
len
(
pattern
)
!=
0
&&
pattern
[
0
]
!=
'/'
{
pattern
=
"/"
+
pattern
}
return
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
var
message
[]
byte
...
...
@@ -47,7 +64,7 @@ func HttpHandlerFunc(prefix string) http.HandlerFunc {
w
.
WriteHeader
(
http
.
StatusInternalServerError
)
return
}
path
:=
r
.
URL
.
Path
[
len
(
p
refix
)
:
]
path
:=
r
.
URL
.
Path
[
len
(
p
attern
)
:
]
status
,
response
,
result
:=
backend
.
HandleProtocolMessage
(
path
,
r
.
Method
,
r
.
Header
,
message
)
w
.
WriteHeader
(
status
)
w
.
Write
(
response
)
...
...
server/irmaserver/cmd/main.go
View file @
91166ae1
...
...
@@ -144,7 +144,7 @@ func configure() error {
IrmaConfigurationPath
:
viper
.
GetString
(
"irmaconf"
),
IssuerPrivateKeysPath
:
viper
.
GetString
(
"privatekeys"
),
CachePath
:
viper
.
GetString
(
"cachepath"
),
U
rl
:
viper
.
GetString
(
"url"
),
U
RL
:
viper
.
GetString
(
"url"
),
Logger
:
logger
,
},
Port
:
viper
.
GetInt
(
"port"
),
...
...
@@ -158,7 +158,7 @@ func configure() error {
}
// replace "port" in url with actual port
replace
:=
"$1:"
+
strconv
.
Itoa
(
conf
.
Port
)
conf
.
U
rl
=
string
(
regexp
.
MustCompile
(
"(https?://[^/]*):port"
)
.
ReplaceAll
([]
byte
(
conf
.
U
rl
),
[]
byte
(
replace
)))
conf
.
U
RL
=
string
(
regexp
.
MustCompile
(
"(https?://[^/]*):port"
)
.
ReplaceAll
([]
byte
(
conf
.
U
RL
),
[]
byte
(
replace
)))
// Handle global permissions
if
len
(
viper
.
GetStringMap
(
"permissions"
))
>
0
{
// First read config file
...
...
server/irmaserver/conf.go
View file @
91166ae1
...
...
@@ -152,11 +152,11 @@ func (conf *Configuration) initialize() error {
}
}
if
conf
.
U
rl
!=
""
{
if
!
strings
.
HasSuffix
(
conf
.
U
rl
,
"/"
)
{
conf
.
U
rl
=
conf
.
U
rl
+
"/"
if
conf
.
U
RL
!=
""
{
if
!
strings
.
HasSuffix
(
conf
.
U
RL
,
"/"
)
{
conf
.
U
RL
=
conf
.
U
RL
+
"/"
}
conf
.
U
rl
=
conf
.
U
rl
+
"irma/"
conf
.
U
RL
=
conf
.
U
RL
+
"irma/"
}
return
nil
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment