Skip to content

Commit

Permalink
feat: save user ids in cookies
Browse files Browse the repository at this point in the history
  • Loading branch information
mledwon-BinaryCortex committed Jul 23, 2023
1 parent caac91b commit d5aced5
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 8 deletions.
17 changes: 17 additions & 0 deletions deployments/infrastructure/base/dynamodb.tf
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ resource "aws_dynamodb_table" "links" {
type = "N"
}

attribute {
name = "GSI_1_PK"
type = "S"
}

attribute {
name = "GSI_1_SK"
type = "S"
}

local_secondary_index {
name = "LSI_1"
range_key = "LSI_1"
Expand Down Expand Up @@ -69,6 +79,13 @@ resource "aws_dynamodb_table" "links" {
projection_type = "ALL"
}

global_secondary_index {
name = "GSI_1"
hash_key = "GSI_1_PK"
range_key = "GSI_1_SK"
projection_type = "ALL"
}

ttl {
attribute_name = "TTL"
enabled = true
Expand Down
19 changes: 15 additions & 4 deletions internal/api/handler/ajax_create_link.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,33 @@ import (
"github.com/go-playground/validator/v10"

"gotiny/internal/api/dto"
"gotiny/internal/api/middleware"
"gotiny/internal/api/util"
"gotiny/internal/core/model"
"gotiny/internal/core/usecase"
)

type AjaxCreateLinkHandler struct {
createShortLink *usecase.CreateShortLink
validate *validator.Validate
template *template.Template
formDecoder *form.Decoder
createShortLink *usecase.CreateShortLink
validate *validator.Validate
template *template.Template
formDecoder *form.Decoder
idCookieMiddleware *middleware.IdCookieMiddleware
}

func NewAjaxCreateLinkHandler(
createShortLink *usecase.CreateShortLink,
validate *validator.Validate,
template *template.Template,
formDecoder *form.Decoder,
idCookieMiddleware *middleware.IdCookieMiddleware,
) *AjaxCreateLinkHandler {
return &AjaxCreateLinkHandler{
createShortLink,
validate,
template,
formDecoder,
idCookieMiddleware,
}
}

Expand All @@ -49,6 +53,7 @@ func (h *AjaxCreateLinkHandler) ServeHTTP(writer http.ResponseWriter, request *h
MaxHits: create_link_dto.MaxHits,
ValidUntil: create_link_dto.ValidUntil,
TrackUntil: create_link_dto.TrackUntil,
UserId: request.Context().Value("user_id").(*string),
}
link, err := h.createShortLink.Call(request.Context(), config)
if err != nil {
Expand All @@ -66,3 +71,9 @@ func (h *AjaxCreateLinkHandler) Path() string {
func (h *AjaxCreateLinkHandler) Method() string {
return http.MethodPost
}

func (h *AjaxCreateLinkHandler) Middlewares() []func(http.Handler) http.Handler {
return []func(http.Handler) http.Handler{
h.idCookieMiddleware.Handle,
}
}
33 changes: 33 additions & 0 deletions internal/api/middleware/id_cookie_middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package middleware

import (
"context"
"net/http"

"github.com/segmentio/ksuid"
)

type IdCookieMiddleware struct{}

func NewIdCookieMiddleware() *IdCookieMiddleware {
return &IdCookieMiddleware{}
}

func (m *IdCookieMiddleware) Handle(next http.Handler) http.Handler {
fn := func(writer http.ResponseWriter, request *http.Request) {
id_cookie, err := request.Cookie("user_id")
if err != nil {
id_cookie = &http.Cookie{
Name: "user_id",
Value: ksuid.New().String(),
}
http.SetCookie(writer, id_cookie)
}

ctx := context.WithValue(request.Context(), "user_id", &id_cookie.Value)

next.ServeHTTP(writer, request.WithContext(ctx))
}

return http.HandlerFunc(fn)
}
1 change: 1 addition & 0 deletions internal/api/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func Providers() []interface{} {
fx.As(new(RouteHandler)),
),
middleware.NewLinkTokenValidator,
middleware.NewIdCookieMiddleware,
util.NewStructuredLogger,
}
}
2 changes: 2 additions & 0 deletions internal/core/model/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Link struct {
Token string
Hits uint
MaxHits *uint
UserId *string
ValidUntil *time.Time
TrackUntil *time.Time
CreatedAt time.Time
Expand All @@ -31,6 +32,7 @@ func NewFromIndex(index uint, linkToCreate LinkToCreate, baseUrl string) Link {
Token: util.RandString(tokenLength),
OriginalLink: linkToCreate.Url,
CreatedAt: now,
UserId: linkToCreate.UserId,
MaxHits: linkToCreate.MaxHits,
TrackUntil: linkToCreate.TrackUntil,
ValidUntil: linkToCreate.ValidUntil,
Expand Down
1 change: 1 addition & 0 deletions internal/core/model/link_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ type LinkToCreate struct {
ValidUntil *time.Time
MaxHits *uint
TrackUntil *time.Time
UserId *string
}
28 changes: 24 additions & 4 deletions internal/data/dto/link_dto.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@ import (
)

const (
LinkPK = "LINK"
LinkSKPrefix = "LINK#"
LinkPK = "LINK"
LinkSKPrefix = "LINK#"
LinkGSI1PKPrefix = "USER#"
LinkGSI1SKPrefix = "LINK#"
)

type LinkDto struct {
PK string
SK string
PK string // Constant
SK string // Link id
ShortLink string
OriginalLink string
Token string
Hits uint
MaxHits *uint
TTL *uint
GSI_1_PK *string // User id
GSI_1_SK *string // Created at
TrackUntil *time.Time
CreatedAt time.Time
}
Expand All @@ -30,6 +34,14 @@ func LinkDtoFromLink(link model.Link) LinkDto {
unix := uint(link.ValidUntil.Unix())
ttl = &unix
}
var gsi1PK *string
var gsi1SK *string
if link.UserId != nil {
pk := LinkGSI1PKPrefix + *link.UserId
sk := LinkGSI1SKPrefix + link.CreatedAt.Format(time.RFC3339Nano)
gsi1PK = &pk
gsi1SK = &sk
}
return LinkDto{
PK: LinkPK,
SK: LinkSKPrefix + link.Id,
Expand All @@ -39,6 +51,8 @@ func LinkDtoFromLink(link model.Link) LinkDto {
Hits: link.Hits,
MaxHits: link.MaxHits,
TTL: ttl,
GSI_1_PK: gsi1PK,
GSI_1_SK: gsi1SK,
TrackUntil: link.TrackUntil,
CreatedAt: link.CreatedAt,
}
Expand All @@ -50,6 +64,11 @@ func (d LinkDto) ToLink() model.Link {
t := time.Unix(int64(*d.TTL), 0)
validUntil = &t
}
var userId *string
if d.GSI_1_PK != nil {
u := (*d.GSI_1_PK)[len(LinkGSI1PKPrefix):]
userId = &u
}
return model.Link{
Id: d.SK[len(LinkSKPrefix):],
ShortLink: d.ShortLink,
Expand All @@ -58,6 +77,7 @@ func (d LinkDto) ToLink() model.Link {
Hits: d.Hits,
MaxHits: d.MaxHits,
ValidUntil: validUntil,
UserId: userId,
CreatedAt: d.CreatedAt,
TrackUntil: d.TrackUntil,
}
Expand Down

0 comments on commit d5aced5

Please sign in to comment.