-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TT-13391] Move upstream OAuth to EE #6684
Conversation
…nts/crypto) in internal packages
This PR is too huge for one to review 💔
Consider breaking it down into multiple small PRs. Check out this guide to learn more about PR best-practices. |
API Changes --- prev.txt 2024-11-05 10:03:35.806275818 +0000
+++ current.txt 2024-11-05 10:03:29.290300396 +0000
@@ -8360,6 +8360,147 @@
func (u Provider) Fill(r *http.Request)
Fill sets the request's HeaderName with AuthValue
+# Package: ./ee/middleware/upstreamoauth
+
+package upstreamoauth // import "github.com/TykTechnologies/tyk/ee/middleware/upstreamoauth"
+
+
+CONSTANTS
+
+const (
+ ErrorEventName = "UpstreamOAuthError"
+ MiddlewareName = "UpstreamOAuth"
+
+ ClientCredentialsAuthorizeType = "clientCredentials"
+ PasswordAuthorizeType = "password"
+)
+
+VARIABLES
+
+var (
+ CtxGetData = ctxData.Get
+ CtxSetData = ctxData.Set
+)
+
+FUNCTIONS
+
+func BuildMetadataMap(token *oauth2.Token, extraMetadataKeys []string) map[string]interface{}
+func CreateTokenDataBytes(encryptedToken string, token *oauth2.Token, extraMetadataKeys []string) ([]byte, error)
+func SetExtraMetadata(r *http.Request, keyList []string, metadata map[string]interface{})
+
+TYPES
+
+type BaseMiddleware interface {
+ model.LoggerProvider
+ FireEvent(name apidef.TykEvent, meta interface{})
+}
+ BaseMiddleware is the subset of BaseMiddleware APIs that the middleware
+ uses.
+
+type Cache interface {
+ // GetToken returns the token from cache or issues a request to obtain it from the OAuth provider.
+ GetToken(r *http.Request) (string, error)
+ // ObtainToken issues a request to obtain the token from the OAuth provider.
+ ObtainToken(ctx context.Context) (*oauth2.Token, error)
+}
+
+type ClientCredentialsClient struct {
+ // Has unexported fields.
+}
+
+func (cache *ClientCredentialsClient) GetToken(r *http.Request) (string, error)
+
+func (cache *ClientCredentialsClient) ObtainToken(ctx context.Context) (*oauth2.Token, error)
+
+type ClientCredentialsOAuthProvider struct{}
+
+type EventUpstreamOAuthMeta struct {
+ model.EventMetaDefault
+ APIID string
+}
+ EventUpstreamOAuthMeta is the metadata structure for an upstream OAuth event
+
+type Gateway interface {
+ model.ConfigProvider
+}
+ Gateway is the subset of Gateway APIs that the middleware uses.
+
+type Middleware struct {
+ Spec model.MergedAPI
+ Gw Gateway
+
+ Base BaseMiddleware
+
+ // Has unexported fields.
+}
+ Middleware implements upstream OAuth middleware.
+
+func NewMiddleware(gw Gateway, mw BaseMiddleware, spec model.MergedAPI, ccStorageHandler Storage, pwStorageHandler Storage) *Middleware
+ NewMiddleware returns a new instance of Middleware.
+
+func (m *Middleware) EnabledForSpec() bool
+ EnabledForSpec checks if streaming is enabled on the config.
+
+func (mw *Middleware) FireEvent(r *http.Request, e event.Event, message string, apiId string)
+ FireEvent emits an upstream OAuth event with an optional custom message.
+
+func (m *Middleware) Init()
+ Init initializes the middleware.
+
+func (m *Middleware) Logger() *logrus.Entry
+ Logger returns a logger with middleware filled out.
+
+func (m *Middleware) Name() string
+ Name returns the name for the middleware.
+
+func (m *Middleware) ProcessRequest(_ http.ResponseWriter, r *http.Request, _ interface{}) (error, int)
+ ProcessRequest will handle upstream OAuth.
+
+type OAuthHeaderProvider interface {
+ // Has unexported methods.
+}
+
+func NewOAuthHeaderProvider(oauthConfig apidef.UpstreamOAuth) (OAuthHeaderProvider, error)
+
+type PasswordClient struct {
+ // Has unexported fields.
+}
+
+func (cache *PasswordClient) GetToken(r *http.Request) (string, error)
+
+func (cache *PasswordClient) ObtainToken(ctx context.Context) (*oauth2.Token, error)
+
+type PasswordOAuthProvider struct{}
+
+type PerAPIClientCredentialsOAuthProvider struct{}
+
+type Provider struct {
+ // Logger is the logger to be used.
+ Logger *logrus.Entry
+ // HeaderName is the header name to be used to fill upstream auth with.
+ HeaderName string
+ // AuthValue is the value of auth header.
+ AuthValue string
+}
+ Provider implements upstream auth provider.
+
+func (u Provider) Fill(r *http.Request)
+ Fill sets the request's HeaderName with AuthValue
+
+type Storage interface {
+ GetKey(key string) (string, error)
+ SetKey(string, string, int64) error
+ Lock(key string, timeout time.Duration) (bool, error)
+}
+ Type Storage is a subset of storage.RedisCluster
+
+type TokenData struct {
+ Token string `json:"token"`
+ ExtraMetadata map[string]interface{} `json:"extra_metadata"`
+}
+
+func UnmarshalTokenData(tokenData string) (TokenData, error)
+
# Package: ./gateway
package gateway // import "github.com/TykTechnologies/tyk/gateway"
@@ -8497,10 +8638,6 @@
ECDSASign = "ecdsa"
)
const (
- UpstreamOAuthErrorEventName = "UpstreamOAuthError"
- UpstreamOAuthMiddlewareName = "UpstreamOAuth"
-)
-const (
ErrOAuthAuthorizationFieldMissing = "oauth.auth_field_missing"
ErrOAuthAuthorizationFieldMalformed = "oauth.auth_field_malformed"
ErrOAuthKeyNotFound = "oauth.key_not_found"
@@ -8575,6 +8712,9 @@
GlobalRate = ratecounter.NewRateCounter(1 * time.Second)
)
var (
+ EncodeRequestToEvent = event.EncodeRequestToEvent
+)
+var (
ErrTokenValidationFailed = errors.New("error happened during the access token validation")
ErrKIDNotAString = errors.New("kid is not a string")
ErrNoMatchingKIDFound = errors.New("no matching KID could be found")
@@ -8649,10 +8789,6 @@
func CreateStandardSession() *user.SessionState
func DoCoprocessReload()
func DurationToMillisecond(d time.Duration) float64
-func EncodeRequestToEvent(r *http.Request) string
- EncodeRequestToEvent will write the request out in wire protocol and encode
- it to base64 and store it in an Event object
-
func EnsureTransport(host, protocol string) string
EnsureTransport sanitizes host/protocol pairs and returns a valid URL.
@@ -9095,8 +9231,6 @@
Skip bool
}
-type ClientCredentialsOAuthProvider struct{}
-
type CoProcessEventHandler struct {
Spec *APISpec
SpecJSON json.RawMessage
@@ -9336,13 +9470,7 @@
EventKeyFailureMeta is the metadata structure for any failure related to a
key, such as quota or auth failures.
-type EventMetaDefault struct {
- Message string
- OriginatingRequest string
-}
- EventMetaDefault is a standard embedded struct to be used with custom event
- metadata types, gives an interface for easily extending event metadata
- objects
+type EventMetaDefault = model.EventMetaDefault
type EventTokenMeta struct {
EventMetaDefault
@@ -9358,12 +9486,6 @@
UsagePercentage int64 `json:"usage_percentage"`
}
-type EventUpstreamOAuthMeta struct {
- EventMetaDefault
- APIID string
-}
- EventUpstreamOAuthMeta is the metadata structure for an upstream OAuth event
-
type EventVersionFailureMeta struct {
EventMetaDefault
Path string
@@ -9468,8 +9590,6 @@
HostCheckTicker chan struct{}
HostCheckerClient *http.Client
TracerProvider otel.TracerProvider
- // UpstreamOAuthCache is used to cache upstream OAuth tokens
- UpstreamOAuthCache UpstreamOAuthCache
SessionLimiter SessionLimiter
SessionMonitor Monitor
@@ -10385,10 +10505,6 @@
in compliance with https://tools.ietf.org/html/rfc7009#section-2.1 ToDo:
set an authentication mechanism
-type OAuthHeaderProvider interface {
- // Has unexported methods.
-}
-
type OAuthManager struct {
API *APISpec
OsinServer *TykOsinServer
@@ -10470,10 +10586,6 @@
func (k *OrganizationMonitor) SetOrgSentinel(orgChan chan bool, orgId string)
-type PasswordOAuthProvider struct{}
-
-type PerAPIClientCredentialsOAuthProvider struct{}
-
type PersistGraphQLOperationMiddleware struct {
*BaseMiddleware
}
@@ -11374,11 +11486,6 @@
Form map[string]string
}
-type TokenData struct {
- Token string `json:"token"`
- ExtraMetadata map[string]interface{} `json:"extra_metadata"`
-}
-
type TraceMiddleware struct {
TykMiddleware
}
@@ -11622,38 +11729,6 @@
Enums representing the various statuses for a VersionInfo Path match during
a proxy request
-type UpstreamOAuth struct {
- *BaseMiddleware
-}
- UpstreamOAuth is a middleware that will do basic authentication for upstream
- connections. UpstreamOAuth middleware is only supported in Tyk OAS API
- definitions.
-
-func (OAuthSpec *UpstreamOAuth) EnabledForSpec() bool
- EnabledForSpec returns true if the middleware is enabled based on API Spec.
-
-func (OAuthSpec *UpstreamOAuth) Name() string
- Name returns the name of middleware.
-
-func (OAuthSpec *UpstreamOAuth) ProcessRequest(_ http.ResponseWriter, r *http.Request, _ interface{}) (error, int)
- ProcessRequest will inject basic auth info into request context so that it
- can be used during reverse proxy.
-
-type UpstreamOAuthCache interface {
- // Has unexported methods.
-}
-
-type UpstreamOAuthProvider struct {
- // HeaderName is the header name to be used to fill upstream auth with.
- HeaderName string
- // AuthValue is the value of auth header.
- AuthValue string
-}
- UpstreamOAuthProvider implements upstream auth provider.
-
-func (u UpstreamOAuthProvider) Fill(r *http.Request)
- Fill sets the request's HeaderName with AuthValue
-
type UptimeReportData struct {
URL string
RequestTime int64 |
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
# Conflicts: # gateway/mw_oauth2_auth.go
…eam-o-auth-to-ee # Conflicts: # gateway/mw_oauth2_auth.go
- moved providers in separate fies - adjusted signature of functions to be less verbose and more receiver-focused - renamed a few variables/parameters with better choices
Quality Gate failedFailed conditions See analysis details on SonarCloud Catch issues before they fail your Quality Gate with our IDE extension SonarLint |
User description
TT-13359
Description
TASK: https://tyktech.atlassian.net/browse/TT-13359
Related Issue
Motivation and Context
How This Has Been Tested
Screenshots (if appropriate)
Types of changes
Checklist
PR Type
enhancement, other
Description
httputil
instead ofctx
.ee
package.crypto
package.model.EventMetaDefault
for consistency.PRDescriptionHeader.CHANGES_WALKTHROUGH
14 files
api.go
Refactor context handling and event firing in API gateway
gateway/api.go
http.Request
context.ctx
package usage withhttputil
.model.EventMetaDefault
.mw_oauth2_auth.go
Replace upstream OAuth with no-op middleware
gateway/mw_oauth2_auth.go
provider.go
Implement upstream OAuth provider with token caching
ee/middleware/upstreamoauth/provider.go
password grants.
mw_url_rewrite.go
Refactor URL rewrite middleware to use httputil
gateway/mw_url_rewrite.go
ctx
package usage withhttputil
for context data handling.rpc_backup_handlers.go
Use crypto package for encryption in RPC backup handlers
gateway/rpc_backup_handlers.go
crypto
package.middleware.go
Refactor middleware context handling and event firing
gateway/middleware.go
ctx
package usage withhttputil
for context handling.model.EventMetaDefault
.event_system.go
Refactor event system to use model package
gateway/event_system.go
EventMetaDefault
tomodel
package.model.EventMetaDefault
.mw_organisation_activity.go
Refactor organisation activity middleware for context and events
gateway/mw_organisation_activity.go
ctx
package usage withhttputil
for context data handling.model.EventMetaDefault
.middleware.go
Implement upstream OAuth middleware for token handling
ee/middleware/upstreamoauth/middleware.go
server.go
Initialize upstream OAuth caches in server
gateway/server.go
helpers.go
Add AES encryption and decryption helpers
internal/crypto/helpers.go
context.go
Add context data handling utilities
internal/httputil/context.go
event.go
Add request encoding to event utility
internal/event/event.go
events.go
Add EventMetaDefault struct for event metadata
internal/model/events.go
EventMetaDefault
struct for event metadata.1 files
ctx.go
Remove context key definitions from ctx package
ctx/ctx.go