Commit dd543638 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Make new irma.Configuration constructors

parent 01536c1f
......@@ -53,7 +53,7 @@ func downloadSchemeManager(dest string, urls []string) error {
}
}
conf, err := irma.NewConfiguration(dest, "")
conf, err := irma.NewConfiguration(dest)
for _, u := range normalizedUrls {
urlparts := strings.Split(u, "/")
managerName := urlparts[len(urlparts)-1]
......
......@@ -42,7 +42,7 @@ func printMetadataAttr(metaint *big.Int, confpath string) error {
if err := fs.AssertPathExists(confpath); err != nil {
return errors.WrapPrefix(err, "Cannot read irma_configuration", 0)
}
conf, err := irma.NewConfiguration(confpath, "")
conf, err := irma.NewConfigurationReadOnly(confpath)
if err != nil {
return errors.WrapPrefix(err, "Failed to parse irma_configuration", 0)
}
......
......@@ -40,7 +40,7 @@ func updateSchemeManager(paths []string) error {
// TODO: this parses all managers within the irma_configuration folder, not just the one specified
// Should make a Configuration constructor that parses just one manager
conf, err := irma.NewConfiguration(irmaconf, "")
conf, err := irma.NewConfiguration(irmaconf)
if err != nil {
return err
}
......
......@@ -63,7 +63,7 @@ func RunVerify(path string, verbose bool) error {
}
func VerifyScheme(path string) error {
conf, err := irma.NewConfiguration(filepath.Dir(path), "")
conf, err := irma.NewConfigurationReadOnly(filepath.Dir(path))
if err != nil {
return err
}
......@@ -76,7 +76,7 @@ func VerifyIrmaConfiguration(path string) error {
fmt.Printf("Notice: specified folder name is '%s'; when using in IRMA applications it should be called 'irma_configuration'\n", filepath.Base(path))
}
conf, err := irma.NewConfiguration(path, "")
conf, err := irma.NewConfigurationReadOnly(path)
if err != nil {
return err
}
......
......@@ -131,7 +131,7 @@ func New(
handler: handler,
}
cm.Configuration, err = irma.NewConfiguration(storagePath+"/irma_configuration", irmaConfigurationPath)
cm.Configuration, err = irma.NewConfigurationFromAssets(storagePath+"/irma_configuration", irmaConfigurationPath)
if err != nil {
return nil, err
}
......
......@@ -59,6 +59,7 @@ type Configuration struct {
reverseHashes map[string]CredentialTypeIdentifier
initialized bool
assets string
readOnly bool
}
// ConfigurationFileHash encodes the SHA256 hash of an authenticated
......@@ -93,9 +94,26 @@ func (sme SchemeManagerError) Error() string {
return fmt.Sprintf("Error parsing scheme manager %s: %s", sme.Manager.Name(), sme.Err.Error())
}
// NewConfiguration returns a new configuration. After this
// newConfiguration returns a new configuration. After this
// ParseFolder() should be called to parse the specified path.
func NewConfiguration(path string, assets string) (conf *Configuration, err error) {
func NewConfiguration(path string) (*Configuration, error) {
return newConfiguration(path, "")
}
func NewConfigurationReadOnly(path string) (*Configuration, error) {
conf, err := newConfiguration(path, "")
if err != nil {
return nil, err
}
conf.readOnly = true
return conf, nil
}
func NewConfigurationFromAssets(path, assets string) (*Configuration, error) {
return newConfiguration(path, assets)
}
func newConfiguration(path string, assets string) (conf *Configuration, err error) {
conf = &Configuration{
Path: path,
assets: assets,
......@@ -191,6 +209,9 @@ func (conf *Configuration) ParseOrRestoreFolder() error {
if _, isSchemeMgrErr := err.(*SchemeManagerError); !isSchemeMgrErr {
return err
}
if err != nil && (conf.assets == "" || conf.readOnly) {
return err
}
for id := range conf.DisabledSchemeManagers {
if err = conf.ReinstallSchemeManager(conf.SchemeManagers[id]); err == nil {
......@@ -422,7 +443,10 @@ func (conf *Configuration) DeleteSchemeManager(id SchemeManagerIdentifier) error
delete(conf.CredentialTypes, cred)
}
}
return os.RemoveAll(filepath.Join(conf.Path, id.Name()))
if !conf.readOnly {
return os.RemoveAll(filepath.Join(conf.Path, id.Name()))
}
return nil
}
// parse $schememanager/$issuer/PublicKeys/$i.xml for $i = 1, ...
......@@ -583,7 +607,7 @@ func (conf *Configuration) Contains(cred CredentialTypeIdentifier) bool {
}
func (conf *Configuration) isUpToDate(scheme SchemeManagerIdentifier) (bool, error) {
if conf.assets == "" {
if conf.assets == "" || conf.readOnly {
return true, nil
}
name := scheme.String()
......@@ -600,7 +624,7 @@ func (conf *Configuration) isUpToDate(scheme SchemeManagerIdentifier) (bool, err
}
func (conf *Configuration) CopyManagerFromAssets(scheme SchemeManagerIdentifier) (bool, error) {
if conf.assets == "" {
if conf.assets == "" || conf.readOnly {
return false, nil
}
// Remove old version; we want an exact copy of the assets version
......@@ -661,13 +685,17 @@ func (conf *Configuration) RemoveSchemeManager(id SchemeManagerIdentifier, fromS
}
delete(conf.SchemeManagers, id)
if fromStorage {
if fromStorage || !conf.readOnly {
return os.RemoveAll(fmt.Sprintf("%s/%s", conf.Path, id.String()))
}
return nil
}
func (conf *Configuration) ReinstallSchemeManager(manager *SchemeManager) (err error) {
if conf.readOnly {
return errors.New("cannot install scheme into a read-only configuration")
}
// Check if downloading stuff from the remote works before we uninstall the specified manager:
// If we can't download anything we should keep the broken version
manager, err = DownloadSchemeManager(manager.URL)
......@@ -684,6 +712,10 @@ func (conf *Configuration) ReinstallSchemeManager(manager *SchemeManager) (err e
// InstallSchemeManager downloads and adds the specified scheme manager to this Configuration,
// provided its signature is valid.
func (conf *Configuration) InstallSchemeManager(manager *SchemeManager, publickey []byte) error {
if conf.readOnly {
return errors.New("cannot install scheme into a read-only configuration")
}
name := manager.ID
if err := fs.EnsureDirectoryExists(filepath.Join(conf.Path, name)); err != nil {
return err
......@@ -717,6 +749,10 @@ func (conf *Configuration) InstallSchemeManager(manager *SchemeManager, publicke
// DownloadSchemeManagerSignature downloads, stores and verifies the latest version
// of the index file and signature of the specified manager.
func (conf *Configuration) DownloadSchemeManagerSignature(manager *SchemeManager) (err error) {
if conf.readOnly {
return errors.New("cannot download into a read-only configuration")
}
t := NewHTTPTransport(manager.URL)
path := fmt.Sprintf("%s/%s", conf.Path, manager.ID)
index := filepath.Join(path, "index")
......@@ -736,6 +772,9 @@ func (conf *Configuration) DownloadSchemeManagerSignature(manager *SchemeManager
// if the current Configuration does not already have them, and checks their authenticity
// using the scheme manager index.
func (conf *Configuration) Download(session SessionRequest) (downloaded *IrmaIdentifierSet, err error) {
if conf.readOnly {
return nil, errors.New("cannot download into a read-only configuration")
}
managers := make(map[string]struct{}) // Managers that we must update
downloaded = &IrmaIdentifierSet{
SchemeManagers: map[SchemeManagerIdentifier]struct{}{},
......@@ -1015,6 +1054,9 @@ func (hash ConfigurationFileHash) Equal(other ConfigurationFileHash) bool {
// It stores the identifiers of new or updated credential types or issuers in the second parameter.
// Note: any newly downloaded files are not yet parsed and inserted into conf.
func (conf *Configuration) UpdateSchemeManager(id SchemeManagerIdentifier, downloaded *IrmaIdentifierSet) (err error) {
if conf.readOnly {
return errors.New("cannot update a read-only configuration")
}
manager, contains := conf.SchemeManagers[id]
if !contains {
return errors.Errorf("Cannot update unknown scheme manager %s", id)
......
......@@ -14,7 +14,7 @@ import (
)
func parseConfiguration(t *testing.T) *Configuration {
conf, err := NewConfiguration("testdata/irma_configuration", "")
conf, err := NewConfiguration("testdata/irma_configuration")
require.NoError(t, err)
require.NoError(t, conf.ParseFolder())
return conf
......@@ -33,7 +33,7 @@ func TestConfigurationAutocopy(t *testing.T) {
path := filepath.Join("testdata", "storage", "test", "irma_configuration")
require.NoError(t, fs.CopyDirectory(filepath.Join("testdata", "irma_configuration"), path))
conf, err := NewConfiguration(path, filepath.Join("testdata", "irma_configuration_updated"))
conf, err := NewConfigurationFromAssets(path, filepath.Join("testdata", "irma_configuration_updated"))
require.NoError(t, err)
require.NoError(t, conf.ParseFolder())
......@@ -45,7 +45,7 @@ func TestConfigurationAutocopy(t *testing.T) {
func TestParseInvalidIrmaConfiguration(t *testing.T) {
// The description.xml of the scheme manager under this folder has been edited
// to invalidate the scheme manager signature
conf, err := NewConfiguration("testdata/irma_configuration_invalid", "")
conf, err := NewConfigurationReadOnly("testdata/irma_configuration_invalid")
require.NoError(t, err)
// Parsing it should return a SchemeManagerError
......@@ -80,7 +80,7 @@ func TestInvalidIrmaConfigurationRestoreFromRemote(t *testing.T) {
test.CreateTestStorage(t)
defer test.ClearTestStorage(t)
conf, err := NewConfiguration("testdata/storage/test/irma_configuration", "testdata/irma_configuration_invalid")
conf, err := NewConfigurationFromAssets("testdata/storage/test/irma_configuration", "testdata/irma_configuration_invalid")
require.NoError(t, err)
err = conf.ParseOrRestoreFolder()
......@@ -94,7 +94,7 @@ func TestInvalidIrmaConfigurationRestoreFromAssets(t *testing.T) {
test.CreateTestStorage(t)
defer test.ClearTestStorage(t)
conf, err := NewConfiguration("testdata/storage/test/irma_configuration", "testdata/irma_configuration_invalid")
conf, err := NewConfigurationFromAssets("testdata/storage/test/irma_configuration", "testdata/irma_configuration_invalid")
require.NoError(t, err)
// Fails: no remote and the version in the assets is broken
......@@ -209,7 +209,7 @@ func TestMetadataAttribute(t *testing.T) {
}
func TestMetadataCompatibility(t *testing.T) {
conf, err := NewConfiguration("testdata/irma_configuration", "")
conf, err := NewConfigurationReadOnly("testdata/irma_configuration")
require.NoError(t, err)
require.NoError(t, conf.ParseFolder())
......
......@@ -33,19 +33,17 @@ func Initialize(configuration *server.Configuration) error {
if conf.IrmaConfiguration == nil {
var err error
var path, assets string
if conf.CachePath == "" {
path = conf.IrmaConfigurationPath
assets = ""
conf.IrmaConfiguration, err = irma.NewConfiguration(conf.IrmaConfigurationPath)
} else {
path = filepath.Join(conf.CachePath, "irma_configuration")
assets = conf.IrmaConfigurationPath
conf.IrmaConfiguration, err = irma.NewConfigurationFromAssets(
filepath.Join(conf.CachePath, "irma_configuration"),
conf.IrmaConfigurationPath,
)
}
conf.IrmaConfiguration, err = irma.NewConfiguration(path, assets)
if err != nil {
return err
}
if conf.IrmaConfigurationPath == "" {
if err := conf.IrmaConfiguration.DownloadDefaultSchemes(); err != nil {
return err
......
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