Bläddra i källkod

AuthorizedKeysCommand should not query db directly (#9371)

* AuthorizedKeysCommand should not query db directly

* Update routers/private/internal.go

* Fix import order
tags/v1.11.0-rc1
zeripath 4 år sedan
förälder
incheckning
d1a49977b0

+ 4
- 6
cmd/keys.go Visa fil

"fmt" "fmt"
"strings" "strings"


"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/private"


"github.com/urfave/cli" "github.com/urfave/cli"
) )
return errors.New("No key type and content provided") return errors.New("No key type and content provided")
} }


if err := initDBDisableConsole(true); err != nil {
return err
}
setup("keys.log")


publicKey, err := models.SearchPublicKeyByContent(content)
authorizedString, err := private.AuthorizedPublicKeyByContent(content)
if err != nil { if err != nil {
return err return err
} }
fmt.Println(publicKey.AuthorizedString())
fmt.Println(strings.TrimSpace(authorizedString))
return nil return nil
} }

+ 1
- 0
docs/content/doc/usage/command-line.en-us.md Visa fil

NB: opensshd requires the gitea program to be owned by root and not NB: opensshd requires the gitea program to be owned by root and not
writable by group or others. The program must be specified by an absolute writable by group or others. The program must be specified by an absolute
path. path.
NB: Gitea must be running for this command to succeed.


#### migrate #### migrate
Migrates the database. This command can be used to run other commands before starting the server for the first time. Migrates the database. This command can be used to run other commands before starting the server for the first time.

+ 41
- 40
integrations/cmd_keys_test.go Visa fil

"bytes" "bytes"
"flag" "flag"
"io" "io"
"net/url"
"os" "os"
"testing" "testing"


) )


func Test_CmdKeys(t *testing.T) { func Test_CmdKeys(t *testing.T) {
defer prepareTestEnv(t)()
onGiteaRun(t, func(*testing.T, *url.URL) {
tests := []struct {
name string
args []string
wantErr bool
expectedOutput string
}{
{"test_empty_1", []string{"keys", "--username=git", "--type=test", "--content=test"}, true, ""},
{"test_empty_2", []string{"keys", "-e", "git", "-u", "git", "-t", "test", "-k", "test"}, true, ""},
{"with_key",
[]string{"keys", "-e", "git", "-u", "git", "-t", "ssh-rsa", "-k", "AAAAB3NzaC1yc2EAAAADAQABAAABgQDWVj0fQ5N8wNc0LVNA41wDLYJ89ZIbejrPfg/avyj3u/ZohAKsQclxG4Ju0VirduBFF9EOiuxoiFBRr3xRpqzpsZtnMPkWVWb+akZwBFAx8p+jKdy4QXR/SZqbVobrGwip2UjSrri1CtBxpJikojRIZfCnDaMOyd9Jp6KkujvniFzUWdLmCPxUE9zhTaPu0JsEP7MW0m6yx7ZUhHyfss+NtqmFTaDO+QlMR7L2QkDliN2Jl3Xa3PhuWnKJfWhdAq1Cw4oraKUOmIgXLkuiuxVQ6mD3AiFupkmfqdHq6h+uHHmyQqv3gU+/sD8GbGAhf6ftqhTsXjnv1Aj4R8NoDf9BS6KRkzkeun5UisSzgtfQzjOMEiJtmrep2ZQrMGahrXa+q4VKr0aKJfm+KlLfwm/JztfsBcqQWNcTURiCFqz+fgZw0Ey/de0eyMzldYTdXXNRYCKjs9bvBK+6SSXRM7AhftfQ0ZuoW5+gtinPrnmoOaSCEJbAiEiTO/BzOHgowiM="},
false,
"# gitea public key\ncommand=\"" + setting.AppPath + " --config='" + setting.CustomConf + "' serv key-1\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDWVj0fQ5N8wNc0LVNA41wDLYJ89ZIbejrPfg/avyj3u/ZohAKsQclxG4Ju0VirduBFF9EOiuxoiFBRr3xRpqzpsZtnMPkWVWb+akZwBFAx8p+jKdy4QXR/SZqbVobrGwip2UjSrri1CtBxpJikojRIZfCnDaMOyd9Jp6KkujvniFzUWdLmCPxUE9zhTaPu0JsEP7MW0m6yx7ZUhHyfss+NtqmFTaDO+QlMR7L2QkDliN2Jl3Xa3PhuWnKJfWhdAq1Cw4oraKUOmIgXLkuiuxVQ6mD3AiFupkmfqdHq6h+uHHmyQqv3gU+/sD8GbGAhf6ftqhTsXjnv1Aj4R8NoDf9BS6KRkzkeun5UisSzgtfQzjOMEiJtmrep2ZQrMGahrXa+q4VKr0aKJfm+KlLfwm/JztfsBcqQWNcTURiCFqz+fgZw0Ey/de0eyMzldYTdXXNRYCKjs9bvBK+6SSXRM7AhftfQ0ZuoW5+gtinPrnmoOaSCEJbAiEiTO/BzOHgowiM= user2@localhost\n",
},
{"invalid", []string{"keys", "--not-a-flag=git"}, true, "Incorrect Usage: flag provided but not defined: -not-a-flag\n\n"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
realStdout := os.Stdout //Backup Stdout
r, w, _ := os.Pipe()
os.Stdout = w


tests := []struct {
name string
args []string
wantErr bool
expectedOutput string
}{
{"test_empty_1", []string{"keys", "--username=git", "--type=test", "--content=test"}, true, ""},
{"test_empty_2", []string{"keys", "-e", "git", "-u", "git", "-t", "test", "-k", "test"}, true, ""},
{"with_key",
[]string{"keys", "-e", "git", "-u", "git", "-t", "ssh-rsa", "-k", "AAAAB3NzaC1yc2EAAAADAQABAAABgQDWVj0fQ5N8wNc0LVNA41wDLYJ89ZIbejrPfg/avyj3u/ZohAKsQclxG4Ju0VirduBFF9EOiuxoiFBRr3xRpqzpsZtnMPkWVWb+akZwBFAx8p+jKdy4QXR/SZqbVobrGwip2UjSrri1CtBxpJikojRIZfCnDaMOyd9Jp6KkujvniFzUWdLmCPxUE9zhTaPu0JsEP7MW0m6yx7ZUhHyfss+NtqmFTaDO+QlMR7L2QkDliN2Jl3Xa3PhuWnKJfWhdAq1Cw4oraKUOmIgXLkuiuxVQ6mD3AiFupkmfqdHq6h+uHHmyQqv3gU+/sD8GbGAhf6ftqhTsXjnv1Aj4R8NoDf9BS6KRkzkeun5UisSzgtfQzjOMEiJtmrep2ZQrMGahrXa+q4VKr0aKJfm+KlLfwm/JztfsBcqQWNcTURiCFqz+fgZw0Ey/de0eyMzldYTdXXNRYCKjs9bvBK+6SSXRM7AhftfQ0ZuoW5+gtinPrnmoOaSCEJbAiEiTO/BzOHgowiM="},
false,
"# gitea public key\ncommand=\"" + setting.AppPath + " --config='" + setting.CustomConf + "' serv key-1\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDWVj0fQ5N8wNc0LVNA41wDLYJ89ZIbejrPfg/avyj3u/ZohAKsQclxG4Ju0VirduBFF9EOiuxoiFBRr3xRpqzpsZtnMPkWVWb+akZwBFAx8p+jKdy4QXR/SZqbVobrGwip2UjSrri1CtBxpJikojRIZfCnDaMOyd9Jp6KkujvniFzUWdLmCPxUE9zhTaPu0JsEP7MW0m6yx7ZUhHyfss+NtqmFTaDO+QlMR7L2QkDliN2Jl3Xa3PhuWnKJfWhdAq1Cw4oraKUOmIgXLkuiuxVQ6mD3AiFupkmfqdHq6h+uHHmyQqv3gU+/sD8GbGAhf6ftqhTsXjnv1Aj4R8NoDf9BS6KRkzkeun5UisSzgtfQzjOMEiJtmrep2ZQrMGahrXa+q4VKr0aKJfm+KlLfwm/JztfsBcqQWNcTURiCFqz+fgZw0Ey/de0eyMzldYTdXXNRYCKjs9bvBK+6SSXRM7AhftfQ0ZuoW5+gtinPrnmoOaSCEJbAiEiTO/BzOHgowiM= user2@localhost\n\n",
},
{"invalid", []string{"keys", "--not-a-flag=git"}, true, "Incorrect Usage: flag provided but not defined: -not-a-flag\n\n"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
realStdout := os.Stdout //Backup Stdout
r, w, _ := os.Pipe()
os.Stdout = w

set := flag.NewFlagSet("keys", 0)
_ = set.Parse(tt.args)
context := cli.NewContext(&cli.App{Writer: os.Stdout}, set, nil)
err := cmd.CmdKeys.Run(context)
if (err != nil) != tt.wantErr {
t.Errorf("CmdKeys.Run() error = %v, wantErr %v", err, tt.wantErr)
}
w.Close()
var buf bytes.Buffer
io.Copy(&buf, r)
commandOutput := buf.String()
if tt.expectedOutput != commandOutput {
t.Errorf("expectedOutput: %#v, commandOutput: %#v", tt.expectedOutput, commandOutput)
}
//Restore stdout
os.Stdout = realStdout
})
}
set := flag.NewFlagSet("keys", 0)
_ = set.Parse(tt.args)
context := cli.NewContext(&cli.App{Writer: os.Stdout}, set, nil)
err := cmd.CmdKeys.Run(context)
if (err != nil) != tt.wantErr {
t.Errorf("CmdKeys.Run() error = %v, wantErr %v", err, tt.wantErr)
}
w.Close()
var buf bytes.Buffer
io.Copy(&buf, r)
commandOutput := buf.String()
if tt.expectedOutput != commandOutput {
t.Errorf("expectedOutput: %#v, commandOutput: %#v", tt.expectedOutput, commandOutput)
}
//Restore stdout
os.Stdout = realStdout
})
}
})
} }

+ 25
- 0
modules/private/key.go Visa fil



import ( import (
"fmt" "fmt"
"io/ioutil"
"net/http"


"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
) )
} }
return nil return nil
} }

// AuthorizedPublicKeyByContent searches content as prefix (leak e-mail part)
// and returns public key found.
func AuthorizedPublicKeyByContent(content string) (string, error) {
// Ask for running deliver hook and test pull request tasks.
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/authorized_keys")
req := newInternalRequest(reqURL, "POST")
req.Param("content", content)
resp, err := req.Response()
if err != nil {
return "", err
}

defer resp.Body.Close()

// All 2XX status codes are accepted and others will return an error
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err)
}
bs, err := ioutil.ReadAll(resp.Body)

return string(bs), err
}

+ 1
- 0
routers/private/internal.go Visa fil

// These APIs will be invoked by internal commands for example `gitea serv` and etc. // These APIs will be invoked by internal commands for example `gitea serv` and etc.
func RegisterRoutes(m *macaron.Macaron) { func RegisterRoutes(m *macaron.Macaron) {
m.Group("/", func() { m.Group("/", func() {
m.Post("/ssh/authorized_keys", AuthorizedPublicKeyByContent)
m.Post("/ssh/:id/update/:repoid", UpdatePublicKeyInRepo) m.Post("/ssh/:id/update/:repoid", UpdatePublicKeyInRepo)
m.Get("/hook/pre-receive/:owner/:repo", HookPreReceive) m.Get("/hook/pre-receive/:owner/:repo", HookPreReceive)
m.Get("/hook/post-receive/:owner/:repo", HookPostReceive) m.Get("/hook/post-receive/:owner/:repo", HookPostReceive)

+ 21
- 4
routers/private/key.go Visa fil

package private package private


import ( import (
"net/http"

"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"


keyID := ctx.ParamsInt64(":id") keyID := ctx.ParamsInt64(":id")
repoID := ctx.ParamsInt64(":repoid") repoID := ctx.ParamsInt64(":repoid")
if err := models.UpdatePublicKeyUpdated(keyID); err != nil { if err := models.UpdatePublicKeyUpdated(keyID); err != nil {
ctx.JSON(500, map[string]interface{}{
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(), "err": err.Error(),
}) })
return return
ctx.PlainText(200, []byte("success")) ctx.PlainText(200, []byte("success"))
return return
} }
ctx.JSON(500, map[string]interface{}{
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(), "err": err.Error(),
}) })
return return
} }
deployKey.UpdatedUnix = timeutil.TimeStampNow() deployKey.UpdatedUnix = timeutil.TimeStampNow()
if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil { if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil {
ctx.JSON(500, map[string]interface{}{
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(), "err": err.Error(),
}) })
return return
} }


ctx.PlainText(200, []byte("success"))
ctx.PlainText(http.StatusOK, []byte("success"))
}

// AuthorizedPublicKeyByContent searches content as prefix (leak e-mail part)
// and returns public key found.
func AuthorizedPublicKeyByContent(ctx *macaron.Context) {
content := ctx.Query("content")

publicKey, err := models.SearchPublicKeyByContent(content)
if err != nil {
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(),
})
return
}
ctx.PlainText(http.StatusOK, []byte(publicKey.AuthorizedString()))
} }

Laddar…
Avbryt
Spara