Commit 4c99292c authored by Sietse Ringers's avatar Sietse Ringers

feat: periodically delete revocation issuance records of expired credentials

parent 27c3384e
......@@ -10,6 +10,7 @@ import (
"github.com/jinzhu/gorm"
"github.com/privacybydesign/gabi"
"github.com/privacybydesign/gabi/big"
"github.com/privacybydesign/gabi/revocation"
irma "github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/test"
......@@ -318,6 +319,32 @@ func TestRevocationAll(t *testing.T) {
require.NoError(t, err)
require.Equal(t, 2, len(update.Events))
})
t.Run("DeleteExpiredIssuanceRecords", func(t *testing.T) {
startRevocationServer(t, true)
// Insert expired issuance record
rev := revocationConfiguration.IrmaConfiguration.Revocation
require.NoError(t, rev.AddIssuanceRecord(&irma.IssuanceRecord{
Key: "1",
CredType: revocationTestCred,
PKCounter: revocationPkCounter,
Attr: (*irma.RevocationAttribute)(big.NewInt(42)),
Issued: time.Now().Add(-2 * time.Hour).UnixNano(),
ValidUntil: time.Now().Add(-1 * time.Hour).UnixNano(),
}))
// Check existence of insterted record
rec, err := rev.IssuanceRecord(revocationTestCred, "1")
require.NoError(t, err)
require.NotNil(t, rec)
// Run jobs, triggering DELETE
revocationConfiguration.IrmaConfiguration.Scheduler.RunAll()
// Check that issuance record is gone
rec, err = rev.IssuanceRecord(revocationTestCred, "1")
require.Equal(t, gorm.ErrRecordNotFound, err)
})
}
// Helper functions
......
......@@ -136,6 +136,9 @@ const (
// If server mode is enabled for a credential type, then once every so many seconds
// the timestamp in each accumulator is updated to now.
revocationAccumulatorUpdateInterval uint64 = 60
// DELETE issuance records of expired credential every so many minutes
revocationDeleteIssuanceRecordsInterval uint64 = 300
)
// EnableRevocation creates an initial accumulator for a given credential type. This function is the
......@@ -534,6 +537,15 @@ func (rs *RevocationStorage) Load(debug bool, dbtype, connstr string, settings m
}
})
}
rs.conf.Scheduler.Every(revocationDeleteIssuanceRecordsInterval).Minutes().Do(func() {
if !rs.sqlMode {
return
}
if err := rs.db.Delete(IssuanceRecord{}, "valid_until < ?", time.Now().UnixNano()); err != nil {
err = errors.WrapPrefix(err, "failed to delete expired issuance records", 0)
raven.CaptureError(err, nil)
}
})
if connstr == "" {
Logger.Trace("Using memory revocation database")
......
......@@ -22,6 +22,8 @@ type (
Last(dest interface{}, query interface{}, args ...interface{}) error
// Exists checks whether records exist satisfying col = key.
Exists(typ interface{}, query interface{}, args ...interface{}) (bool, error)
// Delete records of the given type satisfying the query.
Delete(typ interface{}, query interface{}, args ...interface{}) error
// Find deserializes into o all records satisfying the specified query.
Find(dest interface{}, query interface{}, args ...interface{}) error
// Latest deserializes into o the last items; amount specified by count, ordered by col.
......@@ -126,6 +128,10 @@ func (s sqlRevStorage) Exists(typ interface{}, query interface{}, args ...interf
return c > 0, db.Error
}
func (s sqlRevStorage) Delete(typ interface{}, query interface{}, args ...interface{}) error {
return s.gorm.Delete(typ, query, args).Error
}
func (s sqlRevStorage) Find(dest interface{}, query interface{}, args ...interface{}) error {
return s.gorm.
Where(query, args...).
......
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