installed gin

This commit is contained in:
2026-01-13 22:07:20 -07:00
parent 851234d9fa
commit 7481cec0d5
29 changed files with 544 additions and 1094 deletions
+40 -41
View File
@@ -3,58 +3,60 @@ package etsy
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"
"ruben/inventory2/internal/domains/platforms/etsy"
"ruben/inventory2/internal/domains/raw_events"
"ruben/inventory2/internal/logging"
"ruben/inventory2/internal/server/response"
"github.com/gin-gonic/gin"
)
type (
Webhooks struct {
log *logging.Logger
cfg Config
db *raw_events.Store
etsy *etsy.Platform
}
Config struct {
OAuthRedirectURIWithAcctIDParam string
}
)
func NewWebhookHandler(
func Webhooks(
r *gin.RouterGroup,
logger *logging.Logger,
db *raw_events.Store,
platform *etsy.Platform,
cfg Config,
) http.Handler {
h := Webhooks{
) {
h := webhooks{
log: logger,
cfg: cfg,
db: db,
etsy: platform,
}
mux := http.NewServeMux()
r.POST("/test", response.Handler(h.test))
mux.HandleFunc("POST /test", h.test)
r.GET(h.cfg.OAuthRedirectURIWithAcctIDParam, response.Handler(h.redirectURI))
mux.HandleFunc("GET "+h.cfg.OAuthRedirectURIWithAcctIDParam, h.redirectURI)
mux.HandleFunc("GET /{acctID}/new-account-link", h.newAccountLink)
return mux
r.GET("/{acctID}/new-account-link", response.Handler(h.newAccountLink))
}
type (
webhooks struct {
log *logging.Logger
cfg Config
db *raw_events.Store
etsy *etsy.Platform
}
)
// POST /test
func (h Webhooks) test(w http.ResponseWriter, r *http.Request) {
func (h webhooks) test(c *gin.Context) (response.Response, error) {
r := c.Request
var body json.RawMessage
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, "Failed to decode body as json: "+err.Error(), 500)
return
return nil, response.Errorf("failed to decode body as json: %w", err)
}
ts := time.Now().UTC()
@@ -75,21 +77,21 @@ func (h Webhooks) test(w http.ResponseWriter, r *http.Request) {
Payload: body,
})
if err != nil {
http.Error(w, "Error occurred saving the body as the event payload: "+err.Error(), 500)
return
return nil, response.Errorf("error occurred saving the body as the event payload: %w", err)
}
w.WriteHeader(201)
return response.Status(201), nil
}
// GET h.cfg.OAuthRedirectURIWithAcctIDParam
func (h Webhooks) redirectURI(w http.ResponseWriter, r *http.Request) {
func (h webhooks) redirectURI(c *gin.Context) (response.Response, error) {
r := c.Request
// get account id for the request
acctID, err := strconv.ParseInt(r.PathValue("acctID"), 10, 64)
acctID, err := strconv.ParseInt(c.Param("acctID"), 10, 64)
if err != nil || acctID <= 0 {
w.WriteHeader(http.StatusNotFound)
return
return nil, response.NotFound()
}
ctx := r.Context()
@@ -113,41 +115,38 @@ func (h Webhooks) redirectURI(w http.ResponseWriter, r *http.Request) {
h.etsy.InvalidateState(ctx, state)
return
return response.Status(200), nil
}
// validate the state to prevent CSRF attacks
ok, err := h.etsy.HandleNewAuthCode(ctx, acctID, state, q.Get("code"))
if err != nil {
w.WriteHeader(http.StatusForbidden)
h.log.Error("failed to handle new auth code", "error", err)
return
return nil, response.Forbidden()
}
if !ok {
w.WriteHeader(http.StatusForbidden)
return
return nil, response.Forbidden()
}
// redirect to the user's account page
http.Redirect(w, r, fmt.Sprintf("/accounts/%d", acctID), http.StatusSeeOther)
return response.SeeOther(fmt.Sprintf("/accounts/%d", acctID)), nil
}
// GET /{acctID}/new-account-link
func (h Webhooks) newAccountLink(w http.ResponseWriter, r *http.Request) {
acctIDStr := r.PathValue("acctID")
func (h webhooks) newAccountLink(c *gin.Context) (response.Response, error) {
r := c.Request
acctIDStr := c.Param("acctID")
acctID, err := strconv.ParseInt(acctIDStr, 10, 64)
if err != nil {
http.Error(w, fmt.Sprintf("account %s not found", acctIDStr), http.StatusNotFound)
return
return nil, response.NotFound().Msgf("account %s not found", acctIDStr)
}
u, err := h.etsy.GenerateConnectionURLForNewAccount(r.Context(), acctID)
if err != nil {
http.Error(w, fmt.Sprintf("failed to generate url for account %d: %v", acctID, err), http.StatusInternalServerError)
return
return nil, fmt.Errorf("failed to generate url for account %d: %w", acctID, err)
}
http.Redirect(w, r, u.String(), http.StatusTemporaryRedirect)
return response.TemporaryRedirect(u.String()), nil
}
+14 -12
View File
@@ -3,21 +3,26 @@ package tiktok
import (
"encoding/json"
"fmt"
"net/http"
"time"
"ruben/inventory2/internal/domains/raw_events"
"ruben/inventory2/internal/logging"
"ruben/inventory2/internal/server/response"
"github.com/gin-gonic/gin"
)
func NewWebhookHandler(logger *logging.Logger, db *raw_events.Store) http.Handler {
mux := http.NewServeMux()
func Webhooks(
r *gin.RouterGroup,
logger *logging.Logger,
db *raw_events.Store,
) {
r.POST("/test", response.Handler(func(c *gin.Context) (response.Response, error) {
r := c.Request
mux.HandleFunc("POST /test", func(w http.ResponseWriter, r *http.Request) {
var body json.RawMessage
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, "Failed to decode body as json: "+err.Error(), 500)
return
return nil, fmt.Errorf("failed to decode body as json: %w", err)
}
ts := time.Now().UTC()
@@ -30,12 +35,9 @@ func NewWebhookHandler(logger *logging.Logger, db *raw_events.Store) http.Handle
Payload: body,
})
if err != nil {
http.Error(w, "Error occurred saving the body as the event payload: "+err.Error(), 500)
return
return nil, fmt.Errorf("error occurred saving the body as the event payload: %w", err)
}
w.WriteHeader(201)
})
return mux
return response.Status(201), nil
}))
}
+23 -28
View File
@@ -1,47 +1,42 @@
package webhooks
import (
"net/http"
etsy_platform "ruben/inventory2/internal/domains/platforms/etsy"
"ruben/inventory2/internal/domains/raw_events"
"ruben/inventory2/internal/logging"
"ruben/inventory2/internal/server/api/webhooks/etsy"
"ruben/inventory2/internal/server/api/webhooks/tiktok"
"ruben/inventory2/internal/server/api/webhooks/wix"
"github.com/gin-gonic/gin"
)
type Config struct {
Etsy etsy.Config
}
// TODO: just move over to the 'site' package, and then consider renaming the site package to something else?
func New(logger *logging.Logger, eventsDB *raw_events.Store, etsyPlatform *etsy_platform.Platform, cfg Config) http.Handler {
wh := http.NewServeMux()
wh.Handle(
"/etsy/",
http.StripPrefix("/etsy", etsy.NewWebhookHandler(
logger.WithGroup("etsy"),
eventsDB,
etsyPlatform,
cfg.Etsy,
)),
func Webhooks(
r *gin.RouterGroup,
logger *logging.Logger,
eventsDB *raw_events.Store,
etsyPlatform *etsy_platform.Platform,
cfg Config,
) {
etsy.Webhooks(
r.Group("/etsy"),
logger.WithGroup("etsy"),
eventsDB,
etsyPlatform,
cfg.Etsy,
)
wh.Handle(
"/tiktok/",
http.StripPrefix("/tiktok", tiktok.NewWebhookHandler(
logger.WithGroup("tiktok"),
eventsDB,
)),
tiktok.Webhooks(
r.Group("/tiktok"),
logger.WithGroup("tiktok"),
eventsDB,
)
wh.Handle(
"/wix/",
http.StripPrefix("/wix", wix.NewWebhookHandler(
logger.WithGroup("wix"),
eventsDB,
)),
wix.Webhooks(
r.Group("/wix"),
logger.WithGroup("wix"),
eventsDB,
)
return wh
}
+14 -12
View File
@@ -3,21 +3,26 @@ package wix
import (
"encoding/json"
"fmt"
"net/http"
"time"
"ruben/inventory2/internal/domains/raw_events"
"ruben/inventory2/internal/logging"
"ruben/inventory2/internal/server/response"
"github.com/gin-gonic/gin"
)
func NewWebhookHandler(logger *logging.Logger, db *raw_events.Store) http.Handler {
mux := http.NewServeMux()
func Webhooks(
r *gin.RouterGroup,
logger *logging.Logger,
db *raw_events.Store,
) {
r.POST("/test", response.Handler(func(c *gin.Context) (response.Response, error) {
r := c.Request
mux.HandleFunc("POST /test", func(w http.ResponseWriter, r *http.Request) {
var body json.RawMessage
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, "Failed to decode body as json: "+err.Error(), 500)
return
return nil, fmt.Errorf("failed to decode body as json: %w", err)
}
ts := time.Now().UTC()
@@ -30,12 +35,9 @@ func NewWebhookHandler(logger *logging.Logger, db *raw_events.Store) http.Handle
Payload: body,
})
if err != nil {
http.Error(w, "Error occurred saving the body as the event payload: "+err.Error(), 500)
return
return nil, fmt.Errorf("error occurred saving the body as the event payload: %w", err)
}
w.WriteHeader(201)
})
return mux
return response.Status(201), nil
}))
}