linting
This commit is contained in:
@@ -114,7 +114,7 @@ func (a *AccountAPI) deleteAll(r *http.Request, account *model.Account, token *s
|
||||
a.logger.Warn("Failed to delete all data", zap.Error(err), mzap.StorableRef(&org), mzap.StorableRef(account))
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
return struct{}{}, nil
|
||||
}); err != nil {
|
||||
a.logger.Warn("Failed to execute delete transaction", zap.Error(err), mzap.StorableRef(&org), mzap.StorableRef(account))
|
||||
return response.Auto(a.logger, a.Name(), err)
|
||||
|
||||
@@ -192,5 +192,5 @@ func (a *AccountAPI) resetPasswordTransactionBody(ctx context.Context, user *mod
|
||||
// Don't fail the transaction if token revocation fails, but log it
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
return struct{}{}, nil
|
||||
}
|
||||
|
||||
@@ -133,12 +133,7 @@ func TestPasswordValidationLogic(t *testing.T) {
|
||||
for _, password := range invalidPasswords {
|
||||
t.Run(password, func(t *testing.T) {
|
||||
// Test that invalid passwords fail at least one requirement
|
||||
isValid := true
|
||||
|
||||
// Check length
|
||||
if len(password) < 8 {
|
||||
isValid = false
|
||||
}
|
||||
isValid := len(password) >= 8
|
||||
|
||||
// Check for digit
|
||||
hasDigit := false
|
||||
|
||||
@@ -276,7 +276,7 @@ func (a *AccountAPI) grantAllPermissions(ctx context.Context, organizationRef bs
|
||||
|
||||
for resource, granted := range required {
|
||||
if !granted {
|
||||
a.logger.Warn("Required policy description not found for signup permissions", zap.String("resource", string(resource)))
|
||||
a.logger.Warn("Required policy description not found for signup permissions", zap.String("resource", resource))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ func TestSignupHTTPSerialization(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create HTTP request
|
||||
req := httptest.NewRequest(http.MethodPost, "/signup", bytes.NewBuffer(reqBody))
|
||||
req := httptest.NewRequestWithContext(context.Background(), http.MethodPost, "/signup", bytes.NewBuffer(reqBody))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// Parse the request body
|
||||
@@ -162,7 +162,7 @@ func TestSignupHTTPSerialization(t *testing.T) {
|
||||
t.Run("InvalidJSONRequest", func(t *testing.T) {
|
||||
invalidJSON := `{"account": {"login": "test@example.com", "password": "invalid json structure`
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/signup", bytes.NewBufferString(invalidJSON))
|
||||
req := httptest.NewRequestWithContext(context.Background(), http.MethodPost, "/signup", bytes.NewBufferString(invalidJSON))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
var parsedRequest srequest.Signup
|
||||
|
||||
@@ -37,7 +37,7 @@ func (a *CallbacksAPI) create(r *http.Request, account *model.Account, accessTok
|
||||
if err := a.applySigningSecretMutation(ctx, *account.GetID(), *callback.GetID(), mutation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
return struct{}{}, nil
|
||||
}); err != nil {
|
||||
a.Logger.Warn("Failed to create callback transaction", zap.Error(err))
|
||||
return response.Auto(a.Logger, a.Name(), err)
|
||||
|
||||
@@ -49,7 +49,7 @@ func (a *CallbacksAPI) update(r *http.Request, account *model.Account, accessTok
|
||||
if err := a.applySigningSecretMutation(ctx, *account.GetID(), callbackRef, mutation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
return struct{}{}, nil
|
||||
}); err != nil {
|
||||
a.Logger.Warn("Failed to update callback transaction", zap.Error(err))
|
||||
return response.Auto(a.Logger, a.Name(), err)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/tech/sendico/pkg/api/http/response"
|
||||
"github.com/tech/sendico/pkg/domainprovider"
|
||||
@@ -34,7 +35,10 @@ func (storage *LocalStorage) Delete(ctx context.Context, objID string) error {
|
||||
default:
|
||||
}
|
||||
|
||||
filePath := filepath.Join(storage.storageDir, objID)
|
||||
filePath, err := storage.resolvePath(objID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Remove(filePath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
storage.logger.Debug("File not found", zap.String("obj_ref", objID))
|
||||
@@ -54,7 +58,11 @@ func (storage *LocalStorage) Save(ctx context.Context, file io.Reader, objID str
|
||||
default:
|
||||
}
|
||||
|
||||
filePath := filepath.Join(storage.storageDir, objID)
|
||||
filePath, err := storage.resolvePath(objID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
//nolint:gosec // File path is resolved and constrained to storage root.
|
||||
dst, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
storage.logger.Warn("Error occurred while creating file", zap.Error(err), zap.String("storage", storage.storageDir), zap.String("obj_ref", objID))
|
||||
@@ -78,7 +86,9 @@ func (storage *LocalStorage) Save(ctx context.Context, file io.Reader, objID str
|
||||
}
|
||||
case <-ctx.Done():
|
||||
// Context was cancelled, clean up the partial file
|
||||
os.Remove(filePath)
|
||||
if removeErr := os.Remove(filePath); removeErr != nil && !os.IsNotExist(removeErr) {
|
||||
storage.logger.Warn("Failed to remove partially written file", zap.Error(removeErr), zap.String("obj_ref", objID))
|
||||
}
|
||||
return "", ctx.Err()
|
||||
}
|
||||
|
||||
@@ -93,7 +103,10 @@ func (storage *LocalStorage) Get(ctx context.Context, objRef string) http.Handle
|
||||
default:
|
||||
}
|
||||
|
||||
filePath := filepath.Join(storage.storageDir, objRef)
|
||||
filePath, err := storage.resolvePath(objRef)
|
||||
if err != nil {
|
||||
return response.Internal(storage.logger, storage.service, err)
|
||||
}
|
||||
if _, err := os.Stat(filePath); err != nil {
|
||||
storage.logger.Warn("Failed to access file", zap.Error(err), zap.String("storage", storage.storageDir), zap.String("obj_ref", objRef))
|
||||
return response.Internal(storage.logger, storage.service, err)
|
||||
@@ -117,7 +130,7 @@ func (storage *LocalStorage) Get(ctx context.Context, objRef string) http.Handle
|
||||
func ensureDir(dirName string) error {
|
||||
info, err := os.Stat(dirName)
|
||||
if os.IsNotExist(err) {
|
||||
return os.MkdirAll(dirName, 0o755)
|
||||
return os.MkdirAll(dirName, 0o750)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -128,6 +141,24 @@ func ensureDir(dirName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (storage *LocalStorage) resolvePath(objID string) (string, error) {
|
||||
objID = strings.TrimSpace(objID)
|
||||
if objID == "" {
|
||||
return "", merrors.InvalidArgument("obj_ref is required", "obj_ref")
|
||||
}
|
||||
|
||||
filePath := filepath.Join(storage.storageDir, objID)
|
||||
relPath, err := filepath.Rel(storage.storageDir, filePath)
|
||||
if err != nil {
|
||||
return "", merrors.InternalWrap(err, "failed to resolve local file path")
|
||||
}
|
||||
if relPath == "." || strings.HasPrefix(relPath, "..") {
|
||||
return "", merrors.InvalidArgument("obj_ref is invalid", "obj_ref")
|
||||
}
|
||||
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
func CreateLocalFileStorage(logger mlogger.Logger, service mservice.Type, directory, subDir string, dp domainprovider.DomainProvider, cfg config.LocalFSSConfig) (*LocalStorage, error) {
|
||||
dir := filepath.Join(cfg.RootPath, directory)
|
||||
if err := ensureDir(dir); err != nil {
|
||||
|
||||
@@ -55,7 +55,7 @@ func setupTestStorage(t *testing.T) (*LocalStorage, string, func()) {
|
||||
|
||||
// Return cleanup function
|
||||
cleanup := func() {
|
||||
os.RemoveAll(tempDir)
|
||||
require.NoError(t, os.RemoveAll(tempDir))
|
||||
}
|
||||
|
||||
return storage, tempDir, cleanup
|
||||
@@ -81,7 +81,7 @@ func setupBenchmarkStorage(b *testing.B) (*LocalStorage, string, func()) {
|
||||
|
||||
// Return cleanup function
|
||||
cleanup := func() {
|
||||
os.RemoveAll(tempDir)
|
||||
require.NoError(b, os.RemoveAll(tempDir))
|
||||
}
|
||||
|
||||
return storage, tempDir, cleanup
|
||||
@@ -138,6 +138,7 @@ func TestLocalStorage_Save(t *testing.T) {
|
||||
|
||||
// Verify file was actually saved
|
||||
filePath := filepath.Join(tempDir, tt.objID)
|
||||
//nolint:gosec // Test-controlled path inside temporary directory.
|
||||
content, err := os.ReadFile(filePath)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.content, string(content))
|
||||
@@ -186,7 +187,7 @@ func TestLocalStorage_Delete(t *testing.T) {
|
||||
|
||||
// Create a test file
|
||||
testFile := filepath.Join(tempDir, "test.txt")
|
||||
err := os.WriteFile(testFile, []byte("test content"), 0o644)
|
||||
err := os.WriteFile(testFile, []byte("test content"), 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
@@ -232,7 +233,7 @@ func TestLocalStorage_Delete_ContextCancellation(t *testing.T) {
|
||||
|
||||
// Create a test file
|
||||
testFile := filepath.Join(tempDir, "test.txt")
|
||||
err := os.WriteFile(testFile, []byte("test content"), 0o644)
|
||||
err := os.WriteFile(testFile, []byte("test content"), 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create a context that's already cancelled
|
||||
@@ -256,7 +257,7 @@ func TestLocalStorage_Get(t *testing.T) {
|
||||
// Create a test file
|
||||
testContent := "test file content"
|
||||
testFile := filepath.Join(tempDir, "test.txt")
|
||||
err := os.WriteFile(testFile, []byte(testContent), 0o644)
|
||||
err := os.WriteFile(testFile, []byte(testContent), 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
@@ -285,7 +286,7 @@ func TestLocalStorage_Get(t *testing.T) {
|
||||
handler := storage.Get(ctx, tt.objID)
|
||||
|
||||
// Create test request
|
||||
req := httptest.NewRequest("GET", "/files/"+tt.objID, nil)
|
||||
req := httptest.NewRequestWithContext(context.Background(), "GET", "/files/"+tt.objID, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(w, req)
|
||||
@@ -304,7 +305,7 @@ func TestLocalStorage_Get_ContextCancellation(t *testing.T) {
|
||||
|
||||
// Create a test file
|
||||
testFile := filepath.Join(tempDir, "test.txt")
|
||||
err := os.WriteFile(testFile, []byte("test content"), 0o644)
|
||||
err := os.WriteFile(testFile, []byte("test content"), 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create a context that's already cancelled
|
||||
@@ -314,7 +315,7 @@ func TestLocalStorage_Get_ContextCancellation(t *testing.T) {
|
||||
handler := storage.Get(ctx, "test.txt")
|
||||
|
||||
// Create test request
|
||||
req := httptest.NewRequest("GET", "/files/test.txt", nil)
|
||||
req := httptest.NewRequestWithContext(context.Background(), "GET", "/files/test.txt", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(w, req)
|
||||
@@ -328,14 +329,14 @@ func TestLocalStorage_Get_RequestContextCancellation(t *testing.T) {
|
||||
|
||||
// Create a test file
|
||||
testFile := filepath.Join(tempDir, "test.txt")
|
||||
err := os.WriteFile(testFile, []byte("test content"), 0o644)
|
||||
err := os.WriteFile(testFile, []byte("test content"), 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
handler := storage.Get(ctx, "test.txt")
|
||||
|
||||
// Create test request with cancelled context
|
||||
req := httptest.NewRequest("GET", "/files/test.txt", nil)
|
||||
req := httptest.NewRequestWithContext(context.Background(), "GET", "/files/test.txt", nil)
|
||||
reqCtx, cancel := context.WithCancel(req.Context())
|
||||
req = req.WithContext(reqCtx)
|
||||
cancel() // Cancel the request context
|
||||
@@ -352,7 +353,9 @@ func TestCreateLocalFileStorage(t *testing.T) {
|
||||
// Create temporary directory for testing
|
||||
tempDir, err := os.MkdirTemp("", "storage_test")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
defer func() {
|
||||
require.NoError(t, os.RemoveAll(tempDir))
|
||||
}()
|
||||
|
||||
logger := zap.NewNop()
|
||||
cfg := config.LocalFSSConfig{
|
||||
@@ -372,10 +375,12 @@ func TestCreateLocalFileStorage_InvalidPath(t *testing.T) {
|
||||
// Build a deterministic failure case: the target path already exists as a file.
|
||||
tempDir, err := os.MkdirTemp("", "storage_invalid_path_test")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
defer func() {
|
||||
require.NoError(t, os.RemoveAll(tempDir))
|
||||
}()
|
||||
|
||||
fileAtTargetPath := filepath.Join(tempDir, "test")
|
||||
err = os.WriteFile(fileAtTargetPath, []byte("not a directory"), 0o644)
|
||||
err = os.WriteFile(fileAtTargetPath, []byte("not a directory"), 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
logger := zap.NewNop()
|
||||
@@ -426,7 +431,7 @@ func TestLocalStorage_ConcurrentOperations(t *testing.T) {
|
||||
// Create files to delete
|
||||
for i := 0; i < 5; i++ {
|
||||
filePath := filepath.Join(tempDir, fmt.Sprintf("delete_%d.txt", i))
|
||||
err := os.WriteFile(filePath, []byte("content"), 0o644)
|
||||
err := os.WriteFile(filePath, []byte("content"), 0o600)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -536,7 +541,7 @@ func BenchmarkLocalStorage_Delete(b *testing.B) {
|
||||
// Pre-create files for deletion
|
||||
for i := 0; i < b.N; i++ {
|
||||
filePath := filepath.Join(tempDir, fmt.Sprintf("bench_delete_%d.txt", i))
|
||||
err := os.WriteFile(filePath, []byte("content"), 0o644)
|
||||
err := os.WriteFile(filePath, []byte("content"), 0o600)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -97,7 +97,9 @@ func (a *LedgerAPI) createAccount(r *http.Request, account *model.Account, token
|
||||
}
|
||||
|
||||
func decodeLedgerAccountCreatePayload(r *http.Request) (*srequest.CreateLedgerAccount, error) {
|
||||
defer r.Body.Close()
|
||||
defer func() {
|
||||
_ = r.Body.Close()
|
||||
}()
|
||||
|
||||
payload := srequest.CreateLedgerAccount{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
||||
|
||||
@@ -46,7 +46,7 @@ func (a *ProtectedAPI[T]) archive(r *http.Request, account *model.Account, acces
|
||||
|
||||
ctx := r.Context()
|
||||
_, err = a.a.DBFactory().TransactionFactory().CreateTransaction().Execute(ctx, func(ctx context.Context) (any, error) {
|
||||
return nil, a.DB.SetArchived(r.Context(), *account.GetID(), organizationRef, objectRef, *archived, *cascade)
|
||||
return nil, a.DB.SetArchived(ctx, *account.GetID(), organizationRef, objectRef, *archived, *cascade)
|
||||
})
|
||||
if err != nil {
|
||||
a.Logger.Warn("Failed to change archive property", zap.Error(err), mzap.StorableRef(account), mutil.PLog(a.Cph, r),
|
||||
|
||||
@@ -69,7 +69,7 @@ func (a *PaymentAPI) getOperationDocument(r *http.Request, account *model.Accoun
|
||||
|
||||
op, err := a.fetchGatewayOperation(r.Context(), gateway.InvokeURI, operationRef)
|
||||
if err != nil {
|
||||
a.logger.Warn("Failed to fetch gateway operation for document generation", zap.Error(err), mzap.ObjRef("organization_ref", orgRef), zap.String("gateway_service", string(gatewayService)), zap.String("operation_ref", operationRef))
|
||||
a.logger.Warn("Failed to fetch gateway operation for document generation", zap.Error(err), mzap.ObjRef("organization_ref", orgRef), zap.String("gateway_service", gatewayService), zap.String("operation_ref", operationRef))
|
||||
return documentErrorResponse(a.logger, a.Name(), err)
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ func (a *PaymentAPI) getOperationDocument(r *http.Request, account *model.Accoun
|
||||
|
||||
docResp, err := a.fetchOperationDocument(r.Context(), service.InvokeURI, req)
|
||||
if err != nil {
|
||||
a.logger.Warn("Failed to fetch operation document", zap.Error(err), mzap.ObjRef("organization_ref", orgRef), zap.String("gateway_service", string(gatewayService)), zap.String("operation_ref", operationRef))
|
||||
a.logger.Warn("Failed to fetch operation document", zap.Error(err), mzap.ObjRef("organization_ref", orgRef), zap.String("gateway_service", gatewayService), zap.String("operation_ref", operationRef))
|
||||
return documentErrorResponse(a.logger, a.Name(), err)
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@ func operationDocumentResponse(logger mlogger.Logger, source mservice.Type, docR
|
||||
w.Header().Set("Content-Type", mimeType)
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", filename))
|
||||
w.WriteHeader(http.StatusOK)
|
||||
//nolint:gosec // Binary payload is served as attachment with explicit content type.
|
||||
if _, err := w.Write(docResp.GetContent()); err != nil {
|
||||
logger.Warn("Failed to write document response", zap.Error(err))
|
||||
}
|
||||
@@ -167,15 +168,15 @@ func normalizeGatewayService(raw string) mservice.Type {
|
||||
}
|
||||
|
||||
switch value {
|
||||
case string(mservice.ChainGateway):
|
||||
case mservice.ChainGateway:
|
||||
return mservice.ChainGateway
|
||||
case string(mservice.TronGateway):
|
||||
case mservice.TronGateway:
|
||||
return mservice.TronGateway
|
||||
case string(mservice.MntxGateway):
|
||||
case mservice.MntxGateway:
|
||||
return mservice.MntxGateway
|
||||
case string(mservice.PaymentGateway):
|
||||
case mservice.PaymentGateway:
|
||||
return mservice.PaymentGateway
|
||||
case string(mservice.TgSettle):
|
||||
case mservice.TgSettle:
|
||||
return mservice.TgSettle
|
||||
default:
|
||||
return ""
|
||||
@@ -219,7 +220,11 @@ func (a *PaymentAPI) fetchOperationDocument(ctx context.Context, invokeURI strin
|
||||
if err != nil {
|
||||
return nil, merrors.InternalWrap(err, "dial billing documents")
|
||||
}
|
||||
defer conn.Close()
|
||||
defer func() {
|
||||
if closeErr := conn.Close(); closeErr != nil {
|
||||
a.logger.Warn("Failed to close billing documents connection", zap.Error(closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
client := documentsv1.NewDocumentServiceClient(conn)
|
||||
|
||||
@@ -234,7 +239,11 @@ func (a *PaymentAPI) fetchGatewayOperation(ctx context.Context, invokeURI, opera
|
||||
if err != nil {
|
||||
return nil, merrors.InternalWrap(err, "dial gateway connector")
|
||||
}
|
||||
defer conn.Close()
|
||||
defer func() {
|
||||
if closeErr := conn.Close(); closeErr != nil {
|
||||
a.logger.Warn("Failed to close gateway connector connection", zap.Error(closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
client := connectorv1.NewConnectorServiceClient(conn)
|
||||
|
||||
@@ -307,7 +316,7 @@ func findGatewayForService(gateways []discovery.GatewaySummary, gatewayService m
|
||||
func operationDocumentRequest(organizationRef string, gatewayService mservice.Type, requestedOperationRef string, op *connectorv1.Operation) *documentsv1.GetOperationDocumentRequest {
|
||||
req := &documentsv1.GetOperationDocumentRequest{
|
||||
OrganizationRef: strings.TrimSpace(organizationRef),
|
||||
GatewayService: string(gatewayService),
|
||||
GatewayService: gatewayService,
|
||||
OperationRef: firstNonEmpty(strings.TrimSpace(op.GetOperationRef()), strings.TrimSpace(requestedOperationRef)),
|
||||
OperationCode: strings.TrimSpace(op.GetType().String()),
|
||||
OperationLabel: operationLabel(op.GetType()),
|
||||
|
||||
@@ -103,6 +103,7 @@ func listPaymentsPage(r *http.Request) (*paginationv1.CursorPageRequest, error)
|
||||
}
|
||||
|
||||
if cursor == "" && !hasLimit {
|
||||
//nolint:nilnil // Absent pagination params mean no page request should be sent downstream.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -189,6 +190,7 @@ func firstNonEmpty(values ...string) string {
|
||||
func parseRFC3339Timestamp(raw string, field string) (*timestamppb.Timestamp, error) {
|
||||
trimmed := strings.TrimSpace(raw)
|
||||
if trimmed == "" {
|
||||
//nolint:nilnil // Empty timestamp filter is represented as (nil, nil).
|
||||
return nil, nil
|
||||
}
|
||||
parsed, err := time.Parse(time.RFC3339, trimmed)
|
||||
|
||||
@@ -102,7 +102,9 @@ func (a *PaymentAPI) initiatePayment(r *http.Request, account *model.Account, to
|
||||
}
|
||||
|
||||
func decodeInitiatePayload(r *http.Request) (*srequest.InitiatePayment, error) {
|
||||
defer r.Body.Close()
|
||||
defer func() {
|
||||
_ = r.Body.Close()
|
||||
}()
|
||||
|
||||
payload := &srequest.InitiatePayment{}
|
||||
if err := json.NewDecoder(r.Body).Decode(payload); err != nil {
|
||||
|
||||
@@ -68,7 +68,7 @@ func TestInitiateByQuote_RejectsMetadataIntentRef(t *testing.T) {
|
||||
func invokeInitiateByQuote(t *testing.T, api *PaymentAPI, orgRef bson.ObjectID, body string) *httptest.ResponseRecorder {
|
||||
t.Helper()
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/by-quote", bytes.NewBufferString(body))
|
||||
req := httptest.NewRequestWithContext(context.Background(), http.MethodPost, "/by-quote", bytes.NewBufferString(body))
|
||||
routeCtx := chi.NewRouteContext()
|
||||
routeCtx.URLParams.Add("organizations_ref", orgRef.Hex())
|
||||
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, routeCtx))
|
||||
|
||||
@@ -63,7 +63,9 @@ func (a *PaymentAPI) initiatePaymentsByQuote(r *http.Request, account *model.Acc
|
||||
}
|
||||
|
||||
func decodeInitiatePaymentsPayload(r *http.Request) (*srequest.InitiatePayments, error) {
|
||||
defer r.Body.Close()
|
||||
defer func() {
|
||||
_ = r.Body.Close()
|
||||
}()
|
||||
|
||||
payload := &srequest.InitiatePayments{}
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/tech/sendico/pkg/auth"
|
||||
"github.com/tech/sendico/pkg/mlogger"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
orchestrationv2 "github.com/tech/sendico/pkg/proto/payments/orchestration/v2"
|
||||
@@ -118,7 +117,7 @@ func TestInitiatePaymentsByQuote_RejectsDeprecatedIntentRefsField(t *testing.T)
|
||||
|
||||
func newBatchAPI(exec executionClient) *PaymentAPI {
|
||||
return &PaymentAPI{
|
||||
logger: mlogger.Logger(zap.NewNop()),
|
||||
logger: zap.NewNop(),
|
||||
execution: exec,
|
||||
enf: fakeEnforcerForBatch{allowed: true},
|
||||
oph: mutil.CreatePH(mservice.Organizations),
|
||||
@@ -129,7 +128,7 @@ func newBatchAPI(exec executionClient) *PaymentAPI {
|
||||
func invokeInitiatePaymentsByQuote(t *testing.T, api *PaymentAPI, orgRef bson.ObjectID, body string) *httptest.ResponseRecorder {
|
||||
t.Helper()
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/by-multiquote", bytes.NewBufferString(body))
|
||||
req := httptest.NewRequestWithContext(context.Background(), http.MethodPost, "/by-multiquote", bytes.NewBufferString(body))
|
||||
routeCtx := chi.NewRouteContext()
|
||||
routeCtx.URLParams.Add("organizations_ref", orgRef.Hex())
|
||||
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, routeCtx))
|
||||
@@ -177,6 +176,7 @@ func (f fakeEnforcerForBatch) Enforce(context.Context, bson.ObjectID, bson.Objec
|
||||
}
|
||||
|
||||
func (fakeEnforcerForBatch) EnforceBatch(context.Context, []model.PermissionBoundStorable, bson.ObjectID, model.Action) (map[bson.ObjectID]bool, error) {
|
||||
//nolint:nilnil // Test stub does not provide batch permissions map.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,9 @@ func (a *PaymentAPI) quotePayments(r *http.Request, account *model.Account, toke
|
||||
}
|
||||
|
||||
func decodeQuotePayload(r *http.Request) (*srequest.QuotePayment, error) {
|
||||
defer r.Body.Close()
|
||||
defer func() {
|
||||
_ = r.Body.Close()
|
||||
}()
|
||||
|
||||
payload := &srequest.QuotePayment{}
|
||||
if err := json.NewDecoder(r.Body).Decode(payload); err != nil {
|
||||
@@ -140,7 +142,9 @@ func decodeQuotePayload(r *http.Request) (*srequest.QuotePayment, error) {
|
||||
}
|
||||
|
||||
func decodeQuotePaymentsPayload(r *http.Request) (*srequest.QuotePayments, error) {
|
||||
defer r.Body.Close()
|
||||
defer func() {
|
||||
_ = r.Body.Close()
|
||||
}()
|
||||
|
||||
payload := &srequest.QuotePayments{}
|
||||
if err := json.NewDecoder(r.Body).Decode(payload); err != nil {
|
||||
|
||||
@@ -256,6 +256,7 @@ func (c *grpcQuotationClient) callContext(ctx context.Context) (context.Context,
|
||||
if timeout <= 0 {
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
//nolint:gosec // Caller receives cancel func and defers it in every call path.
|
||||
return context.WithTimeout(ctx, timeout)
|
||||
}
|
||||
|
||||
@@ -271,7 +272,7 @@ func (a *PaymentAPI) initDiscoveryClient(cfg *eapi.Config) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := discovery.NewClient(a.logger, broker, nil, string(a.Name()))
|
||||
client, err := discovery.NewClient(a.logger, broker, nil, a.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -90,5 +90,5 @@ func (a *PermissionsAPI) changePoliciesImp(
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
return struct{}{}, nil
|
||||
}
|
||||
|
||||
@@ -223,6 +223,7 @@ func (a *WalletAPI) queryBalanceFromGateways(ctx context.Context, gateways []dis
|
||||
a.logger.Debug("Wallet balance fan-out completed without result",
|
||||
zap.String("organization_ref", organizationRef),
|
||||
zap.String("wallet_ref", walletRef))
|
||||
//nolint:nilnil // No gateway returned a balance and no hard error occurred.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -238,7 +239,11 @@ func (a *WalletAPI) queryGatewayBalance(ctx context.Context, gateway discovery.G
|
||||
if err != nil {
|
||||
return nil, merrors.InternalWrap(err, "dial gateway")
|
||||
}
|
||||
defer conn.Close()
|
||||
defer func() {
|
||||
if closeErr := conn.Close(); closeErr != nil {
|
||||
a.logger.Warn("Failed to close gateway connection", zap.Error(closeErr), zap.String("gateway", gateway.ID))
|
||||
}
|
||||
}()
|
||||
|
||||
client := connectorv1.NewConnectorServiceClient(conn)
|
||||
|
||||
|
||||
@@ -173,7 +173,11 @@ func (a *WalletAPI) createWalletOnGateway(ctx context.Context, gateway discovery
|
||||
if err != nil {
|
||||
return "", merrors.InternalWrap(err, "dial gateway")
|
||||
}
|
||||
defer conn.Close()
|
||||
defer func() {
|
||||
if closeErr := conn.Close(); closeErr != nil {
|
||||
a.logger.Warn("Failed to close gateway connection", zap.Error(closeErr), zap.String("gateway", gateway.ID))
|
||||
}
|
||||
}()
|
||||
|
||||
client := connectorv1.NewConnectorServiceClient(conn)
|
||||
|
||||
|
||||
@@ -226,7 +226,11 @@ func (a *WalletAPI) queryGateway(ctx context.Context, gateway discovery.GatewayS
|
||||
if err != nil {
|
||||
return nil, merrors.InternalWrap(err, "dial gateway")
|
||||
}
|
||||
defer conn.Close()
|
||||
defer func() {
|
||||
if closeErr := conn.Close(); closeErr != nil {
|
||||
a.logger.Warn("Failed to close gateway connection", zap.Error(closeErr), zap.String("gateway", gateway.ID))
|
||||
}
|
||||
}()
|
||||
|
||||
client := connectorv1.NewConnectorServiceClient(conn)
|
||||
|
||||
|
||||
@@ -64,18 +64,21 @@ func (a *WalletAPI) rememberWalletRoute(ctx context.Context, organizationRef str
|
||||
|
||||
func (a *WalletAPI) walletRoute(ctx context.Context, organizationRef string, walletRef string) (*model.ChainWalletRoute, error) {
|
||||
if a.routes == nil {
|
||||
//nolint:nilnil // Routing cache is optional and may be disabled.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
walletRef = strings.TrimSpace(walletRef)
|
||||
organizationRef = strings.TrimSpace(organizationRef)
|
||||
if walletRef == "" || organizationRef == "" {
|
||||
//nolint:nilnil // Missing route keys mean no cached route.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
route, err := a.routes.Get(ctx, organizationRef, walletRef)
|
||||
if err != nil {
|
||||
if errors.Is(err, merrors.ErrNoData) {
|
||||
//nolint:nilnil // Route not found in cache.
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
|
||||
@@ -129,7 +129,7 @@ func (a *WalletAPI) initDiscoveryClient(cfg *eapi.Config) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := discovery.NewClient(a.logger, broker, nil, string(a.Name()))
|
||||
client, err := discovery.NewClient(a.logger, broker, nil, a.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user