diff --git a/gui/src/components/api.js b/gui/src/components/api.js index ef2d589b0a4cf7085e3fd2737a630dedee182121..bf0576d1e4b454c00749edcbe5237ccb55426847 100644 --- a/gui/src/components/api.js +++ b/gui/src/components/api.js @@ -192,13 +192,8 @@ class Api { this.onStartLoading = () => null this.onFinishLoading = () => null + this._swaggerClient = Swagger(`${apiBase}/swagger.json`) this.keycloak = keycloak - this.isLoggedIn = true && user - user = user || {} - this.auth_headers = { - 'X-Token': user.token - } - this.swaggerPromise = Api.createSwaggerClient(user.token).catch(handleApiError) // keep a list of localUploads, these are uploads that are currently uploaded through // the browser and that therefore not yet returned by the backend diff --git a/nomad/app/api/admin.py b/nomad/app/api/admin.py index c1254f1b11552204b489b3df32c3a67c6d9bed29..807a70ddbe09343279069b14f050cabe3fce9dec 100644 --- a/nomad/app/api/admin.py +++ b/nomad/app/api/admin.py @@ -12,13 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from flask import request -from flask_restplus import abort, Resource, fields +from flask_restplus import abort, Resource from nomad import infrastructure, config from .api import api -from .auth import admin_login_required +from .auth import authenticate ns = api.namespace('admin', description='Administrative operations') @@ -29,7 +28,7 @@ class AdminResetResource(Resource): @api.doc('exec_reset_command') @api.response(200, 'Reset performed') @api.response(400, 'Reset not available/disabled') - @admin_login_required + @authenticate(admin_only=True) def post(self): """ The ``reset`` command will attempt to clear the contents of all databased and @@ -40,7 +39,7 @@ class AdminResetResource(Resource): if config.services.disable_reset: abort(400, message='Operation is disabled') - infrastructure.reset(repo_content_only=True) + infrastructure.reset() return dict(messager='Reset performed.'), 200 @@ -50,7 +49,7 @@ class AdminRemoveResource(Resource): @api.doc('exec_remove_command') @api.response(200, 'Remove performed') @api.response(400, 'Remove not available/disabled') - @admin_login_required + @authenticate(admin_only=True) def post(self): """ The ``remove``command will attempt to remove all databases. Expect the @@ -65,28 +64,3 @@ class AdminRemoveResource(Resource): infrastructure.remove() return dict(messager='Remove performed.'), 200 - - -pidprefix_model = api.model('PidPrefix', { - 'prefix': fields.Integer(description='The prefix. All new calculations will get an id that is greater.', required=True) -}) - - -# TODO remove after migration -@ns.route('/pidprefix') -class AdminPidPrefixResource(Resource): - @api.doc('exec_pidprefix_command') - @api.response(200, 'Pid prefix set') - @api.response(400, 'Bad pid prefix data') - @api.expect(pidprefix_model) - @admin_login_required - def post(self): - """ - The ``pidprefix``command will set the pid counter to the given value. - - This might be useful while migrating data with old pids. - """ - - infrastructure.set_pid_prefix(**request.get_json()) - - return dict(messager='PID prefix set.'), 200 diff --git a/nomad/app/api/auth.py b/nomad/app/api/auth.py index ab04a6809bc40ea6f893d2e975b30455da4c9c14..533faca1d3634f1ee60b522cb960baff30282279 100644 --- a/nomad/app/api/auth.py +++ b/nomad/app/api/auth.py @@ -41,7 +41,7 @@ import uuid from nomad import config, processing, utils, infrastructure, datamodel -from .app import api +from .api import api # Authentication scheme definitions, for swagger diff --git a/nomad/app/api/repo.py b/nomad/app/api/repo.py index 22d1904caafe2f093219c6dabfb0a9255832814c..95a64bb35e7ce1483d963ed5b253b2ab412196e4 100644 --- a/nomad/app/api/repo.py +++ b/nomad/app/api/repo.py @@ -26,7 +26,7 @@ from nomad import search, utils, datamodel from nomad.app.utils import rfc3339DateTime from nomad.app.optimade import filterparser -from .api import api, rfc3339DateTime +from .api import api from .auth import authenticate from .common import pagination_model, pagination_request_parser, calc_route @@ -357,7 +357,7 @@ class RepoPidResource(Resource): @api.doc('resolve_pid') @api.response(404, 'Entry with PID does not exist') @api.marshal_with(repo_calc_id_model, skip_none=True, code=200, description='Entry resolved') - @login_if_available + @authenticate() def get(self, pid: int): search_request = search.SearchRequest() diff --git a/nomad/cli/admin/admin.py b/nomad/cli/admin/admin.py index 41822409f824b99cdcf68d6d59b7b99056c60bb7..8eb5d12c7bb838fe36ea22d451a9818e0594636f 100644 --- a/nomad/cli/admin/admin.py +++ b/nomad/cli/admin/admin.py @@ -15,7 +15,6 @@ import click import datetime import elasticsearch.helpers -import json from nomad import processing as proc, search, datamodel, infrastructure, utils, config diff --git a/nomad/infrastructure.py b/nomad/infrastructure.py index 92c6c007ca38adc1b0aaae24d7f5e7d22c9642f6..151b4058da3142bb98026fe8ad4de7ee9dcbc59c 100644 --- a/nomad/infrastructure.py +++ b/nomad/infrastructure.py @@ -278,10 +278,11 @@ class Keycloak(): user_id = user.user_id if email is not None and user_id is None: - try: + with utils.lnr(logger, 'Could not use keycloak admin client'): user_id = self._admin_client.get_user_id(email) - except Exception: - raise KeyError('User does not exist') + + if user_id is None: + raise KeyError('User %s does not exist' % email) assert user_id is not None, 'Could not determine user from given kwargs' diff --git a/nomad/search.py b/nomad/search.py index e60804a2867543203f9a95e7bae692214cd98eb1..9a85add85b111602c668292dcfcf553e7c297163 100644 --- a/nomad/search.py +++ b/nomad/search.py @@ -286,7 +286,7 @@ class SearchRequest: raise ValueError('Authentication required for owner value user') q = Q('term', published=False) & Q('term', owners__user_id=user_id) elif owner_type == 'admin': - if user_id is None or not coe_repo.User.from_user_id(user_id).is_admin: + if user_id is None or not datamodel.User.get(user_id=user_id).is_admin: raise ValueError('This can only be used by the admin user.') q = None else: diff --git a/tests/app/test_api.py b/tests/app/test_api.py index 6d933dbad728de85d52c6da60dc9bf34c1d65ab5..83c39206c1628dddde45899cf2507a0a8c9c59e2 100644 --- a/tests/app/test_api.py +++ b/tests/app/test_api.py @@ -25,7 +25,7 @@ from urllib.parse import urlencode import base64 from nomad.app.utils import rfc3339DateTime -from nomad.app.auth import generate_upload_token +from nomad.app.api.auth import generate_upload_token from nomad import search, parsing, files, config, utils, infrastructure from nomad.files import UploadFiles, PublicUploadFiles from nomad.processing import Upload, Calc, SUCCESS @@ -196,7 +196,7 @@ class TestUploads: assert upload['process_running'] additional_keys = ['with_embargo'] - if publish_with_metadata and 'external_id' in metadata: + if 'external_id' in metadata: additional_keys.append('external_id') self.block_until_completed(api, upload_id, test_user_auth) @@ -597,18 +597,21 @@ class TestRepo(): search.Entry.from_calc_with_metadata(calc_with_metadata).save(refresh=True) calc_with_metadata.update( - calc_id='2', uploader=other_test_user.user_id, published=True, with_embargo=False, - upload_time=today - datetime.timedelta(days=5)) + calc_id='2', uploader=other_test_user.user_id, published=True, + with_embargo=False, pid=2, upload_time=today - datetime.timedelta(days=5), + external_id='external_id') calc_with_metadata.update( atoms=['Fe'], comment='this is a specific word', formula='AAA', basis_set='zzz') search.Entry.from_calc_with_metadata(calc_with_metadata).save(refresh=True) calc_with_metadata.update( - calc_id='3', uploader=other_test_user.user_id, published=False, with_embargo=False) + calc_id='3', uploader=other_test_user.user_id, published=False, + with_embargo=False, pid=3, external_id='external_id') search.Entry.from_calc_with_metadata(calc_with_metadata).save(refresh=True) calc_with_metadata.update( - calc_id='4', uploader=other_test_user.user_id, published=True, with_embargo=True) + calc_id='4', uploader=other_test_user.user_id, published=True, + with_embargo=True, pid=4, external_id='external_id') search.Entry.from_calc_with_metadata(calc_with_metadata).save(refresh=True) def assert_search(self, rv: Any, number_of_calcs: int) -> dict: diff --git a/tests/test_search.py b/tests/test_search.py index 1ddfd26a6c0872de502070cfa990c07883aee3fe..7d310d6b96391191c2d4bbdf828ede3e2b410daf 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -16,7 +16,7 @@ from typing import List from elasticsearch_dsl import Q import pytest -from nomad import datamodel, search, processing, parsing, infrastructure, config, coe_repo +from nomad import datamodel, search, processing, parsing, infrastructure, config from nomad.search import Entry, SearchRequest @@ -137,7 +137,7 @@ def test_search_totals(elastic, example_search_data): assert 'quantities' not in results -def test_search_quantity(elastic, normalized: parsing.LocalBackend, test_user: coe_repo.User, other_test_user: coe_repo.User): +def test_search_quantity(elastic, normalized: parsing.LocalBackend, test_user: datamodel.User, other_test_user: datamodel.User): calc_with_metadata = datamodel.CalcWithMetadata(upload_id='test upload id', calc_id='test id') calc_with_metadata.apply_domain_metadata(normalized) calc_with_metadata.uploader = test_user.user_id