Commit 35ba6bb1 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Support scheme auto updating

parent 34fafecc
......@@ -32,6 +32,7 @@ import (
"github.com/dgrijalva/jwt-go"
"github.com/go-errors/errors"
"github.com/jasonlvhit/gocron"
"github.com/privacybydesign/gabi"
"github.com/privacybydesign/gabi/big"
"github.com/privacybydesign/irmago/internal/fs"
......@@ -61,6 +62,7 @@ type Configuration struct {
initialized bool
assets string
readOnly bool
cronchan chan bool
}
// ConfigurationFileHash encodes the SHA256 hash of an authenticated
......@@ -1179,6 +1181,41 @@ func (conf *Configuration) UpdateSchemeManager(id SchemeManagerIdentifier, downl
return
}
func (conf *Configuration) updateSchemes() error {
for id := range conf.SchemeManagers {
Logger.WithField("scheme", id).Info("Auto-updating scheme")
if err := conf.UpdateSchemeManager(id, nil); err != nil {
return err
}
}
return nil
}
func (conf *Configuration) AutoUpdateSchemes(interval uint) {
Logger.Infof("Updating schemes every %d minutes", interval)
gocron.Every(uint64(interval)).Minutes().Do(func() {
if err := conf.updateSchemes(); err != nil {
Logger.Error("Scheme autoupdater failed: ")
if e, ok := err.(*errors.Error); ok {
Logger.Error(e.ErrorStack())
} else {
Logger.Errorf("%s %s", reflect.TypeOf(err).String(), err.Error())
}
}
})
go gocron.RunAll() // Perform updates now
conf.cronchan = gocron.Start() // Schedule updates (first one in interval minutes from now)
}
func (conf *Configuration) StopAutoUpdateSchemes() {
if conf.cronchan != nil {
Logger.Info("Stopped scheme autoupdater")
conf.cronchan <- true
}
}
// Methods containing consistency checks on irma_configuration
func (conf *Configuration) checkIssuer(manager *SchemeManager, issuer *Issuer, dir string) error {
......
......@@ -29,7 +29,9 @@ type Configuration struct {
// Path to writable dir to write cache to (only used if IrmaConfiguration is not given)
CachePath string `json:"cachepath" mapstructure:"cachepath"`
// Whether or not to download default IRMA schemes if the specified irma_configuration is empty
DownloadDefaultSchemes bool
DownloadDefaultSchemes bool `json:"downloadschemes" mapstructure:"downloadschemes"`
// Update all schemes every x minutes (0 to disable)
SchemeUpdateInterval int `json:"schemeupdate" mapstructure:"schemeupdate"`
// Path to issuer private keys to parse
IssuerPrivateKeysPath string `json:"privatekeys" mapstructure:"privatekeys"`
// Issuer private keys
......
......@@ -59,6 +59,12 @@ func Initialize(configuration *server.Configuration) error {
}
}
if conf.SchemeUpdateInterval != 0 {
conf.IrmaConfiguration.AutoUpdateSchemes(uint(conf.SchemeUpdateInterval))
} else {
conf.Logger.Warn("Scheme updating disabled")
}
if conf.IssuerPrivateKeys == nil {
conf.IssuerPrivateKeys = make(map[irma.IssuerIdentifier]*gabi.PrivateKey)
}
......
......@@ -5,6 +5,7 @@ import (
"sync"
"time"
"github.com/jasonlvhit/gocron"
"github.com/privacybydesign/gabi"
"github.com/privacybydesign/gabi/big"
"github.com/privacybydesign/irmago"
......@@ -58,7 +59,11 @@ var (
func init() {
rand.Seed(time.Now().UnixNano())
go sessions.deleteExpired()
gocron.Every(10).Seconds().Do(func() {
sessions.deleteExpired()
})
gocron.Start()
}
func (s *memorySessionStore) get(token string) *session {
......@@ -78,6 +83,8 @@ func (s *memorySessionStore) update(token string, session *session) {
}
func (s memorySessionStore) deleteExpired() {
conf.Logger.Trace("Deleting expired sessions")
// First check which sessions have expired
// We don't need a write lock for this yet, so postpone that for actual deleting
s.RLock()
......@@ -110,11 +117,6 @@ func (s memorySessionStore) deleteExpired() {
delete(s.m, token)
}
s.Unlock()
// Schedule next run
time.AfterFunc(expiryTicker, func() {
s.deleteExpired()
})
}
var one *big.Int = big.NewInt(1)
......
......@@ -73,6 +73,7 @@ func setFlags(cmd *cobra.Command) error {
flags.StringP("irmaconf", "i", "", "path to irma_configuration")
flags.StringP("privatekeys", "k", "", "path to IRMA private keys")
flags.String("cachepath", cachepath, "Directory for writing cache files to")
flags.Uint("schemeupdate", 60, "Update IRMA schemes every x minutes (0 to disable)")
flags.StringP("jwtissuer", "j", "irmaserver", "JWT issuer")
flags.StringP("jwtprivatekey", "w", "", "JWT private key or path to it")
flags.Int("maxrequestage", 300, "Max age in seconds of a session request JWT")
......@@ -138,6 +139,7 @@ func configure() error {
IssuerPrivateKeysPath: viper.GetString("privatekeys"),
CachePath: viper.GetString("cachepath"),
URL: viper.GetString("url"),
SchemeUpdateInterval: viper.GetInt("schemeupdate"),
Logger: logger,
},
ListenAddress: viper.GetString("listenaddr"),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment