Skip to content

Commit 330fdf6

Browse files
100% coverage, minus v2 and admin endpoints.
1 parent 61d2c3e commit 330fdf6

File tree

1 file changed

+166
-27
lines changed

1 file changed

+166
-27
lines changed

service/tests/basic_test.py

Lines changed: 166 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import pyotp
66
import 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
910
from tapisservice.config import conf as tapisconf
1011
from service.models import tenant_configs_cache, DeviceCode
1112
from service.api import app
@@ -23,6 +24,8 @@
2324
TEST_PASSWORD = 'testuser1'
2425
MFA_USERNAME = 'cicsvc'
2526
MFA_GEN_CODE = os.environ.get('MFA_GEN_CODE')
27+
TAPIS_JWT = None
28+
TAPIS_SERVICE_JWT = None
2629

2730
@pytest.fixture
2831
def client():
@@ -92,6 +95,7 @@ def init_db():
9295
if not client:
9396
assert False
9497

98+
@pytest.fixture()
9599
def 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-
212215
def 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-
230232
def 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
252281
def 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
282308
def 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
384481
def 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
562678
def 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

@@ -656,7 +800,7 @@ def test_authorization_code(client, init_db):
656800
assert f'code={auth_code.code}' in response_str
657801

658802

659-
def test_authorization_code_grant(client, init_db):
803+
def test_authorization_code_grant(client):
660804
with client:
661805
# look up the authorization_code from the previous test:
662806
auth_code = models.AuthorizationCode.query.filter_by(tenant_id=TEST_TENANT_ID,
@@ -786,10 +930,6 @@ def test_implicit_grant(client, init_db):
786930

787931
## Device code checks
788932
def 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
8731012
def 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

Comments
 (0)