Skip to content

Commit 5c83d83

Browse files
Possibility for no authentication (#464)
* 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>
1 parent 5ea0553 commit 5c83d83

15 files changed

+535
-34
lines changed

.dockerignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ docker
55
!docker/actinia-core-dev/actinia.cfg
66
!docker/actinia-core-dev/endpoints.csv
77
!docker/actinia-core-tests/actinia-test.cfg
8+
!docker/actinia-core-tests/actinia-test-noauth.cfg
89
.github
910
.travis
1011
.travis.yml

.flake8

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# E402 module level import not at top of file
44
# E501 line too long (80 > 79 characters)
55
# F401 '.health_check.health_check' imported but unused
6+
# F811 redefinition of unused 'verify_password' from line 55
67
# F821 undefined name 'QFile'
78
# W605 invalid escape sequence '\<'
89

@@ -30,6 +31,7 @@ per-file-ignores =
3031
./src/actinia_core/core/interim_results.py: W605
3132
./src/actinia_core/core/list_grass_modules.py: F821
3233
./src/actinia_core/testsuite.py: F401
34+
./src/actinia_core/rest/base/user_auth.py: F811
3335
./src/actinia_core/rest/ephemeral_processing.py: W605
3436
./src/actinia_core/processing/actinia_processing/ephemeral_renderer_base/*: E501
3537
./src/actinia_core/processing/actinia_processing/ephemeral_with_export/raster_export.py: E501

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ docker/redis_queue_data/dump.rdb
5252
!docker/actinia-core-dev/actinia.cfg
5353
!docker/actinia-core-dev/endpoints.csv
5454
!docker/actinia-core-tests/actinia-test.cfg
55+
!docker/actinia-core-tests/actinia-test-noauth.cfg

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@ unittest:
1818
devtest:
1919
sh ./tests_with_redis.sh dev
2020

21+
noauthtest:
22+
sh ./tests_with_redis.sh noauth
23+
2124
integrationtest:
2225
sh ./tests_with_redis.sh integrationtest

docker/actinia-core-tests/Dockerfile

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ RUN grass --tmp-location EPSG:4326 --exec g.extension -s \
4040
# copy needed files and configs for test
4141
COPY docker/actinia-core-alpine/actinia.cfg /etc/default/actinia
4242
COPY docker/actinia-core-tests/actinia-test.cfg /etc/default/actinia_test
43+
COPY docker/actinia-core-tests/actinia-test-noauth.cfg /etc/default/actinia_test_noauth
4344

4445
RUN pip3 install pytest pytest-cov
4546

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[GRASS]
2+
grass_database = /actinia_core/grassdb
3+
grass_user_database = /actinia_core/userdata
4+
grass_tmp_database = /actinia_core/workspace/temp_db
5+
grass_resource_dir = /actinia_core/resources
6+
7+
[API]
8+
force_https_urls = True
9+
authentication = False
10+
11+
[LIMITS]
12+
max_cell_limit = 22500000
13+
process_time_limt = 60
14+
process_num_limit = 20
15+
16+
[REDIS]
17+
worker_logfile = /actinia_core/workspace/tmp/actinia_worker_test.log
18+
redis_server_url = localhost
19+
redis_server_port = 6379
20+
21+
[LOGGING]
22+
log_level = 1
23+
24+
[MISC]
25+
tmp_workdir = /actinia_core/workspace/tmp
26+
download_cache = /actinia_core/workspace/download_cache
+1-19
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,25 @@
11
[GRASS]
2-
grass_gis_start_script = /usr/local/bin/grass
32
grass_database = /actinia_core/grassdb
43
grass_user_database = /actinia_core/userdata
54
grass_tmp_database = /actinia_core/workspace/temp_db
65
grass_resource_dir = /actinia_core/resources
7-
grass_addon_path = /root/.grass8/addons/
8-
grass_gis_base = /usr/local/grass
9-
grass_modules_xml_path = /usr/local/grass/gui/wxpython/xml/module_items.xml
10-
grass_default_location = nc_spm_08
116

127
[API]
13-
plugins = []
148
force_https_urls = True
159

1610
[LIMITS]
1711
max_cell_limit = 22500000
1812
process_time_limt = 60
1913
process_num_limit = 20
20-
number_of_workers = 3
2114

2215
[REDIS]
16+
worker_logfile = /actinia_core/workspace/tmp/actinia_worker_test.log
2317
redis_server_url = localhost
2418
redis_server_port = 6379
25-
redis_queue_server_url = localhost
26-
redis_queue_server_port = 6379
27-
worker_queue_name = actinia_job
28-
worker_logfile = /actinia_core/workspace/tmp/actinia_worker_test.log
2919

3020
[LOGGING]
31-
log_interface = fluentd
32-
log_fluent_host = fluentd
33-
log_fluent_port = 24224
3421
log_level = 1
3522

3623
[MISC]
3724
tmp_workdir = /actinia_core/workspace/tmp
3825
download_cache = /actinia_core/workspace/download_cache
39-
secret_key = token_signing_key_changeme
40-
41-
[MANAGEMENT]
42-
default_user = user
43-
default_user_group = group

pyproject.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,12 @@ API_Docs = "https://redocly.github.io/redoc/?url=https://actinia.mundialis.de/la
9898

9999
[tool.pytest.ini_options]
100100
minversion = "6.0"
101-
addopts = "--cov actinia_core --cov-report term-missing --verbose --tb=line -x"
101+
addopts = "--cov actinia_core --cov-report term-missing --verbose --tb=line -x -s"
102102
testpaths = [
103103
"tests",
104104
]
105105
markers = [
106106
"dev: test current in development",
107107
"unittest: completely independent test",
108+
"noauth: tests for actinia without authentication",
108109
]

src/actinia_core/core/common/app.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# performance processing of geographical data that uses GRASS GIS for
55
# computational tasks. For details, see https://actinia.mundialis.de/
66
#
7-
# Copyright (c) 2016-2018 Sören Gebbert and mundialis GmbH & Co. KG
7+
# Copyright (c) 2016-2023 Sören Gebbert and mundialis GmbH & Co. KG
88
#
99
# This program is free software: you can redistribute it and/or modify
1010
# it under the terms of the GNU General Public License as published by
@@ -116,9 +116,9 @@
116116
from actinia_api import API_VERSION, URL_PREFIX
117117

118118
__license__ = "GPLv3"
119-
__author__ = "Sören Gebbert, Julia Haas"
119+
__author__ = "Sören Gebbert, Julia Haas, Anika Weinmann"
120120
__copyright__ = (
121-
"Copyright 2016-2021, Sören Gebbert and mundialis GmbH & Co. KG"
121+
"Copyright 2016-2023, Sören Gebbert and mundialis GmbH & Co. KG"
122122
)
123123
__maintainer__ = "mundialis"
124124

@@ -165,11 +165,14 @@
165165
}
166166
}
167167
]
168-
else:
168+
elif global_config.AUTHENTICATION:
169169
# Set the security definition in an unconventional way
170170
flask_api._swagger_object["securityDefinitions"] = {
171171
"basicAuth": {"type": "basic"}
172172
}
173173
flask_api._swagger_object["security"] = [{"basicAuth": []}]
174174

175175
auth = HTTPBasicAuth()
176+
else:
177+
# No authentication
178+
auth = HTTPBasicAuth()

src/actinia_core/core/common/config.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# performance processing of geographical data that uses GRASS GIS for
55
# computational tasks. For details, see https://actinia.mundialis.de/
66
#
7-
# Copyright (c) 2016-2018 Sören Gebbert and mundialis GmbH & Co. KG
7+
# Copyright (c) 2016-2023 Sören Gebbert and mundialis GmbH & Co. KG
88
#
99
# This program is free software: you can redistribute it and/or modify
1010
# it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@
3434
__license__ = "GPLv3"
3535
__author__ = "Sören Gebbert, Anika Weinmann"
3636
__copyright__ = (
37-
"Copyright 2016-2022, Sören Gebbert and mundialis GmbH & Co. KG"
37+
"Copyright 2016-2023, Sören Gebbert and mundialis GmbH & Co. KG"
3838
)
3939
__maintainer__ = "mundialis GmbH & Co. KG"
4040

@@ -320,6 +320,8 @@ def __init__(self):
320320
self.PLUGINS = []
321321
# ENDPOINTS_CONFIG: configuration csv file for endpoints
322322
self.ENDPOINTS_CONFIG = None
323+
# AUTHENTICATION: If set False no authentication is needed
324+
self.AUTHENTICATION = True
323325

324326
"""
325327
KEYCLOAK: has only to be set if keycloak server is configured with
@@ -560,6 +562,7 @@ def write(self, path=DEFAULT_CONFIG_PATH):
560562
config.set("API", "FORCE_HTTPS_URLS", str(self.FORCE_HTTPS_URLS))
561563
config.set("API", "PLUGINS", str(self.PLUGINS))
562564
config.set("API", "ENDPOINTS_CONFIG", str(self.ENDPOINTS_CONFIG))
565+
config.set("API", "AUTHENTICATION", str(self.AUTHENTICATION))
563566

564567
config.add_section("KEYCLOAK")
565568
config.set(
@@ -810,6 +813,10 @@ def read(self, path=DEFAULT_CONFIG_PATH):
810813
self.ENDPOINTS_CONFIG = config.get(
811814
"API", "ENDPOINTS_CONFIG"
812815
)
816+
if config.has_option("API", "AUTHENTICATION"):
817+
self.AUTHENTICATION = config.getboolean(
818+
"API", "AUTHENTICATION"
819+
)
813820

814821
if config.has_section("KEYCLOAK"):
815822
if config.has_option("KEYCLOAK", "CONFIG_PATH"):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# -*- coding: utf-8 -*-
2+
#######
3+
# actinia-core - an open source REST API for scalable, distributed, high
4+
# performance processing of geographical data that uses GRASS GIS for
5+
# computational tasks. For details, see https://actinia.mundialis.de/
6+
#
7+
# Copyright (c) 2023 mundialis GmbH & Co. KG
8+
#
9+
# This program is free software: you can redistribute it and/or modify
10+
# it under the terms of the GNU General Public License as published by
11+
# the Free Software Foundation, either version 3 of the License, or
12+
# (at your option) any later version.
13+
#
14+
# This program is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
# GNU General Public License for more details.
18+
#
19+
# You should have received a copy of the GNU General Public License
20+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
#
22+
#######
23+
24+
"""
25+
User management for no authentication
26+
"""
27+
28+
# from passlib.apps import custom_app_context as pwd_context
29+
# import jwt
30+
# from datetime import datetime, timezone, timedelta
31+
from actinia_core.core.common.config import global_config
32+
from actinia_core.core.redis_user import redis_user_interface
33+
from actinia_core.core.common.user import ActiniaUser
34+
35+
36+
__author__ = "Anika Weinmann"
37+
__copyright__ = "Copyright 2023, mundialis GmbH & Co. KG"
38+
__maintainer__ = "mundialis GmbH & Co. KG"
39+
40+
41+
class ActiniaUserNoAuth(ActiniaUser):
42+
"""
43+
The Actinia Core user management class for no authentication
44+
"""
45+
46+
db = redis_user_interface
47+
48+
def __init__(self):
49+
"""Constructor
50+
Initialize and create a user object for no authentication.
51+
"""
52+
self.user_id = global_config.DEFAULT_USER
53+
self.user_group = global_config.DEFAULT_USER_GROUP
54+
self.password_hash = None
55+
self.user_role = "superadmin"
56+
self.permissions = None
57+
self.cell_limit = global_config.MAX_CELL_LIMIT
58+
self.accessible_datasets = {
59+
"nc_spm_08": ["PERMANENT", "user1", "landsat"],
60+
"ECAD": ["PERMANENT"],
61+
"latlong_wgs84": ["PERMANENT"],
62+
}
63+
self.accessible_modules = global_config.MODULE_ALLOW_LIST
64+
self.process_num_limit = global_config.PROCESS_NUM_LIMIT
65+
self.process_time_limit = global_config.PROCESS_TIME_LIMT
66+
67+
@staticmethod
68+
def create_user():
69+
"""Create a new user object for no authentication and initialize it
70+
71+
Returns:
72+
actinia_core_api.common.user_noauth.ActiniaUserNoAuth:
73+
A new user object in case of success, or None in case of failure
74+
"""
75+
user = ActiniaUserNoAuth()
76+
user.hash_password("")
77+
78+
if user.commit() is True:
79+
return user
80+
return None

src/actinia_core/rest/base/user_auth.py

+17-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# performance processing of geographical data that uses GRASS GIS for
66
# computational tasks. For details, see https://actinia.mundialis.de/
77
#
8-
# Copyright (c) 2016-2018 Sören Gebbert and mundialis GmbH & Co. KG
8+
# Copyright (c) 2016-2023 Sören Gebbert and mundialis GmbH & Co. KG
99
#
1010
# This program is free software: you can redistribute it and/or modify
1111
# it under the terms of the GNU General Public License as published by
@@ -33,16 +33,29 @@
3333
from actinia_core.core.common.app import auth
3434
from actinia_core.core.common.keycloak_user import ActiniaKeycloakUser
3535
from actinia_core.core.common.user import ActiniaUser
36+
from actinia_core.core.common.user_noauth import ActiniaUserNoAuth
3637
from actinia_core.core.messages_logger import MessageLogger
3738

3839
__license__ = "GPLv3"
39-
__author__ = "Sören Gebbert, Julia Haas"
40+
__author__ = "Sören Gebbert, Julia Haas, Anika Weinmann"
4041
__copyright__ = (
41-
"Copyright 2016-2022, Sören Gebbert and mundialis GmbH & Co. KG"
42+
"Copyright 2016-2023, Sören Gebbert and mundialis GmbH & Co. KG"
4243
)
4344
__maintainer__ = "mundialis"
4445

4546

47+
if not global_config.AUTHENTICATION:
48+
# No authentication
49+
@auth.login_required
50+
def login_required(a, b):
51+
return False
52+
53+
@auth.verify_password
54+
def verify_password(username_or_token, password):
55+
g.user = ActiniaUserNoAuth.create_user()
56+
return True
57+
58+
4659
if global_config.KEYCLOAK_CONFIG_PATH:
4760

4861
@auth.verify_token
@@ -63,7 +76,7 @@ def verify_token(token):
6376
return True
6477

6578

66-
if global_config.KEYCLOAK_CONFIG_PATH is None:
79+
if global_config.KEYCLOAK_CONFIG_PATH is None and global_config.AUTHENTICATION:
6780

6881
@auth.verify_password
6982
def verify_password(username_or_token, password):

tests/test_common_base.py

-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ class CommonTestCaseBase(unittest.TestCase):
103103
def setUpClass(cls):
104104
if custom_actinia_cfg is not False:
105105
global_config.read(custom_actinia_cfg)
106-
print(global_config)
107106
else:
108107
global_config.REDIS_SERVER_URL = "localhost"
109108
global_config.REDIS_SERVER_PORT = 7000

0 commit comments

Comments
 (0)