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  }