Skip to content

Commit e420f23

Browse files
committed
fix
1 parent 19f66b7 commit e420f23

File tree

4 files changed

+208
-93
lines changed

4 files changed

+208
-93
lines changed

api/routes.go

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ func RegisterRoutes(e *echo.Echo, svc *service.MessageService, pushSvc *service.
2828
e.POST("/_matrix/push/v1/notify", h.matrixPushNotify)
2929
// Matrix Application Service transactions (push events to AS)
3030
e.PUT("/_matrix/app/v1/transactions/:txnId", h.matrixAppTransaction)
31-
32-
// Matrix Media Download Proxy
33-
e.GET("/_matrix/media/v3/download/:serverName/:mediaId", h.proxyMediaDownload)
3431
}
3532

3633
type handler struct {
@@ -232,20 +229,3 @@ func (h handler) matrixAppTransaction(c echo.Context) error {
232229
// As per spec, acknowledge with an empty JSON object and 200 OK.
233230
return c.JSON(http.StatusOK, map[string]interface{}{})
234231
}
235-
236-
// proxyMediaDownload handles media download requests by proxying them to the Matrix homeserver.
237-
func (h handler) proxyMediaDownload(c echo.Context) error {
238-
serverName := c.Param("serverName")
239-
mediaId := c.Param("mediaId")
240-
mxcURL := "mxc://" + serverName + "/" + mediaId
241-
242-
logger.Debug().Str("endpoint", "proxy_media_download").Str("mxc_url", mxcURL).Msg("proxying media download request")
243-
244-
data, contentType, err := h.svc.DownloadMedia(c.Request().Context(), mxcURL)
245-
if err != nil {
246-
logger.Error().Str("endpoint", "proxy_media_download").Str("mxc_url", mxcURL).Err(err).Msg("failed to download media from matrix")
247-
return echo.NewHTTPError(http.StatusNotFound, "media not found")
248-
}
249-
250-
return c.Blob(http.StatusOK, contentType, data)
251-
}

main_test.go

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ 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"
1115
"os"
1216
"strings"
1317
"testing"
@@ -125,6 +129,7 @@ func startTestServer(cfg *testConfig) (*echo.Echo, error) {
125129
ExtAuthURL: "http://localhost:18081",
126130
ExtAuthTimeoutS: 5,
127131
ExtAuthTimeout: 5 * time.Second,
132+
MMMSGURL: os.Getenv("MMMSG_URL"),
128133
}
129134

130135
// Initialize push token database
@@ -506,6 +511,33 @@ func TestIntegration_SendAndFetchImageMessages(t *testing.T) {
506511
t.Skip("Skipping integration tests; set RUN_INTEGRATION_TESTS=1 to run.")
507512
}
508513

514+
// Start mock MMMSG server
515+
var uploadedData []byte
516+
mmmsgServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
517+
if r.Method == "POST" {
518+
t.Logf("Mock MMMSG: received POST request")
519+
w.Header().Set("Content-Type", "application/json")
520+
json.NewEncoder(w).Encode(map[string]string{
521+
"url": "http://" + r.Host + "/upload/123",
522+
})
523+
return
524+
}
525+
if r.Method == "PUT" && strings.HasPrefix(r.URL.Path, "/upload/") {
526+
t.Logf("Mock MMMSG: received PUT request for %s", r.URL.Path)
527+
data, _ := io.ReadAll(r.Body)
528+
uploadedData = data
529+
w.WriteHeader(http.StatusOK)
530+
return
531+
}
532+
t.Logf("Mock MMMSG: received unexpected %s request for %s", r.Method, r.URL.Path)
533+
w.WriteHeader(http.StatusNotFound)
534+
}))
535+
defer mmmsgServer.Close()
536+
537+
// Set MMMSG_URL to point to our mock server
538+
os.Setenv("MMMSG_URL", mmmsgServer.URL)
539+
defer os.Unsetenv("MMMSG_URL")
540+
509541
server, err := startTestServer(cfg)
510542
if err != nil {
511543
t.Fatalf("failed to start test server: %v", err)
@@ -703,27 +735,42 @@ func TestIntegration_SendAndFetchImageMessages(t *testing.T) {
703735
ft.Attachments[0].Preview != nil)
704736
})
705737

706-
// Step 4: Download the actual image from the proxy URL
707-
t.Run("DownloadImageFromProxy", func(t *testing.T) {
708-
resp, err := http.Get(attachment.ContentURL)
709-
if err != nil {
710-
t.Fatalf("failed to download image from proxy: %v", err)
711-
}
712-
defer resp.Body.Close()
713-
714-
if resp.StatusCode != http.StatusOK {
715-
t.Errorf("expected status 200 OK, got %d", resp.StatusCode)
738+
// Step 4: Verify MMMSG upload and encryption
739+
t.Run("VerifyMMMSGUpload", func(t *testing.T) {
740+
if len(uploadedData) == 0 {
741+
t.Fatalf("no data was uploaded to MMMSG")
716742
}
743+
t.Logf("Data uploaded to MMMSG: %d bytes", len(uploadedData))
717744

718-
downloadedData, err := io.ReadAll(resp.Body)
719-
if err != nil {
720-
t.Fatalf("failed to read downloaded image data: %v", err)
745+
if !strings.HasPrefix(attachment.ContentURL, mmmsgServer.URL) {
746+
t.Errorf("attachment content-url %s does not point to mock MMMSG server %s", attachment.ContentURL, mmmsgServer.URL)
721747
}
722748

723-
if len(downloadedData) == 0 {
724-
t.Errorf("downloaded image data is empty")
749+
if attachment.EncryptionKey == "" {
750+
t.Errorf("encryption key is missing in attachment")
725751
} else {
726-
t.Logf("Image downloaded successfully from proxy: %d bytes", len(downloadedData))
752+
t.Logf("Encryption key found: %s", attachment.EncryptionKey)
753+
754+
// Verify that uploaded data is different from original (encrypted)
755+
if bytes.Equal(uploadedData, imageData) {
756+
t.Errorf("uploaded data is not encrypted (matches original)")
757+
} else {
758+
t.Logf("Uploaded data is encrypted (differs from original)")
759+
}
760+
761+
// Try to decrypt and verify
762+
key, _ := hex.DecodeString(attachment.EncryptionKey)
763+
block, _ := aes.NewCipher(key)
764+
iv := make([]byte, aes.BlockSize)
765+
stream := cipher.NewCTR(block, iv)
766+
decrypted := make([]byte, len(uploadedData))
767+
stream.XORKeyStream(decrypted, uploadedData)
768+
769+
if !bytes.Equal(decrypted, imageData) {
770+
t.Errorf("decrypted data does not match original image data")
771+
} else {
772+
t.Logf("Decrypted data matches original image data successfully")
773+
}
727774
}
728775
})
729776
})

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)