Skip to content

Commit

Permalink
feat: Removing sync.Map in favor of Redis storage
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent Boutour <[email protected]>
  • Loading branch information
ViBiOh committed Apr 10, 2021
1 parent 0459dfa commit 45ac804
Show file tree
Hide file tree
Showing 12 changed files with 207 additions and 239 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ Usage of ketchup:
[owasp] Content-Security-Policy {KETCHUP_CSP} (default "default-src 'self'; base-uri 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'")
-dbHost string
[db] Host {KETCHUP_DB_HOST}
-dbMaxConn uint
[db] Max Open Connections {KETCHUP_DB_MAX_CONN} (default 5)
-dbName string
[db] Name {KETCHUP_DB_NAME}
-dbPass string
Expand Down Expand Up @@ -113,6 +115,8 @@ Usage of ketchup:
[mailer] URL (https?:// or amqps?://) {KETCHUP_MAILER_URL}
-notifierLoginID uint
[notifier] Scheduler user ID {KETCHUP_NOTIFIER_LOGIN_ID} (default 1)
-notifierPushUrl string
[notifier] Pushgateway URL {KETCHUP_NOTIFIER_PUSH_URL}
-okStatus int
[http] Healthy HTTP Status code {KETCHUP_OK_STATUS} (default 204)
-port uint
Expand Down Expand Up @@ -149,6 +153,12 @@ Usage of ketchup:
[server] Shutdown Timeout {KETCHUP_SHUTDOWN_TIMEOUT} (default "10s")
-title string
Application title {KETCHUP_TITLE} (default "Ketchup")
-tokenRedisAddress string
[token] Redis Address {KETCHUP_TOKEN_REDIS_ADDRESS} (default "localhost:6379")
-tokenRedisDatabase int
[token] Redis Database {KETCHUP_TOKEN_REDIS_DATABASE}
-tokenRedisPassword string
[token] Redis Password, if any {KETCHUP_TOKEN_REDIS_PASSWORD}
-url string
[alcotest] URL to check {KETCHUP_URL}
-userAgent string
Expand Down
7 changes: 5 additions & 2 deletions cmd/ketchup/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
ketchupStore "github.com/ViBiOh/ketchup/pkg/store/ketchup"
repositoryStore "github.com/ViBiOh/ketchup/pkg/store/repository"
userStore "github.com/ViBiOh/ketchup/pkg/store/user"
"github.com/ViBiOh/ketchup/pkg/token"
mailer "github.com/ViBiOh/mailer/pkg/client"
)

Expand Down Expand Up @@ -68,6 +69,7 @@ func main() {
rendererConfig := renderer.Flags(fs, "", flags.NewOverride("Title", "Ketchup"), flags.NewOverride("PublicURL", "https://ketchup.vibioh.fr"))

dbConfig := db.Flags(fs, "db")
tokenConfig := token.Flags(fs, "token")
mailerConfig := mailer.Flags(fs, "mailer")
githubConfig := github.Flags(fs, "github")
notifierConfig := notifier.Flags(fs, "notifier")
Expand Down Expand Up @@ -107,9 +109,11 @@ func main() {
publicRendererApp, err := renderer.New(rendererConfig, content, ketchup.FuncMap)
logger.Fatal(err)

tokenApp := token.New(tokenConfig)

notifierApp := notifier.New(notifierConfig, repositoryServiceApp, ketchupServiceApp, mailerApp)
schedulerApp := scheduler.New(schedulerConfig, notifierApp)
ketchupApp := ketchup.New(publicRendererApp, ketchupServiceApp, userServiceApp, repositoryServiceApp)
ketchupApp := ketchup.New(publicRendererApp, ketchupServiceApp, userServiceApp, repositoryServiceApp, tokenApp)

publicHandler := publicRendererApp.Handler(ketchupApp.PublicTemplateFunc)
signupHandler := http.StripPrefix(signupPath, ketchupApp.Signup())
Expand All @@ -129,7 +133,6 @@ func main() {
publicHandler.ServeHTTP(w, r)
})

go ketchupApp.Start(healthApp.Done())
go githubApp.Start(prometheusApp.Registerer(), healthApp.Done())
if schedulerApp != nil {
go schedulerApp.Start(healthApp.Done())
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/ViBiOh/auth/v2 v2.6.12
github.com/ViBiOh/httputils/v4 v4.5.1
github.com/ViBiOh/mailer v1.16.5
github.com/go-redis/redis/v8 v8.8.0
github.com/lib/pq v1.10.0
github.com/prometheus/client_golang v1.10.0
gopkg.in/yaml.v2 v2.4.0
Expand Down
47 changes: 46 additions & 1 deletion go.sum

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions infra/redis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: ketchup-redis
namespace: default
spec:
interval: 120m
chart:
spec:
chart: redis
version: "0.0.7"
sourceRef:
kind: HelmRepository
name: vibioh
interval: 120m
install:
skipCRDs: true
maxHistory: 3
upgrade:
remediation:
retries: 3
rollback:
cleanupOnFail: true
values:
secrets:
redis.conf: AgCVnuDaxpyIWj5uWNLgoCgEErfurpFGRw8PcA+R7YogmXu7Nb0pzFAr8p3+PeaSY/CK4CImVIU05AWyX0WMQashA3wHsP+6hfSzIvYOWWQOmXHctw0tam4eVtHKWju3JCCJMIsQTllmNDD7obGks2bGBEQaVZk5KPja5A0uj819XphitKiqSIVcTazeu8Fc2WhNR1AVhXjys3SAL3qdxTtEKYQUCHHrdJFXMu4q1zzQTTBOVVurVOBOWT1fhWDSkPIigcq3SaTs0bPpdgzzygCUmcWI6HHCPRi8Kpmp5JJNiFc0eV60wlWC3TCSqcYpX6ziwJa3OB6Nr9wAMP+1y/6epe79sQ4/KtJCAVxP3j6CjOVIBH8+Jkuff/e0iAy6JrF8yHAtY917zmFQHZ28aWqNREgsmCtb+q45wKWprmyZGAsMBMh48dFUp+Ib66isAhZ45V+q+73zS9NLtyc8nhYfPmRG2zGpJGLlrLjhRw/d+0VjI2Xc76O3d5vfVnjxHq90PG+cLOhdRzNXJeuz5V1W94CkrF6VHjiNkQdxNUbHdKS3+IK/Tb8QmnQBnmDRcr/bl0RwJmn/X3Pn3GSkyF2wGWJ630a2fu0uIqxsO1SkIjcGV+GKeV5C3cnqR9QOcgYNcyADkw7LFpic00xbTRb3K4h/yBWFMw21vbVm4c7GURGkUhXmHWx13UO+GKxC4scOVGFbQMpjHQpEGrgRIRxWbRXdQZTb5AlJnWWPNV+KAQiXSoqE2RdRSRtAjTGOg3hHUyaHukZ87joJr+cwgCwR7eedGvBMpN4rr2I=
4 changes: 3 additions & 1 deletion infra/web.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ spec:
KETCHUP_DB_NAME: ketchup
KETCHUP_DB_USER: ketchup
KETCHUP_SCHEDULER_ENABLED: "false"
KETCHUP_TOKEN_REDIS_ADDRESS: ketchup-redis:80
secrets:
KETCHUP_DB_PASS: AgDOK5Ph8WD8SbBi+Mn/ywPirM59KRfhAjkAqaOqDePJJDd3uIQhoJCKN5HCwYsUoux173go8RrPtyhc5CxKm+/sc6JiqeajZVv/mc/EVPa0MyNpCN376jXIvo0P+joasjBGys/rtqEauhdn7hWGr87PnJbL5A2k+XD3kMauzcKJtMXSYkz2QSTx7TW1kW+5zJs/Cgp3FS9qHZ8buvktggnKeffhd0paYJJrLmtyKxKzmkXcyL8Q3i3QnAbXC3u4vSPxP5PMFMEqDZNrmmYiEJVOmNcW+R0jO7u6q3gwWkATL7E0bbtWuanp6/FXgUhlgpmD+i9BSwTEzrglFHEGPESlg+uYDqXDXOKGBzmQPcq7aAU+/jcEyh5ozkF8aVod7fVxFo+g1nGCbwAhXK5E+iT+KZ1Q50mFkhRIOYSQ9aesHONBPpiaLp8y00OJ6oEmbCSmuDNOBTYXo/JIjUnJ5LFIIskcT5MWKPkYV3hlSzshQBR9JPXLqdaiIEiRicjnfU/qWrwel0PlEaU2L1FL1qsikxPkfGu1HHwj0CusGpGduD3DKC1mTEc1U4zAVvmqSMpoSguyfOYf/2C/m+jcd5YTkiS9JpTGUx4OVFvBD6Ug9uT7igLI8nNFZeTHMCnCerG7GES0wapWehYX/wYFaqw9K1ym0Jz2fHByCVNEt8XH0GxFszdTw2iF6Q4AIH4D8lLB9umdTPP91L5hYVSIOpv9qQPUa9pxB5aNwEG9Q+BQt31mM/zNEglv033PqYOAM12KsGqwew9HJBAUFQU=
KETCHUP_TOKEN_REDIS_PASSWORD: AgDFj9oiAU2G4sqvbTzjqaGYCdsJpOxvRJ+V6jo6tmj1wjFOO1G3HIUGl4/K/rjxClTiXyQAG8jTQS5xOyOUMlRtGEWM1ccHxPzkBJ9k1hSSpaPG0cOJokVbSBAeO7GRBOfOv+hDtOBkPMrFOuo/n79ie6bIk8TEMqHjd2UbLkip31i7zp9kNG+k2JJ+EC/vdN4y5eliFV/0vBAgtC7H2yu6/7oaKt+EuM8tqaJ8E3Jp68vlBo0YqurvjueQCa1HEUt0bcexLW+KGwqfPUoG5SVIwDP2Z572UKsA4hdCYjsuCvfV+KWOoMtLMAqIM+e/H+twsV7pU5TI206dywlniQQUpcTJNk+MbNwWepJizBiHIxSeXxzDcNgRR/5ezRoOzFzTLGOHn7Xr4ya6S9yFoaFR+/GQXluvVoyJ7IsEgqOzcz551SVGB7AsgncAPFKs9r2xRlFgSCvserQm+AbOL/JbobzZtinjzPMXKW+gD9LqLrEddcMu1XeGSpzoYo6WUbPNvh1+ETQsVA8KjzMYVBHuVAMMfoxCY+xprsNxkD9HxYKvJkznit59y+G/MZo/hQcx8ow1T8TbsKRWmYsDP8h2PaejAlk7AOYAbKeqh1an7kBcIh2U/YyAuEaXsLxWOzSajXR1zUuVca73ncthejIP8YUj9bDL3M3o6ug0WkWJ3pEhDhks6ZkNs0FP9MqS+t+BySOx+pX07Bsna5Vb+XagAxqfUeOPZJ63ncRShKyD+Uu6EJ+F72LuFcEe75wEcMb23GRwbd5szZY50qjwo3g=
KETCHUP_GITHUB_TOKEN: AgBsMBks+FDLh1scbW9OCRA2Y5NfFRfXk6OQws/5L2+wilH7DrDB6l80jWbFz9eEc+Lqq4GBw0024m6sWg6pZdkSZjhyYkgxW+amWTJDzjexg5Kwn7hv8566TAJ/KwpHyQTOoIcyPHBilqovd80Iy/LhVXKHRne79lCxEHA0HeWbS63YsV63eu6BgwF+N5Vp6VvAFfCA7+0Yj9bnhEiYNY6PrSRR/DxLhkY204JZvEoO+n+cnrMe2cir3LauofyZ+HoeLTMsF/0zYgGYiax+uk16tcSgq9sb7oWRyhlM429qOQ5YFeZMmbT9pvJeYEAz3fQH8sbepmB23KFAxzblN2LGImAGHRvn2kEKfPhHZgj/uhFGyeHAdk/Rzm/eoG49r8aBxeYfKbe5e5aL/Xp012I5VKuVu4z7vUiUlZMiHlgka1U5i/KicBj1a2z4XTRJLmIqacDl5L9RvBW1KQoH+eqJhlr+A8t5/GyyI0EjWVdQf+qs6AWrRvJRv1cvd/wL+i1zWKsZZ99B8e0JvA89aHGKBQHCNM4OCGXpv5dSizLClqCFF5W61cRmdZQ7QWnIpJoS/yBbY+xuldTtcHC7hWmQq+L2iHNLALlPnXncehVNhbztWnMoAJUNuhWBRL8coGbbI98OxxXSJlZEnkPscQYltTMI/q2laUcwx7NGX3oCOeGfl3Nz8TE62dW7gNIqCOfCDVVUAG/j/AuRjc1HbdAlx6JctW6k8QKQoXds8ULZbamFGcPnfIXC
ingress:
enabled: true
hosts:
- ketchup.vibioh.fr
- ketchup.vibioh.fr
canary:
enabled: true
url: https://ketchup.vibioh.fr
18 changes: 4 additions & 14 deletions pkg/ketchup/ketchup.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import (
"html/template"
"net/http"
"strings"
"time"

"github.com/ViBiOh/httputils/v4/pkg/cron"
"github.com/ViBiOh/httputils/v4/pkg/logger"
"github.com/ViBiOh/httputils/v4/pkg/renderer"
"github.com/ViBiOh/ketchup/pkg/service/ketchup"
"github.com/ViBiOh/ketchup/pkg/service/repository"
"github.com/ViBiOh/ketchup/pkg/service/user"
"github.com/ViBiOh/ketchup/pkg/token"
)

const (
Expand All @@ -26,7 +24,6 @@ var (

// App of package
type App interface {
Start(<-chan struct{})
Handler() http.Handler
Signup() http.Handler
PublicTemplateFunc(*http.Request) (string, int, map[string]interface{}, error)
Expand All @@ -38,27 +35,20 @@ type app struct {
ketchupService ketchup.App
userService user.App
repositoryService repository.App
tokenStore TokenStore
tokenApp token.App
}

// New creates new App from Config
func New(rendererApp renderer.App, ketchupService ketchup.App, userService user.App, repositoryService repository.App) App {
func New(rendererApp renderer.App, ketchupService ketchup.App, userService user.App, repositoryService repository.App, tokenApp token.App) App {
return app{
tokenStore: NewTokenStore(),

rendererApp: rendererApp,
ketchupService: ketchupService,
userService: userService,
repositoryService: repositoryService,
tokenApp: tokenApp,
}
}

func (a app) Start(done <-chan struct{}) {
cron.New().Each(time.Hour).OnError(func(err error) {
logger.Error("error while running token store cleanup: %s", err)
}).Start(a.tokenStore.Clean, done)
}

// Handler for request. Should be use with net/http
func (a app) Handler() http.Handler {
rendererHandler := a.rendererApp.Handler(a.AppTemplateFunc)
Expand Down
12 changes: 9 additions & 3 deletions pkg/ketchup/renderer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ketchup

import (
"context"
"crypto/rand"
"fmt"
"math/big"
Expand All @@ -15,19 +16,24 @@ const (
suggestCount = uint64(5)
)

func (a app) generateToken() (string, int64, error) {
func (a app) generateToken(ctx context.Context) (string, int64, error) {
questionID, err := rand.Int(rand.Reader, big.NewInt(int64(len(colors))))
if err != nil {
return "", 0, fmt.Errorf("unable to generate random int: %w", err)
}

id := questionID.Int64()

return a.tokenStore.Store(id, time.Minute*5), id, nil
token, err := a.tokenApp.Store(ctx, fmt.Sprintf("%d", id), time.Minute*5)
if err != nil {
return token, id, fmt.Errorf("unable to store token: %s", err)
}

return token, id, nil
}

func (a app) PublicTemplateFunc(r *http.Request) (string, int, map[string]interface{}, error) {
token, questionID, err := a.generateToken()
token, questionID, err := a.generateToken(r.Context())
if err != nil {
return "", http.StatusInternalServerError, nil, err
}
Expand Down
22 changes: 16 additions & 6 deletions pkg/ketchup/signup.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"errors"
"fmt"
"net/http"
"strconv"
"strings"

authModel "github.com/ViBiOh/auth/v2/pkg/model"
"github.com/ViBiOh/httputils/v4/pkg/logger"
httpModel "github.com/ViBiOh/httputils/v4/pkg/model"
"github.com/ViBiOh/httputils/v4/pkg/renderer"
"github.com/ViBiOh/ketchup/pkg/model"
Expand All @@ -25,14 +27,20 @@ func (a app) Signup() http.Handler {
}

token := r.FormValue("token")
questionID, ok := a.tokenStore.Load(token)
if !ok {
a.rendererApp.Error(w, errors.New("token has expired"))
questionIDString, err := a.tokenApp.Load(r.Context(), token)
if err != nil {
a.rendererApp.Error(w, httpModel.WrapInvalid(fmt.Errorf("unable to retrieve captcha token: %s", err)))
return
}

if colors[questionID.(int64)].Answer != strings.TrimSpace(r.FormValue("answer")) {
a.rendererApp.Error(w, errors.New("invalid question answer"))
questionID, err := strconv.ParseInt(questionIDString, 10, 64)
if err != nil {
a.rendererApp.Error(w, fmt.Errorf("question id is not numerical: %s", err))
return
}

if colors[questionID].Answer != strings.TrimSpace(r.FormValue("answer")) {
a.rendererApp.Error(w, httpModel.WrapInvalid(errors.New("invalid question answer")))
return
}

Expand All @@ -46,7 +54,9 @@ func (a app) Signup() http.Handler {
return
}

a.tokenStore.Delete(token)
if err := a.tokenApp.Delete(r.Context(), token); err != nil {
logger.Warn("unable to delete token: %s", err)
}

renderer.Redirect(w, r, fmt.Sprintf("%s/", appPath), renderer.NewSuccessMessage("Welcome to ketchup!"))
})
Expand Down
90 changes: 0 additions & 90 deletions pkg/ketchup/token.go

This file was deleted.

Loading

0 comments on commit 45ac804

Please sign in to comment.