Skip to content

Commit 693db80

Browse files
committed
api: Allow unauthenticated access to user's SSH keys
This patch relaxes constraints on getting user's SSH keys via the JSON API. The same has been allowed by both GitHub and Gitlab and the output is already readable via http://domain/user.keys endpoint. The benefit of allowing it via the API are twofold: first this is a structured output and second it can be CORS-enabled. As a privacy precaution the `Title` property is set to an empty string if the request is unauthenticated. Fixes: #30681
1 parent e80466f commit 693db80

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

routers/api/v1/api.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,6 @@ func Routes() *web.Route {
945945
// Users (requires user scope)
946946
m.Group("/users", func() {
947947
m.Group("/{username}", func() {
948-
m.Get("/keys", user.ListPublicKeys)
949948
m.Get("/gpg_keys", user.ListGPGKeys)
950949

951950
m.Get("/followers", user.ListFollowers)
@@ -960,6 +959,13 @@ func Routes() *web.Route {
960959
}, context.UserAssignmentAPI())
961960
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken())
962961

962+
// Users SSH keys (publicly readable)
963+
m.Group("/users", func() {
964+
m.Group("/{username}", func() {
965+
m.Get("/keys", user.ListPublicKeys)
966+
}, context.UserAssignmentAPI())
967+
})
968+
963969
// Users (requires user scope)
964970
m.Group("/user", func() {
965971
m.Get("", user.GetAuthenticatedUser)

routers/api/v1/user/key.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
std_ctx "context"
88
"fmt"
99
"net/http"
10+
"strings"
1011

1112
asymkey_model "code.gitea.io/gitea/models/asymkey"
1213
"code.gitea.io/gitea/models/db"
@@ -89,8 +90,16 @@ func listPublicKeys(ctx *context.APIContext, user *user_model.User) {
8990
apiKeys := make([]*api.PublicKey, len(keys))
9091
for i := range keys {
9192
apiKeys[i] = convert.ToPublicKey(apiLink, keys[i])
92-
if ctx.Doer.IsAdmin || ctx.Doer.ID == keys[i].OwnerID {
93-
apiKeys[i], _ = appendPrivateInformation(ctx, apiKeys[i], keys[i], user)
93+
if ctx.Doer != nil {
94+
if ctx.Doer.IsAdmin || ctx.Doer.ID == keys[i].OwnerID {
95+
apiKeys[i], _ = appendPrivateInformation(ctx, apiKeys[i], keys[i], user)
96+
}
97+
} else {
98+
// unauthenticated requests will not receive the title property
99+
// to preserve privacy
100+
apiKeys[i].Title = ""
101+
// the key comment is truncated to preserve privacy
102+
apiKeys[i].Key = strings.Join(strings.Split(apiKeys[i].Key, " ")[:2], " ")
94103
}
95104
}
96105

0 commit comments

Comments
 (0)