Skip to content

Commit 7f6c4eb

Browse files
committed
fix
1 parent 5a8f39a commit 7f6c4eb

File tree

3 files changed

+281
-63
lines changed

3 files changed

+281
-63
lines changed

main_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@ package main
33
import (
44
"bytes"
55
"context"
6+
"crypto/aes"
7+
"crypto/cipher"
68
"encoding/base64"
9+
"encoding/hex"
710
"encoding/json"
811
"fmt"
912
"io"
1013
"net/http"
14+
"net/http/httptest"
15+
"net/url"
1116
"os"
1217
"strings"
1318
"testing"
@@ -125,6 +130,7 @@ func startTestServer(cfg *testConfig) (*echo.Echo, error) {
125130
ExtAuthURL: "http://localhost:18081",
126131
ExtAuthTimeoutS: 5,
127132
ExtAuthTimeout: 5 * time.Second,
133+
MMMSGURL: os.Getenv("MMMSG_URL"),
128134
}
129135

130136
// Initialize push token database
@@ -506,6 +512,36 @@ func TestIntegration_SendAndFetchImageMessages(t *testing.T) {
506512
t.Skip("Skipping integration tests; set RUN_INTEGRATION_TESTS=1 to run.")
507513
}
508514

515+
// Start mock MMMSG server
516+
uploadedByPath := make(map[string][]byte)
517+
var uploadCounter int
518+
mmmsgServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
519+
if r.Method == "POST" {
520+
uploadCounter++
521+
uploadPath := fmt.Sprintf("/upload/%d", uploadCounter)
522+
t.Logf("Mock MMMSG: received POST request, returning upload path %s", uploadPath)
523+
w.Header().Set("Content-Type", "application/json")
524+
json.NewEncoder(w).Encode(map[string]string{
525+
"url": "http://" + r.Host + uploadPath,
526+
})
527+
return
528+
}
529+
if r.Method == "PUT" && strings.HasPrefix(r.URL.Path, "/upload/") {
530+
t.Logf("Mock MMMSG: received PUT request for %s", r.URL.Path)
531+
data, _ := io.ReadAll(r.Body)
532+
uploadedByPath[r.URL.Path] = data
533+
w.WriteHeader(http.StatusOK)
534+
return
535+
}
536+
t.Logf("Mock MMMSG: received unexpected %s request for %s", r.Method, r.URL.Path)
537+
w.WriteHeader(http.StatusNotFound)
538+
}))
539+
defer mmmsgServer.Close()
540+
541+
// Set MMMSG_URL to point to our mock server
542+
os.Setenv("MMMSG_URL", mmmsgServer.URL)
543+
defer os.Unsetenv("MMMSG_URL")
544+
509545
server, err := startTestServer(cfg)
510546
if err != nil {
511547
t.Fatalf("failed to start test server: %v", err)
@@ -702,6 +738,51 @@ func TestIntegration_SendAndFetchImageMessages(t *testing.T) {
702738
ft.Attachments[0].ContentSize,
703739
ft.Attachments[0].Preview != nil)
704740
})
741+
742+
// Step 4: Verify MMMSG upload and encryption
743+
t.Run("VerifyMMMSGUpload", func(t *testing.T) {
744+
// Locate the uploaded data for this attachment by using the content URL path
745+
parsed, perr := url.Parse(attachment.ContentURL)
746+
if perr != nil {
747+
t.Fatalf("failed to parse attachment content URL: %v", perr)
748+
}
749+
uploadedData, ok := uploadedByPath[parsed.Path]
750+
if !ok || len(uploadedData) == 0 {
751+
t.Fatalf("no data was uploaded to MMMSG for path %s", parsed.Path)
752+
}
753+
t.Logf("Data uploaded to MMMSG: %d bytes (path=%s)", len(uploadedData), parsed.Path)
754+
755+
if !strings.HasPrefix(attachment.ContentURL, mmmsgServer.URL) {
756+
t.Errorf("attachment content-url %s does not point to mock MMMSG server %s", attachment.ContentURL, mmmsgServer.URL)
757+
}
758+
759+
if attachment.EncryptionKey == "" {
760+
t.Errorf("encryption key is missing in attachment")
761+
} else {
762+
t.Logf("Encryption key found: %s", attachment.EncryptionKey)
763+
764+
// Verify that uploaded data is different from original (encrypted)
765+
if bytes.Equal(uploadedData, imageData) {
766+
t.Errorf("uploaded data is not encrypted (matches original)")
767+
} else {
768+
t.Logf("Uploaded data is encrypted (differs from original)")
769+
}
770+
771+
// Try to decrypt and verify
772+
key, _ := hex.DecodeString(attachment.EncryptionKey)
773+
block, _ := aes.NewCipher(key)
774+
iv := make([]byte, aes.BlockSize)
775+
stream := cipher.NewCTR(block, iv)
776+
decrypted := make([]byte, len(uploadedData))
777+
stream.XORKeyStream(decrypted, uploadedData)
778+
779+
if !bytes.Equal(decrypted, imageData) {
780+
t.Errorf("decrypted data does not match original image data")
781+
} else {
782+
t.Logf("Decrypted data matches original image data successfully")
783+
}
784+
}
785+
})
705786
})
706787
}
707788

service/config.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ type Config struct {
4545
ExtAuthURL string
4646
ExtAuthTimeoutS int
4747
ExtAuthTimeout time.Duration
48+
49+
// Acrobits MMMSG configuration
50+
MMMSGURL string
4851
}
4952

5053
// NewConfig loads all configuration from environment variables with validation
@@ -155,6 +158,15 @@ func NewConfig() (*Config, error) {
155158
}
156159
cfg.ExtAuthTimeout = time.Duration(cfg.ExtAuthTimeoutS) * time.Second
157160

161+
// Load MMMSG configuration
162+
cfg.MMMSGURL = os.Getenv("MMMSG_URL")
163+
if cfg.MMMSGURL == "" {
164+
cfg.MMMSGURL = "https://mmmsg.acrobits.net"
165+
logger.Debug().Str("MMMSG_URL", cfg.MMMSGURL).Msg("using default MMMSG URL")
166+
} else {
167+
logger.Debug().Str("MMMSG_URL", cfg.MMMSGURL).Msg("MMMSG URL loaded from environment")
168+
}
169+
158170
logger.Debug().Msg("configuration loading completed successfully")
159171

160172
return cfg, nil
@@ -175,6 +187,7 @@ func NewTestConfig() *Config {
175187
CacheTTL: time.Duration(defaultCacheTTLSeconds) * time.Second,
176188
ExtAuthTimeoutS: defaultExtAuthTimeoutS,
177189
ExtAuthTimeout: time.Duration(defaultExtAuthTimeoutS) * time.Second,
190+
MMMSGURL: "https://mmmsg.acrobits.net",
178191
}
179192
}
180193

0 commit comments

Comments
 (0)