214 lines
4.7 KiB
Go
214 lines
4.7 KiB
Go
package web
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// UserInfo represents user information with tracking details
|
|
type UserInfo struct {
|
|
UserID string `json:"user_id"`
|
|
UserName string `json:"user_name"`
|
|
Trace string `json:"trace"`
|
|
VisitTime time.Time `json:"visit_time"`
|
|
FromIP string `json:"from_ip"`
|
|
}
|
|
|
|
// contextKey is the type for context keys to prevent collisions
|
|
type contextKey string
|
|
|
|
const (
|
|
// Context keys for each field
|
|
UserIDKey contextKey = "userID"
|
|
UserNameKey contextKey = "userName"
|
|
TraceKey contextKey = "trace"
|
|
VisitTimeKey contextKey = "visitTime"
|
|
FromIPKey contextKey = "fromIP"
|
|
)
|
|
|
|
// GetUserID returns user ID from context
|
|
func GetUserID(ctx context.Context) string {
|
|
if ctx == nil {
|
|
return ""
|
|
}
|
|
if val, ok := ctx.Value(UserIDKey).(string); ok {
|
|
return val
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// SetUserID sets user ID in context and returns new context
|
|
func SetUserID(ctx context.Context, userID string) context.Context {
|
|
if ctx == nil {
|
|
ctx = context.Background()
|
|
}
|
|
return context.WithValue(ctx, UserIDKey, userID)
|
|
}
|
|
|
|
// GetUserName returns user name from context
|
|
func GetUserName(ctx context.Context) string {
|
|
if ctx == nil {
|
|
return ""
|
|
}
|
|
if val, ok := ctx.Value(UserNameKey).(string); ok {
|
|
return val
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// SetUserName sets user name in context and returns new context
|
|
func SetUserName(ctx context.Context, userName string) context.Context {
|
|
if ctx == nil {
|
|
ctx = context.Background()
|
|
}
|
|
return context.WithValue(ctx, UserNameKey, userName)
|
|
}
|
|
|
|
// GetTrace returns trace ID from context
|
|
func GetTrace(ctx context.Context) string {
|
|
if ctx == nil {
|
|
return ""
|
|
}
|
|
if val, ok := ctx.Value(TraceKey).(string); ok {
|
|
return val
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// SetTrace sets trace ID in context and returns new context
|
|
func SetTrace(ctx context.Context, trace string) context.Context {
|
|
if ctx == nil {
|
|
ctx = context.Background()
|
|
}
|
|
return context.WithValue(ctx, TraceKey, trace)
|
|
}
|
|
|
|
// GetVisitTime returns visit time from context
|
|
func GetVisitTime(ctx context.Context) time.Time {
|
|
if ctx == nil {
|
|
return time.Time{}
|
|
}
|
|
if val, ok := ctx.Value(VisitTimeKey).(time.Time); ok {
|
|
return val
|
|
}
|
|
return time.Time{}
|
|
}
|
|
|
|
// SetVisitTime sets visit time in context and returns new context
|
|
func SetVisitTime(ctx context.Context, visitTime time.Time) context.Context {
|
|
if ctx == nil {
|
|
ctx = context.Background()
|
|
}
|
|
return context.WithValue(ctx, VisitTimeKey, visitTime)
|
|
}
|
|
|
|
// GetFromIP returns from IP from context
|
|
func GetFromIP(ctx context.Context) string {
|
|
if ctx == nil {
|
|
return ""
|
|
}
|
|
if val, ok := ctx.Value(FromIPKey).(string); ok {
|
|
return val
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// SetFromIP sets from IP in context and returns new context
|
|
func SetFromIP(ctx context.Context, fromIP string) context.Context {
|
|
if ctx == nil {
|
|
ctx = context.Background()
|
|
}
|
|
return context.WithValue(ctx, FromIPKey, fromIP)
|
|
}
|
|
|
|
// FromContext builds UserInfo from individual context fields
|
|
// Returns nil if no fields are found
|
|
func FromContext(ctx context.Context) *UserInfo {
|
|
if ctx == nil {
|
|
return nil
|
|
}
|
|
info := &UserInfo{}
|
|
hasData := false
|
|
|
|
if userID := GetUserID(ctx); userID != "" {
|
|
info.UserID = userID
|
|
hasData = true
|
|
}
|
|
if userName := GetUserName(ctx); userName != "" {
|
|
info.UserName = userName
|
|
hasData = true
|
|
}
|
|
if trace := GetTrace(ctx); trace != "" {
|
|
info.Trace = trace
|
|
hasData = true
|
|
}
|
|
if visitTime := GetVisitTime(ctx); !visitTime.IsZero() {
|
|
info.VisitTime = visitTime
|
|
hasData = true
|
|
}
|
|
if fromIP := GetFromIP(ctx); fromIP != "" {
|
|
info.FromIP = fromIP
|
|
hasData = true
|
|
}
|
|
|
|
if !hasData {
|
|
return nil
|
|
}
|
|
return info
|
|
}
|
|
|
|
// ToContext sets all UserInfo fields to context and returns new context
|
|
func ToContext(ctx context.Context, userInfo *UserInfo) context.Context {
|
|
if ctx == nil {
|
|
ctx = context.Background()
|
|
}
|
|
if userInfo == nil {
|
|
return ctx
|
|
}
|
|
|
|
ctx = SetUserID(ctx, userInfo.UserID)
|
|
ctx = SetUserName(ctx, userInfo.UserName)
|
|
ctx = SetTrace(ctx, userInfo.Trace)
|
|
ctx = SetVisitTime(ctx, userInfo.VisitTime)
|
|
ctx = SetFromIP(ctx, userInfo.FromIP)
|
|
|
|
return ctx
|
|
}
|
|
|
|
// NewUserInfo creates a new UserInfo instance
|
|
func NewUserInfo() *UserInfo {
|
|
return &UserInfo{
|
|
VisitTime: time.Now(),
|
|
}
|
|
}
|
|
|
|
// WithUserID sets the user ID
|
|
func (u *UserInfo) WithUserID(userID string) *UserInfo {
|
|
u.UserID = userID
|
|
return u
|
|
}
|
|
|
|
// WithUserName sets the user name
|
|
func (u *UserInfo) WithUserName(userName string) *UserInfo {
|
|
u.UserName = userName
|
|
return u
|
|
}
|
|
|
|
// WithTrace sets the trace ID
|
|
func (u *UserInfo) WithTrace(trace string) *UserInfo {
|
|
u.Trace = trace
|
|
return u
|
|
}
|
|
|
|
// WithFromIP sets the from IP address
|
|
func (u *UserInfo) WithFromIP(ip string) *UserInfo {
|
|
u.FromIP = ip
|
|
return u
|
|
}
|
|
|
|
// WithVisitTime sets the visit time
|
|
func (u *UserInfo) WithVisitTime(visitTime time.Time) *UserInfo {
|
|
u.VisitTime = visitTime
|
|
return u
|
|
}
|