mirror of
https://github.com/muety/wakapi.git
synced 2025-12-05 14:10:24 -08:00
chore: minor refactorings to shared data middleware logic
This commit is contained in:
@@ -38,13 +38,10 @@ const (
|
||||
KeySubscriptionNotificationSent = "sub_reminder"
|
||||
KeyNewsbox = "newsbox"
|
||||
KeyInviteCode = "invite"
|
||||
KeySharedData = "shared_data"
|
||||
|
||||
SessionKeyDefault = "default"
|
||||
|
||||
MiddlewareKeySharedData = "shared_data"
|
||||
MiddlewareKeyPrincipal = "principal"
|
||||
MiddlewareKeyPrincipalId = "principal_identity"
|
||||
|
||||
SimpleDateFormat = "2006-01-02"
|
||||
SimpleDateTimeFormat = "2006-01-02 15:04:05"
|
||||
|
||||
|
||||
@@ -113,6 +113,7 @@ func initSentry(config sentryConfig, debug bool, releaseVersion string) {
|
||||
func getPrincipal(r *http.Request) string {
|
||||
sharedData := r.Context().Value(MiddlewareKeySharedData)
|
||||
if sharedData == nil {
|
||||
Log().Request(r).Error("request shared data not set while retrieving principal for sentry logging")
|
||||
return ""
|
||||
}
|
||||
val := sharedData.(*SharedData).MustGet(MiddlewareKeyPrincipalId)
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
package config
|
||||
|
||||
import "github.com/muety/wakapi/utils"
|
||||
import (
|
||||
"github.com/muety/wakapi/lib"
|
||||
)
|
||||
|
||||
type SharedDataKey string
|
||||
|
||||
const (
|
||||
MiddlewareKeyPrincipal = SharedDataKey("principal")
|
||||
MiddlewareKeyPrincipalId = SharedDataKey("principal_identity")
|
||||
)
|
||||
|
||||
type SharedData struct {
|
||||
*utils.ConcurrentMap[string, interface{}]
|
||||
*lib.ConcurrentMap[SharedDataKey, interface{}]
|
||||
}
|
||||
|
||||
func NewSharedData() *SharedData {
|
||||
return &SharedData{utils.NewConcurrentMap[string, interface{}]()}
|
||||
return &SharedData{lib.NewConcurrentMap[SharedDataKey, interface{}]()}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ func ParseSummaryFilters(r *http.Request) *models.Filters {
|
||||
}
|
||||
|
||||
func extractUser(r *http.Request) *models.User {
|
||||
val := r.Context().Value(config.MiddlewareKeySharedData).(*config.SharedData).MustGet(config.MiddlewareKeyPrincipal)
|
||||
val := r.Context().Value(config.KeySharedData).(*config.SharedData).MustGet(config.MiddlewareKeyPrincipal)
|
||||
if val == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
44
lib/concurrent_map.go
Normal file
44
lib/concurrent_map.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package lib
|
||||
|
||||
import "sync"
|
||||
|
||||
type ConcurrentMap[K comparable, V any] struct {
|
||||
mu sync.RWMutex
|
||||
items map[K]V
|
||||
}
|
||||
|
||||
func NewConcurrentMap[K comparable, V any]() *ConcurrentMap[K, V] {
|
||||
return &ConcurrentMap[K, V]{
|
||||
items: make(map[K]V),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) Set(key K, value V) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.items[key] = value
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) Get(key K) (V, bool) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
value, ok := m.items[key]
|
||||
return value, ok
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) MustGet(key K) V {
|
||||
val, _ := m.Get(key)
|
||||
return val
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) Delete(key K) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
delete(m.items, key)
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) Len() int {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
return len(m.items)
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/muety/wakapi/config"
|
||||
)
|
||||
|
||||
const key = config.MiddlewareKeySharedData
|
||||
const key = config.KeySharedData
|
||||
|
||||
// This middleware is a bit of a dirty workaround to the fact that a http.Request's context
|
||||
// does not allow to pass values from an inner to an outer middleware. Calling WithContext() on a
|
||||
|
||||
@@ -73,7 +73,7 @@ func mockUserAwareRequest(requestedUser, authorizedUser string) (*http.Request,
|
||||
|
||||
r := httptest.NewRequest("GET", "http://localhost:3000/api/{user}/data", nil)
|
||||
r = withUrlParam(r, "user", requestedUser)
|
||||
r = r.WithContext(context.WithValue(r.Context(), config.MiddlewareKeySharedData, sharedData))
|
||||
r = r.WithContext(context.WithValue(r.Context(), config.KeySharedData, sharedData))
|
||||
|
||||
userServiceMock := new(mocks.UserServiceMock)
|
||||
userServiceMock.On("GetUserById", "user1").Return(&models.User{ID: "user1"}, nil)
|
||||
|
||||
@@ -2,7 +2,6 @@ package utils
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func SubSlice[T any](slice []T, from, to uint) []T {
|
||||
@@ -25,46 +24,3 @@ func CloneStringMap(m map[string]string, keysToLower bool) map[string]string {
|
||||
}
|
||||
return m2
|
||||
}
|
||||
|
||||
// Concurrent hash map implementation
|
||||
|
||||
type ConcurrentMap[K comparable, V any] struct {
|
||||
mu sync.RWMutex
|
||||
items map[K]V
|
||||
}
|
||||
|
||||
func NewConcurrentMap[K comparable, V any]() *ConcurrentMap[K, V] {
|
||||
return &ConcurrentMap[K, V]{
|
||||
items: make(map[K]V),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) Set(key K, value V) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.items[key] = value
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) Get(key K) (V, bool) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
value, ok := m.items[key]
|
||||
return value, ok
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) MustGet(key K) V {
|
||||
val, _ := m.Get(key)
|
||||
return val
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) Delete(key K) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
delete(m.items, key)
|
||||
}
|
||||
|
||||
func (m *ConcurrentMap[K, V]) Len() int {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
return len(m.items)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user