Skip to content

Commit 98fceb8

Browse files
committed
bridge/jira: require explicit rotation of validated credentials
1 parent 1d485f8 commit 98fceb8

3 files changed

Lines changed: 14 additions & 17 deletions

File tree

‎bridge/jira/config.go‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ NOTE: There are a few optional configuration values that you can additionally
1616
set in your git configuration to influence the behavior of the bridge. Please
1717
see the notes at:
1818
https://github.com/git-bug/git-bug/blob/trunk/doc/jira_bridge.md
19+
20+
The bridge retains the credential validated during setup. To rotate it, add
21+
the replacement token with --base-url and reconfigure with --credential.
1922
`
2023

2124
const credTypeText = `

‎bridge/jira/credential_test.go‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,14 @@ func TestTokenCredentials(t *testing.T) {
9090
require.NoError(t, auth.Store(repo, replacement))
9191
credentials, err = configuredCredentials(repo, legacyConf, auth.WithTarget(target))
9292
require.NoError(t, err)
93-
require.Equal(t, replacement.ID(), credentials[0].ID(), "newer tokens must rotate the configured token")
93+
require.Equal(t, token.ID(), credentials[0].ID(), "adding a token must not silently replace the validated credential")
94+
legacyConf[confKeyCredentialID] = replacement.ID().String()
95+
credentials, err = configuredCredentials(repo, legacyConf, auth.WithTarget(target))
96+
require.NoError(t, err)
97+
require.Equal(t, replacement.ID(), credentials[0].ID(), "explicit reconfiguration selects the replacement token")
98+
require.NoError(t, auth.Remove(repo, replacement.ID()))
99+
_, err = configuredCredentials(repo, legacyConf, auth.WithTarget(target))
100+
require.ErrorContains(t, err, "reconfigure the bridge")
94101
}
95102

96103
func TestSessionCredentialsIgnoreNewerToken(t *testing.T) {

‎bridge/jira/jira.go‎

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -136,25 +136,12 @@ func configuredCredentials(repo repository.RepoKeyring, conf core.Configuration,
136136
return nil, err
137137
}
138138
if id := conf[confKeyCredentialID]; id != "" {
139-
configured, err := auth.LoadWithId(repo, entity.Id(id))
139+
_, err := auth.LoadWithId(repo, entity.Id(id))
140140
if err != nil {
141-
if err == auth.ErrCredentialNotExist && len(credentials) > 0 {
142-
return credentials, nil
143-
}
144-
return nil, err
145-
}
146-
// Retain the validated credential form, but permit rotation within
147-
// that form. A newer account password must not replace an API token.
148-
preferred := configured
149-
login, _ := configured.GetMetadata(auth.MetaKeyLogin)
150-
for _, candidate := range credentials {
151-
candidateLogin, _ := candidate.GetMetadata(auth.MetaKeyLogin)
152-
if candidateLogin == login && candidate.Kind() == configured.Kind() && candidate.CreateTime().After(preferred.CreateTime()) {
153-
preferred = candidate
154-
}
141+
return nil, fmt.Errorf("configured Jira credential is missing; reconfigure the bridge with --credential: %w", err)
155142
}
156143
for i, credential := range credentials {
157-
if credential.ID() == preferred.ID() {
144+
if credential.ID().String() == id {
158145
copy(credentials[1:i+1], credentials[:i])
159146
credentials[0] = credential
160147
return credentials, nil

0 commit comments

Comments
 (0)