Skip to content

Commit

Permalink
Merge branch 'master' into frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
costero-e authored Jan 11, 2024
2 parents 920dce7 + 46e0e99 commit 1a521d7
Show file tree
Hide file tree
Showing 83 changed files with 8,244 additions and 376,863 deletions.
59 changes: 59 additions & 0 deletions .github/workflows/push_docker_image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Create and publish a Docker image

on:
push:
branches: ['develop', 'master']
tags:
- 'v*.*.*'
pull_request:
branches: ['develop', 'master']
tags:
- 'v*.*.*'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-image:
runs-on: ubuntu-latest
strategy:
matrix:
platform:
- linux/amd64
- linux/arm64
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
# set latest tag for master branch
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'develop') }}
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
# Indicates that the Docker build context is the current directory.
# Otherwise, it would be a Git URL (doing a separate clean checkout).
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
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
34 changes: 18 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,34 @@ This repository is an implementation of the [Beacon v2.0 Model](https://github.c

* The (Python 3.9+) [source code for beacon](beacon),
* A MongoDB database with sample data to demo the capabilities of the Beacon API.
* AAI and LS-AAI integrated. For LS-AAI, gdi ls aai mock repository is required to be up and running in another docker compose service, and then you will need to create this external network:
```bash
docker network create my-app-network
```
* AAI and LS-AAI integrated.


> [Local deployment instructions](deploy/README.md)
> [Frontend usage instructions](frontend/README.md)
### 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.
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:
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, or run the 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
curl --location --request POST 'http://localhost:8080/oidc/token' \--header 'Content-Type: application/x-www-form-urlencoded' \--data-urlencode 'grant_type=authorization_code' \--data-urlencode 'code=pasteyourcodefrombrowserhere' \--data-urlencode 'client_id=app-123' \--data-urlencode 'client_secret=secret_value' \--data-urlencode 'scope=openid' \
--data-urlencode 'requested_token_type=urn:ietf:params:oauth:token-type:refresh_token'
docker exec beacon-permissions bash permissions/permissions-ui/start.sh
```
When you have your authorization token, pass it in a header in your POST request to get your answers.

### Making real LS AAI work
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.
To give a user a certain type of response for their queries, please modify this file [response_type.yml](https://github.com/EGA-archive/beacon2-ri-api/blob/master/beacon/request/response_type.yml) adding the maximum type of response you want to allow every user.

This repository is made to work with mock LS AAI. It still has not been developed to work with real LS AAI. However, real LS AAI should inmediately work with only a couple of changes. In order to make it work with real LS AAI, please change the mock for the real LS AAI endpoints in the auth.py file inside permissions folder:
Also, you will need to edit the file [conf.py](beacon/conf.py) and introduce the domain where your keycloak is being hosted inside **ldp_user_info** and the issuers you trust for your token inside **trusted_issuers**. In case you want to run your local container, use this configuration:
```bash
idp_user_info = 'http://ls-aai-mock:8080/oidc/userinfo'
idp_introspection = 'http://ls-aai-mock:8080/oidc/introspect'
idp_user_info = 'http://idp:8080/auth/realms/Beacon/protocol/openid-connect/userinfo'
lsaai_user_info = 'https://login.elixir-czech.org/oidc/userinfo'
trusted_issuers = ['http://idp:8080/auth/realms/Beacon', 'https://login.elixir-czech.org/oidc/']
```
Then, if the user is created in LS AAI, just add its permissions in permissions.yml file and you should have a beacon connecting to real LS AAI.

When you have your access token, pass it in a header with **Authorization: Bearer** in your POST request to get your answers. This token works coming from either from LS AAI or from keycloak (idp container).

### Beacon security system

![Beacon security](https://github.com/EGA-archive/beacon2-ri-api/blob/develop/deploy/beacon_security.png?raw=true)

### Version notes

Expand Down
19 changes: 6 additions & 13 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 All @@ -102,25 +102,18 @@
#
# Permissions server configuration
#
permissions_url = 'http://beacon-permissions'
permissions_url = 'http://beacon-permissions:5051/'
#permissions_url = 'http://localhost:5051/'

#
# IdP endpoints (OpenID Connect/Oauth2)
#
# or use Elixir AAI (see https://elixir-europe.org/services/compute/aai)
#
idp_client_id = 'beacon'
idp_client_secret = 'b26ca0f9-1137-4bee-b453-ee51eefbe7ba' # same as in the test IdP
idp_scope = 'profile openid'
idp_user_info = 'https://beacon-network-demo2.ega-archive.org/auth/realms/Beacon/protocol/openid-connect/userinfo'
lsaai_user_info = 'https://login.elixir-czech.org/oidc/userinfo'
trusted_issuers = ['https://beacon-network-demo2.ega-archive.org/auth/realms/Beacon', 'https://login.elixir-czech.org/oidc/']

idp_authorize = 'http://idp/auth/realms/Beacon/protocol/openid-connect/auth'
idp_access_token = 'http://idp/auth/realms/Beacon/protocol/openid-connect/token'
idp_introspection = 'http://idp/auth/realms/Beacon/protocol/openid-connect/token/introspect'
idp_user_info = 'http://idp/auth/realms/Beacon/protocol/openid-connect/userinfo'
idp_logout = 'http://idp/auth/realms/Beacon/protocol/openid-connect/logout'

idp_redirect_uri = 'http://beacon:5050/login'

#
# UI
Expand Down
58 changes: 37 additions & 21 deletions beacon/db/analyses.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@
def include_resultset_responses(query: Dict[str, List[dict]], qparams: RequestParams):
LOG.debug("Include Resultset Responses = {}".format(qparams.query.include_resultset_responses))
include = qparams.query.include_resultset_responses
if include == 'HIT':
query = query
elif include == 'ALL':
query = {}
elif include == 'NONE':
query = {'$text': {'$search': '########'}}
else:
query = query
return query

def apply_request_parameters(query: Dict[str, List[dict]], qparams: RequestParams):
Expand Down Expand Up @@ -50,7 +42,7 @@ def get_analyses(entry_id: Optional[str], qparams: RequestParams):
client.beacon.analyses,
query,
qparams.query.pagination.skip,
count
0
)
negative_query={}
ids_array = []
Expand All @@ -60,20 +52,28 @@ def get_analyses(entry_id: Optional[str], qparams: RequestParams):
ids_array.append(elem_query)

negative_query['$nor']=ids_array
LOG.debug(negative_query)
#LOG.debug(negative_query)
docs = get_documents(
client.beacon.analyses,
negative_query,
qparams.query.pagination.skip,
qparams.query.pagination.limit
0
)
LOG.debug(docs)
count = get_count(client.beacon.analyses, negative_query)
elif include == 'NONE':
docs = get_documents(
client.beacon.analyses,
query,
qparams.query.pagination.skip,
qparams.query.pagination.limit
)
else:
docs = get_documents(
client.beacon.analyses,
query,
qparams.query.pagination.skip,
qparams.query.pagination.limit
0
)
return schema, count, docs

Expand All @@ -92,7 +92,7 @@ def get_analysis_with_id(entry_id: Optional[str], qparams: RequestParams):
client.beacon.analyses,
query,
qparams.query.pagination.skip,
count
0
)
negative_query={}
ids_array = []
Expand All @@ -102,20 +102,28 @@ def get_analysis_with_id(entry_id: Optional[str], qparams: RequestParams):
ids_array.append(elem_query)

negative_query['$nor']=ids_array
LOG.debug(negative_query)
#LOG.debug(negative_query)
docs = get_documents(
client.beacon.analyses,
negative_query,
qparams.query.pagination.skip,
qparams.query.pagination.limit
0
)
LOG.debug(docs)
count = get_count(client.beacon.analyses, negative_query)
elif include == 'NONE':
docs = get_documents(
client.beacon.analyses,
query,
qparams.query.pagination.skip,
qparams.query.pagination.limit
)
else:
docs = get_documents(
client.beacon.analyses,
query,
qparams.query.pagination.skip,
qparams.query.pagination.limit
0
)
return schema, count, docs

Expand All @@ -139,7 +147,7 @@ def get_variants_of_analysis(entry_id: Optional[str], qparams: RequestParams):
client.beacon.genomicVariations,
query,
qparams.query.pagination.skip,
count
0
)
negative_query={}
ids_array = []
Expand All @@ -149,20 +157,28 @@ def get_variants_of_analysis(entry_id: Optional[str], qparams: RequestParams):
ids_array.append(elem_query)

negative_query['$nor']=ids_array
LOG.debug(negative_query)
#LOG.debug(negative_query)
docs = get_documents(
client.beacon.genomicVariations,
negative_query,
qparams.query.pagination.skip,
qparams.query.pagination.limit
0
)
LOG.debug(docs)
count = get_count(client.beacon.genomicVariations, negative_query)
elif include == 'NONE':
docs = get_documents(
client.beacon.genomicVariations,
query,
qparams.query.pagination.skip,
qparams.query.pagination.limit
)
else:
docs = get_documents(
client.beacon.genomicVariations,
query,
qparams.query.pagination.skip,
qparams.query.pagination.limit
0
)
return schema, count, docs

Expand All @@ -176,7 +192,7 @@ def get_filtering_terms_of_analyse(entry_id: Optional[str], qparams: RequestPara
query,
remove_id,
qparams.query.pagination.skip,
qparams.query.pagination.limit
0
)
return schema, count, docs

Loading

0 comments on commit 1a521d7

Please sign in to comment.