-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(webhook): add webhook #2538
Changes from all commits
6074411
31aab47
b5e989a
715a453
e2a6214
cd41cbc
444428b
18c0d51
799f646
c22d3c9
6e0d109
9af0630
b5a29e1
496d67a
df7ffc6
0b7b3e9
8b8297a
f8a833b
d4ac8d6
01f8b57
7f81c14
1c55e8b
a5a3120
a7e239e
7d2117a
4c7538c
6fec3a5
200eb8b
5dc99e4
1a3000a
b40e602
f241759
d9e99a0
d7963fa
652b099
d390ea0
8c215e4
498a067
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,17 +3,29 @@ package client | |
|
||
import ( | ||
"context" | ||
"crypto/hmac" | ||
"crypto/sha256" | ||
"encoding/hex" | ||
"fmt" | ||
"strings" | ||
"time" | ||
|
||
"github.com/dubonzi/otelresty" | ||
"github.com/go-resty/resty/v2" | ||
"github.com/google/uuid" | ||
"github.com/synapsecns/sanguine/core/ginhelper" | ||
"github.com/synapsecns/sanguine/core/metrics" | ||
) | ||
|
||
var ( | ||
// BlacklistEndpoint is the endpoint for blacklisting an address. | ||
BlacklistEndpoint = "/api/data/sync/" | ||
) | ||
|
||
// ScreenerClient is an interface for the Screener API. | ||
type ScreenerClient interface { | ||
ScreenAddress(ctx context.Context, ruleset, address string) (blocked bool, err error) | ||
BlacklistAddress(ctx context.Context, appsecret string, appid string, body BlackListBody) (string, error) | ||
} | ||
|
||
type clientImpl struct { | ||
|
@@ -37,6 +49,7 @@ type blockedResponse struct { | |
Blocked bool `json:"risk"` | ||
} | ||
|
||
// ScreenAddress checks if an address is blocked by the screener. | ||
func (c clientImpl) ScreenAddress(ctx context.Context, ruleset, address string) (bool, error) { | ||
var blockedRes blockedResponse | ||
resp, err := c.rClient.R(). | ||
|
@@ -54,6 +67,54 @@ func (c clientImpl) ScreenAddress(ctx context.Context, ruleset, address string) | |
return blockedRes.Blocked, nil | ||
} | ||
|
||
// BlackListBody is the json payload that represents a blacklisted address. | ||
type BlackListBody struct { | ||
TypeReq string `json:"typereq"` | ||
ID string `json:"id"` | ||
Data string `json:"data"` | ||
Address string `json:"address"` | ||
Network string `json:"network"` | ||
Tag string `json:"tag"` | ||
Remark string `json:"remark"` | ||
} | ||
|
||
type blacklistResponse struct { | ||
Status string `json:"status"` | ||
Error string `json:"error"` | ||
} | ||
|
||
func (c clientImpl) BlacklistAddress(ctx context.Context, appsecret string, appid string, body BlackListBody) (string, error) { | ||
var blacklistRes blacklistResponse | ||
|
||
nonce := strings.ReplaceAll(uuid.New().String(), "-", "")[:32] | ||
timestamp := fmt.Sprintf("%d", time.Now().Unix()) | ||
queryString := "" | ||
|
||
signature := GenerateSignature(appsecret, appid, timestamp, nonce, queryString, body) | ||
|
||
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). | ||
SetBody(body). | ||
Post(BlacklistEndpoint) | ||
|
||
if err != nil { | ||
return resp.Status(), fmt.Errorf("error from server: %s: %w", resp.String(), err) | ||
} | ||
|
||
if resp.IsError() { | ||
return resp.Status(), fmt.Errorf("error from server: %s", resp.String()) | ||
} | ||
|
||
return blacklistRes.Status, nil | ||
} | ||
|
||
// NewNoOpClient creates a new no-op client for the Screener API. | ||
// it returns false for every address. | ||
func NewNoOpClient() (ScreenerClient, error) { | ||
|
@@ -66,4 +127,36 @@ func (n noOpClient) ScreenAddress(_ context.Context, _, _ string) (bool, error) | |
return false, nil | ||
} | ||
|
||
func (n noOpClient) BlacklistAddress(_ context.Context, _ string, _ string, _ BlackListBody) (string, error) { | ||
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", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. poor use of %s, just create a concat(...string) method that does this |
||
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{} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -8,12 +8,27 @@ import ( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
"encoding/json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
"errors" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
"fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/synapsecns/sanguine/contrib/screener-api/trmlabs" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
"gorm.io/gorm/schema" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
"strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
"time" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/synapsecns/sanguine/contrib/screener-api/trmlabs" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
"gorm.io/gorm/schema" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
// BlacklistedAddress is a blacklisted address. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type BlacklistedAddress struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
CreatedAt time.Time `json:"createdAt"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
UpdatedAt time.Time `json:"updatedAt"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
TypeReq string `gorm:"column:typereq" json:"typereq"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
ID string `gorm:"column:id;primary_key" json:"id"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Data string `gorm:"column:data" json:"data"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Address string `gorm:"column:address" json:"address"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Network string `gorm:"column:network" json:"network"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tag string `gorm:"column:tag" json:"tag"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Remark string `gorm:"column:remark" json:"remark"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+18
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure consistent use of Go's convention for initialisms in variable names. - ID string `gorm:"column:id;primary_key" json:"id"`
+ ID string `gorm:"column:ID;primary_key" json:"ID"` The field Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a descriptive comment for the + // AddressIndicators represents the risk indicators associated with an address. It's a good practice to provide comments for exported types to improve code readability and maintainability. Committable suggestion
Suggested change
Add a descriptive comment for the + // addressRiskIndicators defines a list of risk indicators for an address. This comment will help other developers understand the purpose of this type at a glance. Committable suggestion
Suggested change
Add a descriptive comment for the + // ToTRMLabs converts address risk indicators to a format used by TRMLabs. Adding a descriptive comment for this exported method will enhance code readability and maintainability. Committable suggestion
Suggested change
Add a descriptive comment for the + // MakeRecord creates a new AddressIndicators record with the specified address and risk indicators. Documenting public functions helps other developers understand their purpose and usage quickly. Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
// AddressIndicators is the address indicators for a given address. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type AddressIndicators struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
CreatedAt time.Time | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip
Codebase Verification
The expanded search for validation logic within the
BlacklistAddress
method has provided a clear view of the method's implementation. From the output, it is evident that the method primarily focuses on generating a signature, setting up HTTP headers, and making a POST request. There is no explicit validation logic for the fields ofBlackListBody
such asID
,Address
, orNetwork
.Given this information, it appears that the initial review comment pointing out the need for validation of these fields is justified. The method does not currently include any checks to ensure that the values of these fields meet expected formats, which could lead to potential issues if invalid data is processed.
Conclusion:
BlacklistAddress
method lacks validation for the fields ofBlackListBody
. This could lead to processing of invalid data, which is a significant concern for any system dealing with network addresses and identifiers.Recommendation:
BlacklistAddress
method to check the formats ofID
,Address
, andNetwork
fields before proceeding with the business logic.Analysis chain
Validate the fields of
BlackListBody
to ensure they meet expected formats, especially for fields likeID
,Address
, andNetwork
.Scripts Executed
The following scripts were executed for the analysis:
Script:
Length of output: 164
Script:
Length of output: 2612