From 930e069aee3e2c92b5a57ea3609abbb18bdf3b3e Mon Sep 17 00:00:00 2001 From: LandaMm Date: Mon, 2 Jun 2025 13:00:19 +0200 Subject: [PATCH] feat: authorize middleware to check api service activity --- internal/oauth/authorize.go | 73 +++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 internal/oauth/authorize.go diff --git a/internal/oauth/authorize.go b/internal/oauth/authorize.go new file mode 100644 index 0000000..ea70eba --- /dev/null +++ b/internal/oauth/authorize.go @@ -0,0 +1,73 @@ +package oauth + +import ( + "fmt" + "net/http" + "strings" + + "gitea.local/admin/hspguard/internal/web" +) + +// client_id=gitea-client&redirect_uri=https://git.adalspace.com/user/oauth2/Home%20Guard/callback&response_type=code&scope=openid&state=4c3b4a25-9cf9-4b18-afc0-270e1078eb40 +func contains(s []string, str string) bool { + for _, v := range s { + if v == str { + return true + } + } + return false +} + +func (h *OAuthHandler) AuthorizeClient(w http.ResponseWriter, r *http.Request) { + redirectUri := r.URL.Query().Get("redirect_uri") + if redirectUri == "" { + web.Error(w, "redirect_uri is missing in request", http.StatusBadRequest) + return + } + + state := r.URL.Query().Get("state") + + clientId := r.URL.Query().Get("client_id") + if clientId == "" { + uri := fmt.Sprintf("%s?error=invalid_request&error_description=ClientID+is+missing", redirectUri) + if state != "" { + uri += "&state=" + state + } + http.Redirect(w, r, uri, http.StatusFound) + return + } + + client, err := h.repo.GetApiServiceCID(r.Context(), clientId) + if err != nil { + uri := fmt.Sprintf("%s?error=access_denied&error_description=Service+not+authorized", redirectUri) + if state != "" { + uri += "&state=" + state + } + http.Redirect(w, r, uri, http.StatusFound) + return + } + + if !client.IsActive { + uri := fmt.Sprintf("%s?error=temporarily_unavailable&error_description=Service+not+active", redirectUri) + if state != "" { + uri += "&state=" + state + } + http.Redirect(w, r, uri, http.StatusFound) + return + } + + scopes := strings.SplitSeq(strings.TrimSpace(r.URL.Query().Get("scope")), " ") + + for scope := range scopes { + if !contains(client.Scopes, scope) { + uri := fmt.Sprintf("%s?error=invalid_scope&error_description=Scope+%s+is+not+allowed", redirectUri, strings.ReplaceAll(scope, " ", "+")) + if state != "" { + uri += "&state=" + state + } + http.Redirect(w, r, uri, http.StatusFound) + return + } + } + + http.Redirect(w, r, fmt.Sprintf("/auth?%s", r.URL.Query().Encode()), http.StatusFound) +}