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  }