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
8c63cec3
Commit
8c63cec3
authored
Dec 12, 2018
by
Sietse Ringers
Browse files
Make server configurable using flags, env vars, and config file
Co-authored-by:
Confiks
<
confiks@scriptbase.org
>
parent
4df6271b
Changes
5
Hide whitespace changes
Inline
Side-by-side
Gopkg.toml
View file @
8c63cec3
...
@@ -55,3 +55,7 @@
...
@@ -55,3 +55,7 @@
[prune]
[prune]
go-tests
=
true
go-tests
=
true
unused-packages
=
true
unused-packages
=
true
[[constraint]]
name
=
"github.com/spf13/viper"
version
=
"1.3.1"
internal/sessiontest/server_test.go
View file @
8c63cec3
...
@@ -40,6 +40,7 @@ var IrmaServerConfiguration = &irmaserver.Configuration{
...
@@ -40,6 +40,7 @@ var IrmaServerConfiguration = &irmaserver.Configuration{
IrmaConfigurationPath
:
filepath
.
Join
(
testdata
,
"irma_configuration"
),
IrmaConfigurationPath
:
filepath
.
Join
(
testdata
,
"irma_configuration"
),
IssuerPrivateKeysPath
:
filepath
.
Join
(
testdata
,
"privatekeys"
),
IssuerPrivateKeysPath
:
filepath
.
Join
(
testdata
,
"privatekeys"
),
},
},
DisableRequestorAuthentication
:
true
,
Port
:
48682
,
Port
:
48682
,
}
}
...
@@ -50,7 +51,7 @@ var JwtServerConfiguration = &irmaserver.Configuration{
...
@@ -50,7 +51,7 @@ var JwtServerConfiguration = &irmaserver.Configuration{
IssuerPrivateKeysPath
:
filepath
.
Join
(
testdata
,
"privatekeys"
),
IssuerPrivateKeysPath
:
filepath
.
Join
(
testdata
,
"privatekeys"
),
},
},
Port
:
48682
,
Port
:
48682
,
AuthenticateRequestors
:
tru
e
,
DisableRequestorAuthentication
:
fals
e
,
GlobalPermissions
:
irmaserver
.
Permissions
{
GlobalPermissions
:
irmaserver
.
Permissions
{
Disclosing
:
[]
string
{
"*"
},
Disclosing
:
[]
string
{
"*"
},
Signing
:
[]
string
{
"*"
},
Signing
:
[]
string
{
"*"
},
...
...
server/api.go
View file @
8c63cec3
...
@@ -14,13 +14,11 @@ import (
...
@@ -14,13 +14,11 @@ import (
var
Logger
*
logrus
.
Logger
=
logrus
.
StandardLogger
()
var
Logger
*
logrus
.
Logger
=
logrus
.
StandardLogger
()
type
Configuration
struct
{
type
Configuration
struct
{
IrmaConfigurationPath
string
IrmaConfigurationPath
string
`json:"irmaconf" mapstructure:"irmaconf"`
IssuerPrivateKeysPath
string
IssuerPrivateKeysPath
string
`json:"privatekeys" mapstructure:"privatekeys"`
Logger
*
logrus
.
Logger
`json:"-"`
Logger
*
logrus
.
Logger
`json:"-"`
IssuerPrivateKeys
map
[
irma
.
IssuerIdentifier
]
*
gabi
.
PrivateKey
`json:"-"`
IrmaConfiguration
*
irma
.
Configuration
`json:"-"`
IssuerPrivateKeys
map
[
irma
.
IssuerIdentifier
]
*
gabi
.
PrivateKey
`json:"-"`
IrmaConfiguration
*
irma
.
Configuration
`json:"-"`
}
}
type
SessionResult
struct
{
type
SessionResult
struct
{
...
...
server/irmaserver/cmd/main.go
View file @
8c63cec3
package
main
package
main
import
(
import
(
"encoding/json"
"fmt"
"fmt"
"os"
"os"
"strconv"
"github.com/Sirupsen/logrus"
"github.com/go-errors/errors"
"github.com/go-errors/errors"
"github.com/privacybydesign/irmago/server"
"github.com/privacybydesign/irmago/server"
"github.com/privacybydesign/irmago/server/irmaserver"
"github.com/privacybydesign/irmago/server/irmaserver"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
)
var
conf
*
irmaserver
.
Configuration
func
main
()
{
func
main
()
{
var
err
error
var
cmd
=
&
cobra
.
Command
{
defer
func
()
{
Use
:
"irmaserver"
,
if
err
!=
nil
{
Short
:
"IRMA server for verifying and issuing attributes"
,
fmt
.
Println
(
err
.
Error
())
Run
:
func
(
command
*
cobra
.
Command
,
args
[]
string
)
{
os
.
Exit
(
1
)
if
err
:=
configure
();
err
!=
nil
{
}
die
(
errors
.
WrapPrefix
(
err
,
"Failed to configure server"
,
0
))
os
.
Exit
(
0
)
}
}()
if
err
:=
irmaserver
.
Start
(
conf
);
err
!=
nil
{
die
(
errors
.
WrapPrefix
(
err
,
"Failed to start server"
,
0
))
}
},
}
if
len
(
os
.
Args
)
!=
3
{
if
err
:=
setFlags
(
cmd
);
err
!=
nil
{
err
=
errors
.
New
(
"Usage: irmaserver port path"
)
die
(
errors
.
WrapPrefix
(
err
,
"Failed to attach flags"
,
0
))
return
}
}
port
,
err
:=
strconv
.
Atoi
(
os
.
Args
[
1
])
if
err
:=
cmd
.
Execute
();
err
!=
nil
{
if
err
!=
nil
{
die
(
errors
.
WrapPrefix
(
err
,
"Failed to execute command"
,
0
))
err
=
errors
.
New
(
"First argument must be an integer"
)
return
}
}
}
func
die
(
err
*
errors
.
Error
)
{
fmt
.
Println
(
err
.
Error
())
fmt
.
Println
()
fmt
.
Println
(
string
(
err
.
Stack
()))
os
.
Exit
(
1
)
}
func
setFlags
(
cmd
*
cobra
.
Command
)
error
{
flags
:=
cmd
.
Flags
()
flags
.
SortFlags
=
false
flags
.
StringP
(
"irmaconf"
,
"i"
,
"./irma_configuration"
,
"path to irma_configuration"
)
flags
.
StringP
(
"privatekeys"
,
"k"
,
""
,
"path to IRMA private keys"
)
flags
.
StringP
(
"jwtissuer"
,
"j"
,
"irmaserver"
,
"JWT issuer"
)
flags
.
StringP
(
"jwtprivatekey"
,
"w"
,
""
,
"JWT private key or path to it"
)
flags
.
IntP
(
"port"
,
"p"
,
8088
,
"Port at which to listen"
)
flags
.
Bool
(
"noauth"
,
false
,
"Whether or not to authenticate requestors"
)
flags
.
String
(
"permissions"
,
""
,
"Default permissions"
)
flags
.
String
(
"requestors"
,
""
,
"Requestor configuration (in JSON)"
)
return
viper
.
BindPFlags
(
flags
)
}
func
configure
()
error
{
fmt
.
Println
(
"Configuring"
)
// Environment variables
viper
.
SetEnvPrefix
(
"IRMASERVER"
)
viper
.
AutomaticEnv
()
err
=
irmaserver
.
Start
(
&
irmaserver
.
Configuration
{
// Configuration file
viper
.
SetConfigName
(
"config"
)
viper
.
AddConfigPath
(
"."
)
viper
.
AddConfigPath
(
"/etc/irmaserver/"
)
viper
.
AddConfigPath
(
"$HOME/.irmaserver"
)
if
err
:=
viper
.
ReadInConfig
();
err
!=
nil
{
fmt
.
Printf
(
"No configuration file found"
)
}
else
{
fmt
.
Println
(
"Config file: "
,
viper
.
ConfigFileUsed
())
}
// Read configuration from flags and/or environmental variables
conf
=
&
irmaserver
.
Configuration
{
Configuration
:
&
server
.
Configuration
{
Configuration
:
&
server
.
Configuration
{
IrmaConfigurationPath
:
os
.
Args
[
2
],
IrmaConfigurationPath
:
viper
.
GetString
(
"irmaconf"
),
IssuerPrivateKeysPath
:
viper
.
GetString
(
"privatekeys"
),
Logger
:
logrus
.
StandardLogger
(),
},
},
Port
:
port
,
Port
:
viper
.
GetInt
(
"port"
),
})
DisableRequestorAuthentication
:
viper
.
GetBool
(
"noauth"
),
Requestors
:
make
(
map
[
string
]
irmaserver
.
Requestor
),
GlobalPermissions
:
irmaserver
.
Permissions
{},
JwtIssuer
:
viper
.
GetString
(
"jwtissuer"
),
JwtPrivateKey
:
viper
.
GetString
(
"jwtprivatekey"
),
}
// Handle special permissions
permissions
:=
viper
.
GetString
(
"permissions"
)
if
len
(
permissions
)
>
0
{
if
err
:=
json
.
Unmarshal
([]
byte
(
permissions
),
&
conf
.
GlobalPermissions
);
err
!=
nil
{
return
errors
.
WrapPrefix
(
err
,
"Failed to parse permissions"
,
0
)
}
}
else
if
len
(
viper
.
GetStringMap
(
"permissions"
))
>
0
{
if
err
:=
viper
.
UnmarshalKey
(
"permissions"
,
&
conf
.
GlobalPermissions
);
err
!=
nil
{
return
errors
.
WrapPrefix
(
err
,
"Failed to unmarshal permissions"
,
0
)
}
}
requestors
:=
viper
.
GetString
(
"requestors"
)
if
len
(
requestors
)
>
0
{
if
err
:=
json
.
Unmarshal
([]
byte
(
requestors
),
&
conf
.
Requestors
);
err
!=
nil
{
return
errors
.
WrapPrefix
(
err
,
"Failed to parse requestors"
,
0
)
}
}
else
if
len
(
viper
.
GetStringMap
(
"requestors"
))
>
0
{
if
err
:=
viper
.
UnmarshalKey
(
"requestors"
,
&
conf
.
Requestors
);
err
!=
nil
{
return
errors
.
WrapPrefix
(
err
,
"Failed to unmarshal requestors"
,
0
)
}
}
bts
,
_
:=
json
.
MarshalIndent
(
conf
,
""
,
" "
)
fmt
.
Println
(
string
(
bts
))
fmt
.
Println
(
"Done configuring"
)
return
nil
}
}
server/irmaserver/conf.go
View file @
8c63cec3
...
@@ -13,37 +13,42 @@ import (
...
@@ -13,37 +13,42 @@ import (
)
)
type
Configuration
struct
{
type
Configuration
struct
{
*
server
.
Configuration
*
server
.
Configuration
`mapstructure:",squash"`
Port
int
// Whether or not incoming session requests should be authenticated. If false, anyone
// Whether or not incoming session requests should be authenticated. If false, anyone
// can submit session requests. If true, the request is first authenticated against the
// can submit session requests. If true, the request is first authenticated against the
// server configuration before the server accepts it.
// server configuration before the server accepts it.
AuthenticateRequestors
bool
DisableRequestorAuthentication
bool
`json:"noauth" mapstructure:"noauth"`
Requestors
map
[
string
]
Requestor
// Requestor-specific permission and authentication configuration
// Port to listen at
GlobalPermissions
Permissions
// Disclosing, signing or issuance permissions that apply to all requestors
Port
int
`json:"port" mapstructure:"port"`
// Requestor-specific permission and authentication configuration
JwtIssuer
string
// Used in the "iss" field of result JWTs from /result-jwt and /getproof
RequestorsString
string
`json:"-" mapstructure:"requestors"`
JwtPrivateKey
string
// Private key to sign result JWTs with. If absent, /result-jwt and /getproof are disabled.
Requestors
map
[
string
]
Requestor
`json:"requestors"`
// Disclosing, signing or issuance permissions that apply to all requestors
GlobalPermissionsString
string
`json:"-" mapstructure:"permissions"`
GlobalPermissions
Permissions
`json:"permissions"`
// Used in the "iss" field of result JWTs from /result-jwt and /getproof
JwtIssuer
string
`json:"jwtissuer" mapstructure:"jwtissuer"`
// Private key to sign result JWTs with. If absent, /result-jwt and /getproof are disabled.
JwtPrivateKey
string
`json:"jwtprivatekey" mapstructure:"jwtprivatekey"`
jwtPrivateKey
*
rsa
.
PrivateKey
jwtPrivateKey
*
rsa
.
PrivateKey
}
}
// Permissions specify which attributes or credential a requestor may verify or issue.
// Permissions specify which attributes or credential a requestor may verify or issue.
type
Permissions
struct
{
type
Permissions
struct
{
Disclosing
[]
string
Disclosing
[]
string
`json:"disclosing" mapstructure:"disclosing"`
Signing
[]
string
Signing
[]
string
`json:"signing" mapstructure:"signing"`
Issuing
[]
string
Issuing
[]
string
`json:"issuing" mapstructure:"issuing"`
}
}
// Requestor contains all configuration (disclosure or verification permissions and authentication)
// Requestor contains all configuration (disclosure or verification permissions and authentication)
// for a requestor.
// for a requestor.
type
Requestor
struct
{
type
Requestor
struct
{
Permissions
Permissions
`mapstructure:",squash"`
AuthenticationMethod
AuthenticationMethod
AuthenticationMethod
AuthenticationMethod
`json:"authmethod" mapstructure:"authmethod"`
AuthenticationKey
string
AuthenticationKey
string
`json:"key" mapstructure:"key"`
}
}
// CanIssue returns whether or not the specified requestor may issue the specified credentials.
// CanIssue returns whether or not the specified requestor may issue the specified credentials.
...
@@ -109,7 +114,7 @@ func (conf *Configuration) initialize() error {
...
@@ -109,7 +114,7 @@ func (conf *Configuration) initialize() error {
return
err
return
err
}
}
if
!
conf
.
AuthenticateRequestors
{
if
conf
.
DisableRequestorAuthentication
{
conf
.
Logger
.
Warn
(
"Authentication of incoming session requests disabled"
)
conf
.
Logger
.
Warn
(
"Authentication of incoming session requests disabled"
)
authenticators
=
map
[
AuthenticationMethod
]
Authenticator
{
AuthenticationMethodNone
:
NilAuthenticator
{}}
authenticators
=
map
[
AuthenticationMethod
]
Authenticator
{
AuthenticationMethodNone
:
NilAuthenticator
{}}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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