yao/openapi/user/utils.go
Max 5a894c11ab Add authorized info handling and session ID retrieval in OAuth guard
- Introduced methods to set and retrieve authorized information from the context, enhancing the OAuth guard functionality.
- Added a new `AuthorizedInfo` type to encapsulate user-related data such as subject, client ID, user ID, and scope.
- Implemented session ID retrieval from various sources (cookies, headers, query strings) to improve session management.
- Updated test utilities to support the creation of test users and access tokens, ensuring comprehensive testing of OAuth functionalities.
2025-09-23 10:22:52 +08:00

149 lines
3 KiB
Go

package user
import (
"fmt"
"strconv"
"time"
"github.com/yaoapp/gou/process"
"github.com/yaoapp/gou/session"
"github.com/yaoapp/kun/exception"
)
// Session Utilities
// GetUserIDFromSession gets the current user ID from session
// Returns the user ID string or throws an exception if not authenticated
func GetUserIDFromSession(process *process.Process) string {
sessionData, err := session.Global().ID(process.Sid).Get("__user_id")
if err != nil || sessionData == nil {
exception.New("user not authenticated", 401).Throw()
}
userIDStr, ok := sessionData.(string)
if !ok {
exception.New("invalid user_id in session", 401).Throw()
}
return userIDStr
}
// Type Conversion Utilities
// toBool converts various types to boolean
// Supports: bool, int, int64, float64, string
// Returns false for nil or unsupported types
func toBool(v interface{}) bool {
if v == nil {
return false
}
switch val := v.(type) {
case bool:
return val
case int:
return val != 0
case int64:
return val != 0
case float64:
return val != 0
case string:
return val == "true" || val == "1"
default:
return false
}
}
// toString converts various types to string
// Supports: string, int, int64, float64, bool
// Returns empty string for nil or unsupported types
func toString(v interface{}) string {
if v == nil {
return ""
}
switch val := v.(type) {
case string:
return val
case int:
return fmt.Sprintf("%d", val)
case int64:
return fmt.Sprintf("%d", val)
case float64:
return fmt.Sprintf("%.0f", val)
case bool:
if val {
return "true"
}
return "false"
default:
return ""
}
}
// toInt64 converts various types to int64
// Supports: int, int64, float64, string
// Returns 0 for nil or unsupported types
func toInt64(v interface{}) int64 {
if v == nil {
return 0
}
switch val := v.(type) {
case int64:
return val
case int:
return int64(val)
case float64:
return int64(val)
case string:
if parsed, err := strconv.ParseInt(val, 10, 64); err == nil {
return parsed
}
return 0
default:
return 0
}
}
// toTimeString converts various time types to RFC3339 string
// Supports: time.Time, string, int64 (unix timestamp)
// Returns empty string for nil or unsupported types
func toTimeString(v interface{}) string {
if v == nil {
return ""
}
switch val := v.(type) {
case time.Time:
if val.IsZero() {
return ""
}
return val.Format(time.RFC3339)
case string:
// Try to parse as RFC3339 first
if t, err := time.Parse(time.RFC3339, val); err == nil {
return t.Format(time.RFC3339)
}
// Try to parse as other common formats
formats := []string{
"2006-01-02 15:04:05",
"2006-01-02T15:04:05Z",
"2006-01-02T15:04:05.000Z",
}
for _, format := range formats {
if t, err := time.Parse(format, val); err == nil {
return t.Format(time.RFC3339)
}
}
return val // Return as-is if can't parse
case int64:
// Assume unix timestamp
if val > 0 {
return time.Unix(val, 0).Format(time.RFC3339)
}
return ""
default:
return ""
}
}