context.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package request // import "miniflux.app/v2/internal/http/request"
  4. import (
  5. "net/http"
  6. "strconv"
  7. "time"
  8. "miniflux.app/v2/internal/model"
  9. )
  10. // ContextKey represents a context key.
  11. type ContextKey int
  12. // List of context keys.
  13. const (
  14. UserIDContextKey ContextKey = iota
  15. UserNameContextKey
  16. UserTimezoneContextKey
  17. IsAdminUserContextKey
  18. IsAuthenticatedContextKey
  19. UserSessionTokenContextKey
  20. UserLanguageContextKey
  21. UserThemeContextKey
  22. SessionIDContextKey
  23. CSRFContextKey
  24. OAuth2StateContextKey
  25. OAuth2CodeVerifierContextKey
  26. FlashMessageContextKey
  27. FlashErrorMessageContextKey
  28. LastForceRefreshContextKey
  29. ClientIPContextKey
  30. GoogleReaderTokenKey
  31. WebAuthnDataContextKey
  32. )
  33. // WebAuthnSessionData returns WebAuthn session data from the request context, or nil if absent.
  34. func WebAuthnSessionData(r *http.Request) *model.WebAuthnSession {
  35. if v := r.Context().Value(WebAuthnDataContextKey); v != nil {
  36. if value, valid := v.(model.WebAuthnSession); valid {
  37. return &value
  38. }
  39. }
  40. return nil
  41. }
  42. // GoogleReaderToken returns the Google Reader token from the request context, if present.
  43. func GoogleReaderToken(r *http.Request) string {
  44. return getContextStringValue(r, GoogleReaderTokenKey)
  45. }
  46. // IsAdminUser reports whether the logged-in user is an administrator.
  47. func IsAdminUser(r *http.Request) bool {
  48. return getContextBoolValue(r, IsAdminUserContextKey)
  49. }
  50. // IsAuthenticated reports whether the user is authenticated.
  51. func IsAuthenticated(r *http.Request) bool {
  52. return getContextBoolValue(r, IsAuthenticatedContextKey)
  53. }
  54. // UserID returns the logged-in user's ID from the request context.
  55. func UserID(r *http.Request) int64 {
  56. return getContextInt64Value(r, UserIDContextKey)
  57. }
  58. // UserName returns the logged-in user's username, or "unknown" when unset.
  59. func UserName(r *http.Request) string {
  60. value := getContextStringValue(r, UserNameContextKey)
  61. if value == "" {
  62. value = "unknown"
  63. }
  64. return value
  65. }
  66. // UserTimezone returns the user's timezone, defaulting to "UTC" when unset.
  67. func UserTimezone(r *http.Request) string {
  68. value := getContextStringValue(r, UserTimezoneContextKey)
  69. if value == "" {
  70. value = "UTC"
  71. }
  72. return value
  73. }
  74. // UserLanguage returns the user's locale, defaulting to "en_US" when unset.
  75. func UserLanguage(r *http.Request) string {
  76. language := getContextStringValue(r, UserLanguageContextKey)
  77. if language == "" {
  78. language = "en_US"
  79. }
  80. return language
  81. }
  82. // UserTheme returns the user's theme, defaulting to "system_serif" when unset.
  83. func UserTheme(r *http.Request) string {
  84. theme := getContextStringValue(r, UserThemeContextKey)
  85. if theme == "" {
  86. theme = "system_serif"
  87. }
  88. return theme
  89. }
  90. // CSRF returns the CSRF token from the request context.
  91. func CSRF(r *http.Request) string {
  92. return getContextStringValue(r, CSRFContextKey)
  93. }
  94. // SessionID returns the current session ID from the request context.
  95. func SessionID(r *http.Request) string {
  96. return getContextStringValue(r, SessionIDContextKey)
  97. }
  98. // UserSessionToken returns the current user session token from the request context.
  99. func UserSessionToken(r *http.Request) string {
  100. return getContextStringValue(r, UserSessionTokenContextKey)
  101. }
  102. // OAuth2State returns the OAuth2 state value from the request context.
  103. func OAuth2State(r *http.Request) string {
  104. return getContextStringValue(r, OAuth2StateContextKey)
  105. }
  106. // OAuth2CodeVerifier returns the OAuth2 PKCE code verifier from the request context.
  107. func OAuth2CodeVerifier(r *http.Request) string {
  108. return getContextStringValue(r, OAuth2CodeVerifierContextKey)
  109. }
  110. // FlashMessage returns the flash message from the request context, if any.
  111. func FlashMessage(r *http.Request) string {
  112. return getContextStringValue(r, FlashMessageContextKey)
  113. }
  114. // FlashErrorMessage returns the flash error message from the request context, if any.
  115. func FlashErrorMessage(r *http.Request) string {
  116. return getContextStringValue(r, FlashErrorMessageContextKey)
  117. }
  118. // LastForceRefresh returns the last force refresh timestamp from the request context.
  119. func LastForceRefresh(r *http.Request) time.Time {
  120. jsonStringValue := getContextStringValue(r, LastForceRefreshContextKey)
  121. timestamp, err := strconv.ParseInt(jsonStringValue, 10, 64)
  122. if err != nil {
  123. return time.Time{}
  124. }
  125. return time.Unix(timestamp, 0)
  126. }
  127. // ClientIP returns the client IP address stored in the request context.
  128. func ClientIP(r *http.Request) string {
  129. return getContextStringValue(r, ClientIPContextKey)
  130. }
  131. func getContextStringValue(r *http.Request, key ContextKey) string {
  132. if v := r.Context().Value(key); v != nil {
  133. if value, valid := v.(string); valid {
  134. return value
  135. }
  136. }
  137. return ""
  138. }
  139. func getContextBoolValue(r *http.Request, key ContextKey) bool {
  140. if v := r.Context().Value(key); v != nil {
  141. if value, valid := v.(bool); valid {
  142. return value
  143. }
  144. }
  145. return false
  146. }
  147. func getContextInt64Value(r *http.Request, key ContextKey) int64 {
  148. if v := r.Context().Value(key); v != nil {
  149. if value, valid := v.(int64); valid {
  150. return value
  151. }
  152. }
  153. return 0
  154. }