diff --git a/README.md b/README.md index 313671beb..8b00d4f0d 100644 --- a/README.md +++ b/README.md @@ -75,28 +75,31 @@ concerns are: During development, environment variables can be set to control execution: -| Variable | Description | -| :------------------------------------- | :---------------------------------------------------------------- | -| BRAND=[braini, cat, heal, restartr, scidas, eduhelx] | Product context configuration for the appstore. | -| DJANGO_SETTINGS_MODULE=[appstore.settings._settings] | Product settings module configuration for the appstore. | -| DEV_PHASE=[stub, local, dev, val, prod] | In stub, does not require a Tycho service. | -| ALLOW_DJANGO_LOGIN=[TRUE, FALSE] | When true, presents username and password authentication options. | -| SECRET_KEY | Key for securing the application. | -| OAUTH_PROVIDERS | Contains all the providers(google, github). | -| GOOGLE_CLIENT_ID | Contains the client_id of the provider. | -| GOOGLE_SECRET | Contains the secret key for provider. | -| GOOGLE_NAME | Sets the name for the provider. | -| GITHUB_CLIENT_ID | Contains the client_id of the provider. | -| GITHUB_SECRET | Contains the secret key of the provider. | -| GITHUB_NAME | Sets the name for the provider. | -| APPSTORE_DJANGO_USERNAME | Holds superuser username credentials. | -| APPSTORE_DJANGO_PASSWORD | Holds superuser password credentials. | -| TYCHO_URL | Contains the url of the running tycho host. | -| OAUTH_DB_DIR | Contains the path for the database directory. | -| OAUTH_DB_FILE | Contains the path for the database file. | -| APPSTORE_DEFAULT_FROM_EMAIL | Default email address for appstore. | -| APPSTORE_DEFAULT_SUPPORT_EMAIL | Default support email for appstore. | -| ACCOUNT_DEFAULT_HTTP_PROTOCOL | Allows to switch between http and https protocol. | +| Variable | Description | +|:-------------------------------------------------------------|:------------------------------------------------------------------| +| BRAND=[braini, cat, heal, restartr, scidas, eduhelx] | Product context configuration for the appstore. | +| DJANGO_SETTINGS_MODULE=[appstore.settings._settings] | Product settings module configuration for the appstore. | +| DEV_PHASE=[stub, local, dev, val, prod] | In stub, does not require a Tycho service. | +| ALLOW_DJANGO_LOGIN=[TRUE, FALSE] | When true, presents username and password authentication options. | +| SECRET_KEY | Key for securing the application. | +| OAUTH_PROVIDERS | Contains all the providers(google, github, cilogon). | +| CILOGON_CLIENT_ID | Contains the client_id of the provider. | +| CILOGON_SECRET | Contains the secret key for provider. | +| CILOGON_NAME | Sets the name for the provider. | +| GOOGLE_CLIENT_ID | Contains the client_id of the provider. | +| GOOGLE_SECRET | Contains the secret key for provider. | +| GOOGLE_NAME | Sets the name for the provider. | +| GITHUB_CLIENT_ID | Contains the client_id of the provider. | +| GITHUB_SECRET | Contains the secret key of the provider. | +| GITHUB_NAME | Sets the name for the provider. | +| APPSTORE_DJANGO_USERNAME | Holds superuser username credentials. | +| APPSTORE_DJANGO_PASSWORD | Holds superuser password credentials. | +| TYCHO_URL | Contains the url of the running tycho host. | +| OAUTH_DB_DIR | Contains the path for the database directory. | +| OAUTH_DB_FILE | Contains the path for the database file. | +| APPSTORE_DEFAULT_FROM_EMAIL | Default email address for appstore. | +| APPSTORE_DEFAULT_SUPPORT_EMAIL | Default support email for appstore. | +| ACCOUNT_DEFAULT_HTTP_PROTOCOL | Allows to switch between http and https protocol. | The provided .env.sample contains a starter that you can update and source for development. @@ -527,13 +530,17 @@ appstore: EMAIL_HOST_PASSWORD: DOCKSTORE_APPS_BRANCH: oauth: - OAUTH_PROVIDERS: "github,google" + OAUTH_PROVIDERS: "github,google,cilogon" GITHUB_NAME: GITHUB_CLIENT_ID: GITHUB_SECRET: GOOGLE_NAME: GOOGLE_CLIENT_ID: - GOOGLE_SECRET: + GOOGLE_SECRET: + CILOGON_NAME: + CILOGON_CLIENT_ID: + CILOGON_SECRET: + ACCOUNT_DEFAULT_HTTP_PROTOCOL: https appstoreEntrypointArgs: "make start" userStorage: @@ -558,6 +565,9 @@ As part of user configuration, system administration will obtain the following - GOOGLE_NAME - GOOGLE_CLIENT_ID - GOOGLE_SECRET + - CILOGON_NAME + - CILOGON_CLIENT_ID + - CILOGON_SECRET - serverName - IP - nginxTLSSecret diff --git a/appstore/api/v1/views.py b/appstore/api/v1/views.py index e29089457..9285670ed 100644 --- a/appstore/api/v1/views.py +++ b/appstore/api/v1/views.py @@ -873,11 +873,12 @@ def _get_social_providers(self, request, settings): "allauth.account.auth_backends.AuthenticationBackend" in settings.AUTHENTICATION_BACKENDS ): - for provider in socialaccount.providers.registry.get_class_list(): - inst = provider(request, "allauth.socialaccount") + adapter = socialaccount.adapter.get_adapter(request) + providers = adapter.list_providers(request) + for provider in providers: provider_data.append( asdict( - LoginProvider(inst.name, inst.get_login_url(request)) + LoginProvider(provider.name, provider.get_login_url(request)) ) ) diff --git a/appstore/appstore/adapter.py b/appstore/appstore/adapter.py index b2816809d..33be39bc6 100644 --- a/appstore/appstore/adapter.py +++ b/appstore/appstore/adapter.py @@ -16,7 +16,6 @@ def clean_email(self, email): ) return email - class LoginRedirectAdapter(DefaultAccountAdapter, DefaultSocialAccountAdapter): """ For regular form login redirect the user to the correct @@ -60,6 +59,13 @@ def get_logout_redirect_url(self, request): return url class SocialAccountAdapter(DefaultSocialAccountAdapter): + + # debug commenting out for now. + # def populate_user(self, request, sociallogin, data): + # user = super().populate_user(request, sociallogin, data) + # print('sociallogin.account.extra_data:', sociallogin.account.extra_data) + # return user + def on_authentication_error(self, request, provider, error=None, exception=None, extra_context=None): provider_id = provider.id if provider else "unknown" error_code = error.name if error else "unknown" diff --git a/appstore/appstore/settings/base.py b/appstore/appstore/settings/base.py index de8491c93..4f5a5bc54 100644 --- a/appstore/appstore/settings/base.py +++ b/appstore/appstore/settings/base.py @@ -46,11 +46,11 @@ DEV_PHASE = os.environ.get("DEV_PHASE", "local") TYCHO_MODE = os.environ.get("TYCHO_MODE", "null" if DEV_PHASE == "stub" else "live") -# Needs to be JSON-encoded since expressions can contain basically any character that would be used as a delimiter. +# Needs to be JSON-encoded since expressions can contain basically any character that would be used as a delimiter. AUTO_WHITELIST_PATTERNS = json.loads(os.environ.get("AUTO_WHITELIST_PATTERNS", "[]")) # Variables used for an external Tycho app registry. -# ToDo: Consider setting the default value of TYCHO_APP_REGISTRY_REPO to +# ToDo: Consider setting the default value of TYCHO_APP_REGISTRY_REPO to # "https://github.com/helxplatform/helx-apps/raw" and remove any other similar # variable. Maybe don't set and raise a fatal error if not set (still remove # other similar variables). @@ -91,7 +91,7 @@ "corsheaders", "crispy_forms", "rest_framework", - "drf_spectacular", + "drf_spectacular" ] ## Setting to allow for a seamless login that was breaking at django-allauth 0.47. @@ -107,11 +107,52 @@ "tycho", ] +ACCOUNT_EMAIL_REQUIRED = True + +SOCIALACCOUNT_ADAPTER = "appstore.adapter.SocialAccountAdapter" +SOCIALACCOUNT_QUERY_EMAIL = ACCOUNT_EMAIL_REQUIRED +SOCIALACCOUNT_STORE_TOKENS = True +SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True + +SOCIALACCOUNT_PROVIDERS = { + "google": {"SCOPE": ["profile", "email"], "AUTH_PARAMS": {"access_type": "offline"}}, +} + OAUTH_PROVIDERS = os.environ.get("OAUTH_PROVIDERS", "").split(",") + +# Notes: there are currently 3 types of SSO providers that can be specified: +# github,google,cilogon for PROVIDER in OAUTH_PROVIDERS: if PROVIDER != '': THIRD_PARTY_APPS.append(f"allauth.socialaccount.providers.{PROVIDER}") +# get the OIDC name if exists +OIDC_NAME = os.environ.get("OIDC_NAME", "") + +# add in the OIDC params +if OIDC_NAME != "": + # add the oidc provider to the django config + THIRD_PARTY_APPS.append(f"allauth.socialaccount.providers.openid_connect") + + # get the rest of the OIDC parameters + OIDC_CLIENT_ID = os.environ.get("OIDC_CLIENT_ID","") + OIDC_SECRET = os.environ.get("OIDC_SECRET","") + OIDC_SERVER_URL = os.environ.get("OIDC_SERVER_URL","") + + SOCIALACCOUNT_PROVIDERS.update( + { + "openid_connect": { + "APPS": [ + { + "provider_id": OIDC_NAME, + "name": OIDC_NAME, + "client_id": OIDC_CLIENT_ID, + "secret": OIDC_SECRET, + "settings": { "server_url": OIDC_SERVER_URL } + }] + } + }) + INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS WSGI_APPLICATION = "appstore.wsgi.application" @@ -146,7 +187,6 @@ ACCOUNT_ADAPTER = "appstore.adapter.LoginRedirectAdapter" ACCOUNT_DEFAULT_HTTP_PROTOCOL = os.environ.get("ACCOUNT_DEFAULT_HTTP_PROTOCOL", "http") -ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1 ACCOUNT_EMAIL_VERIFICATION = "none" ACCOUNT_RATE_LIMITS= {'login_failed':10} @@ -154,17 +194,12 @@ ACCOUNT_LOGOUT_REDIRECT_URL = "/helx" LOGIN_REDIRECT_URL = "/helx/workspaces/login/success" LOGIN_URL = "/accounts/login" -LOGIN_WHITELIST_URL = "/login_whitelist/" +LOGIN_WHITELIST_URL = "/helx/workspaces/login?whitelist_required=true" OIDC_SESSION_MANAGEMENT_ENABLE = True SAML_URL = "/accounts/saml" SAML_ACS_URL = "/saml2_auth/acs/" #SAML_ACS_URL = "/sso/acs/" -SOCIALACCOUNT_ADAPATER = "appstore.adapter.SocialAccountAdapter" -SOCIALACCOUNT_QUERY_EMAIL = ACCOUNT_EMAIL_REQUIRED -SOCIALACCOUNT_STORE_TOKENS = True -SOCIALACCOUNT_PROVIDERS = { - "google": {"SCOPE": ["profile", "email"], "AUTH_PARAMS": {"access_type": "offline"}} -} + SECURE_CROSS_ORIGIN_OPENER_POLICY = None TEMPLATES = [ diff --git a/appstore/core/management/commands/addingwhitelistedsocialapp.py b/appstore/core/management/commands/addingwhitelistedsocialapp.py index f6c13b40f..b07f910c0 100644 --- a/appstore/core/management/commands/addingwhitelistedsocialapp.py +++ b/appstore/core/management/commands/addingwhitelistedsocialapp.py @@ -25,4 +25,4 @@ def handle(self, *args, **kwargs): if not Group.objects.filter(name='whitelisted'): Group.objects.create(name='whitelisted') - print("Successfully added social applications GitHub and Google and whitelisted to the Group!") + print("Successfully added social applications and whitelisted them into the Group!") diff --git a/appstore/product/configuration.py b/appstore/product/configuration.py index bdd7a7723..f8c10663c 100644 --- a/appstore/product/configuration.py +++ b/appstore/product/configuration.py @@ -34,6 +34,6 @@ class ProductSettings: brand: str = "CommonsShare" title: str = "CommonsShare" logo_url: str = "/static/images/commonsshare/logo-lg.png" - color_scheme: ProductColorScheme = ProductColorScheme() + color_scheme: ProductColorScheme = field(default_factory=lambda: ProductColorScheme()) capabilities: List[str] = field(default_factory=lambda: ['app', 'search'])