From 244160e20e248ca0c927d14e624f1192c50b9008eb591b8f21a9e8736fee3aa1 Mon Sep 17 00:00:00 2001 From: Santiago Zarate Date: Thu, 30 Oct 2025 12:31:07 +0100 Subject: [PATCH 1/5] Update authorization headers For gitea API AuthorizationHeaderToken tokens must be prepended with "token" followed by a space, also fix content type --- gitea_status_proxy/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gitea_status_proxy/main.go b/gitea_status_proxy/main.go index 3ac6b0b..fc049a0 100644 --- a/gitea_status_proxy/main.go +++ b/gitea_status_proxy/main.go @@ -75,7 +75,7 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) { return } - if !strings.EqualFold(token_arr[0], "Bearer") { + if !strings.EqualFold(token_arr[0], "token") { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } @@ -131,8 +131,8 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) { return } - req.Header.Add("Content-Type", "Content-Type") - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", ForgeToken)) + req.Header.Add("Content-Type", "application/json") + req.Header.Add("Authorization", fmt.Sprintf("token %s", ForgeToken)) resp, err := client.Do(req) -- 2.51.1 From d083acfd1c40905397780d1e39f85c9e6face1c71141dd3a039917c203aef19c Mon Sep 17 00:00:00 2001 From: Santiago Zarate Date: Thu, 30 Oct 2025 12:33:34 +0100 Subject: [PATCH 2/5] Be more verbose about authentication errors --- gitea_status_proxy/main.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gitea_status_proxy/main.go b/gitea_status_proxy/main.go index fc049a0..b1a2e77 100644 --- a/gitea_status_proxy/main.go +++ b/gitea_status_proxy/main.go @@ -66,16 +66,19 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) { header := r.Header.Get("Authorization") if header == "" { + common.LogError("Authorization header not found") http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } token_arr := strings.Split(header, " ") if len(token_arr) != 2 { + common.LogError("Authorization header malformed") http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } if !strings.EqualFold(token_arr[0], "token") { + common.LogError("Token not found in Authorization header") http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } @@ -83,6 +86,7 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) { token := token_arr[1] if !slices.Contains(config.Keys, token) { + common.LogError("Provided token is not known") http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } -- 2.51.1 From 1b900e3202b1ab0ad08430e56abd2d20a231233466000c9dc99cccbaa63dffad Mon Sep 17 00:00:00 2001 From: Santiago Zarate Date: Thu, 30 Oct 2025 12:44:18 +0100 Subject: [PATCH 3/5] Properly proxy json input directly to gitea --- gitea_status_proxy/main.go | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/gitea_status_proxy/main.go b/gitea_status_proxy/main.go index b1a2e77..c02c85a 100644 --- a/gitea_status_proxy/main.go +++ b/gitea_status_proxy/main.go @@ -14,15 +14,11 @@ import ( "src.opensuse.org/autogits/common" ) -type Status struct { - Context string `json:"context"` - State string `json:"state"` - TargetUrl string `json:"target_url"` -} - type StatusInput struct { - State string `json:"state"` - TargetUrl string `json:"target_url"` + Description string `json:"description"` + Context string `json:"context"` + State string `json:"state"` + TargetUrl string `json:"target_url"` } func main() { @@ -108,13 +104,8 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } - status := Status{ - Context: "Build in obs", - State: statusinput.State, - TargetUrl: statusinput.TargetUrl, - } - status_payload, err := json.Marshal(status) + status_payload, err := json.Marshal(statusinput) if err != nil { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) -- 2.51.1 From 95c7770cad9d3cbffede47ef318183982aae556aee83e826f253981fea945860 Mon Sep 17 00:00:00 2001 From: Santiago Zarate Date: Fri, 31 Oct 2025 10:27:31 +0100 Subject: [PATCH 4/5] Change log level for auth errors --- gitea_status_proxy/main.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gitea_status_proxy/main.go b/gitea_status_proxy/main.go index c02c85a..7e6dbcf 100644 --- a/gitea_status_proxy/main.go +++ b/gitea_status_proxy/main.go @@ -55,26 +55,26 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) { config, ok := r.Context().Value(configKey).(*Config) if !ok { - common.LogError("Config missing from context") + common.LogDebug("Config missing from context") http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } header := r.Header.Get("Authorization") if header == "" { - common.LogError("Authorization header not found") + common.LogDebug("Authorization header not found") http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } token_arr := strings.Split(header, " ") if len(token_arr) != 2 { - common.LogError("Authorization header malformed") + common.LogDebug("Authorization header malformed") http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } if !strings.EqualFold(token_arr[0], "token") { - common.LogError("Token not found in Authorization header") + common.LogDebug("Token not found in Authorization header") http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } @@ -82,7 +82,7 @@ func StatusProxy(w http.ResponseWriter, r *http.Request) { token := token_arr[1] if !slices.Contains(config.Keys, token) { - common.LogError("Provided token is not known") + common.LogDebug("Provided token is not known") http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } -- 2.51.1 From 55846562c1d9dcb395e545f7c8e0bcb74c47b85693f4e955ef488530781b9bf2 Mon Sep 17 00:00:00 2001 From: Santiago Zarate Date: Thu, 30 Oct 2025 13:03:28 +0100 Subject: [PATCH 5/5] Add simple readme for gitea_status_proxy --- gitea_status_proxy/readme.md | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 gitea_status_proxy/readme.md diff --git a/gitea_status_proxy/readme.md b/gitea_status_proxy/readme.md new file mode 100644 index 0000000..eddfca2 --- /dev/null +++ b/gitea_status_proxy/readme.md @@ -0,0 +1,48 @@ +# gitea_status_proxy + +Allows bots without code owner permission to set Gitea's commit status + +## Basic usage + +To beging, you need the json config and a Gitea token with permissions to the repository you want to write to. + +Keys should be randomly generated, i.e by using openssl: `openssl rand -base64 48` + +Generate a json config file, with the key generated from running the command above, save as example.json: + +``` +{ + "forge_url": "https://src.opensuse.org/api/v1", + "keys": ["$YOUR_TOKEN_GOES_HERE"] +} +``` + +### start the proxy: + +``` +GITEA_TOKEN=YOURTOKEN ./gitea_status_proxy -config example.json +2025/10/30 12:53:18 [I] server up and listening on :3000 +``` + +Now the proxy should be able to accept requests under: `localhost:3000/repos/{owner}/{repo}/statuses/{sha}`, the token to be used when authenticating to the proxy must be in the `keys` list of the configuration json file (example.json above) + +### example: + +On a separate terminal, you can use curl to post a status to the proxy, if the GITEA_TOKEN has permissions on the target +repository, it will result in a new status being set for the given commit + +``` +curl -X 'POST' \ + 'localhost:3000/repos/szarate/test-actions-gitea/statuses/cd5847c92fb65a628bdd6015f96ee7e569e1ad6e4fc487acc149b52e788262f9' \ + -H 'accept: application/json' \ + -H 'Authorization: token $YOUR_TOKEN_GOES_HERE' \ + -H 'Content-Type: application/json' \ + -d '{ + "context": "Proxy test", + "description": "Status posted from the proxy", + "state": "success", + "target_url": "https://src.opensuse.org" +}' +``` + +After this you should be able to the results in the pull request, e.g from above: https://src.opensuse.org/szarate/test-actions-gitea/pulls/1 -- 2.51.1