Skip to content
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

Pass redirect path through response body to script and remove it from… #67

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions adserver/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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,
Expand All @@ -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,
})
}

Expand Down
2 changes: 1 addition & 1 deletion adserver/handlers/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
11 changes: 5 additions & 6 deletions common/dto/CustomToken.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}
15 changes: 7 additions & 8 deletions common/tokenhandler/tokenhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down Expand Up @@ -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)
Expand Down
10 changes: 3 additions & 7 deletions common/tokenhandler/tokenhandler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)

Expand All @@ -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) {
Expand All @@ -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)
}
Expand Down
37 changes: 17 additions & 20 deletions eventserver/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package handlers

import (
"encoding/base64"
"fmt"
"log"
"net/http"
"os"
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
25 changes: 12 additions & 13 deletions eventserver/handlers/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,19 @@ 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
}

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
}

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion panel/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -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
PANEL_PUBLIC_HOSTNAME=localhost
3 changes: 2 additions & 1 deletion panel/asset/scriptTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ function clickHandler(data) {
method: "POST",
body: JSON.stringify({
token: data["click_token"]
redirectPath: data["redirect_path"]
})
})
.then((res) => {
Expand All @@ -68,4 +69,4 @@ function onVisibilityChange(el, callback) {
callback()
}
}
}
}
3 changes: 2 additions & 1 deletion publisherwebsite/static/js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -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=>{
Expand Down
Loading