Skip to content

Commit 9c002c9

Browse files
authored
Merging to release-5.8: [ TT-14504] Tyk OAS API definition is not available to Response Plugin if no Request Plugin loaded (#7053)
[ TT-14504] Tyk OAS API definition is not available to Response Plugin if no Request Plugin loaded (#7053) ### **User description** <details open> <summary><a href="https://tyktech.atlassian.net/browse/TT-14504" title="TT-14504" target="_blank">TT-14504</a></summary> <br /> <table> <tr> <th>Summary</th> <td>Tyk OAS API definition is not available to Response Plugin if no Request Plugin loaded</td> </tr> <tr> <th>Type</th> <td> <img alt="Bug" src="https://tyktech.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10303?size=medium" /> Bug </td> </tr> <tr> <th>Status</th> <td>In Dev</td> </tr> <tr> <th>Points</th> <td>N/A</td> </tr> <tr> <th>Labels</th> <td><a href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20Commercial_candidate_rel3-2025%20ORDER%20BY%20created%20DESC" title="Commercial_candidate_rel3-2025">Commercial_candidate_rel3-2025</a>, <a href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20codilime_refined%20ORDER%20BY%20created%20DESC" title="codilime_refined">codilime_refined</a></td> </tr> </table> </details> <!-- do not remove this marker as it will break jira-lint's functionality. added_by_jira_lint --> --- <!-- Provide a general summary of your changes in the Title above --> ## Description <!-- Describe your changes in detail --> context specification osa specification into req context in ResponseGoPluginMiddleware ## Related Issue <!-- This project only accepts pull requests related to open issues. --> <!-- If suggesting a new feature or change, please discuss it in an issue first. --> <!-- If fixing a bug, there should be an issue describing it with steps to reproduce. --> <!-- OSS: Please link to the issue here. Tyk: please create/link the JIRA ticket. --> ## Motivation and Context <!-- Why is this change required? What problem does it solve? --> ## How This Has Been Tested <!-- Please describe in detail how you tested your changes --> <!-- Include details of your testing environment, and the tests --> <!-- you ran to see how your change affects other areas of the code, etc. --> <!-- This information is helpful for reviewers and QA. --> ## Screenshots (if appropriate) ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ x] Refactoring or add test (improvements in base code or adds test coverage to functionality) ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply --> <!-- If there are no documentation updates required, mark the item as checked. --> <!-- Raise up any additional concerns not covered by the checklist. --> - [x] I ensured that the documentation is up to date - [ ] I explained why this PR updates go.mod in detail with reasoning why it's required - [ ] I would like a code coverage CI quality gate exception and have explained why ___ ### **PR Type** Bug fix, Tests ___ ### **Description** - Fix OAS API definition injection for response plugins - Refactor context injection logic into APISpec method - Add test for OAS definition access in response plugin - Enhance test plugin to support response middleware ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table> <tr> <td> <details> <summary><strong>model_apispec.go</strong><dd><code>Add APISpec.injectIntoReqContext for unified context injection</code></dd></summary> <hr> gateway/model_apispec.go <li>Added <code>injectIntoReqContext</code> method to <code>APISpec</code> for context injection<br> <li> Unified OAS and non-OAS API definition context setting </details> </td> <td><a href="https://github.com/TykTechnologies/tyk/pull/7053/files#diff-80c49b9bdb411a3d5a4706ec3ff138ef44154d0306040c19eba1cb5559f199d6">+9/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td> <details> <summary><strong>mw_go_plugin.go</strong><dd><code>Use APISpec.injectIntoReqContext in request plugin middleware</code></dd></summary> <hr> gateway/mw_go_plugin.go <li>Replaced direct context injection with new <code>injectIntoReqContext</code> method<br> <li> Refactored request plugin middleware to use unified logic </details> </td> <td><a href="https://github.com/TykTechnologies/tyk/pull/7053/files#diff-0f31abef73bf795e1a8d331202330c73011a74d10fd66e49b9359716a6d18fd9">+1/-7</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td> <details> <summary><strong>test_goplugin.go</strong><dd><code>Add response plugin for OAS definition access and header constant</code></dd></summary> <hr> test/goplugins/test_goplugin.go <li>Added constant for OAS doc title header<br> <li> Added response plugin function to access OAS definition<br> <li> Updated plugin to use header constant </details> </td> <td><a href="https://github.com/TykTechnologies/tyk/pull/7053/files#diff-6b57b162c0610abdd8c4edf02dab0718ef7daa1c986aeae2e13adf9904ec3459">+12/-2</a>&nbsp; &nbsp; </td> </tr> </table></td></tr><tr><td><strong>Bug fix</strong></td><td><table> <tr> <td> <details> <summary><strong>res_handler_go_plugin.go</strong><dd><code>Use APISpec.injectIntoReqContext in response plugin middleware</code></dd></summary> <hr> gateway/res_handler_go_plugin.go <li>Replaced direct context injection with <code>injectIntoReqContext</code> in <br>response plugin middleware<br> <li> Ensured OAS definition is available to response plugins </details> </td> <td><a href="https://github.com/TykTechnologies/tyk/pull/7053/files#diff-6f8975149bf9fc9034010738cb14f23f240ffc5521cdbe43a82b12d2072f68f4">+1/-2</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></td></tr><tr><td><strong>Tests</strong></td><td><table> <tr> <td> <details> <summary><strong>mw_go_plugin_test.go</strong><dd><code>Add test for OAS definition in response plugin</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary> <hr> goplugin/mw_go_plugin_test.go <li>Added test for response plugin accessing OAS API definition<br> <li> Verified OAS doc title is available in response headers </details> </td> <td><a href="https://github.com/TykTechnologies/tyk/pull/7053/files#diff-0ad6c75c29b2656d9d5cfa9108d32a3b242c339c1688ce168516ed213a5f482b">+48/-0</a>&nbsp; &nbsp; </td> </tr> </table></td></tr></tr></tbody></table> ___ > <details> <summary> Need help?</summary><li>Type <code>/help how to ...</code> in the comments thread for any questions about PR-Agent usage.</li><li>Check out the <a href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a> for more information.</li></details>
1 parent 6fc4da4 commit 9c002c9

File tree

5 files changed

+71
-11
lines changed

5 files changed

+71
-11
lines changed

gateway/model_apispec.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/TykTechnologies/tyk/apidef"
1414
"github.com/TykTechnologies/tyk/apidef/oas"
1515
"github.com/TykTechnologies/tyk/config"
16+
"github.com/TykTechnologies/tyk/ctx"
1617
"github.com/TykTechnologies/tyk/internal/graphengine"
1718
)
1819

@@ -131,3 +132,11 @@ func (a *APISpec) getMatchPathAndMethod(r *http.Request, mode URLStatus) (string
131132

132133
return matchPath, method
133134
}
135+
136+
func (a *APISpec) injectIntoReqContext(req *http.Request) {
137+
if a.IsOAS {
138+
ctx.SetOASDefinition(req, &a.OAS)
139+
} else {
140+
ctx.SetDefinition(req, a.APIDefinition)
141+
}
142+
}

gateway/mw_go_plugin.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"net/http"
99
"time"
1010

11-
"github.com/TykTechnologies/tyk/ctx"
12-
1311
"github.com/TykTechnologies/tyk-pump/analytics"
1412
"github.com/TykTechnologies/tyk/apidef"
1513

@@ -222,11 +220,7 @@ func (m *GoPluginMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Reque
222220
t1 := time.Now()
223221

224222
// Inject definition into request context:
225-
if m.Spec.IsOAS {
226-
ctx.SetOASDefinition(r, &m.Spec.OAS)
227-
} else {
228-
ctx.SetDefinition(r, m.Spec.APIDefinition)
229-
}
223+
m.Spec.injectIntoReqContext(r)
230224

231225
handler(rw, r)
232226
if session := ctxGetSession(r); session != nil {

gateway/res_handler_go_plugin.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"github.com/sirupsen/logrus"
99

1010
"github.com/TykTechnologies/tyk/apidef"
11-
"github.com/TykTechnologies/tyk/ctx"
1211
"github.com/TykTechnologies/tyk/goplugin"
1312
"github.com/TykTechnologies/tyk/user"
1413
)
@@ -89,7 +88,7 @@ func (h *ResponseGoPluginMiddleware) HandleGoPluginResponse(w http.ResponseWrite
8988
}()
9089

9190
// Inject definition into response context
92-
ctx.SetDefinition(req, h.Spec.APIDefinition)
91+
h.Spec.injectIntoReqContext(req)
9392

9493
// wrap ResponseWriter to check if response was sent
9594
rw := &customResponseWriter{

goplugin/mw_go_plugin_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/TykTechnologies/kin-openapi/openapi3"
1414
"github.com/stretchr/testify/assert"
15+
"github.com/stretchr/testify/require"
1516

1617
"github.com/TykTechnologies/tyk/apidef"
1718
"github.com/TykTechnologies/tyk/apidef/oas"
@@ -557,6 +558,53 @@ func TestGoPlugin_AccessingOASAPIDef(t *testing.T) {
557558
}...)
558559
}
559560

561+
func TestGoPlugin_MyResponsePluginAccessingOASAPI(t *testing.T) {
562+
ts := gateway.StartTest(nil)
563+
defer ts.Close()
564+
565+
oasDoc := oas.OAS{}
566+
oasDoc.OpenAPI = "3.0.3"
567+
oasDoc.Info = &openapi3.Info{
568+
Version: "1",
569+
Title: "My OAS Documentation TestGoPlugin_MyResponsePluginAccessingOASAPI",
570+
}
571+
oasDoc.Paths = openapi3.Paths{}
572+
oasDoc.SetTykExtension(&oas.XTykAPIGateway{})
573+
err := oasDoc.Validate(context.Background())
574+
575+
require.NoError(t, err)
576+
577+
ts.Gw.BuildAndLoadAPI(func(spec *gateway.APISpec) {
578+
spec.IsOAS = true
579+
spec.OAS = oasDoc
580+
spec.Proxy.ListenPath = "/goplugin-response"
581+
spec.UseKeylessAccess = true
582+
spec.UseStandardAuth = false
583+
spec.UseGoPluginAuth = false
584+
spec.CustomMiddleware = apidef.MiddlewareSection{
585+
Driver: apidef.GoPluginDriver,
586+
Response: []apidef.MiddlewareDefinition{
587+
{
588+
Name: "MyResponsePluginAccessingOASAPI",
589+
Path: goPluginFilename(),
590+
},
591+
},
592+
}
593+
})
594+
595+
t.Run("Run Go-plugin all middle-wares", func(t *testing.T) {
596+
ts.Run(t, []test.TestCase{
597+
{
598+
Path: "/goplugin-response/plugin_hit",
599+
Code: http.StatusOK,
600+
HeadersMatch: map[string]string{
601+
"X-OAS-Doc-Title": oasDoc.Info.Title,
602+
},
603+
},
604+
}...)
605+
})
606+
}
607+
560608
func TestGoPlugin_PreventDoubleError(t *testing.T) {
561609
ts := gateway.StartTest(nil)
562610
defer ts.Close()

test/goplugins/test_goplugin.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import (
1616
"github.com/TykTechnologies/tyk/user"
1717
)
1818

19+
const (
20+
XOASDocTitle = "X-OAS-Doc-Title"
21+
)
22+
1923
// MyPluginPre checks if session is NOT present, adds custom header
2024
// with initial URI path and will be used as "pre" custom MW
2125
func MyPluginPre(rw http.ResponseWriter, r *http.Request) {
@@ -196,12 +200,18 @@ func MyAnalyticsPluginMaskJSONLoginBody(record *analytics.AnalyticsRecord) {
196200

197201
func MyPluginAccessingOASAPI(rw http.ResponseWriter, r *http.Request) {
198202
oas := ctx.GetOASDefinition(r)
199-
rw.Header().Add("X-OAS-Doc-Title", oas.Info.Title)
203+
rw.Header().Add(XOASDocTitle, oas.Info.Title)
204+
}
205+
206+
// MyResponsePluginAccessingOASAPI fake
207+
func MyResponsePluginAccessingOASAPI(rw http.ResponseWriter, _ *http.Response, req *http.Request) {
208+
oas := ctx.GetOASDefinition(req)
209+
rw.Header().Add(XOASDocTitle, oas.Info.Title)
200210
}
201211

202212
func MyPluginReturningError(rw http.ResponseWriter, r *http.Request) {
203213
rw.WriteHeader(http.StatusTeapot)
204-
rw.Write([]byte(http.StatusText(http.StatusTeapot)))
214+
_, _ = rw.Write([]byte(http.StatusText(http.StatusTeapot)))
205215
}
206216

207217
func MyPluginApplyingPolicy(rw http.ResponseWriter, r *http.Request) {

0 commit comments

Comments
 (0)