diff --git a/CHANGELOG.md b/CHANGELOG.md index e05ca7498..df4c090c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to SODA will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## v.12.4.2 - 2023-12-21 + +## Bug fixes: + +- Fixed Pennsieve login bug for accounts with Emails containing periods. + ## v.12.4.1 - 2023-12-19 ## Feature Additions: diff --git a/package-lock.json b/package-lock.json index 45a4982f7..2006ddb36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "soda-for-sparc", - "version": "12.4.1", + "version": "12.4.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "soda-for-sparc", - "version": "12.4.1", + "version": "12.4.2", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index f857605a8..fc815de18 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "soda-for-sparc", "productName": "SODA for SPARC", - "version": "12.4.1", + "version": "12.4.2", "description": "Keep Calm and Curate ", "main": "main.js", "scripts": { diff --git a/pyflask/authentication/authenticate.py b/pyflask/authentication/authenticate.py index a154a2362..27bbd7676 100644 --- a/pyflask/authentication/authenticate.py +++ b/pyflask/authentication/authenticate.py @@ -2,6 +2,7 @@ import requests from os.path import expanduser, join, exists from configparser import ConfigParser +from configUtils import format_agent_profile_name from flask import abort from os import mkdir import time @@ -139,7 +140,6 @@ def bf_delete_default_profile(): if "global" not in config: return - default_profile_name = config["global"]["default_profile"] config.remove_section("global") with open(configpath, "w") as configfile: @@ -179,7 +179,7 @@ def create_unique_profile_name(token, email, account_name): organization = org["organization"]["name"] # create an updated profile name that is unqiue to the user and their workspace - return f"{account_name}-{email_sub}-{organization}" + return format_agent_profile_name(f"{account_name}-{email_sub}-{organization}") except Exception as e: raise e @@ -197,16 +197,11 @@ def bf_add_account_username(keyname, key, secret): """ global namespace_logger - temp_keyname = "SODA_temp_generated" - # first delete the pre-existing default_profile entry , but not the profile itself - - # lowercase the key name - keyname = keyname.lower() + # format the keyname to lowercase and replace '.' with '_' + formatted_account_name = format_agent_profile_name(keyname) bf_delete_default_profile() try: - keyname = keyname.strip() - bfpath = join(userpath, ".pennsieve") # Load existing or create new config file config = ConfigParser() @@ -223,23 +218,18 @@ def bf_add_account_username(keyname, key, secret): config.set(agentkey, "upload_workers", "10") config.set(agentkey, "upload_chunk_size", "32") - - # ensure that if the profile already exists it has an api_host entry - # if config.has_section(keyname): - # config.set(keyname, "api_host", PENNSIEVE_URL) - # Add new account if it does not already exist - if not config.has_section(keyname): - config.add_section(keyname) + namespace_logger.info(f"Adding account {formatted_account_name} to config file") + if not config.has_section(formatted_account_name): + config.add_section(formatted_account_name) - config.set(keyname, "api_token", key) - config.set(keyname, "api_secret", secret) - # config.set(keyname, "api_host", PENNSIEVE_URL) + config.set(formatted_account_name, "api_token", key) + config.set(formatted_account_name, "api_secret", secret) # set profile name in global section if not config.has_section("global"): config.add_section("global") - config.set("global", "default_profile", keyname) + config.set("global", "default_profile", formatted_account_name) with open(configpath, "w") as configfile: @@ -253,7 +243,7 @@ def bf_add_account_username(keyname, key, secret): token = get_access_token() except Exception as e: namespace_logger.error(e) - bf_delete_account(keyname) + bf_delete_account(formatted_account_name) abort(401, "Please check that key name, key, and secret are entered properly" ) @@ -268,7 +258,7 @@ def bf_add_account_username(keyname, key, secret): with open(configpath, "w+") as configfile: config.write(configfile) - return {"message": f"Successfully added account {keyname}"} + return {"message": f"Successfully added account {formatted_account_name}"} except Exception as e: bf_delete_account(keyname) diff --git a/pyflask/configUtils/__init__.py b/pyflask/configUtils/__init__.py index d9fe0145a..041b5d942 100644 --- a/pyflask/configUtils/__init__.py +++ b/pyflask/configUtils/__init__.py @@ -1 +1 @@ -from .config import add_api_host_to_config, lowercase_account_names \ No newline at end of file +from .config import add_api_host_to_config, lowercase_account_names, format_agent_profile_name \ No newline at end of file diff --git a/pyflask/configUtils/config.py b/pyflask/configUtils/config.py index f8c7ffa7f..fbdc3f572 100644 --- a/pyflask/configUtils/config.py +++ b/pyflask/configUtils/config.py @@ -3,6 +3,7 @@ """ from constants import PENNSIEVE_URL + def add_api_host_to_config(configparser, target_section_name, configpath): """ Args: @@ -26,6 +27,18 @@ def add_api_host_to_config(configparser, target_section_name, configpath): +def format_agent_profile_name(profile_name): + """ + Args: + profile_name: the profile name to format + Returns: + The formatted profile name + Notes: + We replace the '.' with '_' because the config parser on the Node side does not like '.' in the profile name. + """ + return profile_name.lower().replace('.', '_').strip() + + def lowercase_account_names(config, account_name, configpath): """ Args: @@ -34,19 +47,20 @@ def lowercase_account_names(config, account_name, configpath): Action: Converts the account name and global default_profile value to lowercase and updates the config file. """ + formatted_account_name = format_agent_profile_name(account_name) # if the section exists lowercased do nothing - if config.has_section(account_name.lower()): + if config.has_section(formatted_account_name): return # add the section back with the lowercase account name - config.add_section(account_name.lower()) - config.set(account_name.lower(), "api_token", config.get(account_name, "api_token")) - config.set(account_name.lower(), "api_secret", config.get(account_name, "api_secret")) + config.add_section(formatted_account_name) + config.set(formatted_account_name, "api_token", config.get(formatted_account_name, "api_token")) + config.set(formatted_account_name, "api_secret", config.get(formatted_account_name, "api_secret")) # set the global default_profile option to lowercase - config.set("global", "default_profile", account_name.lower()) + config.set("global", "default_profile", formatted_account_name) - # remove the existing section + # remove the unformatted account name config.remove_section(account_name) # finalize the changes diff --git a/pyflask/manageDatasets/manage_datasets.py b/pyflask/manageDatasets/manage_datasets.py index 4ac92711d..be572b484 100644 --- a/pyflask/manageDatasets/manage_datasets.py +++ b/pyflask/manageDatasets/manage_datasets.py @@ -32,7 +32,7 @@ from authentication import get_access_token, bf_delete_account from users import get_user_information, update_config_account_name from permissions import has_edit_permissions, pennsieve_get_current_user_permissions -from configUtils import lowercase_account_names +from configUtils import lowercase_account_names, format_agent_profile_name from constants import PENNSIEVE_URL from pysodaUtils import ( check_forbidden_characters_ps, @@ -125,11 +125,11 @@ def bf_add_account_api_key(keyname, key, secret): Adds account to the Pennsieve configuration file (local machine) """ try: - keyname = keyname.strip() - if (not keyname) or (not key) or (not secret): + formatted_key_name = format_agent_profile_name(keyname) + if (not formatted_key_name) or (not key) or (not secret): abort(401, "Please enter valid keyname, key, and/or secret") - if (keyname.isspace()) or (key.isspace()) or (secret.isspace()): + if (formatted_key_name.isspace()) or (key.isspace()) or (secret.isspace()): abort(401, "Please enter valid keyname, key, and/or secret") ps_path = join(userpath, ".pennsieve") @@ -137,7 +137,7 @@ def bf_add_account_api_key(keyname, key, secret): config = ConfigParser() if exists(configpath): config.read(configpath) - if config.has_section(keyname): + if config.has_section(formatted_key_name): abort(400, "Key name already exists") else: if not exists(ps_path): @@ -154,14 +154,14 @@ def bf_add_account_api_key(keyname, key, secret): config.set(agentkey, "upload_chunk_size", "32") # Add new account - config.add_section(keyname) - config.set(keyname, "api_token", key) - config.set(keyname, "api_secret", secret) + config.add_section(formatted_key_name) + config.set(formatted_key_name, "api_token", key) + config.set(formatted_key_name, "api_secret", secret) if not config.has_section("global"): config.add_section("global") - config.set("global", "default_profile", keyname) + config.set("global", "default_profile", formatted_key_name) with open(configpath, "w") as configfile: config.write(configfile) @@ -174,7 +174,7 @@ def bf_add_account_api_key(keyname, key, secret): token = get_access_token() except Exception as e: namespace_logger.error(e) - bf_delete_account(keyname) + bf_delete_account(formatted_key_name) abort(401, "Please check that key name, key, and secret are entered properly" ) @@ -195,7 +195,7 @@ def bf_add_account_api_key(keyname, key, secret): config.add_section("global") default_acc = config["global"] - default_acc["default_profile"] = keyname + default_acc["default_profile"] = formatted_key_name with open(configpath, "w") as configfile: config.write(configfile) @@ -203,7 +203,7 @@ def bf_add_account_api_key(keyname, key, secret): return {"message": f"Successfully added account {str(bf)}"} except Exception as e: - bf_delete_account(keyname) + bf_delete_account(formatted_key_name) raise e def check_forbidden_characters_ps(my_string): @@ -279,7 +279,7 @@ def bf_get_accounts(): lowercase_account_names(config, default_profile, configpath) try: get_access_token() - return default_profile.lower() + return format_agent_profile_name(default_profile) except Exception as e: print(e) else: @@ -300,7 +300,7 @@ def bf_get_accounts(): lowercase_account_names(config, account, configpath) - return account.lower() + return format_agent_profile_name(account) return "" diff --git a/pyflask/startup/minimumApiVersion.py b/pyflask/startup/minimumApiVersion.py index 1a603342d..cc3c27aae 100644 --- a/pyflask/startup/minimumApiVersion.py +++ b/pyflask/startup/minimumApiVersion.py @@ -4,4 +4,4 @@ def get_api_version(): """ Returns the version of the API """ - return {'version': os.getenv('API_VERSION', "12.4.1")} + return {'version': os.getenv('API_VERSION', "12.4.2")} diff --git a/pyflask/users/user.py b/pyflask/users/user.py index e9b4e10bd..f19b14263 100644 --- a/pyflask/users/user.py +++ b/pyflask/users/user.py @@ -1,6 +1,7 @@ import requests from os.path import join, expanduser, exists from configparser import ConfigParser +from configUtils import format_agent_profile_name from constants import PENNSIEVE_URL from utils import ( create_request_headers, @@ -74,6 +75,8 @@ def get_user_information(token): def set_preferred_organization(organization_id, email, password, account_name): + # format the keyname to lowercase and replace '.' with '_' + formatted_account_name = format_agent_profile_name(account_name) try: token = get_cognito_userpool_access_token(email, password) @@ -137,14 +140,15 @@ def set_preferred_organization(organization_id, email, password, account_name): organization = org["organization"]["name"] # create an updated profile name that is unqiue to the user and their workspace - account_name = f"{account_name}-{email_sub}-{organization}" + formatted_account_name = format_agent_profile_name(f"{account_name}-{email_sub}-{organization}") + except Exception as e: raise e try: # create the new profile for the user, associate the api key and secret with the profile, and set it as the default profile - bf_add_account_username(account_name, key, secret) + bf_add_account_username(formatted_account_name, key, secret) except Exception as e: raise e @@ -176,15 +180,18 @@ def get_user_organizations(): userpath = expanduser("~") configpath = join(userpath, ".pennsieve", "config.ini") def update_config_account_name(accountname): + # format the keyname to lowercase and replace '.' with '_' + formatted_account_name = format_agent_profile_name(accountname) + if exists(configpath): config = ConfigParser() config.read(configpath) if not config.has_section("global"): config.add_section("global") - config.set("global", "default_profile", accountname) + config.set("global", "default_profile", formatted_account_name) else: - config["global"]["default_profile"] = accountname + config["global"]["default_profile"] = formatted_account_name with open(configpath, "w") as configfile: config.write(configfile) \ No newline at end of file diff --git a/scripts/meta/announcements.json b/scripts/meta/announcements.json index 1da206160..a1ffe29c4 100644 --- a/scripts/meta/announcements.json +++ b/scripts/meta/announcements.json @@ -1,4 +1,10 @@ { + "12.4.2": { + "announcements": { + "bug-fixes": ["Fixed Pennsieve login bug for accounts with Emails containing periods."], + "features": [] + } + }, "12.4.1": { "announcements": { "features": [