airavata-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From machris...@apache.org
Subject [airavata-django-portal] 07/07: AIRAVATA-2859 External login options and configuration
Date Sat, 21 Jul 2018 20:13:01 GMT
This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git

commit c2fbef8616c00140413c9385f24323451bcf91c7
Author: Marcus Christie <machrist@iu.edu>
AuthorDate: Sat Jul 21 16:04:56 2018 -0400

    AIRAVATA-2859 External login options and configuration
---
 .gitignore                                         |  2 +
 .../auth/templates/django_airavata_auth/login.html | 44 +++++++++++++---------
 django_airavata/apps/auth/urls.py                  |  2 +-
 django_airavata/apps/auth/views.py                 | 14 ++++++-
 django_airavata/settings.py                        | 17 ++++++++-
 django_airavata/settings_local.py.sample           | 14 +++++++
 6 files changed, 71 insertions(+), 22 deletions(-)

diff --git a/.gitignore b/.gitignore
index e9e2ea5..73476c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,5 @@ settings_local.py
 node_modules
 dist/
 ENV
+venv/
+.vscode/
diff --git a/django_airavata/apps/auth/templates/django_airavata_auth/login.html b/django_airavata/apps/auth/templates/django_airavata_auth/login.html
index 69ece3c..ede2663 100644
--- a/django_airavata/apps/auth/templates/django_airavata_auth/login.html
+++ b/django_airavata/apps/auth/templates/django_airavata_auth/login.html
@@ -3,11 +3,29 @@
 {% block content %}
 
 <div class="container">
+    {% if options.external %}
     <div class="row">
-        <div class="col-md-6 col-md-offset-3">
-            <div class="panel panel-default">
-                <div class="panel-body">
-                    <h3>Login</h3>
+        <div class="col">
+            <div class="card">
+                <div class="card-body">
+                    <h5 class="card-title">Log in with your existing organizational
login</h5>
+                    {% for external in options.external %}
+                    <a href="{% url 'django_airavata_auth:redirect_login' external.idp_alias
%}" class="btn btn-primary btn-block mt-3">
+                        Sign in with {{ external.name }}
+                    </a>
+                    {% endfor %}
+                </div>
+            </div>
+        </div>
+    </div>
+    {% endif %}
+    
+    {% if options.password %}
+    <div class="row">
+        <div class="col">
+            <div class="card">
+                <div class="card-body">
+                    <h5 class="card-title">Log in with {{ options.password.name|default:"a
username and password" }}</h5>
                     <form action="{% url 'django_airavata_auth:handle_login' %}" method="post">
                         {% csrf_token %}
                         <div class="form-group">
@@ -21,23 +39,15 @@
                         {% if next %}
                         <input type="hidden" name="next" value="{{ next }}"/>
                         {% endif %}
-                        <button type="submit" class="btn btn-default">Submit</button>
+                        <button type="submit" class="btn btn-primary btn-block">
+                            Sign in with {{ options.password.name|default:"a username and
password" }}
+                        </button>
                     </form>
                 </div>
             </div>
         </div>
     </div>
-    <div class="row">
-        <div class="col-md-6 col-md-offset-3">
-            <div class="panel panel-default">
-                <div class="panel-body">
-                    <h3>CILogon</h3>
-                    <a href="{% url 'django_airavata_auth:redirect_login' %}" class="btn
btn-default">
-                        Sign in with CILogon
-                    </a>
-                </div>
-            </div>
-        </div>
-    </div>
+    {% endif %}
+</div>
 </div>
 {% endblock content %}
diff --git a/django_airavata/apps/auth/urls.py b/django_airavata/apps/auth/urls.py
index da9133d..df83056 100644
--- a/django_airavata/apps/auth/urls.py
+++ b/django_airavata/apps/auth/urls.py
@@ -6,7 +6,7 @@ from . import views
 app_name = 'django_airavata_auth'
 urlpatterns = [
     url(r'^login$', views.start_login, name='login'),
-    url(r'^redirect_login$', views.redirect_login, name='redirect_login'),
+    url(r'^redirect_login/(\w+)/$', views.redirect_login, name='redirect_login'),
     url(r'^handle_login$', views.handle_login, name='handle_login'),
     url(r'^logout$', views.start_logout, name='logout'),
     url(r'^callback', views.callback, name='callback'),
diff --git a/django_airavata/apps/auth/views.py b/django_airavata/apps/auth/views.py
index d4412b8..0c7f719 100644
--- a/django_airavata/apps/auth/views.py
+++ b/django_airavata/apps/auth/views.py
@@ -12,11 +12,13 @@ logger = logging.getLogger(__name__)
 
 def start_login(request):
     return render(request, 'django_airavata_auth/login.html', {
-        'next': request.GET.get('next', None)
+        'next': request.GET.get('next', None),
+        'options': settings.AUTHENTICATION_OPTIONS,
     })
 
 
-def redirect_login(request):
+def redirect_login(request, idp_alias):
+    _validate_idp_alias(idp_alias)
     client_id = settings.KEYCLOAK_CLIENT_ID
     base_authorize_url = settings.KEYCLOAK_AUTHORIZE_URL
     oauth2_session = OAuth2Session(
@@ -25,11 +27,19 @@ def redirect_login(request):
             reverse('django_airavata_auth:callback')))
     authorization_url, state = oauth2_session.authorization_url(
         base_authorize_url)
+    authorization_url += '&kc_idp_hint=' + quote(idp_alias)
     # Store state in session for later validation (see backends.py)
     request.session['OAUTH2_STATE'] = state
     return redirect(authorization_url)
 
 
+def _validate_idp_alias(idp_alias):
+    external_auth_options = settings.AUTHENTICATION_OPTIONS['external']
+    valid_idp_aliases = [ext['idp_alias'] for ext in external_auth_options]
+    if idp_alias not in valid_idp_aliases:
+        raise Exception("idp_alias is not valid")
+
+
 def handle_login(request):
     username = request.POST['username']
     password = request.POST['password']
diff --git a/django_airavata/settings.py b/django_airavata/settings.py
index 9149c66..2748bc7 100644
--- a/django_airavata/settings.py
+++ b/django_airavata/settings.py
@@ -186,11 +186,24 @@ WAGTAIL_SITE_NAME = 'Django Airavata Portal'
 WAGTAILIMAGES_JPEG_QUALITY = 100
 
 
-
 LOGIN_URL = 'django_airavata_auth:login'
 LOGIN_REDIRECT_URL = 'django_airavata_workspace:dashboard'
 LOGOUT_REDIRECT_URL = 'home'
 
+AUTHENTICATION_OPTIONS = {
+    # Control whether username/password authentication is allowed
+    'password': {
+        'name': 'your account',
+    },
+    # Can have multiple external logins
+    # 'external': [
+    #     {
+    #         'idp_alias': 'cilogon',
+    #         'name': 'CILogon',
+    #     }
+    # ]
+}
+
 LOGGING = {
     'version': 1,
     'handlers': {
@@ -208,6 +221,6 @@ LOGGING = {
 
 # Allow all settings to be overridden by settings_local.py file
 try:
-    from django_airavata.settings_local import *
+    from django_airavata.settings_local import *  # noqa
 except ImportError:
     pass
diff --git a/django_airavata/settings_local.py.sample b/django_airavata/settings_local.py.sample
index d7b8814..6cf09ce 100644
--- a/django_airavata/settings_local.py.sample
+++ b/django_airavata/settings_local.py.sample
@@ -27,6 +27,20 @@ KEYCLOAK_LOGOUT_URL = '...'
 #KEYCLOAK_CA_CERTFILE = os.path.join(BASE_DIR, "django_airavata", "resources", "incommon_rsa_server_ca.pem")
 KEYCLOAK_VERIFY_SSL = True
 
+AUTHENTICATION_OPTIONS = {
+    # Control whether username/password authentication is allowed
+    'password': {
+        'name': 'your account',
+    },
+    # Can have multiple external logins
+    # 'external': [
+    #     {
+    #         'idp_alias': 'cilogon',
+    #         'name': 'CILogon',
+    #     }
+    # ]
+}
+
 # Airavata API Configuration
 GATEWAY_ID = 'default'
 AIRAVATA_API_HOST = 'localhost'


Mime
View raw message