• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FIWARE / VCVerifier / 18774193082

24 Oct 2025 08:27AM UTC coverage: 42.954% (-0.3%) from 43.214%
18774193082

push

github

web-flow
Merge pull request #68 from FIWARE/default-scope

use defautl scope

7 of 22 new or added lines in 3 files covered. (31.82%)

2 existing lines in 1 file now uncovered.

1588 of 3697 relevant lines covered (42.95%)

0.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

10.05
/verifier/credentialsConfig.go
1
package verifier
2

3
import (
4
        "context"
5
        "errors"
6
        "fmt"
7
        "net/url"
8
        "time"
9

10
        "github.com/fiware/VCVerifier/tir"
11
        "github.com/procyon-projects/chrono"
12

13
        "github.com/fiware/VCVerifier/common"
14
        "github.com/fiware/VCVerifier/config"
15
        "github.com/fiware/VCVerifier/logging"
16
        "github.com/patrickmn/go-cache"
17
        "golang.org/x/exp/maps"
18
)
19

20
var ErrorNoDefaultScope = errors.New("no_default_scope_configured")
21

22
const CACHE_EXPIRY = 60
23

24
/**
25
* Provides information about credentialTypes associated with services and there trust anchors.
26
 */
27
type CredentialsConfig interface {
28
        // should return the list of scopes to be requested via the scope parameter
29
        GetScope(serviceIdentifier string) (scopes []string, err error)
30
        // should return the configured default scope
31
        GetDefaultScope(serviceIdentifier string) (scope string, err error)
32
        // should return the authorization type to be provided in the redirect
33
        GetAuthorizationType(serviceIdentifier string) (path string, err error)
34
        // should return the authorization path to be provided in the redirect
35
        GetAuthorizationPath(serviceIdentifier string) (path string)
36
        // should return the presentationDefinition be requested via the scope parameter
37
        GetPresentationDefinition(serviceIdentifier string, scope string) (presentationDefinition *config.PresentationDefinition)
38
        // should return the presentatiodcql to be requested via the scope parameter
39
        GetDcqlQuery(serviceIdentifier string, scope string) (dcql *config.DCQL)
40
        // get (EBSI TrustedIssuersRegistry compliant) endpoints for the given service/credential combination, to check its issued by a trusted participant.
41
        GetTrustedParticipantLists(serviceIdentifier string, scope string, credentialType string) (trustedIssuersRegistryUrl []config.TrustedParticipantsList, err error)
42
        // get (EBSI TrustedIssuersRegistry compliant) endpoints for the given service/credential combination, to check that credentials are issued by trusted issuers
43
        // and that the issuer has permission to issue such claims.
44
        GetTrustedIssuersLists(serviceIdentifier string, scope string, credentialType string) (trustedIssuersRegistryUrl []string, err error)
45
        // The credential types that are required for the given service and scope
46
        RequiredCredentialTypes(serviceIdentifier string, scope string) (credentialTypes []string, err error)
47
        // Get holder verification
48
        GetHolderVerification(serviceIdentifier string, scope string, credentialType string) (isEnabled bool, holderClaim string, err error)
49
        // Get compliance requirement
50
        GetComplianceRequired(serviceIdentifier string, scope string, credentialType string) (isRequired bool, err error)
51
        // Get include in jwt
52
        GetJwtInclusion(serviceIdentifier string, scope string, credentialType string) (jwtInclusion config.JwtInclusion, err error)
53
        // If flatClaims should be used
54
        GetFlatClaims(serviceIdentifier string, scope string) (flatClaims bool, err error)
55
}
56

57
type ServiceBackedCredentialsConfig struct {
58
        initialConfig *config.ConfigRepo
59
        configClient  *config.ConfigClient
60
}
61

62
func InitServiceBackedCredentialsConfig(repoConfig *config.ConfigRepo) (credentialsConfig CredentialsConfig, err error) {
1✔
63
        var configClient config.ConfigClient
1✔
64
        var static = repoConfig.ConfigEndpoint == ""
1✔
65
        if repoConfig.ConfigEndpoint == "" {
2✔
66
                logging.Log().Warn("No endpoint for the configuration service is configured. Only static configuration will be provided.")
1✔
67
        } else {
1✔
68

×
69
                _, err = url.Parse(repoConfig.ConfigEndpoint)
×
70
                if err != nil {
×
71
                        logging.Log().Errorf("The service endpoint %s is not a valid url. Err: %v", repoConfig.ConfigEndpoint, err)
×
72
                        return
×
73
                }
×
74
                configClient, err = config.NewCCSHttpClient(repoConfig.ConfigEndpoint)
×
75
                if err != nil {
×
76
                        logging.Log().Warnf("Was not able to instantiate the config client.")
×
77
                }
×
78
        }
79

80
        scb := ServiceBackedCredentialsConfig{configClient: &configClient, initialConfig: repoConfig}
1✔
81

1✔
82
        err = scb.fillStaticValues(static)
1✔
83
        if err != nil {
1✔
84
                return nil, err
×
85
        }
×
86

87
        if repoConfig.ConfigEndpoint != "" {
1✔
88

×
89
                _, err := chrono.NewDefaultTaskScheduler().ScheduleAtFixedRate(scb.fillCache, time.Duration(repoConfig.UpdateInterval)*time.Second)
×
90
                if err != nil {
×
91
                        logging.Log().Errorf("failed scheduling task: %v", err)
×
92
                        return nil, err
×
93
                }
×
94
        }
95

96
        return scb, err
1✔
97
}
98

99
func (cc ServiceBackedCredentialsConfig) fillStaticValues(static bool) error {
1✔
100
        var exipiration = cache.DefaultExpiration
1✔
101
        if static {
2✔
102
                exipiration = cache.NoExpiration
1✔
103
        }
1✔
104
        for _, configuredService := range cc.initialConfig.Services {
1✔
105
                logging.Log().Debugf("Add service %s to cache.", logging.PrettyPrintObject(configuredService))
×
106
                common.GlobalCache.ServiceCache.Set(configuredService.Id, configuredService, exipiration)
×
107
        }
×
108
        return nil
1✔
109
}
110

111
func (cc ServiceBackedCredentialsConfig) fillCache(context.Context) {
×
112
        configClient := *(cc.configClient)
×
113
        services, err := configClient.GetServices()
×
114
        if err != nil {
×
115
                logging.Log().Warnf("Was not able to update the credentials config from the external service. Will try again. Err: %v.", err)
×
116
                return
×
117
        }
×
118
        for _, configuredService := range services {
×
119
                common.GlobalCache.ServiceCache.Set(configuredService.Id, configuredService, cache.DefaultExpiration)
×
120

×
121
                var tirEndpoints []string
×
122

×
123
                for serviceScope, scopeEntry := range configuredService.ServiceScopes {
×
124
                        for _, credential := range scopeEntry.Credentials {
×
125
                                serviceIssuersLists, err := cc.GetTrustedIssuersLists(configuredService.Id, serviceScope, credential.Type)
×
126
                                if err != nil {
×
127
                                        logging.Log().Errorf("failed caching issuers lists in fillCache(): %v", err)
×
128
                                } else {
×
129
                                        tirEndpoints = append(tirEndpoints, serviceIssuersLists...)
×
130
                                }
×
131
                        }
132
                }
133
                common.GlobalCache.TirEndpoints.Set(tir.TirEndpointsCache, tirEndpoints, cache.NoExpiration)
×
134
        }
135

136
}
137

138
func (cc ServiceBackedCredentialsConfig) RequiredCredentialTypes(serviceIdentifier string, scope string) (credentialTypes []string, err error) {
×
139
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
140
        if hit {
×
141
                logging.Log().Debugf("Found service for %s", serviceIdentifier)
×
142
                configuredService := cacheEntry.(config.ConfiguredService)
×
143
                return configuredService.GetRequiredCredentialTypes(scope), nil
×
144
        }
×
145
        logging.Log().Errorf("No service entry for %s", serviceIdentifier)
×
146
        return []string{}, fmt.Errorf("no service %s configured", serviceIdentifier)
×
147
}
148

NEW
149
func (cc ServiceBackedCredentialsConfig) GetDefaultScope(serviceIdentifier string) (scope string, err error) {
×
NEW
150
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
NEW
151
        if hit {
×
NEW
152
                configuredService := cacheEntry.(config.ConfiguredService)
×
NEW
153
                logging.Log().Debugf("Found scope %s for %s", logging.PrettyPrintObject(configuredService.ServiceScopes), serviceIdentifier)
×
NEW
154
                return configuredService.DefaultOidcScope, nil
×
NEW
155
        }
×
NEW
156
        logging.Log().Debugf("No scope entry for %s", serviceIdentifier)
×
NEW
157
        return "", ErrorNoDefaultScope
×
158
}
159

160
func (cc ServiceBackedCredentialsConfig) GetScope(serviceIdentifier string) (scopes []string, err error) {
×
161
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
162
        if hit {
×
163
                configuredService := cacheEntry.(config.ConfiguredService)
×
164
                logging.Log().Debugf("Found scope %s for %s", logging.PrettyPrintObject(configuredService.ServiceScopes), serviceIdentifier)
×
165
                return maps.Keys(configuredService.ServiceScopes), nil
×
166
        }
×
167
        logging.Log().Debugf("No scope entry for %s", serviceIdentifier)
×
168
        return []string{}, nil
×
169
}
170

171
func (cc ServiceBackedCredentialsConfig) GetAuthorizationType(serviceIdentifier string) (path string, err error) {
×
172
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
173
        if hit {
×
174
                logging.Log().Debugf("Found authorization-type for %s", serviceIdentifier)
×
175
                configuredService := cacheEntry.(config.ConfiguredService)
×
176
                return configuredService.AuthorizationType, nil
×
177
        }
×
178
        logging.Log().Debugf("No authorization-type entry for %s", serviceIdentifier)
×
179
        return "", nil
×
180
}
181

182
func (cc ServiceBackedCredentialsConfig) GetAuthorizationPath(serviceIdentifier string) (path string) {
×
183
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
184
        if hit {
×
185
                logging.Log().Debugf("Found authorization-endpoint for %s", serviceIdentifier)
×
186
                configuredService := cacheEntry.(config.ConfiguredService)
×
187
                return configuredService.AuthorizationPath
×
188
        }
×
189
        logging.Log().Debugf("No authorization-path entry for %s", serviceIdentifier)
×
190
        return ""
×
191
}
192
func (cc ServiceBackedCredentialsConfig) GetPresentationDefinition(serviceIdentifier string, scope string) (presentationDefinition *config.PresentationDefinition) {
×
193
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
194
        if hit {
×
195
                return cacheEntry.(config.ConfiguredService).GetPresentationDefinition(scope)
×
196

×
197
        }
×
198
        logging.Log().Debugf("No presentation definition for %s - %s", serviceIdentifier, scope)
×
199
        return presentationDefinition
×
200
}
201

202
func (cc ServiceBackedCredentialsConfig) GetDcqlQuery(serviceIdentifier string, scope string) (dcql *config.DCQL) {
×
203
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
204
        logging.Log().Debug("Get the dcql")
×
205
        if hit {
×
206
                return cacheEntry.(config.ConfiguredService).GetDcqlQuery(scope)
×
207

×
208
        }
×
209
        logging.Log().Debugf("No dcql for %s - %s", serviceIdentifier, scope)
×
210
        return dcql
×
211
}
212

213
func (cc ServiceBackedCredentialsConfig) GetTrustedParticipantLists(serviceIdentifier string, scope string, credentialType string) (trustedIssuersRegistryUrl []config.TrustedParticipantsList, err error) {
×
214
        logging.Log().Debugf("Get participants list for %s - %s - %s.", serviceIdentifier, scope, credentialType)
×
215
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
216
        if hit {
×
217
                credential, ok := cacheEntry.(config.ConfiguredService).GetCredential(scope, credentialType)
×
218
                if ok {
×
219
                        logging.Log().Debugf("Found trusted participants %s for %s - %s", credential.TrustedParticipantsLists, serviceIdentifier, credentialType)
×
220
                        return credential.TrustedParticipantsLists, nil
×
221
                }
×
222
        }
223
        logging.Log().Debugf("No trusted participants for %s - %s", serviceIdentifier, credentialType)
×
224
        return []config.TrustedParticipantsList{}, nil
×
225
}
226

227
func (cc ServiceBackedCredentialsConfig) GetTrustedIssuersLists(serviceIdentifier string, scope string, credentialType string) (trustedIssuersRegistryUrl []string, err error) {
×
228
        logging.Log().Debugf("Get issuers list for %s - %s - %s.", serviceIdentifier, scope, credentialType)
×
229
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
230
        if hit {
×
231
                credential, ok := cacheEntry.(config.ConfiguredService).GetCredential(scope, credentialType)
×
232
                if ok {
×
233
                        logging.Log().Debugf("Found trusted issuers for %s for %s - %s", credential.TrustedIssuersLists, serviceIdentifier, credentialType)
×
234
                        return credential.TrustedIssuersLists, nil
×
235
                }
×
236
        }
237
        logging.Log().Debugf("No trusted issuers for %s - %s", serviceIdentifier, credentialType)
×
238
        return []string{}, nil
×
239
}
240

241
func (cc ServiceBackedCredentialsConfig) GetComplianceRequired(serviceIdentifier string, scope string, credentialType string) (isRequired bool, err error) {
×
242
        logging.Log().Debugf("Get compliance requirement for %s - %s - %s.", serviceIdentifier, scope, credentialType)
×
243
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
244
        if hit {
×
245
                credential, ok := cacheEntry.(config.ConfiguredService).GetCredential(scope, credentialType)
×
246
                if ok {
×
247
                        logging.Log().Debugf("Found compliance requirement for %s - %v", credentialType, credential.RequireCompliance)
×
248
                        return credential.RequireCompliance, nil
×
249
                }
×
250
        }
251
        logging.Log().Debugf("No compliance requirement for %s - %s", serviceIdentifier, credentialType)
×
252
        return false, nil
×
253
}
254

255
func (cc ServiceBackedCredentialsConfig) GetFlatClaims(serviceIdentifier string, scope string) (flatClaims bool, err error) {
×
256
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
257
        if hit {
×
258
                logging.Log().Debugf("Found scope for %s", serviceIdentifier)
×
259
                configuredService := cacheEntry.(config.ConfiguredService)
×
260
                scope, ok := configuredService.ServiceScopes[scope]
×
261
                if ok {
×
262
                        return scope.FlatClaims, nil
×
263
                }
×
264
        }
265
        logging.Log().Debugf("No scope entry and flatclaims config for %s - %s", serviceIdentifier, scope)
×
266
        return false, nil
×
267
}
268

269
func (cc ServiceBackedCredentialsConfig) GetJwtInclusion(serviceIdentifier string, scope string, credentialType string) (jwtInclusion config.JwtInclusion, err error) {
×
270
        logging.Log().Debugf("Get jwt inclusion for %s - %s - %s.", serviceIdentifier, scope, credentialType)
×
271
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
272
        if hit {
×
273
                credential, ok := cacheEntry.(config.ConfiguredService).GetCredential(scope, credentialType)
×
274
                if ok {
×
275
                        logging.Log().Debugf("Found jwt inclusion for %s - %v", credentialType, credential.RequireCompliance)
×
276
                        return credential.JwtInclusion, nil
×
277
                }
×
278
        }
279
        logging.Log().Debugf("No jwt inclusion for %s - %s", serviceIdentifier, credentialType)
×
280
        return jwtInclusion, nil
×
281
}
282

283
func (cc ServiceBackedCredentialsConfig) GetHolderVerification(serviceIdentifier string, scope string, credentialType string) (isEnabled bool, holderClaim string, err error) {
×
284
        logging.Log().Debugf("Get holder verification for %s - %s - %s.", serviceIdentifier, scope, credentialType)
×
285
        cacheEntry, hit := common.GlobalCache.ServiceCache.Get(serviceIdentifier)
×
286
        if hit {
×
287
                credential, ok := cacheEntry.(config.ConfiguredService).GetCredential(scope, credentialType)
×
288
                if ok {
×
289
                        logging.Log().Debugf("Found holder verification %v:%s for %s - %s", credential.HolderVerification.Enabled, credential.HolderVerification.Claim, serviceIdentifier, credentialType)
×
290
                        return credential.HolderVerification.Enabled, credential.HolderVerification.Claim, nil
×
291
                }
×
292
        }
293
        logging.Log().Debugf("No holder verification for %s - %s", serviceIdentifier, credentialType)
×
294
        return false, "", nil
×
295
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc