LFID login for both projects 30/70830/11 2.1.0-rc1
authorSean Smith <ssmith@iol.unh.edu>
Wed, 19 Aug 2020 15:00:50 +0000 (11:00 -0400)
committerAdam Hassick <ahassick@iol.unh.edu>
Fri, 4 Dec 2020 19:20:41 +0000 (14:20 -0500)
Signed-off-by: Sean Smith <ssmith@iol.unh.edu>
Change-Id: I4a14dc75d7890a6d395b3f52177a7000ae1a2150

config.env.sample
src/account/views.py
src/dashboard/views.py
src/laas_dashboard/settings.py
src/templates/akraino/base.html
src/templates/akraino/dashboard/landing.html
src/templates/base/base.html
src/templates/base/dashboard/landing.html
src/templates/base/dashboard/login.html

index 137ecb0..5b34217 100644 (file)
@@ -22,6 +22,12 @@ DB_PASS=sample_pass
 DB_SERVICE=postgres
 DB_PORT=5432
 
+# tells the dashboard to expect host forwarding from proxy (if using LFID, needs to be True)
+EXPECT_HOST_FORWARDING=False
+
+# string indicating what authorization to deploy with
+AUTH_SETTING=choose_auth # LFID or OAUTH
+
 # SECURITY WARNING: keep the secret key used in production secret!
 SECRET_KEY=http://www.miniwebtool.com/django-secret-key-generator/
 
@@ -43,6 +49,11 @@ OIDC_AUTHORIZATION_ENDPOINT=https://linuxfoundation-test.auth0.com/authorize
 OIDC_TOKEN_ENDPOINT=https://linuxfoundation-test.auth0.com/oauth/token
 OIDC_USER_ENDPOINT=https://linuxfoundation-test.auth0.com/userinfo
 
+CLAIMS_ENDPOINT=https://sso.linuxfoundation.org/claims/
+
+OIDC_RP_SIGN_ALGO=RS256
+OIDC_OP_JWKS_ENDPOINT=https://sso.linuxfoundation.org/.well-known/jwks.json
+
 # Rabbitmq
 RABBITMQ_DEFAULT_USER=opnfv
 RABBITMQ_DEFAULT_PASS=opnfvopnfv
index f282369..08da918 100644 (file)
@@ -61,15 +61,44 @@ class AccountSettingsView(UpdateView):
 
 class MyOIDCAB(OIDCAuthenticationBackend):
     def filter_users_by_claims(self, claims):
-        email = claims.get('email')
-        if not email:
-            return self.User.objects.none()
+        """
+        Checks to see if user exists and create user if not
+
+        Linux foundation does not allow users to change their
+        username, so chose to match users based on their username.
+        If this changes we will need to match users based on some
+        other criterea.
+        """
+        username = claims.get(os.environ['CLAIMS_ENDPOINT'] + 'username')
+
+        if not username:
+            return HttpResponse('No username provided, contact support.')
 
         try:
-            profile = UserProfile.objects.get('email')
-            return profile
-        except UserProfile.DoesNotExist:
-            return self.User.objects.none()
+            # For literally no (good) reason user needs to be a queryset
+            user = User.objects.filter(username=username)
+            return user
+        except User.DoesNotExist:
+            return self.UserModel.objects.none()
+
+    def create_user(self, claims):
+        """ This creates a user and user profile"""
+        user = super(MyOIDCAB, self).create_user(claims)
+        user.username = claims.get(os.environ['CLAIMS_ENDPOINT'] + 'username')
+        user.save()
+
+        up = UserProfile()
+        up.user = user
+        up.email_addr = claims.get('email')
+        up.save()
+        return user
+
+    def update_user(self, user, claims):
+        """ If their account has different email, change the email """
+        up = UserProfile.objects.get(user=user)
+        up.email_addr = claims.get('email')
+        up.save()
+        return user
 
 
 class JiraLoginView(RedirectView):
index f9a908c..7c85250 100644 (file)
@@ -22,6 +22,8 @@ from booking.models import Booking
 from resource_inventory.models import Image, ResourceProfile, ResourceQuery
 from workflow.workflow_manager import ManagerTracker
 
+import os
+
 
 def lab_list_view(request):
     labs = Lab.objects.all()
@@ -78,13 +80,15 @@ def landing_view(request):
     else:
         bookings = None
 
+    LFID = True if os.environ['AUTH_SETTING'] == 'LFID' else False
     return render(
         request,
         'dashboard/landing.html',
         {
             'manager': manager is not None,
             'title': "Welcome to the Lab as a Service Dashboard",
-            'bookings': bookings
+            'bookings': bookings,
+            'LFID': LFID
         }
     )
 
index 92f763f..a32b1c5 100644 (file)
@@ -53,19 +53,29 @@ MIDDLEWARE = [
     'account.middleware.TimezoneMiddleware',
 ]
 
-AUTHENTICATION_BACKENDS = ['account.views.MyOIDCAB']
+if os.environ['AUTH_SETTING'] == 'LFID':
+    AUTHENTICATION_BACKENDS = ['account.views.MyOIDCAB']
 
+    # OpenID Authentications
+    OIDC_RP_CLIENT_ID = os.environ['OIDC_CLIENT_ID']
+    OIDC_RP_CLIENT_SECRET = os.environ['OIDC_CLIENT_SECRET']
 
-# OpenID Authentications
-OIDC_RP_CLIENT_ID = os.environ['OIDC_CLIENT_ID']
-OIDC_RP_CLIENT_SECRET = os.environ['OIDC_CLIENT_SECRET']
+    OIDC_OP_AUTHORIZATION_ENDPOINT = os.environ['OIDC_AUTHORIZATION_ENDPOINT']
+    OIDC_OP_TOKEN_ENDPOINT = os.environ['OIDC_TOKEN_ENDPOINT']
+    OIDC_OP_USER_ENDPOINT = os.environ['OIDC_USER_ENDPOINT']
 
-OIDC_OP_AUTHORIZATION_ENDPOINT = os.environ['OIDC_AUTHORIZATION_ENDPOINT']
-OIDC_OP_TOKEN_ENDPOINT = os.environ['OIDC_TOKEN_ENDPOINT']
-OIDC_OP_USER_ENDPOINT = os.environ['OIDC_USER_ENDPOINT']
+    LOGIN_REDIRECT_URL = os.environ['DASHBOARD_URL']
+    LOGOUT_REDIRECT_URL = os.environ['DASHBOARD_URL']
 
-LOGIN_REDIRECT_URL = os.environ['DASHBOARD_URL']
-LOGOUT_REDIRECT_URL = os.environ['DASHBOARD_URL']
+    OIDC_RP_SIGN_ALGO = os.environ["OIDC_RP_SIGN_ALGO"]
+
+    if OIDC_RP_SIGN_ALGO == "RS256":
+        OIDC_OP_JWKS_ENDPOINT = os.environ["OIDC_OP_JWKS_ENDPOINT"]
+
+# This is for LFID auth setups w/ an HTTPS proxy
+if os.environ['EXPECT_HOST_FORWARDING'] == 'True':
+    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', "https")
+    USE_X_FORWARDED_HOST = True
 
 ROOT_URLCONF = 'laas_dashboard.urls'
 
index b93dcd2..1368476 100644 (file)
 {% endblock logo %}
 {% block dropDown %}
 {% endblock dropDown %}
-
-{% block login %}
-    <div class="dropdown-menu dropdown-menu-right">
-        {% if user.is_authenticated %}
-        <a href="{% url 'account:settings' %}" class="text-dark dropdown-item">
-            <i class="fas fa-cog"></i>
-                Settings
-        </a>
-        <a href="{% url 'oidc_logout' %}" class="text-dark dropdown-item">
-            <i class="fas fa-sign-out-alt"></i>
-                Logout
-        </a>
-        {% else %}
-        <a href="{% url 'oidc_authentication_init' %}" class="text-dark dropdown-item">
-            <i class="fas fa-sign-in-alt"></i>
-                Login with LFID
-        </a>
-        {% endif %}
-    </div>
-{% endblock login %}
\ No newline at end of file
index 39eebb6..5533469 100644 (file)
 <a class="btn btnAkr btn-lg d-flex flex-column justify-content-center align-content-center border text-white p-4" href="/booking/quick/">Book a Pod</a>
 {% endblock btnGrp %}
 
-{% block biglogin %}
-<h4 class="text-center">
-    To get started, please log in with <a href="{% url 'oidc_authentication_init' %}"> Linux Foundation ID</a>
-</h4>
-{% endblock biglogin %}
-
 {% block returningUsers %}
 {% endblock returningUsers %}
index f86cff8..3ecad1a 100644 (file)
                             {% endif %}
                             <i class="fas fa-caret-down rotate"></i>
                         </a>
-                        {% block login %}
                         <div class="dropdown-menu dropdown-menu-right">
-                            {% if user.is_authenticated %}
+                            {% if LFID %}
+                                {% if user.is_authenticated %}
                                 <a href="{% url 'account:settings' %}" class="text-dark dropdown-item">
                                     <i class="fas fa-cog"></i>
-                                    Settings
+                                        Settings
                                 </a>
-                                <a href="{% url 'account:logout' %}?next={{ request.path }}" class="text-dark dropdown-item">
+                                <a id="logout_btn" href="#" method="post" class="text-dark dropdown-item">
                                     <i class="fas fa-sign-out-alt"></i>
-                                    Logout
+                                        Logout
                                 </a>
-                            {% else %}
-                                <a href="{% url 'account:login' %}" class="text-dark dropdown-item">
+                                <form id="logout_form" action="{% url 'oidc_logout' %}" method="post" style="visibility: hidden;">
+                                    {% csrf_token %}
+                                    <input type="submit" value="logout">
+                                </form>
+                                <script>
+                                    const logout_btn = document.getElementById("logout_btn");
+
+                                    const logout_form = document.getElementById("logout_form");
+
+                                    logout_btn.onclick = function() { logout_form.submit(); };
+                                </script>
+                                {% else %}
+                                <a href="{% url 'oidc_authentication_init' %}" class="text-dark dropdown-item">
                                     <i class="fas fa-sign-in-alt"></i>
-                                    Login with Jira
+                                        Login with LFID
                                 </a>
+                                {% endif %}
+                            {% else %}
+                                {% if user.is_authenticated %}
+                                    <a href="{% url 'account:settings' %}" class="text-dark dropdown-item">
+                                        <i class="fas fa-cog"></i>
+                                        Settings
+                                    </a>
+                                    <a href="{% url 'account:logout' %}?next={{ request.path }}" class="text-dark dropdown-item">
+                                        <i class="fas fa-sign-out-alt"></i>
+                                        Logout
+                                    </a>
+                                {% else %}
+                                    <a href="{% url 'account:login' %}" class="text-dark dropdown-item">
+                                        <i class="fas fa-sign-in-alt"></i>
+                                        Login with Jira
+                                    </a>
+                                {% endif %}
                             {% endif %}
                         </div>
-                        {% endblock login %}
                     </li>
                 </ul>
             </div>
index 3291606..4ed2ec1 100644 (file)
     <div class="col-12 col-lg-6 mb-4">
         <h2 class="border-bottom">Get Started</h2>
         {% if request.user.is_anonymous %}
-        {% block biglogin %}
+        {% if LFID %}
+        <h4 class="text-center">
+            To get started, please log in with <a href="{% url 'oidc_authentication_init' %}">Linux Foundation ID</a>
+        </h4>
+        {% else %}
         <h4 class="text-center">
             To get started, please log in with your <a href="/accounts/login">Linux Foundation Jira account</a>
         </h4>
-        {% endblock biglogin %}
+        {% endif %}
         {% else %}
         {% block btnGrp %}
         <p>To get started, book a server below:</p>
index d3aa4ad..5af201a 100644 (file)
@@ -1,8 +1,7 @@
 {% extends "base.html" %}
 
 {% block content %}
-<h3>You Must Login To Do That</h3>
-
-<a href="/accounts/login">Login Here</a>
+<h3> You Must Login To Do That<h3>
 
+<a href="{% url 'oidc_authentication_init' %}"> Login Here </a>
 {% endblock %}