genofire/hs_monolith
genofire
/
hs_monolith
Archived
1
0
Fork 0

[TASK] move worker to lib + add permission handler to lib

This commit is contained in:
Martin Geno 2017-04-05 20:23:29 +02:00
parent 38f51b29a9
commit 8103a9768c
No known key found for this signature in database
GPG Key ID: F0D39A37E925E941
13 changed files with 154 additions and 17 deletions

View File

@ -27,6 +27,7 @@ func main() {
// load config // load config
config = models.ReadConfigFile(configFile) config = models.ReadConfigFile(configFile)
web.GoodAvailablityTemplate = config.GoodAvailablityTemplate web.GoodAvailablityTemplate = config.GoodAvailablityTemplate
models.CacheConfig = config.CacheClean
log.Log.Info("Starting rezension monolith") log.Log.Info("Starting rezension monolith")
@ -35,7 +36,7 @@ func main() {
log.Log.Panic(err) log.Log.Panic(err)
} }
grw := models.NewGoodReleaseWorker(config.GoodRelease) grw := models.NewGoodReleaseWorker(config.GoodRelease)
cw := models.NewCacheWorker(config.CacheClean) cw := models.NewCacheWorker()
go grw.Start() go grw.Start()
go cw.Start() go cw.Start()
// Startwebsrver // Startwebsrver

26
lib/http/permission.go Normal file
View File

@ -0,0 +1,26 @@
package http
import "net/http"
type HasPermission func(string, int) (bool, error)
func PermissionHandler(h func(w http.ResponseWriter, r *http.Request), perm HasPermission, permission int) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
session, err := r.Cookie("session")
if err != nil {
http.Error(w, err.Error(), http.StatusNonAuthoritativeInfo)
return
}
ok, err := perm(session.Value, permission)
if err != nil {
http.Error(w, err.Error(), http.StatusGatewayTimeout)
return
}
if ok {
h(w, r)
return
}
http.Error(w, "Not allowed", http.StatusForbidden)
}
}

View File

@ -0,0 +1,55 @@
package http
import (
"errors"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPermission(t *testing.T) {
assert := assert.New(t)
w := httptest.NewRecorder()
r, _ := http.NewRequest("GET", "/", nil)
// Request without session cookie
reached := false
PermissionHandler(func(w http.ResponseWriter, r *http.Request) {
reached = true
}, func(s string, i int) (bool, error) {
return true, nil
}, 1)(w, r)
assert.False(reached)
r.AddCookie(&http.Cookie{Name: "session"})
// HasPermission respond a true
reached = false
PermissionHandler(func(w http.ResponseWriter, r *http.Request) {
reached = true
}, func(s string, i int) (bool, error) {
return true, nil
}, 1)(w, r)
assert.True(reached)
// HasPermission respond a false
reached = false
PermissionHandler(func(w http.ResponseWriter, r *http.Request) {
reached = true
}, func(s string, i int) (bool, error) {
return false, nil
}, 1)(w, r)
assert.False(reached)
// HasPermission respond a error
reached = false
PermissionHandler(func(w http.ResponseWriter, r *http.Request) {
reached = true
}, func(s string, i int) (bool, error) {
return false, errors.New("text")
}, 1)(w, r)
assert.False(reached)
}

View File

@ -1,4 +1,4 @@
package models package worker
import "time" import "time"

24
lib/worker/worker_test.go Normal file
View File

@ -0,0 +1,24 @@
package worker
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestWorker(t *testing.T) {
assert := assert.New(t)
runtime := 0
w := NewWorker(time.Duration(5)*time.Millisecond, func() {
runtime = runtime + 1
})
go w.Start()
time.Sleep(time.Duration(18) * time.Millisecond)
w.Close()
assert.Equal(3, runtime)
time.Sleep(time.Duration(8) * time.Millisecond)
}

View File

@ -27,9 +27,8 @@ type permissionMicroServiceCache struct {
func (c *permissionMicroServiceCache) HasPermission(p Permission) (bool, error) { func (c *permissionMicroServiceCache) HasPermission(p Permission) (bool, error) {
c.LastCheck = time.Now() c.LastCheck = time.Now()
if cache, ok := c.permissions[p]; ok { if cache, ok := c.permissions[p]; ok {
// cache for 5min before := time.Now().Add(-CacheConfig.After.Duration)
before := time.Now().Add(-time.Minute * 5) if before.After(cache.LastCheck) {
if !cache.LastCheck.Before(before) {
return cache.Value, nil return cache.Value, nil
} }
} }

View File

@ -12,4 +12,8 @@ func TestAuth(t *testing.T) {
perm, err := HasPermission("session", PermissionCreateGood) perm, err := HasPermission("session", PermissionCreateGood)
assert.NoError(err) assert.NoError(err)
assert.True(perm) assert.True(perm)
perm, err = HasPermission("session", PermissionCreateGood)
assert.NoError(err)
assert.True(perm)
} }

View File

@ -1,23 +1,30 @@
package models package models
import "time" import (
"time"
"github.com/genofire/hs_master-kss-monolith/lib/worker"
)
var CacheConfig CacheWorkerConfig
type CacheWorkerConfig struct { type CacheWorkerConfig struct {
Every Duration Every Duration
After Duration After Duration
} }
func NewCacheWorker(config CacheWorkerConfig) (w *Worker) { func NewCacheWorker() (w *worker.Worker) {
return NewWorker(config.Every.Duration, func() { return worker.NewWorker(CacheConfig.Every.Duration, func() {
before := time.Now().Add(-CacheConfig.After.Duration)
// Cache if product exists // Cache if product exists
for index, cache := range productExistCache { for index, cache := range productExistCache {
if cache.LastCheck.After(time.Now().Add(-config.After.Duration)) { if before.After(cache.LastCheck) {
delete(productExistCache, index) delete(productExistCache, index)
} }
} }
// Cache for permissions // Cache for permissions
for index, cache := range permissionCache { for index, cache := range permissionCache {
if cache.LastCheck.After(time.Now().Add(-config.After.Duration)) { if before.After(cache.LastCheck) {
delete(permissionCache, index) delete(permissionCache, index)
} }
} }

View File

@ -0,0 +1,24 @@
package models
import (
"testing"
"time"
)
func TestCacheWorker(t *testing.T) {
productExistCache[2] = boolMicroServiceCache{LastCheck: time.Now(), Value: true}
permissionCache["blub"] = &permissionMicroServiceCache{
LastCheck: time.Now(),
session: "blub",
permissions: make(map[Permission]boolMicroServiceCache),
}
CacheConfig = CacheWorkerConfig{
Every: Duration{Duration: time.Duration(3) * time.Millisecond},
After: Duration{Duration: time.Duration(5) * time.Millisecond},
}
cw := NewCacheWorker()
go cw.Start()
time.Sleep(time.Duration(15) * time.Millisecond)
cw.Close()
}

View File

@ -4,6 +4,7 @@ import (
"time" "time"
"github.com/genofire/hs_master-kss-monolith/lib/database" "github.com/genofire/hs_master-kss-monolith/lib/database"
"github.com/genofire/hs_master-kss-monolith/lib/worker"
) )
type GoodReleaseConfig struct { type GoodReleaseConfig struct {
@ -11,8 +12,8 @@ type GoodReleaseConfig struct {
Every Duration `toml:"every"` Every Duration `toml:"every"`
} }
func NewGoodReleaseWorker(grc GoodReleaseConfig) *Worker { func NewGoodReleaseWorker(grc GoodReleaseConfig) *worker.Worker {
return NewWorker(grc.Every.Duration, func() { return worker.NewWorker(grc.Every.Duration, func() {
goodRelease(grc.After.Duration) goodRelease(grc.After.Duration)
}) })
} }

View File

@ -24,12 +24,8 @@ func init() {
func (p *Product) Exists() (bool, error) { func (p *Product) Exists() (bool, error) {
if cache, ok := productExistCache[p.ID]; ok { if cache, ok := productExistCache[p.ID]; ok {
// cache for 5min
before := time.Now().Add(-time.Minute * 5)
if !cache.LastCheck.Before(before) {
return cache.Value, nil return cache.Value, nil
} }
}
url := fmt.Sprintf(ProductURL, p.ID) url := fmt.Sprintf(ProductURL, p.ID)
log.Log.WithField("url", url).Info("exists product?") log.Log.WithField("url", url).Info("exists product?")