Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: auto-update mechanism of IRMA configuration not working in Docke… #336

Merged
merged 3 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
### Fixed
- Auto-update mechanism of IRMA configuration not working in ghcr.io/privacybydesign/irma Docker container

## [0.13.2] - 2023-08-22
### Changed
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ COPY --from=build --chown=irma:irma /home/irma/ /home/irma/
# Switch to application user
USER irma

# Include schemes in the Docker image to speed up the start-up time
RUN ["/bin/irma", "scheme", "download"]
# Include schemes as assets in the Docker image to speed up the start-up time
RUN ["/bin/irma", "scheme", "download", "--use-schemes-assets-path"]

ENTRYPOINT ["/bin/irma"]
5 changes: 5 additions & 0 deletions irma/cmd/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ var downloadCmd = &cobra.Command{
var path string
var urls []string
defaultIrmaconf := irma.DefaultSchemesPath()
if useSchemeAssetsPath, _ := cmd.Flags().GetBool("use-schemes-assets-path"); useSchemeAssetsPath {
defaultIrmaconf = irma.EnsureDefaultSchemesAssetsPathExists()
}

if len(args) == 0 {
path = defaultIrmaconf
Expand Down Expand Up @@ -84,5 +87,7 @@ func downloadHelp() string {
}

func init() {
flags := downloadCmd.Flags()
flags.Bool("use-schemes-assets-path", false, "download the schemes to the schemes assets path instead of the schemes path")
schemeCmd.AddCommand(downloadCmd)
}
2 changes: 1 addition & 1 deletion irma/cmd/keyshare-myirma.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func init() {

flags.StringP("config", "c", "", "path to configuration file")
flags.StringP("schemes-path", "s", irma.DefaultSchemesPath(), "path to irma_configuration")
flags.String("schemes-assets-path", "", "if specified, copy schemes from here into --schemes-path")
flags.String("schemes-assets-path", irma.DefaultSchemesAssetsPath(), "if specified, copy schemes from here into --schemes-path")
flags.Int("schemes-update", 60, "update IRMA schemes every x minutes (0 to disable)")
flags.StringP("url", "u", "", "external URL to server to which the IRMA client connects, \":port\" being replaced by --port value")
flags.String("static-path", "", "Host files under this path as static files (leave empty to disable)")
Expand Down
2 changes: 1 addition & 1 deletion irma/cmd/keyshare-server.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func init() {
flags.SortFlags = false
flags.StringP("config", "c", "", "path to configuration file")
flags.StringP("schemes-path", "s", irma.DefaultSchemesPath(), "path to irma_configuration")
flags.String("schemes-assets-path", "", "if specified, copy schemes from here into --schemes-path")
flags.String("schemes-assets-path", irma.DefaultSchemesAssetsPath(), "if specified, copy schemes from here into --schemes-path")
flags.Int("schemes-update", 60, "update IRMA schemes every x minutes (0 to disable)")
flags.StringP("privkeys", "k", "", "path to IRMA private keys")
flags.StringP("url", "u", "", "external URL to server to which the IRMA client connects, \":port\" being replaced by --port value")
Expand Down
16 changes: 11 additions & 5 deletions irma/cmd/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@ var metaCmd = &cobra.Command{
Short: "Parse an IRMA metadata attribute and print its contents",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
confpath, err := cmd.Flags().GetString("irmaconf")
confPath, err := cmd.Flags().GetString("irmaconf")
if err != nil {
die("Failed to get irma_configuration flag", err)
}
confAssetsPath, err := cmd.Flags().GetString("irmaconf-assets")
if err != nil {
die("Failed to get irma_configuration flag", err)
}

metaint := new(big.Int)
_, ok := metaint.SetString(args[0], 10)
if !ok {
Expand All @@ -38,18 +43,18 @@ var metaCmd = &cobra.Command{
metaint.SetBytes(bts)
}

if err := printMetadataAttr(metaint, confpath); err != nil {
if err := printMetadataAttr(metaint, confPath, confAssetsPath); err != nil {
die("", err)
}
return nil
},
}

func printMetadataAttr(metaint *big.Int, confpath string) error {
if err := common.AssertPathExists(confpath); err != nil {
func printMetadataAttr(metaint *big.Int, confPath string, confAssetsPath string) error {
if err := common.AssertPathExists(confPath); err != nil {
return errors.WrapPrefix(err, "Cannot read irma_configuration", 0)
}
conf, err := irma.NewConfiguration(confpath, irma.ConfigurationOptions{ReadOnly: true})
conf, err := irma.NewConfiguration(confPath, irma.ConfigurationOptions{ReadOnly: true, Assets: confAssetsPath})
if err != nil {
return errors.WrapPrefix(err, "Failed to parse irma_configuration", 0)
}
Expand Down Expand Up @@ -99,4 +104,5 @@ func init() {
RootCmd.AddCommand(metaCmd)

metaCmd.Flags().StringP("irmaconf", "i", irma.DefaultSchemesPath(), "path to irma_configuration")
metaCmd.Flags().String("irmaconf-assets", irma.DefaultSchemesAssetsPath(), "if specified, copy schemes from here into irmaconf")
}
19 changes: 12 additions & 7 deletions irma/cmd/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,29 +83,33 @@ func signRequest(request irma.RequestorRequest, name, authmethod, key string) (s
}

func configureRequest(cmd *cobra.Command) (irma.RequestorRequest, *irma.Configuration, error) {
irmaconfigPath, err := cmd.Flags().GetString("schemes-path")
irmaConfigPath, err := cmd.Flags().GetString("schemes-path")
if err != nil {
return nil, nil, err
}
irmaconfig, err := irma.NewConfiguration(irmaconfigPath, irma.ConfigurationOptions{})
irmaConfigAssetsPath, err := cmd.Flags().GetString("schemes-assets-path")
if err != nil {
return nil, nil, err
}
if err = irmaconfig.ParseFolder(); err != nil {
irmaConfig, err := irma.NewConfiguration(irmaConfigPath, irma.ConfigurationOptions{Assets: irmaConfigAssetsPath})
if err != nil {
return nil, nil, err
}
if err = irmaConfig.ParseFolder(); err != nil {
return nil, nil, err
}
if len(irmaconfig.SchemeManagers) == 0 {
if err = irmaconfig.DownloadDefaultSchemes(); err != nil {
if len(irmaConfig.SchemeManagers) == 0 {
if err = irmaConfig.DownloadDefaultSchemes(); err != nil {
return nil, nil, err
}
}

request, err := constructSessionRequest(cmd, irmaconfig)
request, err := constructSessionRequest(cmd, irmaConfig)
if err != nil {
return nil, nil, err
}

return request, irmaconfig, nil
return request, irmaConfig, nil
}

// Helper functions
Expand Down Expand Up @@ -316,6 +320,7 @@ func authmethodAlias(f *pflag.FlagSet, name string) pflag.NormalizedName {

func addRequestFlags(flags *pflag.FlagSet) {
flags.StringP("schemes-path", "s", irma.DefaultSchemesPath(), "path to irma_configuration")
flags.String("schemes-assets-path", irma.DefaultSchemesAssetsPath(), "if specified, copy schemes from here into --schemes-path")
flags.StringP("auth-method", "a", "none", "Authentication method to server (none, token, rsa, hmac)")
flags.SetNormalizeFunc(authmethodAlias)
flags.String("key", "", "Key to sign request with")
Expand Down
16 changes: 9 additions & 7 deletions irma/cmd/revoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ var revokeCmd = &cobra.Command{
Args: cobra.ExactArgs(3),
Run: func(cmd *cobra.Command, args []string) {
flags := cmd.Flags()
schemespath, _ := flags.GetString("schemes-path")
authmethod, _ := flags.GetString("auth-method")
schemesPath, _ := flags.GetString("schemes-path")
schemesAssetsPath, _ := flags.GetString("schemes-assets-path")
authMethod, _ := flags.GetString("auth-method")
key, _ := flags.GetString("key")
name, _ := flags.GetString("name")
verbosity, _ := cmd.Flags().GetCount("verbose")
Expand All @@ -27,15 +28,15 @@ var revokeCmd = &cobra.Command{
Key: args[1],
}

postRevocation(request, url, schemespath, authmethod, key, name, verbosity)
postRevocation(request, url, schemesPath, schemesAssetsPath, authMethod, key, name, verbosity)
},
}

func postRevocation(request *irma.RevocationRequest, url, schemespath, authmethod, key, name string, verbosity int) {
func postRevocation(request *irma.RevocationRequest, url, schemesPath, schemesAssetsPath, authMethod, key, name string, verbosity int) {
logger.Level = server.Verbosity(verbosity)
irma.SetLogger(logger)

conf, err := irma.NewConfiguration(schemespath, irma.ConfigurationOptions{ReadOnly: true})
conf, err := irma.NewConfiguration(schemesPath, irma.ConfigurationOptions{ReadOnly: true, Assets: schemesAssetsPath})
if err != nil {
die("failed to open irma_configuration", err)
}
Expand All @@ -53,15 +54,15 @@ func postRevocation(request *irma.RevocationRequest, url, schemespath, authmetho

transport := irma.NewHTTPTransport(url, false)

switch authmethod {
switch authMethod {
case "none":
err = transport.Post("revocation", nil, request)
case "token":
transport.SetHeader("Authorization", key)
err = transport.Post("revocation", nil, request)
case "hmac", "rsa":
// Prevent that err is redeclared in the inner scope
sk, jwtalg, errJwtKey := configureJWTKey(authmethod, key)
sk, jwtalg, errJwtKey := configureJWTKey(authMethod, key)
if errJwtKey != nil {
die("failed to configure JWT key", errJwtKey)
}
Expand Down Expand Up @@ -90,6 +91,7 @@ func postRevocation(request *irma.RevocationRequest, url, schemespath, authmetho
func init() {
flags := revokeCmd.Flags()
flags.StringP("schemes-path", "s", irma.DefaultSchemesPath(), "path to irma_configuration")
flags.String("schemes-assets-path", irma.DefaultSchemesAssetsPath(), "if specified, copy schemes from here into --schemes-path")
flags.StringP("auth-method", "a", "none", "Authentication method to server (none, token, rsa, hmac)")
flags.String("key", "", "Key to sign request with")
flags.String("name", "", "Requestor name")
Expand Down
7 changes: 4 additions & 3 deletions irma/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,15 @@ func setFlags(cmd *cobra.Command, production bool) error {
}
}

schemespath := irma.DefaultSchemesPath()
schemesPath := irma.DefaultSchemesPath()
schemesAssetsPath := irma.DefaultSchemesAssetsPath()

flags := cmd.Flags()
flags.SortFlags = false

flags.StringP("config", "c", "", "path to configuration file")
flags.StringP("schemes-path", "s", schemespath, "path to irma_configuration")
flags.String("schemes-assets-path", "", "if specified, copy schemes from here into --schemes-path")
flags.StringP("schemes-path", "s", schemesPath, "path to irma_configuration")
flags.String("schemes-assets-path", schemesAssetsPath, "if specified, copy schemes from here into --schemes-path")
flags.Int("schemes-update", 60, "update IRMA schemes every x minutes (0 to disable)")
flags.StringP("privkeys", "k", "", "path to IRMA private keys")
flags.String("static-path", "", "Host files under this path as static files (leave empty to disable)")
Expand Down
27 changes: 27 additions & 0 deletions irmaconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,33 @@ func DefaultSchemesPath() string {
return p
}

// DefaultSchemesAssetsPath returns the default storage path for irma_configuration assets,
// namely DefaultDataPath + "/irma_configuration_assets" if it exists. Otherwise, it returns the empty string.
func DefaultSchemesAssetsPath() string {
p := defaultSchemesAssetsPath()
if exists, err := common.PathExists(p); err != nil || !exists {
return ""
}
return p
}

// EnsureDefaultSchemesAssetsPathExists ensures that the default storage path for irma_configuration assets exists and returns it.
func EnsureDefaultSchemesAssetsPathExists() string {
p := defaultSchemesAssetsPath()
if err := common.EnsureDirectoryExists(p); err != nil {
return ""
}
return p
}

func defaultSchemesAssetsPath() string {
p := DefaultDataPath()
if p == "" {
return ""
}
return filepath.Join(p, "irma_configuration_assets")
}

func firstExistingPath(paths []string) string {
for _, p := range paths {
if err := common.EnsureDirectoryExists(p); err == nil {
Expand Down