Skip to content

Commit

Permalink
Possibility for no authentication (#464)
Browse files Browse the repository at this point in the history
* add a no-auth user
* tests running with right config
* Apply suggestions from code review

Co-authored-by: Carmen Tawalika <mmacata@users.noreply.github.com>
  • Loading branch information
anikaweinmann and mmacata authored Aug 31, 2023
1 parent 5ea0553 commit 5c83d83
Show file tree
Hide file tree
Showing 15 changed files with 535 additions and 34 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ docker
!docker/actinia-core-dev/actinia.cfg
!docker/actinia-core-dev/endpoints.csv
!docker/actinia-core-tests/actinia-test.cfg
!docker/actinia-core-tests/actinia-test-noauth.cfg
.github
.travis
.travis.yml
Expand Down
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# E402 module level import not at top of file
# E501 line too long (80 > 79 characters)
# F401 '.health_check.health_check' imported but unused
# F811 redefinition of unused 'verify_password' from line 55
# F821 undefined name 'QFile'
# W605 invalid escape sequence '\<'

Expand Down Expand Up @@ -30,6 +31,7 @@ per-file-ignores =
./src/actinia_core/core/interim_results.py: W605
./src/actinia_core/core/list_grass_modules.py: F821
./src/actinia_core/testsuite.py: F401
./src/actinia_core/rest/base/user_auth.py: F811
./src/actinia_core/rest/ephemeral_processing.py: W605
./src/actinia_core/processing/actinia_processing/ephemeral_renderer_base/*: E501
./src/actinia_core/processing/actinia_processing/ephemeral_with_export/raster_export.py: E501
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@ docker/redis_queue_data/dump.rdb
!docker/actinia-core-dev/actinia.cfg
!docker/actinia-core-dev/endpoints.csv
!docker/actinia-core-tests/actinia-test.cfg
!docker/actinia-core-tests/actinia-test-noauth.cfg
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@ unittest:
devtest:
sh ./tests_with_redis.sh dev

noauthtest:
sh ./tests_with_redis.sh noauth

integrationtest:
sh ./tests_with_redis.sh integrationtest
1 change: 1 addition & 0 deletions docker/actinia-core-tests/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ RUN grass --tmp-location EPSG:4326 --exec g.extension -s \
# copy needed files and configs for test
COPY docker/actinia-core-alpine/actinia.cfg /etc/default/actinia
COPY docker/actinia-core-tests/actinia-test.cfg /etc/default/actinia_test
COPY docker/actinia-core-tests/actinia-test-noauth.cfg /etc/default/actinia_test_noauth

RUN pip3 install pytest pytest-cov

Expand Down
26 changes: 26 additions & 0 deletions docker/actinia-core-tests/actinia-test-noauth.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[GRASS]
grass_database = /actinia_core/grassdb
grass_user_database = /actinia_core/userdata
grass_tmp_database = /actinia_core/workspace/temp_db
grass_resource_dir = /actinia_core/resources

[API]
force_https_urls = True
authentication = False

[LIMITS]
max_cell_limit = 22500000
process_time_limt = 60
process_num_limit = 20

[REDIS]
worker_logfile = /actinia_core/workspace/tmp/actinia_worker_test.log
redis_server_url = localhost
redis_server_port = 6379

[LOGGING]
log_level = 1

[MISC]
tmp_workdir = /actinia_core/workspace/tmp
download_cache = /actinia_core/workspace/download_cache
20 changes: 1 addition & 19 deletions docker/actinia-core-tests/actinia-test.cfg
Original file line number Diff line number Diff line change
@@ -1,43 +1,25 @@
[GRASS]
grass_gis_start_script = /usr/local/bin/grass
grass_database = /actinia_core/grassdb
grass_user_database = /actinia_core/userdata
grass_tmp_database = /actinia_core/workspace/temp_db
grass_resource_dir = /actinia_core/resources
grass_addon_path = /root/.grass8/addons/
grass_gis_base = /usr/local/grass
grass_modules_xml_path = /usr/local/grass/gui/wxpython/xml/module_items.xml
grass_default_location = nc_spm_08

[API]
plugins = []
force_https_urls = True

[LIMITS]
max_cell_limit = 22500000
process_time_limt = 60
process_num_limit = 20
number_of_workers = 3

[REDIS]
worker_logfile = /actinia_core/workspace/tmp/actinia_worker_test.log
redis_server_url = localhost
redis_server_port = 6379
redis_queue_server_url = localhost
redis_queue_server_port = 6379
worker_queue_name = actinia_job
worker_logfile = /actinia_core/workspace/tmp/actinia_worker_test.log

[LOGGING]
log_interface = fluentd
log_fluent_host = fluentd
log_fluent_port = 24224
log_level = 1

[MISC]
tmp_workdir = /actinia_core/workspace/tmp
download_cache = /actinia_core/workspace/download_cache
secret_key = token_signing_key_changeme

[MANAGEMENT]
default_user = user
default_user_group = group
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,12 @@ API_Docs = "https://redocly.github.io/redoc/?url=https://actinia.mundialis.de/la

[tool.pytest.ini_options]
minversion = "6.0"
addopts = "--cov actinia_core --cov-report term-missing --verbose --tb=line -x"
addopts = "--cov actinia_core --cov-report term-missing --verbose --tb=line -x -s"
testpaths = [
"tests",
]
markers = [
"dev: test current in development",
"unittest: completely independent test",
"noauth: tests for actinia without authentication",
]
11 changes: 7 additions & 4 deletions src/actinia_core/core/common/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# performance processing of geographical data that uses GRASS GIS for
# computational tasks. For details, see https://actinia.mundialis.de/
#
# Copyright (c) 2016-2018 Sören Gebbert and mundialis GmbH & Co. KG
# Copyright (c) 2016-2023 Sören Gebbert and mundialis GmbH & Co. KG
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -116,9 +116,9 @@
from actinia_api import API_VERSION, URL_PREFIX

__license__ = "GPLv3"
__author__ = "Sören Gebbert, Julia Haas"
__author__ = "Sören Gebbert, Julia Haas, Anika Weinmann"
__copyright__ = (
"Copyright 2016-2021, Sören Gebbert and mundialis GmbH & Co. KG"
"Copyright 2016-2023, Sören Gebbert and mundialis GmbH & Co. KG"
)
__maintainer__ = "mundialis"

Expand Down Expand Up @@ -165,11 +165,14 @@
}
}
]
else:
elif global_config.AUTHENTICATION:
# Set the security definition in an unconventional way
flask_api._swagger_object["securityDefinitions"] = {
"basicAuth": {"type": "basic"}
}
flask_api._swagger_object["security"] = [{"basicAuth": []}]

auth = HTTPBasicAuth()
else:
# No authentication
auth = HTTPBasicAuth()
11 changes: 9 additions & 2 deletions src/actinia_core/core/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# performance processing of geographical data that uses GRASS GIS for
# computational tasks. For details, see https://actinia.mundialis.de/
#
# Copyright (c) 2016-2018 Sören Gebbert and mundialis GmbH & Co. KG
# Copyright (c) 2016-2023 Sören Gebbert and mundialis GmbH & Co. KG
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -34,7 +34,7 @@
__license__ = "GPLv3"
__author__ = "Sören Gebbert, Anika Weinmann"
__copyright__ = (
"Copyright 2016-2022, Sören Gebbert and mundialis GmbH & Co. KG"
"Copyright 2016-2023, Sören Gebbert and mundialis GmbH & Co. KG"
)
__maintainer__ = "mundialis GmbH & Co. KG"

Expand Down Expand Up @@ -320,6 +320,8 @@ def __init__(self):
self.PLUGINS = []
# ENDPOINTS_CONFIG: configuration csv file for endpoints
self.ENDPOINTS_CONFIG = None
# AUTHENTICATION: If set False no authentication is needed
self.AUTHENTICATION = True

"""
KEYCLOAK: has only to be set if keycloak server is configured with
Expand Down Expand Up @@ -560,6 +562,7 @@ def write(self, path=DEFAULT_CONFIG_PATH):
config.set("API", "FORCE_HTTPS_URLS", str(self.FORCE_HTTPS_URLS))
config.set("API", "PLUGINS", str(self.PLUGINS))
config.set("API", "ENDPOINTS_CONFIG", str(self.ENDPOINTS_CONFIG))
config.set("API", "AUTHENTICATION", str(self.AUTHENTICATION))

config.add_section("KEYCLOAK")
config.set(
Expand Down Expand Up @@ -810,6 +813,10 @@ def read(self, path=DEFAULT_CONFIG_PATH):
self.ENDPOINTS_CONFIG = config.get(
"API", "ENDPOINTS_CONFIG"
)
if config.has_option("API", "AUTHENTICATION"):
self.AUTHENTICATION = config.getboolean(
"API", "AUTHENTICATION"
)

if config.has_section("KEYCLOAK"):
if config.has_option("KEYCLOAK", "CONFIG_PATH"):
Expand Down
80 changes: 80 additions & 0 deletions src/actinia_core/core/common/user_noauth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
#######
# actinia-core - an open source REST API for scalable, distributed, high
# performance processing of geographical data that uses GRASS GIS for
# computational tasks. For details, see https://actinia.mundialis.de/
#
# Copyright (c) 2023 mundialis GmbH & Co. KG
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
#######

"""
User management for no authentication
"""

# from passlib.apps import custom_app_context as pwd_context
# import jwt
# from datetime import datetime, timezone, timedelta
from actinia_core.core.common.config import global_config
from actinia_core.core.redis_user import redis_user_interface
from actinia_core.core.common.user import ActiniaUser


__author__ = "Anika Weinmann"
__copyright__ = "Copyright 2023, mundialis GmbH & Co. KG"
__maintainer__ = "mundialis GmbH & Co. KG"


class ActiniaUserNoAuth(ActiniaUser):
"""
The Actinia Core user management class for no authentication
"""

db = redis_user_interface

def __init__(self):
"""Constructor
Initialize and create a user object for no authentication.
"""
self.user_id = global_config.DEFAULT_USER
self.user_group = global_config.DEFAULT_USER_GROUP
self.password_hash = None
self.user_role = "superadmin"
self.permissions = None
self.cell_limit = global_config.MAX_CELL_LIMIT
self.accessible_datasets = {
"nc_spm_08": ["PERMANENT", "user1", "landsat"],
"ECAD": ["PERMANENT"],
"latlong_wgs84": ["PERMANENT"],
}
self.accessible_modules = global_config.MODULE_ALLOW_LIST
self.process_num_limit = global_config.PROCESS_NUM_LIMIT
self.process_time_limit = global_config.PROCESS_TIME_LIMT

@staticmethod
def create_user():
"""Create a new user object for no authentication and initialize it
Returns:
actinia_core_api.common.user_noauth.ActiniaUserNoAuth:
A new user object in case of success, or None in case of failure
"""
user = ActiniaUserNoAuth()
user.hash_password("")

if user.commit() is True:
return user
return None
21 changes: 17 additions & 4 deletions src/actinia_core/rest/base/user_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# performance processing of geographical data that uses GRASS GIS for
# computational tasks. For details, see https://actinia.mundialis.de/
#
# Copyright (c) 2016-2018 Sören Gebbert and mundialis GmbH & Co. KG
# Copyright (c) 2016-2023 Sören Gebbert and mundialis GmbH & Co. KG
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -33,16 +33,29 @@
from actinia_core.core.common.app import auth
from actinia_core.core.common.keycloak_user import ActiniaKeycloakUser
from actinia_core.core.common.user import ActiniaUser
from actinia_core.core.common.user_noauth import ActiniaUserNoAuth
from actinia_core.core.messages_logger import MessageLogger

__license__ = "GPLv3"
__author__ = "Sören Gebbert, Julia Haas"
__author__ = "Sören Gebbert, Julia Haas, Anika Weinmann"
__copyright__ = (
"Copyright 2016-2022, Sören Gebbert and mundialis GmbH & Co. KG"
"Copyright 2016-2023, Sören Gebbert and mundialis GmbH & Co. KG"
)
__maintainer__ = "mundialis"


if not global_config.AUTHENTICATION:
# No authentication
@auth.login_required
def login_required(a, b):
return False

@auth.verify_password
def verify_password(username_or_token, password):
g.user = ActiniaUserNoAuth.create_user()
return True


if global_config.KEYCLOAK_CONFIG_PATH:

@auth.verify_token
Expand All @@ -63,7 +76,7 @@ def verify_token(token):
return True


if global_config.KEYCLOAK_CONFIG_PATH is None:
if global_config.KEYCLOAK_CONFIG_PATH is None and global_config.AUTHENTICATION:

@auth.verify_password
def verify_password(username_or_token, password):
Expand Down
1 change: 0 additions & 1 deletion tests/test_common_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ class CommonTestCaseBase(unittest.TestCase):
def setUpClass(cls):
if custom_actinia_cfg is not False:
global_config.read(custom_actinia_cfg)
print(global_config)
else:
global_config.REDIS_SERVER_URL = "localhost"
global_config.REDIS_SERVER_PORT = 7000
Expand Down
Loading

0 comments on commit 5c83d83

Please sign in to comment.