github.com/craicoverflow/tyk@v2.9.6-rc3+incompatible/coprocess/python/coprocess_id_extractor_python_test.go (about) 1 package python 2 3 import ( 4 "net/http" 5 "net/url" 6 "testing" 7 "time" 8 9 "github.com/TykTechnologies/tyk/config" 10 "github.com/TykTechnologies/tyk/gateway" 11 "github.com/TykTechnologies/tyk/test" 12 ) 13 14 var pythonIDExtractorHeaderValue = map[string]string{ 15 "manifest.json": ` 16 { 17 "file_list": [ 18 "middleware.py" 19 ], 20 "custom_middleware": { 21 "driver": "python", 22 "auth_check": { 23 "name": "MyAuthHook" 24 }, 25 "id_extractor": { 26 "extract_from": "header", 27 "extract_with": "value", 28 "extractor_config": { 29 "header_name": "Authorization" 30 } 31 } 32 } 33 } 34 `, 35 "middleware.py": ` 36 import time 37 from tyk.decorators import * 38 from gateway import TykGateway as tyk 39 40 counter = 0 41 42 @Hook 43 def MyAuthHook(request, session, metadata, spec): 44 global counter 45 counter = counter + 1 46 auth_header = request.get_header('Authorization') 47 if auth_header == 'valid_token' and counter < 2: 48 session.rate = 1000.0 49 session.per = 1.0 50 session.id_extractor_deadline = int(time.time()) + 60 51 metadata["token"] = "valid_token" 52 return request, session, metadata 53 `, 54 } 55 56 var pythonIDExtractorFormValue = map[string]string{ 57 "manifest.json": ` 58 { 59 "file_list": [ 60 "middleware.py" 61 ], 62 "custom_middleware": { 63 "driver": "python", 64 "auth_check": { 65 "name": "MyAuthHook" 66 }, 67 "id_extractor": { 68 "extract_from": "form", 69 "extract_with": "value", 70 "extractor_config": { 71 "param_name": "auth" 72 } 73 } 74 } 75 } 76 `, 77 "middleware.py": ` 78 import time 79 from tyk.decorators import * 80 from gateway import TykGateway as tyk 81 from urllib import parse 82 83 counter = 0 84 85 @Hook 86 def MyAuthHook(request, session, metadata, spec): 87 global counter 88 counter = counter + 1 89 auth_param = parse.parse_qs(request.object.body)["auth"] 90 if auth_param and auth_param[0] == 'valid_token' and counter < 2: 91 session.rate = 1000.0 92 session.per = 1.0 93 session.id_extractor_deadline = int(time.time()) + 60 94 metadata["token"] = "valid_token" 95 return request, session, metadata 96 `, 97 } 98 99 var pythonIDExtractorHeaderRegex = map[string]string{ 100 "manifest.json": ` 101 { 102 "file_list": [ 103 "middleware.py" 104 ], 105 "custom_middleware": { 106 "driver": "python", 107 "auth_check": { 108 "name": "MyAuthHook" 109 }, 110 "id_extractor": { 111 "extract_from": "header", 112 "extract_with": "regex", 113 "extractor_config": { 114 "header_name": "Authorization", 115 "regex_expression": "[0-9]+", 116 "regex_match_index": 0 117 } 118 } 119 } 120 } 121 `, 122 "middleware.py": ` 123 import time 124 from tyk.decorators import * 125 from gateway import TykGateway as tyk 126 127 counter = 0 128 129 @Hook 130 def MyAuthHook(request, session, metadata, spec): 131 print("MyAuthHook3 is called") 132 global counter 133 counter = counter + 1 134 _, auth_header = request.get_header('Authorization').split('-') 135 if auth_header and auth_header == '12345' and counter < 2: 136 session.rate = 1000.0 137 session.per = 1.0 138 session.id_extractor_deadline = int(time.time()) + 60 139 metadata["token"] = "valid_token" 140 return request, session, metadata 141 `, 142 } 143 144 /* Value Extractor tests, using "header" source */ 145 // Goal of ID extractor is to cache auth plugin calls 146 // Our `pythonBundleWithAuthCheck` plugin restrict more then 1 call 147 // With ID extractor, it should run multiple times (because cache) 148 func TestValueExtractorHeaderSource(t *testing.T) { 149 ts := gateway.StartTest(gateway.TestConfig{ 150 CoprocessConfig: config.CoProcessConfig{ 151 EnableCoProcess: true, 152 PythonPathPrefix: pkgPath, 153 }, 154 Delay: 10 * time.Millisecond, 155 }) 156 defer ts.Close() 157 158 spec := gateway.BuildAPI(func(spec *gateway.APISpec) { 159 spec.Proxy.ListenPath = "/" 160 spec.UseKeylessAccess = false 161 spec.EnableCoProcessAuth = true 162 })[0] 163 t.Run("Header value", func(t *testing.T) { 164 bundleID := gateway.RegisterBundle("id_extractor_header_value", pythonIDExtractorHeaderValue) 165 spec.CustomMiddlewareBundle = bundleID 166 spec.APIID = "api1" 167 168 gateway.LoadAPI(spec) 169 time.Sleep(1 * time.Second) 170 171 ts.Run(t, []test.TestCase{ 172 {Path: "/", Headers: map[string]string{"Authorization": "valid_token"}, Code: http.StatusOK}, 173 {Path: "/", Headers: map[string]string{"Authorization": "valid_token"}, Code: http.StatusOK}, 174 {Path: "/", Headers: map[string]string{"Authorization": "invalid_token"}, Code: http.StatusForbidden}, 175 }...) 176 }) 177 t.Run("Form value", func(t *testing.T) { 178 bundleID := gateway.RegisterBundle("id_extractor_form_value", pythonIDExtractorFormValue) 179 spec.CustomMiddlewareBundle = bundleID 180 spec.APIID = "api2" 181 182 gateway.LoadAPI(spec) 183 time.Sleep(1 * time.Second) 184 185 formHeaders := map[string]string{"Content-Type": "application/x-www-form-urlencoded"} 186 187 ts.Run(t, []test.TestCase{ 188 {Method: "POST", Path: "/", Headers: formHeaders, Data: url.Values{"auth": []string{"valid_token"}}.Encode(), Code: http.StatusOK}, 189 {Method: "POST", Path: "/", Headers: formHeaders, Data: url.Values{"auth": []string{"valid_token"}}.Encode(), Code: http.StatusOK}, 190 {Method: "POST", Path: "/", Headers: formHeaders, Data: url.Values{"auth": []string{"invalid_token"}}.Encode(), Code: http.StatusForbidden}, 191 }...) 192 }) 193 t.Run("Header regex", func(t *testing.T) { 194 bundleID := gateway.RegisterBundle("id_extractor_header_regex", pythonIDExtractorHeaderRegex) 195 spec.CustomMiddlewareBundle = bundleID 196 spec.APIID = "api3" 197 198 gateway.LoadAPI(spec) 199 time.Sleep(1 * time.Second) 200 201 ts.Run(t, []test.TestCase{ 202 {Path: "/", Headers: map[string]string{"Authorization": "prefix-12345"}, Code: http.StatusOK}, 203 {Path: "/", Headers: map[string]string{"Authorization": "prefix-12345"}, Code: http.StatusOK}, 204 {Path: "/", Headers: map[string]string{"Authorization": "prefix-123456"}, Code: http.StatusForbidden}, 205 }...) 206 }) 207 }