-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add internal routes for ssh hook comands #1471
Changes from 5 commits
c015e57
af91984
d4570aa
dc5980e
c76983c
4f2c3a7
def1241
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package private | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because Go don't allow a package named There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ooh right, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And private.go, for that same reason... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @strk |
||
|
||
import ( | ||
"crypto/tls" | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
|
||
"code.gitea.io/gitea/modules/httplib" | ||
"code.gitea.io/gitea/modules/log" | ||
"code.gitea.io/gitea/modules/setting" | ||
) | ||
|
||
func newRequest(url, method string) *httplib.Request { | ||
return httplib.NewRequest(url, method).Header("Authorization", | ||
fmt.Sprintf("Bearer %s", setting.InternalToken)) | ||
} | ||
|
||
// Response internal request response | ||
type Response struct { | ||
Err string `json:"err"` | ||
} | ||
|
||
func decodeJSONError(resp *http.Response) *Response { | ||
var res Response | ||
err := json.NewDecoder(resp.Body).Decode(&res) | ||
if err != nil { | ||
res.Err = err.Error() | ||
} | ||
return &res | ||
} | ||
|
||
// UpdatePublicKeyUpdated update publick key updates | ||
func UpdatePublicKeyUpdated(keyID int64) error { | ||
// Ask for running deliver hook and test pull request tasks. | ||
reqURL := setting.LocalURL + fmt.Sprintf("internal/ssh/%d/update", keyID) | ||
log.GitLogger.Trace("UpdatePublicKeyUpdated: %s", reqURL) | ||
|
||
resp, err := newRequest(reqURL, "POST").SetTLSClientConfig(&tls.Config{ | ||
InsecureSkipVerify: true, | ||
}).Response() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
resp.Body.Close() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. |
||
if resp.StatusCode/100 != 2 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Valid if the StatusCode is in 200...299 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just copy the code from https://github.com/go-gitea/gitea/blob/master/cmd/hook.go#L224 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, got it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lunny Please add a comment above as it's not clear why this check is here :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. |
||
return fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err) | ||
} | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ import ( | |
"code.gitea.io/gitea/modules/user" | ||
|
||
"github.com/Unknwon/com" | ||
"github.com/dgrijalva/jwt-go" | ||
_ "github.com/go-macaron/cache/memcache" // memcache plugin for cache | ||
_ "github.com/go-macaron/cache/redis" | ||
"github.com/go-macaron/session" | ||
|
@@ -443,14 +444,15 @@ var ( | |
ShowFooterTemplateLoadTime bool | ||
|
||
// Global setting objects | ||
Cfg *ini.File | ||
CustomPath string // Custom directory path | ||
CustomConf string | ||
CustomPID string | ||
ProdMode bool | ||
RunUser string | ||
IsWindows bool | ||
HasRobotsTxt bool | ||
Cfg *ini.File | ||
CustomPath string // Custom directory path | ||
CustomConf string | ||
CustomPID string | ||
ProdMode bool | ||
RunUser string | ||
IsWindows bool | ||
HasRobotsTxt bool | ||
InternalToken string // internal access token | ||
) | ||
|
||
// DateLang transforms standard language locale name to corresponding value in datetime plugin. | ||
|
@@ -765,6 +767,43 @@ please consider changing to GITEA_CUSTOM`) | |
ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER") | ||
MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6) | ||
ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false) | ||
InternalToken = sec.Key("INTERNAL_TOKEN").String() | ||
if len(InternalToken) == 0 { | ||
secretBytes := make([]byte, 32) | ||
_, err := io.ReadFull(rand.Reader, secretBytes) | ||
if err != nil { | ||
log.Fatal(4, "Error reading random bytes: %v", err) | ||
} | ||
|
||
secretKey := base64.RawURLEncoding.EncodeToString(secretBytes) | ||
|
||
now := time.Now() | ||
InternalToken, err = jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ | ||
"nbf": now.Unix(), | ||
}).SignedString([]byte(secretKey)) | ||
|
||
if err != nil { | ||
log.Fatal(4, "Error generate internal token: %v", err) | ||
} | ||
|
||
// Save secret | ||
cfgSave := ini.Empty() | ||
if com.IsFile(CustomConf) { | ||
// Keeps custom settings if there is already something. | ||
if err := cfgSave.Append(CustomConf); err != nil { | ||
log.Error(4, "Failed to load custom conf '%s': %v", CustomConf, err) | ||
} | ||
} | ||
|
||
cfgSave.Section("security").Key("INTERNAL_TOKEN").SetValue(InternalToken) | ||
|
||
if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil { | ||
log.Fatal(4, "Failed to create '%s': %v", CustomConf, err) | ||
} | ||
if err := cfgSave.SaveTo(CustomConf); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see a reason to keep that token in the Ini file either, just have it randomly generated upon start and let it die/regenerate on restart There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because we have to share the token between There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @strk There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. got it, thanks |
||
log.Fatal(4, "Error saving generated JWT Secret to custom config: %v", err) | ||
} | ||
} | ||
|
||
sec = Cfg.Section("attachment") | ||
AttachmentPath = sec.Key("PATH").MustString(path.Join(AppDataPath, "attachments")) | ||
|
@@ -935,7 +974,6 @@ var Service struct { | |
EnableOpenIDSignUp bool | ||
OpenIDWhitelist []*regexp.Regexp | ||
OpenIDBlacklist []*regexp.Regexp | ||
|
||
} | ||
|
||
func newService() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright 2017 The Gitea Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package private includes all internal routes. The package name internal is ideal but Golang is not allowed, so we use private as package name instead. | ||
package private | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I will change all There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NVM actually, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe you can just call it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just realized there already is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @typeless it's not only for ssh, it's also for hooks commands. The hooks commands will be fired by both SSH and HTTPS. So I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bkcsoft done. |
||
|
||
import ( | ||
"strings" | ||
|
||
"code.gitea.io/gitea/models" | ||
"code.gitea.io/gitea/modules/setting" | ||
macaron "gopkg.in/macaron.v1" | ||
) | ||
|
||
// CheckInternalToken check internal token is set | ||
func CheckInternalToken(ctx *macaron.Context) { | ||
tokens := ctx.Req.Header.Get("Authorization") | ||
fields := strings.Fields(tokens) | ||
if len(fields) != 2 || fields[0] != "Bearer" || fields[1] != setting.InternalToken { | ||
ctx.Error(403) | ||
} | ||
} | ||
|
||
// UpdatePublicKey update publick key updates | ||
func UpdatePublicKey(ctx *macaron.Context) { | ||
keyID := ctx.ParamsInt64(":id") | ||
if err := models.UpdatePublicKeyUpdated(keyID); err != nil { | ||
ctx.JSON(500, map[string]interface{}{ | ||
"err": err.Error(), | ||
}) | ||
return | ||
} | ||
|
||
ctx.PlainText(200, []byte("success")) | ||
} | ||
|
||
// RegisterRoutes registers all internal APIs routes to web application. | ||
// These APIs will be invoked by internal commands for example `gitea serv` and etc. | ||
func RegisterRoutes(m *macaron.Macaron) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We really need to start doing this in more places ❤️ |
||
m.Group("/", func() { | ||
m.Post("/ssh/:id/update", UpdatePublicKey) | ||
}, CheckInternalToken) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one should go in
/api/internal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.