Skip to content

Commit

Permalink
fix screener 502
Browse files Browse the repository at this point in the history
  • Loading branch information
golangisfun123 committed May 28, 2024
1 parent 5233a25 commit 3ef75a6
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 58 deletions.
63 changes: 28 additions & 35 deletions contrib/screener-api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"strings"
"time"
Expand Down Expand Up @@ -90,18 +91,27 @@ func (c clientImpl) BlacklistAddress(ctx context.Context, appsecret string, appi
timestamp := fmt.Sprintf("%d", time.Now().Unix())
queryString := ""

signature := GenerateSignature(appsecret, appid, timestamp, nonce, queryString, body)
bodyBz, err := json.Marshal(body)
if err != nil {
return "", fmt.Errorf("error marshalling body: %w", err)

Check failure on line 96 in contrib/screener-api/client/client.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

`marshalling` is a misspelling of `marshaling` (misspell)
}
bodyStr := string(bodyBz)

message := fmt.Sprintf("%s%s%s%s%s%s%s",
appid, timestamp, nonce, "POST", BlacklistEndpoint, queryString, bodyStr)

signature := GenerateSignature(appsecret, message)

resp, err := c.rClient.R().
SetContext(ctx).
SetHeader("Content-Type", "application/json").
SetHeader("appid", appid).
SetHeader("timestamp", timestamp).
SetHeader("nonce", nonce).
SetHeader("queryString", queryString).
SetHeader("signature", signature).
SetResult(&blacklistRes).
SetHeader("Appid", appid).
SetHeader("Timestamp", timestamp).
SetHeader("Nonce", nonce).
SetHeader("QueryString", queryString).
SetHeader("Signature", signature).
SetBody(body).
SetResult(&blacklistRes).
Post(BlacklistEndpoint)

if err != nil {
Expand All @@ -115,6 +125,17 @@ func (c clientImpl) BlacklistAddress(ctx context.Context, appsecret string, appi
return blacklistRes.Status, nil
}

// GenerateSignature generates a signature for the request.
func GenerateSignature(
secret,
message string,
) string {
key := []byte(secret)
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
return hex.EncodeToString(h.Sum(nil))
}

// NewNoOpClient creates a new no-op client for the Screener API.
// it returns false for every address.
func NewNoOpClient() (ScreenerClient, error) {
Expand All @@ -131,32 +152,4 @@ func (n noOpClient) BlacklistAddress(_ context.Context, _ string, _ string, _ Bl
return "", nil
}

// GenerateSignature generates a signature for the request.
func GenerateSignature(secret string,
appid string,
timestamp string,
nonce string,
queryString string,
body BlackListBody,
) string {
key := []byte(secret)

// Concatenate the body.
message := fmt.Sprintf(
"%s%s%s%s%s%s%s",
appid,
timestamp,
nonce,
"POST",
BlacklistEndpoint,
queryString,
body,
)

h := hmac.New(sha256.New, key)
h.Write([]byte(message))

return strings.ToLower(hex.EncodeToString(h.Sum(nil)))
}

var _ ScreenerClient = noOpClient{}
40 changes: 18 additions & 22 deletions contrib/screener-api/screener/screener.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
"sync"
Expand Down Expand Up @@ -93,8 +94,7 @@ func NewScreener(ctx context.Context, cfg config.Config, metricHandler metrics.H
screener.router.Use(screener.metrics.Gin())
screener.router.Handle(http.MethodGet, "/:ruleset/address/:address", screener.screenAddress)

screener.router.Handle(http.MethodPost, "/api/data/sync", screener.authMiddleware(cfg), screener.blacklistAddress)

screener.router.POST("/api/data/sync", screener.authMiddleware(cfg), screener.blacklistAddress)
screener.router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))

return &screener, nil
Expand Down Expand Up @@ -190,6 +190,7 @@ func (s *screenerImpl) blacklistAddress(c *gin.Context) {

case "update":
if err := s.db.UpdateBlacklistedAddress(c, blacklistedAddress.ID, blacklistedAddress); err != nil {
span.AddEvent("error", trace.WithAttributes(attribute.String("error", err.Error())))

Check warning on line 193 in contrib/screener-api/screener/screener.go

View check run for this annotation

Codecov / codecov/patch

contrib/screener-api/screener/screener.go#L193

Added line #L193 was not covered by tests
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
Expand All @@ -199,6 +200,7 @@ func (s *screenerImpl) blacklistAddress(c *gin.Context) {

case "delete":
if err := s.db.DeleteBlacklistedAddress(c, blacklistedAddress.Address); err != nil {
span.AddEvent("error", trace.WithAttributes(attribute.String("error", err.Error())))

Check warning on line 203 in contrib/screener-api/screener/screener.go

View check run for this annotation

Codecov / codecov/patch

contrib/screener-api/screener/screener.go#L203

Added line #L203 was not covered by tests
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
Expand All @@ -207,6 +209,7 @@ func (s *screenerImpl) blacklistAddress(c *gin.Context) {
return

default:
span.AddEvent("error", trace.WithAttributes(attribute.String("error", err.Error())))

Check warning on line 212 in contrib/screener-api/screener/screener.go

View check run for this annotation

Codecov / codecov/patch

contrib/screener-api/screener/screener.go#L212

Added line #L212 was not covered by tests
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid type"})
return
}
Expand All @@ -216,34 +219,27 @@ func (s *screenerImpl) blacklistAddress(c *gin.Context) {
// compare it with the signature provided. If they match, the request is allowed to pass through.
func (s *screenerImpl) authMiddleware(cfg config.Config) gin.HandlerFunc {
return func(c *gin.Context) {
var blacklistBody client.BlackListBody
appID := c.Request.Header.Get("Appid")
timestamp := c.Request.Header.Get("Timestamp")
nonce := c.Request.Header.Get("Nonce")
signature := c.Request.Header.Get("Signature")

if err := c.ShouldBindBodyWith(&blacklistBody, binding.JSON); err != nil {
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
c.Abort()
return
}
bodyBytes, _ := io.ReadAll(c.Request.Body)
bodyString := string(bodyBytes)

appid := cfg.AppID
appsecret := cfg.AppSecret
c.Request.Body = io.NopCloser(strings.NewReader(bodyString))

nonce := c.GetHeader("nonce")
timestamp := c.GetHeader("timestamp")
queryString := c.GetHeader("queryString")
if nonce == "" || timestamp == "" || appid == "" {
c.JSON(http.StatusConflict, gin.H{"error": "missing headers"})
c.Abort()
return
}
message := fmt.Sprintf("%s%s%s%s%s%s",
appID, timestamp, nonce, "POST", client.BlacklistEndpoint, bodyString)

// reconstruct signature
expected := client.GenerateSignature(appsecret, appid, timestamp, nonce, queryString, blacklistBody)
expectedSignature := client.GenerateSignature(cfg.AppSecret, message)

if c.GetHeader("Signature") != expected {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
if expectedSignature != signature {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid signature"})
c.Abort()
return
}

c.Next()
}
}
Expand Down
2 changes: 1 addition & 1 deletion contrib/screener-api/screener/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (s *ScreenerSuite) TestScreener() {
s.T().Setenv("TRM_URL", "")

cfg := config.Config{
AppSecret: "appsecret",
AppSecret: "secret",
AppID: "appid",
TRMKey: "",
Rulesets: map[string]config.RulesetConfig{
Expand Down

0 comments on commit 3ef75a6

Please sign in to comment.