From 2eb82a4fe9c61d699c262d4286d0fcc47afb0510 Mon Sep 17 00:00:00 2001 From: hadleyking Date: Tue, 16 Apr 2024 08:37:05 -0400 Subject: [PATCH] Updated config file to `.secrets` also updated accounts/describe Changes to be committed: modified: .gitignore new file: .secrets.example modified: authentication/selectors.py modified: biocompute/apis.py modified: biocompute/models.py modified: biocompute/selectors.py modified: config/settings.py deleted: server.conf deleted: sever.conf.example --- .gitignore | 5 +- .secrets.example | 14 +++++ authentication/selectors.py | 19 ++----- biocompute/apis.py | 2 +- biocompute/models.py | 2 +- biocompute/selectors.py | 22 ++++++++ config/settings.py | 103 ++++++------------------------------ server.conf | 74 -------------------------- sever.conf.example | 74 -------------------------- 9 files changed, 60 insertions(+), 255 deletions(-) create mode 100644 .secrets.example delete mode 100644 server.conf delete mode 100644 sever.conf.example diff --git a/.gitignore b/.gitignore index 26b09561..6c6c4d42 100755 --- a/.gitignore +++ b/.gitignore @@ -130,11 +130,8 @@ dmypy.json # --- USER-ADDED IGNORES --- # -# The settings file. -config/settings.py - # The server configuration file. -server.conf +.secrets # The migrations folder. # bco_api/api/migrations/ diff --git a/.secrets.example b/.secrets.example new file mode 100644 index 00000000..864ec4bc --- /dev/null +++ b/.secrets.example @@ -0,0 +1,14 @@ +[DJANGO_KEYS] +SECRET_KEY= +ANON_KEY= + +[SERVER] +PRODUCTION= +SERVER_VERSION= +HOSTNAME= +HUMAN_READABLE_HOSTNAME= +PUBLIC_HOSTNAME= +SERVER_URL= +#DATABASE= +DATABASE= +EMAIL_BACKEND= \ No newline at end of file diff --git a/authentication/selectors.py b/authentication/selectors.py index 7904c271..17168d19 100644 --- a/authentication/selectors.py +++ b/authentication/selectors.py @@ -5,7 +5,8 @@ from django.contrib.auth.models import User, Permission from authentication.models import Authentication, NewUser from rest_framework.authtoken.models import Token - +from prefix.selectors import get_user_prefixes +from biocompute.selectors import get_authorized_bcos def get_anon()-> User: """Get AnonymosUser @@ -73,27 +74,15 @@ def get_user_info(user: User) -> dict: other_info = { "permissions": {}, "account_creation": "", - "account_expiration": "", } - user_perms = {"user": [], "groups": []} - - for permission in user.user_permissions.all(): - if permission.name not in user_perms["user"]: - user_perms["user"].append(permission.name) - - for group in user.groups.all(): - if group.name not in user_perms["groups"]: - user_perms["groups"].append(group.name) - for permission in Permission.objects.filter(group=group): - if permission.name not in user_perms["user"]: - user_perms["user"].append(permission.name) + user_perms = {"prefixes": get_user_prefixes(user), "BCOs": get_authorized_bcos(user)} other_info["permissions"] = user_perms other_info["account_creation"] = user.date_joined return { - "hostname": settings.ALLOWED_HOSTS[0], + "hostname": settings.HOSTNAME, "human_readable_hostname": settings.HUMAN_READABLE_HOSTNAME, "public_hostname": settings.PUBLIC_HOSTNAME, "token": token.key, diff --git a/biocompute/apis.py b/biocompute/apis.py index fdfc96a9..5de73c80 100644 --- a/biocompute/apis.py +++ b/biocompute/apis.py @@ -53,7 +53,7 @@ ), "authorized_users": openapi.Schema( type=openapi.TYPE_ARRAY, - description="Users which can access the BCO draft.", + description="Users that can access the BCO draft.", items=openapi.Schema(type=openapi.TYPE_STRING, example="tester") ), "contents": openapi.Schema( diff --git a/biocompute/models.py b/biocompute/models.py index 2948d82a..274b81be 100644 --- a/biocompute/models.py +++ b/biocompute/models.py @@ -30,7 +30,7 @@ class Bco(models.Model): owner = ForeignKey(User) String representing the django.contrib.auth.models.User that 'owns' the object authorized_users: ManyToManyField(User) - String representing the User that has access to the object + String representing the Users that have access to the object prefix: str Prefix for the BCO state:str diff --git a/biocompute/selectors.py b/biocompute/selectors.py index 3a0fe3f8..37519c59 100644 --- a/biocompute/selectors.py +++ b/biocompute/selectors.py @@ -10,6 +10,7 @@ from datetime import datetime from django.conf import settings from django.contrib.auth. models import User +from django.db.models import Q from prefix.selectors import ( user_can_view_prefix, user_can_modify_prefix, @@ -225,6 +226,27 @@ def retrieve_bco(bco_accession:str, user:User, bco_version:str=None) -> bool: return bco_instance +def get_authorized_bcos(user: User): + """ + Retrieve all BioCompute Objects (BCOs) that a specific user is authorized + to access, excluding those in 'DELETE' state. + + Parameters: + - user (User): + The Django User instance for whom to retrieve authorized BCOs. + + Returns: + - QuerySet: + A Django QuerySet containing the BCOs the user is authorized to access. + """ + + bcos = Bco.objects.filter( + Q(owner=user) | Q(authorized_users=user) + ).exclude(state='DELETE').values_list('object_id', flat=True).distinct() + + + return bcos + def object_id_deconstructor(object_id=str) -> list: """ Deconstructs a BioCompute Object (BCO) identifier into its constituent diff --git a/config/settings.py b/config/settings.py index 3831a96c..9df00dd4 100644 --- a/config/settings.py +++ b/config/settings.py @@ -9,80 +9,30 @@ # --- SECURITY SETTINGS --- # # Load the server config file. -server_config = configparser.ConfigParser() -server_config.read(BASE_DIR + "/server.conf") - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ - -# Is this a production server? -PRODUCTION = server_config["PRODUCTION"]["production"] +secrets = configparser.ConfigParser() +secrets.read(BASE_DIR + "/.secrets") +PRODUCTION = secrets["SERVER"]["PRODUCTION"] +DEBUG = PRODUCTION # Set the anonymous user's key. -ANON_KEY = server_config["KEYS"]["anon"] +ANON_KEY = secrets["DJANGO_KEYS"]["ANON_KEY"] # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = "$vz@#@^q(od&$rf&*6^z!m5nh6qw2*cq*j6fha#^h9(r7$xqy4" +SECRET_KEY = secrets["DJANGO_KEYS"]["SECRET_KEY"] # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = PRODUCTION +# The publicly accessible hostname. +HOSTNAME = secrets["SERVER"]["HOSTNAME"] # The human-readable hostname. -HUMAN_READABLE_HOSTNAME = server_config["HRHOSTNAME"]["hrnames"] - -if server_config["GROUP_PREFIX"]["allow_all_creation"] == "True": - GROUP = True - PREFIX = True -elif server_config["GROUP_PREFIX"]["allow_group_creation"] == "True": - GROUP = True -elif server_config["GROUP_PREFIX"]["allow_prefix_creation"] == "True": - PREFIX = True - +HUMAN_READABLE_HOSTNAME = secrets["SERVER"]["HUMAN_READABLE_HOSTNAME"] # The publicly accessible hostname. -if server_config["PRODUCTION"]["production"] == "True": - PUBLIC_HOSTNAME = server_config["PUBLICHOSTNAME"]["prod_name"] -elif server_config["PRODUCTION"]["production"] == "False": - PUBLIC_HOSTNAME = server_config["PUBLICHOSTNAME"]["name"] +PUBLIC_HOSTNAME = secrets["SERVER"]["PUBLIC_HOSTNAME"] +# import pdb; pdb.set_trace() -# Source: https://dzone.com/articles/how-to-fix-django-cors-error -# Check for open (public) access to the API. -if server_config["REQUESTS_FROM"]["public"].strip() == "false": - - # Process the requester groups. - - # configparser automatically strips white space off the - # ends of arguments. - requesters = [ - server_config["REQUESTS_FROM"][i].strip() - for i in server_config["REQUESTS_FROM"] - ] - requesters.remove("false") - requesters = [i.split(",") for i in requesters] - - # Flatten the list. - # Source: https://stackabuse.com/python-how-to-flatten-list-of-lists/ - flattened = [item.strip() for sublist in requesters for item in sublist] - - if server_config["PRODUCTION"]["production"] == "True": - ALLOWED_HOSTS = [ - i.strip() for i in server_config["HOSTNAMES"]["prod_names"].split(",") - ] - elif server_config["PRODUCTION"]["production"] == "False": - ALLOWED_HOSTS = [ - i.strip() for i in server_config["HOSTNAMES"]["names"].split(",") - ] - - CORS_ORIGIN_ALLOW_ALL = False - CORS_ORIGIN_WHITELIST = tuple(flattened) - -elif server_config["REQUESTS_FROM"]["public"].strip() == "true": - if server_config["PRODUCTION"]["production"] == "True": - ALLOWED_HOSTS = [server_config["HOSTNAMES"]["prod_names"].split(",")[0], "*"] - CORS_ORIGIN_ALLOW_ALL = True - elif server_config["PRODUCTION"]["production"] == "False": - ALLOWED_HOSTS = [server_config["HOSTNAMES"]["names"].split(",")[0], "*"] - CORS_ORIGIN_ALLOW_ALL = True +CORS_ORIGIN_ALLOW_ALL = True +CORS_ORIGIN_WHITELIST = ["*"] # Use the REST framework REST_FRAMEWORK = { @@ -94,8 +44,6 @@ ], "DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"], "DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.coreapi.AutoSchema", - - } JWT_AUTH = { @@ -197,7 +145,7 @@ DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", - "NAME": server_config["DATABASES"]["path"], + "NAME": secrets["SERVER"]["DATABASE"], } } @@ -219,8 +167,8 @@ # https://docs.djangoproject.com/en/3.0/howto/static-files/ STATIC_URL = "/api/static/" -# STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] -STATIC_ROOT = "/var/www/bcoeditor/bco_api/bco_api/static/" +STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] +# STATIC_ROOT = "/var/www/bcoeditor/bco_api/bco_api/static/" # ----- CUSTOM VARIABLES AND METHODS ----- # # Load request and validation templates (definitions). @@ -229,26 +177,9 @@ # First, the request definitions. # Make the object naming accessible as a dictionary. -OBJECT_NAMING = {} - -if server_config["PRODUCTION"]["production"] == "True": - - for i in server_config["OBJECT_NAMING"]: - if i.split("_")[0] == "prod": - - # Strip out the production flag. - STRIPPED = "_".join(i.split("_")[1:]) - - OBJECT_NAMING[STRIPPED] = server_config["OBJECT_NAMING"][i] - -elif server_config["PRODUCTION"]["production"] == "False": - - for i in server_config["OBJECT_NAMING"]: - if i.split("_")[0] != "prod": - OBJECT_NAMING[i] = server_config["OBJECT_NAMING"][i] # emailing notifications -EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" +EMAIL_BACKEND = secrets["SERVER"]["EMAIL_BACKEND"] EMAIL_HOST = "localhost" EMAIL_PORT = 25 DEFAULT_AUTO_FIELD = "django.db.models.AutoField" diff --git a/server.conf b/server.conf deleted file mode 100644 index 209f01d2..00000000 --- a/server.conf +++ /dev/null @@ -1,74 +0,0 @@ -# This is the main server configuration file for the BCO API. - -# --- Production and publishing flags --- # -# NOTE: Valid values are True or False (note the capitalization). -[PRODUCTION] -production=False - -# DB Version -[VERSION] -version=23.09 - -# NOTE: Valid values are True or False (note the capitalization). -# Is this a publish-only server? -[PUBLISHONLY] -publishonly=False - -# --- Security settings --- # - -# Create a key for an anonymous public user. -[KEYS] -anon=627626823549f787c3ec763ff687169206626149 - -[DATABASES] -# default settting -path=./db.sqlite3 -# path=/Users/hadleyking/GitHub/biocompute-objects/dev/data/db.sqlite3 - -# Which host names do you want to associate with the server? -# Note: the local hostname (i.e. 127.0.0.1) should come at the end. -[HOSTNAMES] -prod_names=test.portal.biochemistry.gwu.edu,127.0.0.1 -names=127.0.0.1:8000,127.0.0.1 - -# Give the human-readable hostnames -[HRHOSTNAME] -hrnames=BCO Server (Default) - -# The public hostname of the server (i.e. the one to make requests to) -[PUBLICHOSTNAME] -prod_name=https://test.portal.biochemistry.gwu.edu -name=http://127.0.0.1:8000 - -# Who gets to make requests? -[REQUESTS_FROM] -portal=https://test.portal.biochemistry.gwu.edu -local_development_portal=http://127.0.0.1:3000,http://localhost:3000 -public=true - -# --- Namings --- # -# How do you want to name your objects? -[OBJECT_NAMING] -prod_root_uri=https://test.portal.biochemistry.gwu.edu -root_uri=http://127.0.0.1:8000 -prod_uri_regex=root_uri/prefix_(\d+)/(\d+).(\d+) -uri_regex=root_uri/prefix_(\d+)/(\d+).(\d+) - -# --- Requests --- # -# Where are the request templates defined? -[REQUESTS] -folder=../api/request_definitions/ - -# --- Group and Prefix creation --- # -# To enable all users to create a prefix, group creation needs to be enabled. -# When a prefix is created it has assocaited groups created as well. If the -# user does not have permission to creat the needed groups the prefix creation -# will fail. -[GROUP_PREFIX] -allow_all_creation=True -allow_group_creation=True -allow_prefix_creation=True - -# Where are the validation templates defined? -# [VALIDATIONS] -# folder=../api/validation_definitions/ \ No newline at end of file diff --git a/sever.conf.example b/sever.conf.example deleted file mode 100644 index 454a7100..00000000 --- a/sever.conf.example +++ /dev/null @@ -1,74 +0,0 @@ -# This is the main server configuration file for the BCO API. - -# --- Production and publishing flags --- # -# NOTE: Valid values are True or False (note the capitalization). -[PRODUCTION] -production=False - -# DB Version -[VERSION] -version=22.11 - -# NOTE: Valid values are True or False (note the capitalization). -# Is this a publish-only server? -[PUBLISHONLY] -publishonly=False - -# --- Security settings --- # - -# Create a key for an anonymous public user. -[KEYS] -anon=627626823549f787c3ec763ff687169206626149 - -[DATABASES] -# default settting -path=./db.sqlite3 -# path=/Users/hadleyking/GitHub/biocompute-objects/dev/data/db.sqlite3 - -# Which host names do you want to associate with the server? -# Note: the local hostname (i.e. 127.0.0.1) should come at the end. -[HOSTNAMES] -prod_names=test.portal.biochemistry.gwu.edu,127.0.0.1 -names=127.0.0.1:8000,127.0.0.1 - -# Give the human-readable hostnames -[HRHOSTNAME] -hrnames=BCO Server (Default) - -# The public hostname of the server (i.e. the one to make requests to) -[PUBLICHOSTNAME] -prod_name=https://test.portal.biochemistry.gwu.edu -name=http://127.0.0.1:8000 - -# Who gets to make requests? -[REQUESTS_FROM] -portal=https://test.portal.biochemistry.gwu.edu -local_development_portal=http://127.0.0.1:3000,http://localhost:3000 -public=true - -# --- Namings --- # -# How do you want to name your objects? -[OBJECT_NAMING] -prod_root_uri=https://test.portal.biochemistry.gwu.edu -root_uri=http://127.0.0.1:8000 -prod_uri_regex=root_uri/prefix_(\d+)/(\d+).(\d+) -uri_regex=root_uri/prefix_(\d+)/(\d+).(\d+) - -# --- Requests --- # -# Where are the request templates defined? -[REQUESTS] -folder=../api/request_definitions/ - -# --- Group and Prefix creation --- # -# To enable all users to create a prefix, group creation needs to be enabled. -# When a prefix is created it has assocaited groups created as well. If the -# user does not have permission to creat the needed groups the prefix creation -# will fail. -[GROUP_PREFIX] -allow_all_creation=True -allow_group_creation=True -allow_prefix_creation=True - -# Where are the validation templates defined? -# [VALIDATIONS] -# folder=../api/validation_definitions/ \ No newline at end of file