Skip to content

Commit

Permalink
Merge pull request #242 from EGA-archive/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
costero-e authored Nov 9, 2023
2 parents 7ec65de + eb8e7b7 commit ff0a481
Show file tree
Hide file tree
Showing 56 changed files with 2,055 additions and 147 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ RUN apt-get update && \
COPY deploy/nginx.conf /beacon/nginx.conf
COPY deploy/supervisord.conf /beacon/supervisord.conf
COPY deploy/entrypoint.sh /usr/local/bin/entrypoint.sh
COPY deploy/permissions.sh /usr/local/bin/permissions.sh
COPY beacon /beacon/beacon
COPY ui /beacon/ui

Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ docker network create my-app-network
### Managing AAI-LSAAI permissions

To give the right permissions for AAI you will need to set the permissions of the users inside permissions folder, within the [permissions.yml](permissions/permissions.yml) file.
To give the right permissions for AAI you will need to set the permissions of the users inside permissions folder, within the [public_datasets.yml](permissions/public_datasets.yml), [registered_datasets.yml](permissions/registered_datasets.yml), [controlled_datasets.yml](permissions/controlled_datasets.yml) files.
Now we have developed a UI (beacon admin page∫) that allows you to manage all the permissions in a friendly way and no need to open .yml files. Just start the UI, that will run in http://localhost:8010, by executing this command from the deploy folder after the containers are up and running:
```bash
docker exec beacon-permissions bash permissions/permissions-ui/start.sh
```
Please, bear in mind that the name of the user has to be the same that you used when creating the user in LS or in IDP, whatever the AAI method you are working with.
Furthermore, if you are using LS-AAI method, you will need to get the authorization code following LS-AAI authorization flow method with a browser (for example http://localhost:8080/oidc/auth/authorize?response_type=code&client_id=app-123) and then pass this code via a POST request to get the authorization token. For example:
```bash
Expand Down
4 changes: 2 additions & 2 deletions beacon/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
beacon_id = 'org.ega-archive.ga4gh-approval-beacon-test' # ID of the Beacon
beacon_name = 'GA4GH Approval Beacon Test' # Name of the Beacon service
api_version = 'v2.0.0' # Version of the Beacon implementation
uri = 'https://beacon-apis-demo.ega-archive.org/api/'
uri = 'https://beacon-apis-test.ega-archive.org/api/'

#
# Beacon granularity
Expand Down Expand Up @@ -78,7 +78,7 @@
#
# Database connection
#
database_host = '127.0.0.1'
database_host = 'mongo'
database_port = 27017
database_user = 'root'
database_password = 'example'
Expand Down
184 changes: 83 additions & 101 deletions beacon/request/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,131 +59,113 @@ async def wrapper(request: Request):

LOG.debug(access_token)
if access_token is not None:
with open("/beacon/beacon/request/public_datasets.yml", 'r') as stream:
public_datasets = yaml.safe_load(stream)
list_of_public_datasets= public_datasets['public_datasets']
try:
specific_datasets = qparams.query.request_parameters['datasets']
except Exception:
specific_datasets = []
access_token = access_token[7:] # cut out 7 characters: len('Bearer ')

print('we have access token')
else:
access_token = 'Bearer public'
try:
specific_datasets = qparams.query.request_parameters['datasets']
except Exception:
specific_datasets = []
access_token = access_token[7:] # cut out 7 characters: len('Bearer ')
LOG.debug(access_token)



authorized_datasets, authenticated = await resolve_token(access_token, search_datasets)
LOG.debug(authorized_datasets)
#LOG.debug('all datasets: %s', all_datasets)
LOG.info('resolved datasets: %s', authorized_datasets)
LOG.debug(authenticated)
LOG.debug(specific_datasets)


specific_datasets_unauthorized = []
specific_datasets_unauthorized_and_found = []
bio_list = []
search_and_authorized_datasets = []
specific_search_datasets = []
# Get response
if specific_datasets != []:
for element in authorized_datasets:
if element in specific_datasets:
search_and_authorized_datasets.append(element)
for elemento in specific_datasets:
if elemento not in search_and_authorized_datasets:
specific_datasets_unauthorized.append(elemento)
qparams.query.request_parameters = {}
qparams.query.request_parameters['datasets'] = '*******'
_, _, datasets = get_datasets(None, qparams)
beacon_datasets = [ r for r in datasets ]
all_datasets = [r['id'] for r in beacon_datasets]


authorized_datasets, authenticated = await resolve_token(access_token, search_datasets)
LOG.debug(authorized_datasets)
#LOG.debug('all datasets: %s', all_datasets)
LOG.info('resolved datasets: %s', authorized_datasets)
LOG.debug(authenticated)
LOG.debug(specific_datasets)
response_datasets = [ r['id'] for r in beacon_datasets if r['id'] in search_and_authorized_datasets]
LOG.debug(specific_search_datasets)
LOG.debug(response_datasets)

list_of_dataset_dicts=[]

specific_datasets_unauthorized = []
specific_datasets_unauthorized_and_found = []
bio_list = []
search_and_authorized_datasets = []
specific_search_datasets = []
for public_dataset in list_of_public_datasets:
authorized_datasets.append(public_dataset)
# Get response
if specific_datasets != []:
for element in authorized_datasets:
if element in specific_datasets:
search_and_authorized_datasets.append(element)
for elemento in specific_datasets:
if elemento not in search_and_authorized_datasets:
specific_datasets_unauthorized.append(elemento)
qparams.query.request_parameters = {}
qparams.query.request_parameters['datasets'] = '*******'
_, _, datasets = get_datasets(None, qparams)
beacon_datasets = [ r for r in datasets ]
all_datasets = [r['id'] for r in beacon_datasets]

response_datasets = [ r['id'] for r in beacon_datasets if r['id'] in search_and_authorized_datasets]
LOG.debug(specific_search_datasets)
LOG.debug(response_datasets)

list_of_dataset_dicts=[]

for data_r in response_datasets:
dict_dataset = {}
dict_dataset['dataset']=data_r
dict_dataset['ids']=[ r['ids'] for r in beacon_datasets if r['id'] == data_r ]
list_of_dataset_dicts.append(dict_dataset)
for data_r in response_datasets:
dict_dataset = {}
dict_dataset['dataset']=data_r
dict_dataset['ids']=[ r['ids'] for r in beacon_datasets if r['id'] == data_r ]
list_of_dataset_dicts.append(dict_dataset)

for dataset_searched in specific_datasets_unauthorized:
if dataset_searched not in all_datasets:
dict_dataset = {}
dict_dataset['dataset']=dataset_searched
dict_dataset['ids'] = ['Dataset not found']
LOG.debug(dict_dataset['dataset'])
LOG.debug(dict_dataset['ids'])
list_of_dataset_dicts.append(dict_dataset)

for data_s in specific_datasets_unauthorized_and_found:
for dataset_searched in specific_datasets_unauthorized:
if dataset_searched not in all_datasets:
dict_dataset = {}
dict_dataset['dataset']=data_s
dict_dataset['ids'] = ['Unauthorized dataset']
dict_dataset['dataset']=dataset_searched
dict_dataset['ids'] = ['Dataset not found']
LOG.debug(dict_dataset['dataset'])
LOG.debug(dict_dataset['ids'])
list_of_dataset_dicts.append(dict_dataset)

for data_s in specific_datasets_unauthorized_and_found:
dict_dataset = {}
dict_dataset['dataset']=data_s
dict_dataset['ids'] = ['Unauthorized dataset']
list_of_dataset_dicts.append(dict_dataset)

LOG.debug(specific_datasets_unauthorized_and_found)
LOG.debug(specific_datasets_unauthorized)
LOG.debug(list_of_dataset_dicts)
LOG.debug(specific_datasets_unauthorized_and_found)
LOG.debug(specific_datasets_unauthorized)
LOG.debug(list_of_dataset_dicts)

else:
qparams.query.request_parameters = {}
qparams.query.request_parameters['datasets'] = '*******'
_, _, datasets = get_datasets(None, qparams)
beacon_datasets = [ r for r in datasets ]
LOG.debug(authorized_datasets)
specific_datasets = [ r['id'] for r in beacon_datasets if r['id'] not in authorized_datasets]
response_datasets = [ r['id'] for r in beacon_datasets if r['id'] in authorized_datasets]
LOG.debug(specific_datasets)
LOG.debug(response_datasets)
specific_datasets_unauthorized.append(specific_datasets)
for unauth in specific_datasets_unauthorized:
for unauth_spec in unauth:
biosample_ids = [ r['ids'] for r in beacon_datasets if r['id'] == unauth_spec ]
bio_list.append(biosample_ids)

list_of_dataset_dicts=[]

for data_r in response_datasets:
dict_dataset = {}
dict_dataset['dataset']=data_r
dict_dataset['ids']=[ r['ids'] for r in beacon_datasets if r['id'] == data_r ]
list_of_dataset_dicts.append(dict_dataset)

for data_s in specific_datasets:
dict_dataset = {}
dict_dataset['dataset']=data_s
dict_dataset['ids'] = ['Unauthorized dataset']
list_of_dataset_dicts.append(dict_dataset)
#LOG.debug(list_of_dataset_dicts)
else:
#write here code for public datasets
list_of_dataset_dicts=[]
qparams.query.request_parameters = {}
qparams.query.request_parameters['datasets'] = '*******'
_, _, datasets = get_datasets(None, qparams)
beacon_datasets = [ r for r in datasets ]
with open("/beacon/beacon/request/public_datasets.yml", 'r') as stream:
public_datasets = yaml.safe_load(stream)
list_of_public_datasets= public_datasets['public_datasets']
LOG.debug(list_of_public_datasets)
for data_r in list_of_public_datasets:
LOG.debug(authorized_datasets)
specific_datasets = [ r['id'] for r in beacon_datasets if r['id'] not in authorized_datasets]
response_datasets = [ r['id'] for r in beacon_datasets if r['id'] in authorized_datasets]
LOG.debug(specific_datasets)
LOG.debug(response_datasets)
specific_datasets_unauthorized.append(specific_datasets)
for unauth in specific_datasets_unauthorized:
for unauth_spec in unauth:
biosample_ids = [ r['ids'] for r in beacon_datasets if r['id'] == unauth_spec ]
bio_list.append(biosample_ids)

list_of_dataset_dicts=[]

for data_r in response_datasets:
dict_dataset = {}
dict_dataset['dataset']=data_r
dict_dataset['ids']=[ r['ids'] for r in beacon_datasets if r['id'] == data_r ]
list_of_dataset_dicts.append(dict_dataset)

for data_s in specific_datasets:
dict_dataset = {}
dict_dataset['dataset']=data_s
dict_dataset['ids'] = ['Unauthorized dataset']
list_of_dataset_dicts.append(dict_dataset)
#LOG.debug(list_of_dataset_dicts)




qparams = RequestParams(**json_body).from_request(request)

if access_token is not None:
if access_token != 'public':
decoded = jwt.decode(access_token, options={"verify_signature": False})
LOG.debug(decoded)
token_username = decoded['preferred_username']
Expand Down
2 changes: 0 additions & 2 deletions beacon/request/public_datasets.yml

This file was deleted.

2 changes: 2 additions & 0 deletions beacon/utils/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ async def resolve_token(token, requested_datasets_ids):
'Accept': 'application/json'},
json={'datasets': requested_datasets_ids}, # will set the Content-Type to application/json
) as resp:
'''
if resp.status > 200:
LOG.error('Permissions server error %d', resp.status)
error = await resp.text()
LOG.error('Error: %s', error)
raise web.HTTPUnauthorized(body=error)
'''
content = await resp.content.read()
authorized_datasets = content.decode('utf-8')
authorized_datasets_list = authorized_datasets.split('"')
Expand Down
2 changes: 1 addition & 1 deletion deploy/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
beacon_id = 'org.ega-archive.ga4gh-approval-beacon-test' # ID of the Beacon
beacon_name = 'GA4GH Approval Beacon Test' # Name of the Beacon service
api_version = 'v2.0.0' # Version of the Beacon implementation
uri = 'https://beacon-apis-demo.ega-archive.org/api/'
uri = 'https://beacon-apis-test.ega-archive.org/api/'

#
# Beacon granularity
Expand Down
2 changes: 1 addition & 1 deletion deploy/data/individuals_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"id" : "NCIT:C42331",
"label" : "African"
},
"id" : "HG00096",
"id" : "AV0101",
"info" : {
"eid" : "fake1"
},
Expand Down
3 changes: 3 additions & 0 deletions deploy/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ services:
- ./logger.yml:/beacon/logger.yml
ports:
- "5051:5051"
- 8010:8000
networks:
- beacon-priv
- pub
Expand Down Expand Up @@ -178,3 +179,5 @@ services:
volumes:
- ../frontend:/usr/src/app



3 changes: 3 additions & 0 deletions deploy/permissions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
bash permissions/permissions-ui/start.sh
python -m permissions
11 changes: 8 additions & 3 deletions permissions/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ async def get_user_info(access_token):
else:
LOG.error('Content: %s', content)
LOG.error('Invalid token')
raise web.HTTPUnauthorized()
user = 'public'
return user

user = None
async with ClientSession(trust_env=True) as session:
Expand All @@ -75,7 +76,8 @@ async def get_user_info(access_token):
else:
content = await resp.text()
LOG.error('Content: %s', content)
raise web.HTTPUnauthorized()
user = 'public'
return user



Expand All @@ -96,7 +98,10 @@ async def decorated(request):
LOG.info('The user is: %r', user)
if user is None:
raise web.HTTPUnauthorized()
username = user.get('preferred_username')
elif user == 'public':
username = 'public'
else:
username = user.get('preferred_username')
LOG.debug('username: %s', username)

return await func(request, username)
Expand Down
7 changes: 5 additions & 2 deletions permissions/controlled_datasets.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
controlled_datasets:
- CINECA_synthetic_cohort_EUROPE_UK1
app-user3:
- CINECA_synthetic_cohort_EUROPE_UK1
- AV_Dataset
hola:
- CINECA_synthetic_cohort_EUROPE_UK1
4 changes: 4 additions & 0 deletions permissions/permissions-ui/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.dockerignore
*.pyc
__pycache__
env
Empty file.
3 changes: 3 additions & 0 deletions permissions/permissions-ui/bash/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions permissions/permissions-ui/bash/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class BashConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'bash'
3 changes: 3 additions & 0 deletions permissions/permissions-ui/bash/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.db import models

# Create your models here.
3 changes: 3 additions & 0 deletions permissions/permissions-ui/bash/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
11 changes: 11 additions & 0 deletions permissions/permissions-ui/bash/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.urls import path
#from .views import HomePageView
from . import views
app_name = 'bash'

urlpatterns = [
path('', views.bash_view, name='index'),
path('public', views.public_view, name='public'),
path('registered', views.registered_view, name='registered'),
path('controlled', views.controlled_view, name='controlled')
]
Loading

0 comments on commit ff0a481

Please sign in to comment.