55import pyotp
66import os
77
8- from tapisservice .auth import validate_token
8+ from tapisservice .auth import validate_token , get_service_tapis_client
9+ from tapisservice .tenants import tenant_cache as auth_tenants
910from tapisservice .config import conf as tapisconf
1011from service .models import tenant_configs_cache , DeviceCode
1112from service .api import app
2324TEST_PASSWORD = 'testuser1'
2425MFA_USERNAME = 'cicsvc'
2526MFA_GEN_CODE = os .environ .get ('MFA_GEN_CODE' )
27+ TAPIS_JWT = None
28+ TAPIS_SERVICE_JWT = None
2629
2730@pytest .fixture
2831def client ():
@@ -92,6 +95,7 @@ def init_db():
9295 if not client :
9396 assert False
9497
98+ @pytest .fixture ()
9599def teardown_module ():
96100 # clean up all the mess we made
97101 with app .app_context ():
@@ -208,7 +212,6 @@ def check_device_code_table(client_id, user_code, device_code, verification_url,
208212 assert retrieved .status == status
209213 assert retrieved .verification_uri == verification_url
210214
211-
212215def validate_refresh_token (response ):
213216 """
214217 Validate that a response has a refresh token and it is properly formatted.
@@ -226,15 +229,13 @@ def validate_refresh_token(response):
226229 assert claims ['tapis/access_token' ]['sub' ] == f'{ TEST_USERNAME } @{ TEST_TENANT_ID } '
227230 return claims
228231
229-
230232def get_jwt (client ):
231- # TODO: add assertions for failing to get a token -- this should fail the current test somehow
232- # auth_header = {'Authorization': get_basic_auth_header(TEST_CLIENT_ID, TEST_CLIENT_KEY)}
233233 payload = {
234234 'grant_type' : 'password' ,
235235 'username' : TEST_USERNAME ,
236236 'password' : TEST_PASSWORD
237237 }
238+ # print(f'DEBUG:: about to get token with payload: {json.dumps(payload, indent=4)}')
238239 response = client .post (
239240 "http://localhost:5000/v3/oauth2/tokens" ,
240241 # headers=auth_header,
@@ -244,9 +245,37 @@ def get_jwt(client):
244245 assert response .status_code == 200
245246 assert 'access_token' in response .json ['result' ]
246247 # access_token:
248+ # print(f'DEBUG:: Successfully got access token for {TEST_USERNAME}')
247249 access_token_str = response .json ['result' ]['access_token' ]['access_token' ]
248250 return access_token_str
249251
252+ @pytest .fixture
253+ def tapis_jwt (client ):
254+ if globals ()['TAPIS_JWT' ] is not None :
255+ return globals ()['TAPIS_JWT' ]
256+ jwt = get_jwt (client )
257+ globals ()['TAPIS_JWT' ] = jwt
258+ return jwt
259+
260+ @pytest .fixture
261+ def tapis_service_jwt (client ):
262+ if globals ()['TAPIS_SERVICE_JWT' ] is not None :
263+ return globals ()['TAPIS_SERVICE_JWT' ]
264+ t = get_service_tapis_client (tenants = auth_tenants ,
265+ # todo -- change back once tokens api update is in prod
266+ resource_set = 'dev'
267+ )
268+ service_jwt = t .service_tokens ['admin' ]['access_token' ].access_token
269+ # jwt = get_jwt(client, username='admin', password=tapisconf['service_password'], admin=True)
270+ # jwt = get_service_tapis_client(tenant_id=tapisconf['service_tenant_id'],
271+ # base_url=None,
272+ # jwt=None,
273+ # resource_set='tapipy', #todo -- change back to resource_set='tapipy'
274+ # custom_spec_dict=None,
275+ # download_latest_specs=False,
276+ # tenants=None):
277+ globals ()['TAPIS_SERVICE_JWT' ] = service_jwt
278+ return service_jwt
250279
251280@pytest .fixture
252281def mfa_token (tokencode = None ):
@@ -256,9 +285,7 @@ def mfa_token(tokencode=None):
256285 """
257286 if tokencode is None :
258287 tokencode = MFA_GEN_CODE
259- print (f'DEBUG:: generating MFA token with tokencode: { tokencode } ' )
260- if tokencode is None :
261- print (f'ERROR! tokencode should not be None! Env: { os .environ .items ()} ' )
288+ # print(f'DEBUG:: generating MFA token with tokencode: {tokencode}')
262289 totp = pyotp .TOTP (tokencode )
263290 return totp .now ()
264291
@@ -277,7 +304,6 @@ def test_get_jwt(client):
277304 result = get_jwt (client )
278305 print (f'got result = { result } ' )
279306
280-
281307# get mfa config
282308def test_get_mfa_config (client ):
283309 print ('top of get mfa config' )
@@ -330,9 +356,49 @@ def test_get_metadata(client):
330356
331357## Admin
332358# get_config
333- # TODO
334- # update_config
335- # TODO
359+ # def test_get_admin_config(client, tapis_service_jwt):
360+ # with client:
361+ # header = {
362+ # 'X-Tapis-Token': tapis_service_jwt,
363+ # 'X-Tapis-Tenant': TEST_TENANT_ID,
364+ # 'X-Tapis-User': 'authenticator'
365+ # }
366+ # response = client.get('http://localhost:5000/v3/oauth2/admin/config', headers=header)
367+ # print(f'got response:: {response.json}')
368+ # assert response.status_code == 200
369+ # # TODO: this doesn't seem to work.
370+ # # retrieved_config = response.json['result']
371+ # # tenant_config = tenant_configs_cache.get_config(TEST_TENANT_ID).serialize
372+ # # print(f'got config:: {retrieved_config}')
373+ # # print(f'checking against cached config: {tenant_config}')
374+ # # assert retrieved_config == tenant_config
375+
376+ # # update_config
377+ # def test_update_admin_config(client, tapis_service_jwt):
378+ # with client:
379+ # # get the config first, so we can compare after the change
380+ # current_config = tenant_configs_cache.get_config(TEST_TENANT_ID).serialize
381+ # # just change one thing
382+ # payload = {
383+ # "impers_oauth_client_id": "TEST"
384+ # }
385+ # # make request
386+ # header = {
387+ # 'X-Tapis-Token': tapis_service_jwt,
388+ # 'X-Tapis-Tenant': TEST_TENANT_ID,
389+ # 'X-Tapis-User': 'authenticator'
390+ # }
391+ # response = client.put(
392+ # 'http://localhost:5000/v3/oauth2/admin/config',
393+ # data=json.dumps(payload),
394+ # headers=header,
395+ # content_type="application/json"
396+ # )
397+ # print(f'DEBUG: got response:: {response}')
398+ # assert response.status_code == 200
399+
400+
401+
336402
337403## Clients
338404
@@ -344,7 +410,7 @@ def test_invalid_post(client):
344410
345411
346412# list_clients
347- def test_authenticator_list_clients (client , capsys ):
413+ def test_authenticator_list_clients (client ):
348414 # result = client.authenticator.list_clients()
349415 with client :
350416 header = {'X-Tapis-Token' : get_jwt (client )}
@@ -353,9 +419,9 @@ def test_authenticator_list_clients(client, capsys):
353419
354420
355421# create_client
356- def test_authenticator_create_clients (client , capsys ): ## TODO: this works, but doing it twice violates uniqueness constraint. Need to find a way to reliably erase it without using another endpoint
422+ def test_authenticator_create_clients (client , tapis_jwt ): ## TODO: this works, but doing it twice violates uniqueness constraint. Need to find a way to reliably erase it without using another endpoint
357423 # result = client.authenticator.create_client(client_id=TEST_CLIENT_ID, callback_url='https://foo.example.com/oauth2/callback')
358- header = {'X-Tapis-Token' : get_jwt ( client ) }
424+ header = {'X-Tapis-Token' : tapis_jwt }
359425 payload = {
360426 "client_id" : TEST_CLIENT_ID ,
361427 "client_key" : TEST_CLIENT_KEY ,
@@ -375,10 +441,41 @@ def test_authenticator_create_clients(client, capsys): ## TODO: this works, but
375441 check_clients_table (TEST_CLIENT_ID , TEST_CLIENT_REDIRECT_URI , 'A Test Client' , "This is a client just for testing" )
376442
377443# Get client details
378- # TODO
444+ def test_authenticator_get_client (client , tapis_jwt ):
445+ with client :
446+ header = {'X-Tapis-Token' : tapis_jwt }
447+ url = f'http://localhost:5000/v3/oauth2/clients/{ TEST_CLIENT_ID } '
448+ result = client .get (f'http://localhost:5000/v3/oauth2/clients/{ TEST_CLIENT_ID } ' , headers = header )
449+ assert result .status_code == 200
450+ check_clients_table (TEST_CLIENT_ID )
379451
380452# Update client details
381- # TODO
453+ def test_authenticator_update_client (client , tapis_jwt ):
454+ header = {'X-Tapis-Token' : tapis_jwt }
455+ payload = json .dumps ({
456+ "callback_url" : "http://localhost:5000/testsuite/update_client_test"
457+ })
458+ result = client .put (
459+ f'http://localhost:5000/v3/oauth2/clients/{ TEST_CLIENT_ID } ' ,
460+ headers = header ,
461+ data = payload ,
462+ content_type = 'application/json'
463+ )
464+ print (f'DEBUG: got result of update client:: { result } ' )
465+ assert result .status_code == 200
466+ check_clients_table (TEST_CLIENT_ID )
467+ # TODO: we should create a better setup / teardown for these tests
468+ payload = json .dumps ({
469+ "callback_url" : TEST_CLIENT_REDIRECT_URI
470+ })
471+ result = client .put (
472+ f'http://localhost:5000/v3/oauth2/clients/{ TEST_CLIENT_ID } ' ,
473+ headers = header ,
474+ data = payload ,
475+ content_type = 'application/json'
476+ )
477+ assert result .status_code == 200 # fail if we can't put it back correctly
478+
382479
383480# Permanantly set a client to inactive
384481def test_authenticator_delete_clients (client ):
@@ -556,7 +653,26 @@ def test_password_grant_no_client(client, init_db):
556653 assert 'refresh_token' not in response .json ['result' ]
557654
558655# Create a v2 bearer token from a Tapis v3 JWT
559- # TODO
656+ # def test_get_v2_bearer_token(client, tapis_jwt):
657+ # with client:
658+ # payload = json.dumps(
659+ # {
660+ # "access_token": tapis_jwt
661+ # }
662+ # )
663+ # header = ({
664+ # "X-Tapis-Token": tapis_jwt
665+ # })
666+ # result = client.post(
667+ # 'http://localhost:5000/v3/oauth2/v2/token',
668+ # data=payload,
669+ # headers=header,
670+ # content_type='application/json'
671+ # )
672+ # print(f'DEBUG:: got result generating v2 token: {result.json}')
673+ # assert result.status_code == 200
674+ # raise Exception()
675+ ## TODO!!! this is likely deprecated now that v2 is down...
560676
561677# Revoke a token
562678def test_revoke_token (client , init_db ):
@@ -609,15 +725,43 @@ def test_revoke_token(client, init_db):
609725
610726 check_refresh_token_table (refresh_token_claims , "password" , True , TEST_CLIENT_ID )
611727
728+ ## Device Code
612729# Note: Device code checks are below
613730
614731## Profiles
615732# get_userinfo
616- # TODO
733+ def test_get_userinfo (client , tapis_jwt ):
734+ with client :
735+ header = {
736+ "X-Tapis-Token" : tapis_jwt
737+ }
738+ result = client .get (
739+ 'http://localhost:5000/v3/oauth2/userinfo' ,
740+ headers = header
741+ )
742+ assert result .status_code == 200
617743# list_profiles
618- # TODO
744+ def test_list_profiles (client , tapis_jwt ):
745+ with client :
746+ header = {
747+ "X-Tapis-Token" : tapis_jwt
748+ }
749+ result = client .get (
750+ 'http://localhost:5000/v3/oauth2/profiles' ,
751+ headers = header
752+ )
753+ assert result .status_code == 200
619754# get_profile
620- # TODO
755+ def test_get_profile (client , tapis_jwt ):
756+ with client :
757+ header = {
758+ "X-Tapis-Token" : tapis_jwt
759+ }
760+ result = client .get (
761+ f'http://localhost:5000/v3/oauth2/profiles/{ TEST_USERNAME } ' ,
762+ headers = header
763+ )
764+ assert result .status_code == 200
621765
622766## grant type tests
623767
@@ -786,10 +930,6 @@ def test_implicit_grant(client, init_db):
786930
787931## Device code checks
788932def test_get_device_code (client ):
789- # TODO: get a device code, then use it to get a token
790- # verify that we get a access token using it
791- # verify that the code can't be used a second time to get another token
792- # verify that the device code is tied to the user in the db
793933 with client :
794934 # get device code url
795935 data = {'client_id' : TEST_CLIENT_ID }
@@ -869,7 +1009,6 @@ def test_exchange_device_code(client):
8691009 validate_access_token (response )
8701010
8711011## MFA tests
872- # TODO
8731012def test_mfa_valid_code (mfa_token ):
8741013 # uses the cicsvc creds to auth.
8751014 response = mfa .call_mfa (mfa_token , TEST_TENANT_ID , MFA_USERNAME )
0 commit comments