diff --git a/adserver/handlers/handlers.go b/adserver/handlers/handlers.go index ee44d5d..73e89bf 100644 --- a/adserver/handlers/handlers.go +++ b/adserver/handlers/handlers.go @@ -35,7 +35,8 @@ func (h *AdServerHandler) GetAd(c *gin.Context) { } eventServerPort := os.Getenv("EVENT_SERVER_PORT") - hostName := os.Getenv("EVENT_SERVER_PUBLIC_HOSTNAME") + //hostName := os.Getenv("EVENT_SERVER_PUBLIC_HOSTNAME") + hostName := os.Getenv("EVENT_SERVER_HOSTNAME") eventServerURL := "http://" + hostName + ":" + eventServerPort clickReqPath := os.Getenv("CLICK_REQ_PATH") @@ -46,8 +47,8 @@ func (h *AdServerHandler) GetAd(c *gin.Context) { privateKey := os.Getenv("PRIVATE_KEY") key, _ := base64.StdEncoding.DecodeString(privateKey) - clickToken, _ := h.tokenHandler.GenerateToken(models.Click, chosenAd.ID, uint(publisherId), chosenAd.Bid, chosenAd.Website, key) - impressionToken, _ := h.tokenHandler.GenerateToken(models.Impression, chosenAd.ID, uint(publisherId), chosenAd.Bid, chosenAd.Website, key) + clickToken, _ := h.tokenHandler.GenerateToken(models.Click, chosenAd.ID, uint(publisherId), chosenAd.Bid, key) + impressionToken, _ := h.tokenHandler.GenerateToken(models.Impression, chosenAd.ID, uint(publisherId), chosenAd.Bid, key) c.JSON(http.StatusOK, gin.H{ "image_link": chosenAd.ImagePath, @@ -56,6 +57,7 @@ func (h *AdServerHandler) GetAd(c *gin.Context) { "click_link": eventServerURL + "/" + clickReqPath, "impression_token": impressionToken, "click_token": clickToken, + "redirect_path": chosenAd.Website, }) } diff --git a/adserver/handlers/handlers_test.go b/adserver/handlers/handlers_test.go index 35becc9..d6d1151 100644 --- a/adserver/handlers/handlers_test.go +++ b/adserver/handlers/handlers_test.go @@ -37,7 +37,7 @@ type MockTokenHandler struct { GenerateTokenError error } -func (m *MockTokenHandler) GenerateToken(interaction models.AdsInteractionType, adID, publisherID uint, bid int64, redirectPath string, key []byte) (string, error) { +func (m *MockTokenHandler) GenerateToken(interaction models.AdsInteractionType, adID, publisherID uint, bid int64, key []byte) (string, error) { return m.GenerateTokenResult, m.GenerateTokenError } diff --git a/common/dto/CustomToken.go b/common/dto/CustomToken.go index f2013f6..0ac9d77 100644 --- a/common/dto/CustomToken.go +++ b/common/dto/CustomToken.go @@ -5,10 +5,9 @@ import ( ) type CustomToken struct { - Interaction models.AdsInteractionType `json:"interaction"` - AdID uint `json:"ad_id"` - PublisherID uint `json:"publisher_id"` - RedirectPath string `json:"redirect_path"` - Bid int64 `json:"bid"` - CreatedAt int64 `json:"created_at"` + Interaction models.AdsInteractionType `json:"interaction"` + AdID uint `json:"ad_id"` + PublisherID uint `json:"publisher_id"` + Bid int64 `json:"bid"` + CreatedAt int64 `json:"created_at"` } diff --git a/common/tokenhandler/tokenhandler.go b/common/tokenhandler/tokenhandler.go index 42aef28..1944b1e 100644 --- a/common/tokenhandler/tokenhandler.go +++ b/common/tokenhandler/tokenhandler.go @@ -15,7 +15,7 @@ import ( ) type TokenHandlerInterface interface { - GenerateToken(interaction models.AdsInteractionType, adID, publisherID uint, bid int64, redirectPath string, key []byte) (string, error) + GenerateToken(interaction models.AdsInteractionType, adID, publisherID uint, bid int64, key []byte) (string, error) VerifyToken(encryptedToken string, key []byte) (*dto.CustomToken, error) } @@ -45,14 +45,13 @@ func (th *TokenHandlerService) encrypt(data []byte, key []byte) (string, error) return base64.StdEncoding.EncodeToString(ciphertext), nil } -func (th *TokenHandlerService) GenerateToken(interaction models.AdsInteractionType, adID, publisherID uint, bid int64, redirectPath string, key []byte) (string, error) { +func (th *TokenHandlerService) GenerateToken(interaction models.AdsInteractionType, adID, publisherID uint, bid int64, key []byte) (string, error) { token := dto.CustomToken{ - Interaction: interaction, - AdID: adID, - PublisherID: publisherID, - Bid: bid, - RedirectPath: redirectPath, - CreatedAt: time.Now().Unix(), + Interaction: interaction, + AdID: adID, + PublisherID: publisherID, + Bid: bid, + CreatedAt: time.Now().Unix(), } tokenBytes, err := json.Marshal(token) diff --git a/common/tokenhandler/tokenhandler_test.go b/common/tokenhandler/tokenhandler_test.go index 3ec5a3d..ec55f46 100644 --- a/common/tokenhandler/tokenhandler_test.go +++ b/common/tokenhandler/tokenhandler_test.go @@ -19,9 +19,8 @@ func TestGenerateToken_Success(t *testing.T) { adID := uint(1) publisherID := uint(100) bid := int64(20000) - redirectPath := "http://example.com" - token, err := th.GenerateToken(interaction, adID, publisherID, bid, redirectPath, key) + token, err := th.GenerateToken(interaction, adID, publisherID, bid, key) assert.NoError(t, err) assert.NotEmpty(t, token) } @@ -34,10 +33,9 @@ func TestVerifyToken_Success(t *testing.T) { adID := uint(1) publisherID := uint(100) bid := int64(20000) - redirectPath := "http://example.com" // Generate token - token, err := th.GenerateToken(interaction, adID, publisherID, bid, redirectPath, key) + token, err := th.GenerateToken(interaction, adID, publisherID, bid, key) assert.NoError(t, err) assert.NotEmpty(t, token) @@ -49,7 +47,6 @@ func TestVerifyToken_Success(t *testing.T) { assert.Equal(t, adID, verifiedToken.AdID) assert.Equal(t, publisherID, verifiedToken.PublisherID) assert.Equal(t, bid, verifiedToken.Bid) - assert.Equal(t, redirectPath, verifiedToken.RedirectPath) } func TestGenerateToken_EncryptError(t *testing.T) { @@ -60,9 +57,8 @@ func TestGenerateToken_EncryptError(t *testing.T) { adID := uint(1) publisherID := uint(100) bid := int64(20000) - redirectPath := "http://example.com" - token, err := th.GenerateToken(interaction, adID, publisherID, bid, redirectPath, key) + token, err := th.GenerateToken(interaction, adID, publisherID, bid, key) assert.Error(t, err) assert.Empty(t, token) } diff --git a/eventserver/handlers/handlers.go b/eventserver/handlers/handlers.go index 233d83d..adb53b8 100644 --- a/eventserver/handlers/handlers.go +++ b/eventserver/handlers/handlers.go @@ -2,7 +2,6 @@ package handlers import ( "encoding/base64" - "fmt" "log" "net/http" "os" @@ -37,7 +36,8 @@ func NewEventServerHandler(tokenHandler tokenhandler.TokenHandlerInterface, cach } type TokenRequest struct { - Token string `json:"token"` + Token string `json:"token"` + RedirectPath string `json:"redirectPath"` } // PostClick handles click events and produces them to a Kafka topic. @@ -55,18 +55,10 @@ func (h *EventServerHandler) PostClick(c *gin.Context) { return } - token := req.Token - data, err := h.tokenHandler.VerifyToken(token, key) - if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid token"}) - return - } + c.Redirect(http.StatusMovedPermanently, req.RedirectPath) // Running in goroutine so the server wouldn't have to wait - go h.produceClickIfTokenValid(token, data) - fmt.Println("slkdfjdfkdfjgkdfldf") - - c.Redirect(http.StatusMovedPermanently, data.RedirectPath) + go h.produceClickIfTokenValid(req.Token, key) } // PostImpression handles impression events and produces them to a Kafka topic. @@ -84,18 +76,17 @@ func (h *EventServerHandler) PostImpression(c *gin.Context) { return } - token := req.Token + // Running in goroutine so the server wouldn't have to wait + go h.produceImpressionIfTokenValid(req.Token, key) +} + +func (h *EventServerHandler) produceImpressionIfTokenValid(token string, key []byte) { data, err := h.tokenHandler.VerifyToken(token, key) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid token"}) + log.Printf("Failed to verify token: %v", err) return } - // Running in goroutine so the server wouldn't have to wait - go h.produceImpressionIfTokenValid(token, data) -} - -func (h *EventServerHandler) produceImpressionIfTokenValid(token string, data *dto.CustomToken) { present := h.cacheService.IsPresent(token) if present { log.Printf("Token %s already present", token) @@ -126,7 +117,13 @@ func (h *EventServerHandler) produceImpressionIfTokenValid(token string, data *d } } -func (h *EventServerHandler) produceClickIfTokenValid(token string, data *dto.CustomToken) { +func (h *EventServerHandler) produceClickIfTokenValid(token string, key []byte) { + data, err := h.tokenHandler.VerifyToken(token, key) + if err != nil { + log.Printf("Failed to verify token: %v", err) + return + } + present := h.cacheService.IsPresent(token) if present { log.Printf("Token %s already present", token) diff --git a/eventserver/handlers/handlers_test.go b/eventserver/handlers/handlers_test.go index 5956df1..f7c9c04 100644 --- a/eventserver/handlers/handlers_test.go +++ b/eventserver/handlers/handlers_test.go @@ -29,7 +29,7 @@ func setupEnv() { // Mock TokenHandler type MockTokenHandler struct{} -func (m *MockTokenHandler) GenerateToken(interaction models.AdsInteractionType, adID, publisherID uint, bid int64, redirectPath string, key []byte) (string, error) { +func (m *MockTokenHandler) GenerateToken(interaction models.AdsInteractionType, adID, publisherID uint, bid int64, key []byte) (string, error) { // Not needed for these tests return "duplicate", nil } @@ -37,12 +37,11 @@ func (m *MockTokenHandler) GenerateToken(interaction models.AdsInteractionType, func (m *MockTokenHandler) VerifyToken(encryptedToken string, key []byte) (*dto.CustomToken, error) { // Return a mock token return &dto.CustomToken{ - Interaction: models.Click, - AdID: 123, - PublisherID: 234, - RedirectPath: "http://example.com", - CreatedAt: time.Now().Unix(), - Bid: 1000, + Interaction: models.Click, + AdID: 123, + PublisherID: 234, + CreatedAt: time.Now().Unix(), + Bid: 1000, }, nil } @@ -81,14 +80,14 @@ func TestProduceImpressionIfTokenValid(t *testing.T) { handler := NewEventServerHandler(mockTokenHandler, mockCacheService, mockProducerService) - data, _ := mockTokenHandler.VerifyToken("", []byte("")) + _, _ = mockTokenHandler.VerifyToken("", []byte("")) - handler.produceImpressionIfTokenValid("", data) + handler.produceImpressionIfTokenValid("", []byte("")) assert.Equal(t, mockProducerService.clickCnt, 0) assert.Equal(t, mockProducerService.impCnt, 1) - handler.produceImpressionIfTokenValid("", data) + handler.produceImpressionIfTokenValid("", []byte("")) assert.Equal(t, mockProducerService.clickCnt, 0) assert.Equal(t, mockProducerService.impCnt, 1) @@ -103,14 +102,14 @@ func TestProduceClickIfTokenValid(t *testing.T) { handler := NewEventServerHandler(mockTokenHandler, mockCacheService, mockProducerService) - data, _ := mockTokenHandler.VerifyToken("", []byte("")) + _, _ = mockTokenHandler.VerifyToken("", []byte("")) - handler.produceClickIfTokenValid("", data) + handler.produceClickIfTokenValid("", []byte("")) assert.Equal(t, mockProducerService.clickCnt, 1) assert.Equal(t, mockProducerService.impCnt, 0) - handler.produceClickIfTokenValid("", data) + handler.produceClickIfTokenValid("", []byte("")) assert.Equal(t, mockProducerService.clickCnt, 1) assert.Equal(t, mockProducerService.impCnt, 0) diff --git a/panel/.env.example b/panel/.env.example index 3fece08..c88a5a7 100644 --- a/panel/.env.example +++ b/panel/.env.example @@ -8,4 +8,4 @@ TEST_DB_PATH="asset/test.db" AD_COST_CHECK_DURATION_SECS=60 PANEL_HOSTNAME=localhost TIMEOUT=10 -PANEL_PUBLIC_HOSTNAME=localhost \ No newline at end of file +PANEL_PUBLIC_HOSTNAME=localhost diff --git a/panel/asset/scriptTemplate.js b/panel/asset/scriptTemplate.js index 93afe9e..8f32f66 100644 --- a/panel/asset/scriptTemplate.js +++ b/panel/asset/scriptTemplate.js @@ -42,6 +42,7 @@ function clickHandler(data) { method: "POST", body: JSON.stringify({ token: data["click_token"] + redirectPath: data["redirect_path"] }) }) .then((res) => { @@ -68,4 +69,4 @@ function onVisibilityChange(el, callback) { callback() } } -} \ No newline at end of file +} diff --git a/publisherwebsite/static/js/script.js b/publisherwebsite/static/js/script.js index 7eea85c..cdb5e0f 100644 --- a/publisherwebsite/static/js/script.js +++ b/publisherwebsite/static/js/script.js @@ -68,7 +68,8 @@ function clickHandler(data) { fetch(data["click_link"], { method: "POST", body: JSON.stringify({ - token: data["click_token"] + token: data["click_token"], + redirectPath: data["redirect_path"] }) }) .then(res=>{