Skip to content

Commit a0f014f

Browse files
reana: access token implementation
* Closes #1113. Signed-off-by: Ioannis Tsanaktsidis <ioannis.tsanaktsidis@cern.ch>
1 parent b916a06 commit a0f014f

File tree

5 files changed

+113
-23
lines changed

5 files changed

+113
-23
lines changed

cap/config.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,5 +640,13 @@ def _(x):
640640

641641
# Reana server url
642642
# ================
643-
REANA_ACCESS_TOKEN = os.environ.get(
644-
'APP_REANA_ACCESS_TOKEN', None)
643+
REANA_ACCESS_TOKEN = {
644+
'ATLAS': os.environ.get(
645+
'APP_REANA_ATLAS_ACCESS_TOKEN', None),
646+
'ALICE': os.environ.get(
647+
'APP_REANA_ALICE_ACCESS_TOKEN', None),
648+
'CMS': os.environ.get(
649+
'APP_REANA_CMS_ACCESS_TOKEN', None),
650+
'LHCb': os.environ.get(
651+
'APP_REANA_LHCb_ACCESS_TOKEN', None)
652+
}

cap/modules/reana/errors.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# This file is part of CERN Analysis Preservation Framework.
4+
# Copyright (C) 2018 CERN.
5+
#
6+
# CERN Analysis Preservation Framework is free software; you can redistribute
7+
# it and/or modify it under the terms of the GNU General Public License as
8+
# published by the Free Software Foundation; either version 2 of the
9+
# License, or (at your option) any later version.
10+
#
11+
# CERN Analysis Preservation Framework is distributed in the hope that it will
12+
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
# General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with CERN Analysis Preservation Framework; if not, write to the
18+
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19+
# MA 02111-1307, USA.
20+
#
21+
# In applying this license, CERN does not
22+
# waive the privileges and immunities granted to it by virtue of its status
23+
# as an Intergovernmental Organization or submit itself to any jurisdiction.
24+
25+
"""Reana exceptions."""
26+
27+
from invenio_rest.errors import RESTException
28+
29+
30+
class ExperimentIsNotValid(RESTException):
31+
"""Experiment not present."""
32+
33+
code = 400
34+
35+
def __init__(self, description, **kwargs):
36+
"""Initialize exception."""
37+
super(ExperimentIsNotValid, self).__init__(**kwargs)
38+
39+
self.description = description or self.description

cap/modules/reana/views.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,19 @@
2424

2525

2626
"""CAP REANA views."""
27+
import json
2728

2829
from flask import Blueprint, abort, current_app, jsonify, request
2930

3031
from flask_login import current_user
31-
from invenio_pidstore.models import PersistentIdentifier, PIDDoesNotExistError
3232

33+
from invenio_pidstore.models import PersistentIdentifier, PIDDoesNotExistError
3334
from invenio_db import db
34-
import json
35+
36+
from .errors import ExperimentIsNotValid
3537
from .models import ReanaJob
3638
from .serializers import ReanaJobSchema
39+
from cap.modules.records.api import CAPRecord
3740
from reana_client.api.client import create_workflow_from_json, \
3841
start_workflow, get_workflow_status, get_workflow_logs
3942

@@ -78,15 +81,25 @@ def create_workflow():
7881
"mc15_13TeV.123456.cap_recast_demo_signal_one.root"
7982
}
8083
}
81-
access_token = current_app.config.get('REANA_ACCESS_TOKEN')
82-
response = create_workflow_from_json(
83-
workflow_json, name, access_token, parameters, workflow_engine)
8484

8585
try:
8686
uuid = PersistentIdentifier.get('recid', record_id).object_uuid
87+
experiment = CAPRecord.get_record(uuid).get('_experiment', None)
88+
if experiment is None:
89+
raise ExperimentIsNotValid('Experiment is not valid.')
90+
access_token = current_app.config.get(
91+
'REANA_ACCESS_TOKEN').get(experiment, None)
92+
if access_token is None:
93+
raise ExperimentIsNotValid(
94+
'Access token for {} is not available'.format(
95+
experiment))
96+
8797
except PIDDoesNotExistError:
8898
abort(404)
8999

100+
response = create_workflow_from_json(
101+
workflow_json, name, access_token, parameters, workflow_engine)
102+
90103
reana_job = ReanaJob(
91104
user_id=current_user.id,
92105
record_id=uuid,

tests/conftest.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,8 @@ def create_deposit(app, db, es, location, jsonschemas_host,
312312

313313
with db_.session.begin_nested():
314314

315-
def _create_deposit(user, schema_name, metadata=None, experiment=None, publish=False):
315+
def _create_deposit(user, schema_name,
316+
metadata=None, experiment=None, publish=False):
316317
"""
317318
Create a new deposit for given user and schema name
318319
e.g cms-analysis-v0.0.1,
@@ -364,6 +365,14 @@ def deposit(users, create_deposit):
364365
return create_deposit(users['superuser'], 'cms-analysis-v0.0.1')
365366

366367

368+
@pytest.fixture
369+
def record(users, create_deposit):
370+
return create_deposit(users['superuser'],
371+
'cms-analysis-v0.0.1',
372+
experiment='CMS',
373+
publish=True)
374+
375+
367376
@pytest.fixture
368377
def record_metadata(deposit):
369378
return deposit.get_record_metadata()

tests/integration/test_api_reana.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,42 @@
2828

2929
import json
3030

31-
from pytest import mark
31+
from invenio_pidstore.models import PersistentIdentifier
3232
from cap.modules.reana.models import ReanaJob
3333

34+
#################
35+
# api/reana/create
36+
#################
37+
38+
39+
def test_create_workflow_returns_404_when_record_does_not_exist(app,
40+
auth_headers_for_superuser,
41+
json_headers):
42+
data = {
43+
'record_id': 'wrong_pid',
44+
'workflow_name': 'test_workflow',
45+
'workflow_json': {}
46+
}
47+
with app.test_client() as client:
48+
resp = client.post('/reana/create', data=json.dumps(data),
49+
headers=auth_headers_for_superuser + json_headers)
50+
51+
assert resp.status_code == 404
52+
3453

3554
#################
3655
# api/reana/jobs
3756
#################
38-
@mark.skip
39-
def test_get_reana_jobs_when_user_not_logged_in_returns_401(app, users, deposit):
57+
58+
def test_get_reana_jobs_when_user_not_logged_in_returns_401(app, users, record):
4059
with app.test_client() as client:
41-
resp = client.get('/reana/jobs/{}'.format(deposit.id))
60+
resp = client.get(
61+
'/reana/jobs/{}'.format(record['_deposit']['pid']['value']))
4262

4363
assert resp.status_code == 401
4464

4565

46-
@mark.skip
47-
def test_get_reana_jobs_when_depid_doesnt_exists_returns_404(app,
66+
def test_get_reana_jobs_when_recid_doesnt_exists_returns_404(app,
4867
auth_headers_for_superuser):
4968
with app.test_client() as client:
5069
resp = client.get('/reana/jobs/{}'.format('non-existing-pid'),
@@ -53,23 +72,24 @@ def test_get_reana_jobs_when_depid_doesnt_exists_returns_404(app,
5372
assert resp.status_code == 404
5473

5574

56-
@mark.skip
5775
def test_get_reana_jobs_when_no_jobs_returns_empty_list(app, auth_headers_for_superuser,
58-
deposit):
76+
record):
5977
with app.test_client() as client:
60-
resp = client.get('/reana/jobs/{}'.format(deposit['_deposit']['id']),
78+
resp = client.get('/reana/jobs/{}'.format(record['_deposit']['pid']['value']),
6179
headers=auth_headers_for_superuser)
6280

6381
assert json.loads(resp.data) == []
6482

6583

66-
@mark.skip
6784
def test_get_reana_jobs_returns_list_with_user_jobs(db, app, users,
6885
auth_headers_for_superuser,
69-
deposit):
86+
record):
87+
88+
uuid = PersistentIdentifier.get('recid', record['_deposit'][
89+
'pid']['value']).object_uuid
7090
db.session.add(ReanaJob(
71-
user=users['superuser'],
72-
record=deposit.get_record_metadata(),
91+
user_id=users['superuser'].id,
92+
record_id=uuid,
7393
name='my_workflow_run',
7494
params={
7595
'param_1': 1,
@@ -78,8 +98,9 @@ def test_get_reana_jobs_returns_list_with_user_jobs(db, app, users,
7898
db.session.commit()
7999

80100
with app.test_client() as client:
81-
resp = client.get('/reana/jobs/{}'.format(deposit['_deposit']['id']),
82-
headers=auth_headers_for_superuser)
101+
resp = client.get('/reana/jobs/{}'.format(
102+
record['_deposit']['pid']['value']),
103+
headers=auth_headers_for_superuser)
83104

84105
serialized_reana_job = {
85106
'name': 'my_workflow_run',

0 commit comments

Comments
 (0)