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