mirror of
https://github.com/muety/wakapi.git
synced 2025-12-05 22:20:24 -08:00
chore: minor refactorings to shared data middleware logic
This commit is contained in:
@@ -38,13 +38,10 @@ const (
|
|||||||
KeySubscriptionNotificationSent = "sub_reminder"
|
KeySubscriptionNotificationSent = "sub_reminder"
|
||||||
KeyNewsbox = "newsbox"
|
KeyNewsbox = "newsbox"
|
||||||
KeyInviteCode = "invite"
|
KeyInviteCode = "invite"
|
||||||
|
KeySharedData = "shared_data"
|
||||||
|
|
||||||
SessionKeyDefault = "default"
|
SessionKeyDefault = "default"
|
||||||
|
|
||||||
MiddlewareKeySharedData = "shared_data"
|
|
||||||
MiddlewareKeyPrincipal = "principal"
|
|
||||||
MiddlewareKeyPrincipalId = "principal_identity"
|
|
||||||
|
|
||||||
SimpleDateFormat = "2006-01-02"
|
SimpleDateFormat = "2006-01-02"
|
||||||
SimpleDateTimeFormat = "2006-01-02 15:04:05"
|
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 {
|
func getPrincipal(r *http.Request) string {
|
||||||
sharedData := r.Context().Value(MiddlewareKeySharedData)
|
sharedData := r.Context().Value(MiddlewareKeySharedData)
|
||||||
if sharedData == nil {
|
if sharedData == nil {
|
||||||
|
Log().Request(r).Error("request shared data not set while retrieving principal for sentry logging")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
val := sharedData.(*SharedData).MustGet(MiddlewareKeyPrincipalId)
|
val := sharedData.(*SharedData).MustGet(MiddlewareKeyPrincipalId)
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
package config
|
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 {
|
type SharedData struct {
|
||||||
*utils.ConcurrentMap[string, interface{}]
|
*lib.ConcurrentMap[SharedDataKey, interface{}]
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSharedData() *SharedData {
|
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 {
|
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 {
|
if val == nil {
|
||||||
return 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"
|
"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
|
// 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
|
// 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 := httptest.NewRequest("GET", "http://localhost:3000/api/{user}/data", nil)
|
||||||
r = withUrlParam(r, "user", requestedUser)
|
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 := new(mocks.UserServiceMock)
|
||||||
userServiceMock.On("GetUserById", "user1").Return(&models.User{ID: "user1"}, nil)
|
userServiceMock.On("GetUserById", "user1").Return(&models.User{ID: "user1"}, nil)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func SubSlice[T any](slice []T, from, to uint) []T {
|
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
|
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