AuthorizedKeysCommand should not query db directly (#9371)
* AuthorizedKeysCommand should not query db directly * Update routers/private/internal.go * Fix import order
This commit is contained in:
		
							parent
							
								
									1707f59966
								
							
						
					
					
						commit
						d1a49977b0
					
				
					 6 changed files with 93 additions and 50 deletions
				
			
		
							
								
								
									
										10
									
								
								cmd/keys.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								cmd/keys.go
									
									
									
									
									
								
							|  | @ -9,7 +9,7 @@ import ( | |||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/modules/private" | ||||
| 
 | ||||
| 	"github.com/urfave/cli" | ||||
| ) | ||||
|  | @ -62,14 +62,12 @@ func runKeys(c *cli.Context) error { | |||
| 		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 { | ||||
| 		return err | ||||
| 	} | ||||
| 	fmt.Println(publicKey.AuthorizedString()) | ||||
| 	fmt.Println(strings.TrimSpace(authorizedString)) | ||||
| 	return nil | ||||
| } | ||||
|  |  | |||
|  | @ -281,6 +281,7 @@ provided key. You should also set the value | |||
| 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 | ||||
| path. | ||||
| NB: Gitea must be running for this command to succeed. | ||||
| 
 | ||||
| #### migrate | ||||
| Migrates the database. This command can be used to run other commands before starting the server for the first time.   | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ import ( | |||
| 	"bytes" | ||||
| 	"flag" | ||||
| 	"io" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| 	"testing" | ||||
| 
 | ||||
|  | @ -18,8 +19,7 @@ import ( | |||
| ) | ||||
| 
 | ||||
| func Test_CmdKeys(t *testing.T) { | ||||
| 	defer prepareTestEnv(t)() | ||||
| 
 | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		tests := []struct { | ||||
| 			name           string | ||||
| 			args           []string | ||||
|  | @ -31,7 +31,7 @@ func Test_CmdKeys(t *testing.T) { | |||
| 			{"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", | ||||
| 				"# 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"}, | ||||
| 		} | ||||
|  | @ -59,4 +59,5 @@ func Test_CmdKeys(t *testing.T) { | |||
| 				os.Stdout = realStdout | ||||
| 			}) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ package private | |||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| ) | ||||
|  | @ -27,3 +29,26 @@ func UpdatePublicKeyInRepo(keyID, repoID int64) error { | |||
| 	} | ||||
| 	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 | ||||
| } | ||||
|  |  | |||
|  | @ -76,6 +76,7 @@ func CheckUnitUser(ctx *macaron.Context) { | |||
| // These APIs will be invoked by internal commands for example `gitea serv` and etc.
 | ||||
| func RegisterRoutes(m *macaron.Macaron) { | ||||
| 	m.Group("/", func() { | ||||
| 		m.Post("/ssh/authorized_keys", AuthorizedPublicKeyByContent) | ||||
| 		m.Post("/ssh/:id/update/:repoid", UpdatePublicKeyInRepo) | ||||
| 		m.Get("/hook/pre-receive/:owner/:repo", HookPreReceive) | ||||
| 		m.Get("/hook/post-receive/:owner/:repo", HookPostReceive) | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ | |||
| package private | ||||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 
 | ||||
|  | @ -17,7 +19,7 @@ func UpdatePublicKeyInRepo(ctx *macaron.Context) { | |||
| 	keyID := ctx.ParamsInt64(":id") | ||||
| 	repoID := ctx.ParamsInt64(":repoid") | ||||
| 	if err := models.UpdatePublicKeyUpdated(keyID); err != nil { | ||||
| 		ctx.JSON(500, map[string]interface{}{ | ||||
| 		ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ | ||||
| 			"err": err.Error(), | ||||
| 		}) | ||||
| 		return | ||||
|  | @ -29,18 +31,33 @@ func UpdatePublicKeyInRepo(ctx *macaron.Context) { | |||
| 			ctx.PlainText(200, []byte("success")) | ||||
| 			return | ||||
| 		} | ||||
| 		ctx.JSON(500, map[string]interface{}{ | ||||
| 		ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ | ||||
| 			"err": err.Error(), | ||||
| 		}) | ||||
| 		return | ||||
| 	} | ||||
| 	deployKey.UpdatedUnix = timeutil.TimeStampNow() | ||||
| 	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(), | ||||
| 		}) | ||||
| 		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())) | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue