Skip to content

Commit 3f95c1f

Browse files
authored
Merge pull request #660 from cjuega/main
fix(#659): allow client to request credentials in each call via envvar
2 parents cca5480 + ed9aca6 commit 3f95c1f

File tree

4 files changed

+101
-0
lines changed

4 files changed

+101
-0
lines changed

pkg/client/client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ func (c *KpmClient) SetNoSumCheck(noSumCheck bool) {
7777

7878
// GetCredsClient will return the credential client.
7979
func (c *KpmClient) GetCredsClient() (*downloader.CredClient, error) {
80+
reloadCreds, _ := c.settings.ForceReloadCredsPerUse()
81+
if reloadCreds {
82+
return downloader.LoadCredentialFile(c.settings.CredentialsFile)
83+
}
84+
8085
if c.credsClient == nil {
8186
credCli, err := downloader.LoadCredentialFile(c.settings.CredentialsFile)
8287
if err != nil {

pkg/client/client_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2783,3 +2783,43 @@ func TestUpdateGitNewLocalStorage(t *testing.T) {
27832783
}
27842784
RunTestWithGlobalLockAndKpmCli(t, []TestSuite{{Name: "TestUpdateGitNewLocalStorage", TestFunc: testFunc}})
27852785
}
2786+
2787+
func TestGetCredsClientReloadBehavior(t *testing.T) {
2788+
// preserve and restore env
2789+
orig := os.Getenv("KPM_RELOAD_CREDS")
2790+
defer os.Setenv("KPM_RELOAD_CREDS", orig)
2791+
2792+
// Prepare a temporary credentials file path
2793+
tmpDir := t.TempDir()
2794+
credsPath := filepath.Join(tmpDir, "config.json")
2795+
// Create an empty file; the oras docker auth client tolerates empty store for constructing client
2796+
_ = os.WriteFile(credsPath, []byte("{}"), 0644)
2797+
2798+
// Helper to build client with injected settings path
2799+
newClientWithCredsPath := func() *KpmClient {
2800+
cli, err := NewKpmClient()
2801+
assert.Nil(t, err)
2802+
// overwrite settings to point to our temp creds file and reload env
2803+
cli.settings.CredentialsFile = credsPath
2804+
_, _ = cli.settings.LoadSettingsFromEnv()
2805+
return cli
2806+
}
2807+
2808+
// OFF (default) -> cached; repeated calls should return the same pointer
2809+
_ = os.Setenv("KPM_RELOAD_CREDS", "off")
2810+
c := newClientWithCredsPath()
2811+
cc1, err := c.GetCredsClient()
2812+
assert.Nil(t, err)
2813+
cc2, err := c.GetCredsClient()
2814+
assert.Nil(t, err)
2815+
assert.Equal(t, cc1, cc2)
2816+
2817+
// ON -> reload each time; repeated calls should return different pointers
2818+
_ = os.Setenv("KPM_RELOAD_CREDS", "on")
2819+
c = newClientWithCredsPath()
2820+
cc3, err := c.GetCredsClient()
2821+
assert.Nil(t, err)
2822+
cc4, err := c.GetCredsClient()
2823+
assert.Nil(t, err)
2824+
assert.NotEqual(t, cc3, cc4)
2825+
}

pkg/settings/settings.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type KpmConf struct {
3131
DefaultOciRegistry string
3232
DefaultOciRepo string
3333
DefaultOciPlainHttp *bool `json:",omitempty"`
34+
ReloadCredsPerUse *bool `json:",omitempty"`
3435
}
3536

3637
const ON = "on"
@@ -41,6 +42,7 @@ const DEFAULT_OCI_PLAIN_HTTP = ON
4142
const DEFAULT_REGISTRY_ENV = "KPM_REG"
4243
const DEFAULT_REPO_ENV = "KPM_REPO"
4344
const DEFAULT_OCI_PLAIN_HTTP_ENV = "OCI_REG_PLAIN_HTTP"
45+
const DEFAULT_RELOAD_CREDS_ENV = "KPM_RELOAD_CREDS"
4446

4547
// This is a singleton that loads kpm settings from 'kpm.json'
4648
// and is only initialized on the first call by 'Init()' or 'GetSettings()'
@@ -53,6 +55,7 @@ func DefaultKpmConf() KpmConf {
5355
DefaultOciRegistry: DEFAULT_REGISTRY,
5456
DefaultOciRepo: DEFAULT_REPO,
5557
DefaultOciPlainHttp: nil,
58+
ReloadCredsPerUse: nil,
5659
}
5760
}
5861

@@ -153,6 +156,14 @@ func (settings *Settings) ForceOciPlainHttp() (bool, bool) {
153156
return *settings.Conf.DefaultOciPlainHttp, true
154157
}
155158

159+
// ForceReloadCredsPerUse returns whether reloading credentials per use is forced.
160+
func (settings *Settings) ForceReloadCredsPerUse() (bool, bool) {
161+
if settings.Conf.ReloadCredsPerUse == nil {
162+
return false, false
163+
}
164+
return *settings.Conf.ReloadCredsPerUse, true
165+
}
166+
156167
// DefaultOciRef return the default OCI ref 'ghcr.io/kcl-lang'.
157168
func (settings *Settings) DefaultOciRef() string {
158169
return utils.JoinPath(settings.Conf.DefaultOciRegistry, settings.Conf.DefaultOciRepo)
@@ -184,6 +195,20 @@ func (settings *Settings) LoadSettingsFromEnv() (*Settings, *reporter.KpmEvent)
184195
)
185196
}
186197
}
198+
199+
// Load the env KPM_RELOAD_CREDS (ON/OFF)
200+
reloadCreds := os.Getenv(DEFAULT_RELOAD_CREDS_ENV)
201+
if len(reloadCreds) > 0 {
202+
shouldReload, err := isOn(reloadCreds)
203+
settings.Conf.ReloadCredsPerUse = &shouldReload
204+
if err != nil {
205+
return settings, reporter.NewErrorEvent(
206+
reporter.UnknownEnv,
207+
err,
208+
fmt.Sprintf("unknown environment variable '%s=%s'", DEFAULT_RELOAD_CREDS_ENV, reloadCreds),
209+
)
210+
}
211+
}
187212
return settings, nil
188213
}
189214

pkg/settings/settings_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,34 @@ func TestSettingEnv(t *testing.T) {
187187
settings = GetSettings()
188188
assert.Equal(t, settings.DefaultOciPlainHttp(), false)
189189
}
190+
191+
func TestReloadCredsEnvParsing(t *testing.T) {
192+
// preserve and restore env
193+
orig := os.Getenv("KPM_RELOAD_CREDS")
194+
defer os.Setenv("KPM_RELOAD_CREDS", orig)
195+
196+
// invalid value -> UnknownEnv error
197+
_ = os.Setenv("KPM_RELOAD_CREDS", "true")
198+
s := &Settings{Conf: DefaultKpmConf()}
199+
_, evt := s.LoadSettingsFromEnv()
200+
assert.NotNil(t, evt)
201+
assert.Equal(t, reporter.UnknownEnv, evt.Type())
202+
203+
// ON -> true
204+
_ = os.Setenv("KPM_RELOAD_CREDS", "on")
205+
s = &Settings{Conf: DefaultKpmConf()}
206+
_, evt = s.LoadSettingsFromEnv()
207+
assert.Nil(t, evt)
208+
reload, force := s.ForceReloadCredsPerUse()
209+
assert.True(t, force)
210+
assert.True(t, reload)
211+
212+
// OFF -> false
213+
_ = os.Setenv("KPM_RELOAD_CREDS", "off")
214+
s = &Settings{Conf: DefaultKpmConf()}
215+
_, evt = s.LoadSettingsFromEnv()
216+
assert.Nil(t, evt)
217+
reload, force = s.ForceReloadCredsPerUse()
218+
assert.True(t, force)
219+
assert.False(t, reload)
220+
}

0 commit comments

Comments
 (0)