M gitsrht-update-hook/go.mod => gitsrht-update-hook/go.mod +1 -0
@@ 3,6 3,7 @@ module git.sr.ht/~sircmpwn/git.sr.ht/gitsrht-update-hook
go 1.13
require (
+ github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001
github.com/go-redis/redis v6.15.6+incompatible
github.com/google/uuid v1.1.1
github.com/lib/pq v1.2.0
M gitsrht-update-hook/go.sum => gitsrht-update-hook/go.sum +2 -0
@@ 6,6 6,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
+github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001 h1:/UMxx5lGDg30aioUL9e7xJnbJfJeX7vhcm57fa5udaI=
+github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-redis/redis v6.15.6+incompatible h1:H9evprGPLI8+ci7fxQx6WNZHJSb7be8FqJQRhdQZ5Sg=
M gitsrht-update-hook/post-update.go => gitsrht-update-hook/post-update.go +3 -1
@@ 32,7 32,7 @@ type DbInfo struct {
RepoName string
Visibility string
OwnerUsername string
- OwnerToken string
+ OwnerToken *string
AsyncWebhooks []WebhookSubscription
SyncWebhooks []WebhookSubscription
}
@@ 136,6 136,8 @@ func postUpdate() {
printAutocreateInfo(context)
}
+ initSubmitter()
+
payload := WebhookPayload{
Push: pushUuid,
Pusher: context.User,
M gitsrht-update-hook/submitter.go => gitsrht-update-hook/submitter.go +55 -5
@@ 12,19 12,47 @@ import (
"strings"
"unicode/utf8"
+ "github.com/fernet/fernet-go"
"github.com/microcosm-cc/bluemonday"
"github.com/pkg/errors"
"gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing/object"
)
+var (
+ fernetKey *fernet.Key
+ clientId string
+)
+
+// TODO: Consider moving Fernet code to a shared SourceHut Go module
+func initSubmitter() {
+ netkey, ok := config.Get("sr.ht", "network-key")
+ if !ok {
+ logger.Fatal("Configuration error: [sr.ht].network-key missing")
+ }
+ var err error
+ fernetKey, err = fernet.DecodeKey(netkey)
+ if err != nil {
+ logger.Fatalf("Error decoding [sr.ht].network-key: %v", err)
+ }
+ clientId, ok = config.Get("git.sr.ht", "oauth-client-id")
+ if !ok {
+ logger.Fatal("Configuration error: [git.sr.ht].oauth-client-id missing")
+ }
+}
+
+type InternalRequestAuthorization struct {
+ ClientId string `json:"client_id"`
+ Username string `json:"username"`
+}
+
type BuildSubmitter interface {
// Return a list of build manifests and their names
FindManifests() (map[string]string, error)
// Get builds.sr.ht origin
GetBuildsOrigin() string
// Get builds.sr.ht OAuth token
- GetOauthToken() string
+ GetOauthToken() *string
// Get a checkout-able string to append to matching source URLs
GetCommitId() string
// Get the build note which corresponds to this commit
@@ 50,7 78,7 @@ type GitBuildSubmitter struct {
Commit *object.Commit
GitOrigin string
OwnerName string
- OwnerToken string
+ OwnerToken *string
RepoName string
Repository *git.Repository
Visibility string
@@ 110,7 138,7 @@ func (submitter GitBuildSubmitter) GetBuildsOrigin() string {
return submitter.BuildOrigin
}
-func (submitter GitBuildSubmitter) GetOauthToken() string {
+func (submitter GitBuildSubmitter) GetOauthToken() *string {
return submitter.OwnerToken
}
@@ 167,6 195,29 @@ type BuildSubmission struct {
Url string
}
+func configureRequestAuthorization(submitter BuildSubmitter,
+ req *http.Request) {
+
+ if submitter.GetOauthToken() != nil {
+ req.Header.Add("Authorization", fmt.Sprintf("token %s",
+ *submitter.GetOauthToken()))
+ } else {
+ auth := InternalRequestAuthorization{
+ ClientId: clientId,
+ Username: submitter.GetOwnerName(),
+ }
+ authPayload, err := json.Marshal(&auth)
+ if err != nil {
+ logger.Fatalf("Failed to marshal internal authorization: %v", err)
+ }
+ enc, err := fernet.EncryptAndSign(authPayload, fernetKey)
+ if err != nil {
+ logger.Fatalf("Failed to encrypt internal authorization: %v", err)
+ }
+ req.Header.Add("X-Srht-Authorization", string(enc))
+ }
+}
+
// TODO: Move this to scm.sr.ht
func SubmitBuild(submitter BuildSubmitter) ([]BuildSubmission, error) {
manifests, err := submitter.FindManifests()
@@ 204,8 255,7 @@ func SubmitBuild(submitter BuildSubmitter) ([]BuildSubmission, error) {
req, err := http.NewRequest("POST", fmt.Sprintf("%s/api/jobs",
submitter.GetBuildsOrigin()), body)
- req.Header.Add("Authorization", fmt.Sprintf("token %s",
- submitter.GetOauthToken()))
+ configureRequestAuthorization(submitter, req)
req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
M gitsrht/blueprints/email.py => gitsrht/blueprints/email.py +1 -1
@@ 13,7 13,7 @@ from gitsrht.git import Repository as GitRepository, commit_time, diffstat
from gitsrht.git import get_log
from scmsrht.access import get_repo_or_redir
from srht.config import cfg, cfgi, cfgb
-from srht.flask import loginrequired, current_user
+from srht.oauth import loginrequired, current_user
from srht.validation import Validation
from tempfile import NamedTemporaryFile
from textwrap import TextWrapper