Fix panic of ssh public key page after deletion of auth source (#31829) (#31836)

Backport #31829 by @lunny

Fix #31730

This PR rewrote the function `PublicKeysAreExternallyManaged` with a
simple test. The new function removed the loop to make it more readable.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
(cherry picked from commit 5fa90ad9bc7fe800d657e909462e5e1caefc7193)
This commit is contained in:
Giteabot 2024-08-16 01:50:57 +08:00 committed by Earl Warren
parent 4c5e4e672d
commit 64c7687308
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
2 changed files with 17 additions and 16 deletions

View file

@ -229,35 +229,26 @@ func UpdatePublicKeyUpdated(ctx context.Context, id int64) error {
// PublicKeysAreExternallyManaged returns whether the provided KeyID represents an externally managed Key // PublicKeysAreExternallyManaged returns whether the provided KeyID represents an externally managed Key
func PublicKeysAreExternallyManaged(ctx context.Context, keys []*PublicKey) ([]bool, error) { func PublicKeysAreExternallyManaged(ctx context.Context, keys []*PublicKey) ([]bool, error) {
sources := make([]*auth.Source, 0, 5) sourceCache := make(map[int64]*auth.Source, len(keys))
externals := make([]bool, len(keys)) externals := make([]bool, len(keys))
keyloop:
for i, key := range keys { for i, key := range keys {
if key.LoginSourceID == 0 { if key.LoginSourceID == 0 {
externals[i] = false externals[i] = false
continue keyloop continue
} }
var source *auth.Source source, ok := sourceCache[key.LoginSourceID]
if !ok {
sourceloop:
for _, s := range sources {
if s.ID == key.LoginSourceID {
source = s
break sourceloop
}
}
if source == nil {
var err error var err error
source, err = auth.GetSourceByID(ctx, key.LoginSourceID) source, err = auth.GetSourceByID(ctx, key.LoginSourceID)
if err != nil { if err != nil {
if auth.IsErrSourceNotExist(err) { if auth.IsErrSourceNotExist(err) {
externals[i] = false externals[i] = false
sources[i] = &auth.Source{ sourceCache[key.LoginSourceID] = &auth.Source{
ID: key.LoginSourceID, ID: key.LoginSourceID,
} }
continue keyloop continue
} }
return nil, err return nil, err
} }

View file

@ -12,6 +12,8 @@ import (
"strings" "strings"
"testing" "testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/42wim/sshsig" "github.com/42wim/sshsig"
@ -501,3 +503,11 @@ func runErr(t *testing.T, stdin []byte, args ...string) {
t.Fatal("expected error") t.Fatal("expected error")
} }
} }
func Test_PublicKeysAreExternallyManaged(t *testing.T) {
key1 := unittest.AssertExistsAndLoadBean(t, &PublicKey{ID: 1})
externals, err := PublicKeysAreExternallyManaged(db.DefaultContext, []*PublicKey{key1})
require.NoError(t, err)
assert.Len(t, externals, 1)
assert.False(t, externals[0])
}