Skip to content

Commit

Permalink
moving token verification to permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
costero-e committed Nov 24, 2023
1 parent b70b418 commit 0e993a6
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 50 deletions.
44 changes: 6 additions & 38 deletions beacon/request/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ async def wrapper(request: Request):
access_token = request.headers.get('Authorization')


visa_datasets=[]

LOG.debug(access_token)
if access_token is not None:
pass
Expand All @@ -70,37 +70,12 @@ async def wrapper(request: Request):
specific_datasets = []
access_token = access_token[7:] # cut out 7 characters: len('Bearer ')
LOG.debug(access_token)
if access_token != 'public':
decoded = jwt.decode(access_token, options={"verify_signature": False})
LOG.debug(decoded)
user = await check_user(access_token)
LOG.debug(user)
try:
token_username = user['preferred_username']
except Exception:
token_username = None
LOG.debug(token_username)
issuer = decoded['iss']
try:
visa_datasets = user['ga4gh_passport_v1']
except Exception:
pass



authorized_datasets, authenticated = await resolve_token(access_token, search_datasets)
authorized_datasets, authenticated, username = await resolve_token(access_token, search_datasets)
LOG.debug(authorized_datasets)
if visa_datasets:
for visa_dataset in visa_datasets:
try:
visa = jwt.decode(visa_dataset, options={"verify_signature": False}, algorithms=["RS256"])
LOG.debug(visa)
LOG.debug(visa["ga4gh_visa_v1"]["value"])
dataset_url = visa["ga4gh_visa_v1"]["value"]
dataset_url_splitted = dataset_url.split('/')
visa_dataset = dataset_url_splitted[-1]
authorized_datasets.append(visa_dataset)
except Exception:
visa_dataset = None


#LOG.debug('all datasets: %s', all_datasets)
LOG.info('resolved datasets: %s', authorized_datasets)
Expand Down Expand Up @@ -197,16 +172,13 @@ async def wrapper(request: Request):
if access_token != 'public':


if issuer in conf.trusted_issuers:
pass
else:
raise web.HTTPUnauthorized('invalid token')


with open("/beacon/beacon/request/response_type.yml", 'r') as response_type_file:
response_type_dict = yaml.safe_load(response_type_file)

try:
response_type = response_type_dict[token_username]
response_type = response_type_dict[username]
except Exception:
LOG.debug(Exception)
response_type = ['boolean']
Expand Down Expand Up @@ -286,10 +258,6 @@ async def wrapper(request: Request):
specific_datasets = []
access_token = access_token[7:] # cut out 7 characters: len('Bearer ')


decoded = jwt.decode(access_token, options={"verify_signature": False})
LOG.debug(decoded)
token_username = decoded['preferred_username']

authorized_datasets, authenticated = await resolve_token(access_token, search_datasets)
LOG.debug(authorized_datasets)
Expand Down
2 changes: 1 addition & 1 deletion beacon/request/response_type.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
dummy_user:
- record
- count
costero-e:
- record
10 changes: 8 additions & 2 deletions beacon/utils/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,22 @@ async def resolve_token(token, requested_datasets_ids):
raise web.HTTPUnauthorized(body=error)
'''
content = await resp.content.read()
authorized_datasets = content.decode('utf-8')
content = content.decode('utf-8')
content_splitted= content.split(':')
authorized_datasets = content_splitted[-1]
authorized_datasets_list = authorized_datasets.split('"')
username_ = content_splitted[1]
username_list = username_.split('"')
username = username_list[1]
LOG.debug(username)
auth_datasets = []
for auth_dataset in authorized_datasets_list:
if ',' not in auth_dataset:
if '[' not in auth_dataset:
if ']' not in auth_dataset:
auth_datasets.append(auth_dataset)
LOG.debug(auth_datasets)
return auth_datasets, True
return auth_datasets, True, username

async def check_user(access_token):
user = None
Expand Down
14 changes: 11 additions & 3 deletions permissions/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
LOG = logging.getLogger(__name__)

@bearer_required
async def permission(request: Request, username: Optional[str]):
async def permission(request: Request, username: Optional[str], list_visa_datasets: Optional [list]):

if request.headers.get('Content-Type') == 'application/json':
post_data = await request.json()
Expand All @@ -43,8 +43,16 @@ async def permission(request: Request, username: Optional[str]):
LOG.debug('requested datasets: %s', requested_datasets)
datasets = await request.app['permissions'].get(username, requested_datasets=requested_datasets)
LOG.debug('selected datasets: %s', datasets)

return web.json_response(list(datasets or [])) # cuz python-json doesn't like sets
dict_returned={}
dict_returned['username']=username
datasets=list(datasets)
LOG.error('visa_datasets: {}'.format(list_visa_datasets))
for visa_dataset in list_visa_datasets:
datasets.append(visa_dataset)
dict_returned['datasets']=list(datasets)
LOG.error(dict_returned['datasets'])

return web.json_response(dict_returned) # cuz python-json doesn't like sets

async def initialize(app):
"""Initialize server."""
Expand Down
39 changes: 34 additions & 5 deletions permissions/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"""
import json
import logging
import jwt

from aiohttp import ClientSession, BasicAuth, FormData
from aiohttp import web
Expand All @@ -22,6 +23,7 @@

idp_user_info = conf.idp_user_info
lsaai_user_info = conf.lsaai_user_info

#idp_user_info = 'http://localhost:8080/oidc/userinfo'
#idp_user_info = 'http://ls-aai-mock:8080/oidc/userinfo'
#idp_user_info = 'http://idp:8080/auth/realms/Beacon/protocol/openid-connect/userinfo'
Expand Down Expand Up @@ -57,6 +59,16 @@ async def get_user_info(access_token):
user = 'public'
return user
'''
decoded = jwt.decode(access_token, options={"verify_signature": False})
LOG.error(decoded)
issuer = decoded['iss']
list_visa_datasets=[]
visa_datasets=None

if issuer in conf.trusted_issuers:
pass
else:
raise web.HTTPUnauthorized('invalid token')

user = None
async with ClientSession(trust_env=True) as session:
Expand All @@ -67,7 +79,7 @@ async def get_user_info(access_token):
if resp.status == 200:
user = await resp.json()
LOG.error(user)
return user
return user, list_visa_datasets
else:
content = await resp.text()
LOG.error('Not a Keycloak token')
Expand All @@ -82,13 +94,30 @@ async def get_user_info(access_token):
LOG.debug('Response %s', resp)
if resp.status == 200:
user = await resp.json()
return user
try:
visa_datasets = user['ga4gh_passport_v1']
except Exception:
pass
if visa_datasets is not None:
for visa_dataset in visa_datasets:
try:
visa = jwt.decode(visa_dataset, options={"verify_signature": False}, algorithms=["RS256"])
LOG.debug(visa)
LOG.debug(visa["ga4gh_visa_v1"]["value"])
dataset_url = visa["ga4gh_visa_v1"]["value"]
dataset_url_splitted = dataset_url.split('/')
visa_dataset = dataset_url_splitted[-1]
list_visa_datasets.append(visa_dataset)
except Exception:
visa_dataset = None
LOG.error('list_visa: {}'.format(list_visa_datasets))
return user, list_visa_datasets
else:
content = await resp.text()
LOG.error('Not a LS AAI token')
LOG.error('Content: %s', content)
user = 'public'
return user
return user, list_visa_datasets


def bearer_required(func):
Expand All @@ -102,7 +131,7 @@ async def decorated(request):
access_token = auth[7:].strip() # 7 = len('Bearer ')

# We make a round-trip to the userinfo. We might not have a JWT token.
user = await get_user_info(access_token)
user, list_visa_datasets = await get_user_info(access_token)
LOG.info('The user is: %r', user)
if user is None:
raise web.HTTPUnauthorized()
Expand All @@ -112,5 +141,5 @@ async def decorated(request):
username = user.get('preferred_username')
LOG.debug('username: %s', username)

return await func(request, username)
return await func(request, username, list_visa_datasets)
return decorated
2 changes: 2 additions & 0 deletions permissions/controlled_datasets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ app-user3:
costero-e: []
dummy_user: []
hola: []
test_user:
- CINECA_synthetic_cohort_EUROPE_UK1
4 changes: 3 additions & 1 deletion permissions/public_datasets.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
public_datasets:
- public
- CINECA_dataset
- CINECA_synthetic_cohort_EUROPE_UK1
- AV_Dataset

0 comments on commit 0e993a6

Please sign in to comment.