From 7f7c2c091873ede49cc3191d67101d6dfb184081 Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 6 Feb 2026 04:43:17 +0100 Subject: [PATCH] feat: show note that user has no SSH keys (#11143) - Resolves forgejo/forgejo#11064 - Show a note similar to that of GPG keys, when a user has no SSH keys uploaded through Forgejo. The content is recognized as a comment in SSH authorized files format and ends with a newline. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11143 Reviewed-by: Mathieu Fenniak Reviewed-by: Beowulf Co-authored-by: Gusted Co-committed-by: Gusted --- routers/web/user/home.go | 5 +++++ tests/integration/user_test.go | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 618ce3c608..a7e24d79bb 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -713,6 +713,11 @@ func ShowSSHKeys(ctx *context.Context) { buf.WriteString(keys[i].OmitEmail()) buf.WriteString("\n") } + + if buf.Len() == 0 { + buf.WriteString("# Note: This user hasn't uploaded any SSH keys.\n") + } + ctx.PlainTextBytes(http.StatusOK, buf.Bytes()) } diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index 0109ab2435..2eb82f1c8a 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -1237,3 +1237,21 @@ func TestActivateEmailAddress(t *testing.T) { unittest.AssertNotExistsBean(t, &auth_model.AuthorizationToken{ID: authToken.ID}) unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{UID: user2.ID, IsActivated: true, Email: "newemail@example.org"}) } + +func TestExportUserSSHKeys(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + t.Run("No exported keys", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + resp := MakeRequest(t, NewRequest(t, "GET", "/user1.keys"), http.StatusOK) + + assert.Equal(t, "# Note: This user hasn't uploaded any SSH keys.\n", resp.Body.String()) + }) + + t.Run("Exported key", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + resp := MakeRequest(t, NewRequest(t, "GET", "/user2.keys"), http.StatusOK) + + assert.Equal(t, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDWVj0fQ5N8wNc0LVNA41wDLYJ89ZIbejrPfg/avyj3u/ZohAKsQclxG4Ju0VirduBFF9EOiuxoiFBRr3xRpqzpsZtnMPkWVWb+akZwBFAx8p+jKdy4QXR/SZqbVobrGwip2UjSrri1CtBxpJikojRIZfCnDaMOyd9Jp6KkujvniFzUWdLmCPxUE9zhTaPu0JsEP7MW0m6yx7ZUhHyfss+NtqmFTaDO+QlMR7L2QkDliN2Jl3Xa3PhuWnKJfWhdAq1Cw4oraKUOmIgXLkuiuxVQ6mD3AiFupkmfqdHq6h+uHHmyQqv3gU+/sD8GbGAhf6ftqhTsXjnv1Aj4R8NoDf9BS6KRkzkeun5UisSzgtfQzjOMEiJtmrep2ZQrMGahrXa+q4VKr0aKJfm+KlLfwm/JztfsBcqQWNcTURiCFqz+fgZw0Ey/de0eyMzldYTdXXNRYCKjs9bvBK+6SSXRM7AhftfQ0ZuoW5+gtinPrnmoOaSCEJbAiEiTO/BzOHgowiM=\n", resp.Body.String()) + }) +}