4
4
from sqlalchemy import create_engine , Column , Integer , DateTime , String , ForeignKey
5
5
from sqlalchemy .orm import sessionmaker , relationship
6
6
from sqlalchemy .ext .declarative import declarative_base
7
- from flask import Blueprint , make_response , json
7
+ from flask import Blueprint , make_response , json , request
8
8
from marshmallow_jsonapi .flask import Schema , Relationship
9
9
from marshmallow import Schema as MarshmallowSchema
10
10
from marshmallow_jsonapi import fields
11
11
from marshmallow import ValidationError
12
+ from werkzeug .exceptions import Unauthorized
12
13
13
14
from flask_combo_jsonapi import Api , ResourceList , ResourceDetail , ResourceRelationship , JsonApiException
14
15
from flask_combo_jsonapi .pagination import add_pagination_links
@@ -231,9 +232,26 @@ def address(session, address_model):
231
232
232
233
233
234
@pytest .fixture (scope = "module" )
234
- def dummy_decorator ():
235
+ def custom_auth_decorator ():
235
236
def deco (f ):
236
237
def wrapper_f (* args , ** kwargs ):
238
+ auth = request .headers .get ("auth" , None )
239
+ if auth == '123' :
240
+ raise Unauthorized ()
241
+ return f (* args , ** kwargs )
242
+
243
+ return wrapper_f
244
+
245
+ yield deco
246
+
247
+
248
+ @pytest .fixture (scope = "module" )
249
+ def custom_auth_decorator_2 ():
250
+ def deco (f ):
251
+ def wrapper_f (* args , ** kwargs ):
252
+ auth = request .headers .get ("auth" , None )
253
+ if auth == '1234' :
254
+ raise Unauthorized ()
237
255
return f (* args , ** kwargs )
238
256
239
257
return wrapper_f
@@ -405,16 +423,14 @@ def before_delete_object_(self, obj, view_kwargs):
405
423
406
424
407
425
@pytest .fixture (scope = "module" )
408
- def person_list (session , person_model , dummy_decorator , person_schema , before_create_object ):
426
+ def person_list (session , person_model , person_schema , before_create_object ):
409
427
class PersonList (ResourceList ):
410
428
schema = person_schema
411
429
data_layer = {
412
430
"model" : person_model ,
413
431
"session" : session ,
414
432
"methods" : {"before_create_object" : before_create_object },
415
433
}
416
- get_decorators = [dummy_decorator ]
417
- post_decorators = [dummy_decorator ]
418
434
get_schema_kwargs = dict ()
419
435
post_schema_kwargs = dict ()
420
436
@@ -459,7 +475,8 @@ class PersonList(ResourceList):
459
475
460
476
461
477
@pytest .fixture (scope = "module" )
462
- def person_detail (session , person_model , dummy_decorator , person_schema , before_update_object , before_delete_object ):
478
+ def person_detail (session , person_model , person_schema , before_update_object , before_delete_object ,
479
+ custom_auth_decorator_2 ):
463
480
class PersonDetail (ResourceDetail ):
464
481
schema = person_schema
465
482
data_layer = {
@@ -468,25 +485,19 @@ class PersonDetail(ResourceDetail):
468
485
"url_field" : "person_id" ,
469
486
"methods" : {"before_update_object" : before_update_object , "before_delete_object" : before_delete_object },
470
487
}
471
- get_decorators = [dummy_decorator ]
472
- patch_decorators = [dummy_decorator ]
473
- delete_decorators = [dummy_decorator ]
474
488
get_schema_kwargs = dict ()
475
489
patch_schema_kwargs = dict ()
476
490
delete_schema_kwargs = dict ()
491
+ decorators = (custom_auth_decorator_2 ,)
477
492
478
493
yield PersonDetail
479
494
480
495
481
496
@pytest .fixture (scope = "module" )
482
- def person_computers (session , person_model , dummy_decorator , person_schema ):
497
+ def person_computers (session , person_model , person_schema ):
483
498
class PersonComputersRelationship (ResourceRelationship ):
484
499
schema = person_schema
485
500
data_layer = {"session" : session , "model" : person_model , "url_field" : "person_id" }
486
- get_decorators = [dummy_decorator ]
487
- post_decorators = [dummy_decorator ]
488
- patch_decorators = [dummy_decorator ]
489
- delete_decorators = [dummy_decorator ]
490
501
491
502
yield PersonComputersRelationship
492
503
@@ -566,7 +577,7 @@ class ComputerList(ResourceList):
566
577
567
578
568
579
@pytest .fixture (scope = "module" )
569
- def computer_detail (session , computer_model , dummy_decorator , computer_schema ):
580
+ def computer_detail (session , computer_model , computer_schema ):
570
581
class ComputerDetail (ResourceDetail ):
571
582
schema = computer_schema
572
583
data_layer = {"model" : computer_model , "session" : session }
@@ -576,7 +587,7 @@ class ComputerDetail(ResourceDetail):
576
587
577
588
578
589
@pytest .fixture (scope = "module" )
579
- def computer_owner (session , computer_model , dummy_decorator , computer_schema ):
590
+ def computer_owner (session , computer_model , computer_schema ):
580
591
class ComputerOwnerRelationship (ResourceRelationship ):
581
592
schema = computer_schema
582
593
data_layer = {"session" : session , "model" : computer_model }
@@ -628,6 +639,7 @@ def register_routes(
628
639
client ,
629
640
app ,
630
641
api_blueprint ,
642
+ custom_auth_decorator ,
631
643
person_list ,
632
644
person_detail ,
633
645
person_computers ,
@@ -643,7 +655,7 @@ def register_routes(
643
655
string_json_attribute_person_detail ,
644
656
string_json_attribute_person_list ,
645
657
):
646
- api = Api (blueprint = api_blueprint )
658
+ api = Api (blueprint = api_blueprint , decorators = ( custom_auth_decorator ,) )
647
659
api .route (person_list , "person_list" , "/persons" )
648
660
api .route (person_list_custom_qs_manager , "person_list_custom_qs_manager" , "/persons_qs" )
649
661
api .route (person_detail , "person_detail" , "/persons/<int:person_id>" )
@@ -941,6 +953,7 @@ def test_post_list_nested(client, register_routes, computer):
941
953
assert response .status_code == 201
942
954
assert json .loads (response .get_data ())["data" ]["attributes" ]["tags" ][0 ]["key" ] == "k1"
943
955
956
+
944
957
def test_post_list_nested_field (client , register_routes ):
945
958
"""
946
959
Test a schema contains a nested field is correctly serialized and deserialized
@@ -991,6 +1004,19 @@ def test_get_detail(client, register_routes, person):
991
1004
assert response .status_code == 200
992
1005
993
1006
1007
+ def test_get_detail_custom_auth_decorator_global (client , register_routes , person ):
1008
+ with client :
1009
+ response = client .get ("/persons/" + str (person .person_id ), content_type = "application/vnd.api+json" ,
1010
+ headers = {'auth' : '123' })
1011
+ assert response .status_code == 401
1012
+
1013
+ def test_get_detail_custom_auth_decorator_resource_level (client , register_routes , person ):
1014
+ with client :
1015
+ response = client .get ("/persons/" + str (person .person_id ), content_type = "application/vnd.api+json" ,
1016
+ headers = {'auth' : '1234' })
1017
+ assert response .status_code == 401
1018
+
1019
+
994
1020
def test_patch_detail (client , register_routes , computer , person ):
995
1021
payload = {
996
1022
"data" : {
0 commit comments