Skip to content

Commit

Permalink
api: Allow unauthenticated access to user's SSH keys
Browse files Browse the repository at this point in the history
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: go-gitea#30681
  • Loading branch information
wiktor-k committed Apr 29, 2024
1 parent e80466f commit 693db80
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
8 changes: 7 additions & 1 deletion routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,6 @@ func Routes() *web.Route {
// Users (requires user scope)
m.Group("/users", func() {
m.Group("/{username}", func() {
m.Get("/keys", user.ListPublicKeys)
m.Get("/gpg_keys", user.ListGPGKeys)

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

// Users SSH keys (publicly readable)
m.Group("/users", func() {
m.Group("/{username}", func() {
m.Get("/keys", user.ListPublicKeys)
}, context.UserAssignmentAPI())
})

// Users (requires user scope)
m.Group("/user", func() {
m.Get("", user.GetAuthenticatedUser)
Expand Down
13 changes: 11 additions & 2 deletions routers/api/v1/user/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
std_ctx "context"
"fmt"
"net/http"
"strings"

asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
Expand Down Expand Up @@ -89,8 +90,16 @@ func listPublicKeys(ctx *context.APIContext, user *user_model.User) {
apiKeys := make([]*api.PublicKey, len(keys))
for i := range keys {
apiKeys[i] = convert.ToPublicKey(apiLink, keys[i])
if ctx.Doer.IsAdmin || ctx.Doer.ID == keys[i].OwnerID {
apiKeys[i], _ = appendPrivateInformation(ctx, apiKeys[i], keys[i], user)
if ctx.Doer != nil {
if ctx.Doer.IsAdmin || ctx.Doer.ID == keys[i].OwnerID {
apiKeys[i], _ = appendPrivateInformation(ctx, apiKeys[i], keys[i], user)
}
} else {
// unauthenticated requests will not receive the title property
// to preserve privacy
apiKeys[i].Title = ""
// the key comment is truncated to preserve privacy
apiKeys[i].Key = strings.Join(strings.Split(apiKeys[i].Key, " ")[:2], " ")
}
}

Expand Down

0 comments on commit 693db80

Please sign in to comment.