refactor to use net/http

This commit is contained in:
2025-05-30 14:43:47 +05:30
parent df9478a920
commit e5d07f0ce6
5 changed files with 121 additions and 129 deletions

View File

@@ -11,7 +11,6 @@ import (
type Config struct { type Config struct {
ForgeEndpoint string `json:"forge_url"` ForgeEndpoint string `json:"forge_url"`
ForgeToken string `json:"token"`
Keys []string `json:"keys"` Keys []string `json:"keys"`
} }

View File

@@ -3,10 +3,6 @@ package main
import ( import (
"context" "context"
"net/http" "net/http"
"slices"
"strings"
"src.opensuse.org/autogits/common"
) )
func ConfigMiddleWare(cfg *Config) func(http.Handler) http.Handler { func ConfigMiddleWare(cfg *Config) func(http.Handler) http.Handler {
@@ -17,38 +13,3 @@ func ConfigMiddleWare(cfg *Config) func(http.Handler) http.Handler {
}) })
} }
} }
func ProxyAuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
header := r.Header.Get("Authorization")
if header == "" {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
token_arr := strings.Split(header, " ")
if len(token_arr) != 2 {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
if !strings.EqualFold(token_arr[0], "Bearer") {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
token := token_arr[1]
config, ok := r.Context().Value(configKey).(*Config)
if !ok {
common.LogError("Config missing from context")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
if !slices.Contains(config.Keys, token) {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}

View File

@@ -7,17 +7,20 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"time" "os"
"slices"
"strings"
"src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
) )
type Status struct { type Status struct {
Context string `json:"context"` Context string `json:"context"`
Description string `json:"description"` State string `json:"state"`
TargetUrl string `json:"target_url"`
}
type StatusInput struct {
State string `json:"state"` State string `json:"state"`
TargetUrl string `json:"target_url"` TargetUrl string `json:"target_url"`
} }
@@ -38,28 +41,12 @@ func main() {
return return
} }
r := chi.NewRouter() mux := http.NewServeMux()
r.Use(ConfigMiddleWare(config)) mux.Handle("/repos/{owner}/{repo}/statuses/{sha}", ConfigMiddleWare(config)(http.HandlerFunc(StatusProxy)))
r.Use(middleware.RequestID)
r.Use(middleware.RealIP)
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(middleware.Timeout(60 * time.Second))
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hi"))
})
r.Route("/repos/{owner}/{repo}/statuses/{sha}", func(r chi.Router) {
r.Use(ProxyAuthMiddleware)
r.Post("/", StatusProxy)
})
common.LogInfo("server up and listening on :3000") common.LogInfo("server up and listening on :3000")
err = http.ListenAndServe(":3000", r) err = http.ListenAndServe(":3000", mux)
if err != nil { if err != nil {
common.LogError("Server failed to start up", err) common.LogError("Server failed to start up", err)
@@ -68,11 +55,42 @@ func main() {
} }
func StatusProxy(w http.ResponseWriter, r *http.Request) { func StatusProxy(w http.ResponseWriter, r *http.Request) {
owner := chi.URLParam(r, "owner") if r.Method == http.MethodPost {
repo := chi.URLParam(r, "repo")
sha := chi.URLParam(r, "sha")
config, ok := r.Context().Value(configKey).(*Config) config, ok := r.Context().Value(configKey).(*Config)
if !ok {
common.LogError("Config missing from context")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
header := r.Header.Get("Authorization")
if header == "" {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
token_arr := strings.Split(header, " ")
if len(token_arr) != 2 {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
if !strings.EqualFold(token_arr[0], "Bearer") {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
token := token_arr[1]
if !slices.Contains(config.Keys, token) {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
owner := r.PathValue("owner")
repo := r.PathValue("repo")
sha := r.PathValue("sha")
if !ok { if !ok {
common.LogError("Failed to get config from context, is it set?") common.LogError("Failed to get config from context, is it set?")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@@ -80,12 +98,18 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) {
posturl := fmt.Sprintf("%s/repos/%s/%s/statuses/%s", config.ForgeEndpoint, owner, repo, sha) posturl := fmt.Sprintf("%s/repos/%s/%s/statuses/%s", config.ForgeEndpoint, owner, repo, sha)
decoder := json.NewDecoder(r.Body) decoder := json.NewDecoder(r.Body)
var status Status var statusinput StatusInput
err := decoder.Decode(&status) err := decoder.Decode(&statusinput)
if err != nil { if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return return
} }
status := Status{
Context: "Build in obs",
State: statusinput.State,
TargetUrl: statusinput.TargetUrl,
}
status_payload, err := json.Marshal(status) status_payload, err := json.Marshal(status)
if err != nil { if err != nil {
@@ -99,9 +123,16 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return return
} }
ForgeToken := os.Getenv("GITEA_TOKEN")
if ForgeToken == "" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
common.LogError("GITEA_TOKEN was not set, all requests will fail")
return
}
req.Header.Add("Content-Type", "Content-Type") req.Header.Add("Content-Type", "Content-Type")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", config.ForgeToken)) req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", ForgeToken))
resp, err := client.Do(req) resp, err := client.Do(req)
@@ -131,4 +162,8 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
common.LogError("Error copying response body: %v", err) common.LogError("Error copying response body: %v", err)
} }
} else {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
} }

1
go.mod
View File

@@ -16,7 +16,6 @@ require (
require ( require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/go-chi/chi/v5 v5.2.1 // indirect
github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect github.com/go-openapi/analysis v0.23.0 // indirect

2
go.sum
View File

@@ -3,8 +3,6 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=