Skip to content

Commit

Permalink
Merge pull request #1572 from GovReady/am/feature_inactivity_timeout
Browse files Browse the repository at this point in the history
Am/feature inactivity timeout
  • Loading branch information
davidpofo committed Apr 26, 2021
2 parents 0a689b2 + 1540377 commit 8299b1e
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 11 deletions.
13 changes: 8 additions & 5 deletions install.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,14 @@ def create_environment_json(path):
secret_key = ''.join(secrets.choice(alphabet) for i in range(50))
# NOTE: `environment` here refers to locally-created environment data object and not OS-level environment variables
environment = {
"govready-url": GOVREADYURL,
"static": "static_root",
"secret-key": secret_key,
"test_visible": False,
"debug": True
"govready-url": GOVREADYURL,
"static": "static_root",
"secret-key": secret_key,
"test_visible": False,
"debug": True,
"session_security_expire_at_browser_close" : True,
"session_security_warn_after" : 1200,
"session_security_expire_after" : 1800
}
# Create local directory
if not os.path.exists('local'):
Expand Down
5 changes: 4 additions & 1 deletion requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,12 @@ markupsafe==1.1.1 # BSD 3
# Excel exports
openpyxl # MIT License

# Session timeout & security
django-session-security # MIT License

# Profiling
nplusone==1.0.0 # MIT License
django-querycount==0.7.0 # MIT License

# Helper Library
django-extensions==3.1.2 # MIT License
django-extensions==3.1.2 # MIT License
11 changes: 7 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,15 @@ django-notifications-hq==1.6 \
--hash=sha256:debeb71b7076b08487b40bf07664d1cc43b9977c4480bbc969b30236dda7a461 \
--hash=sha256:dfc6f8bd4034ceae91143bc3802ddfb6e276eaec90e63dd23e2584c052561576
# via -r requirements.in
django-session-security==2.6.6 \
--hash=sha256:3b263e16e21e0a1d0e91a2b4c44c48d2ee3aeb86e8c4c33d72ef7f5ac1204a1b
# via -r requirements.in
django-simple-history==3.0.0 \
--hash=sha256:66fe76c560054be393c52b1799661e104fbe372918d37d151e5d41c676158118 \
--hash=sha256:a312adfe8fbec4c450b08e641b11249a8a589a7e7d1ba2404764b8b5bed53552
django-querycount==0.7.0 \
--hash=sha256:8f5123d78716ff0704f2373e746a7200b8d8417798ce4a99bf2de87e3768f9ce
# via -r requirements.in
django-simple-history==2.12.0 \
--hash=sha256:3b7bf6bfbcf973afca123c5786c72b917ed4d92d7bf3b6cb70fe2e3850e763a3 \
--hash=sha256:e7e830cb7a768dc90d6ba0507f8023f889bcb62fe31a08f18fac102c55eec539
# via -r requirements.in
django==3.1.8 \
--hash=sha256:c348b3ddc452bf4b62361f0752f71a339140c777ebea3cdaaaa8fdb7f417a862 \
Expand All @@ -233,6 +236,7 @@ django==3.1.8 \
# django-guardian
# django-model-utils
# django-notifications-hq
# django-session-security
# djangorestframework
# jsonfield
djangorestframework==3.12.4 \
Expand Down Expand Up @@ -782,7 +786,6 @@ six==1.15.0 \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced
# via
# bandit
# django-simple-history
# fs
# html5lib
# jsonschema
Expand Down
10 changes: 10 additions & 0 deletions siteapp/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os, os.path, json
from platform import uname, system
from django.core.exceptions import ValidationError

# What's the name of the app containing this file? That determines
# the module for the main URLconf etc.
primary_app = os.path.basename(os.path.dirname(__file__))
Expand Down Expand Up @@ -102,6 +103,7 @@ def make_secret_key():
'django.contrib.messages',
'django.contrib.humanize',
'django.contrib.admindocs',
'session_security',

]
THIRD_PARTY_APPS = [
Expand Down Expand Up @@ -145,6 +147,7 @@ def make_secret_key():
'simple_history.middleware.HistoryRequestMiddleware',
'pyinstrument.middleware.ProfilerMiddleware',
#'django.middleware.cache.FetchFromCacheMiddleware',
'session_security.middleware.SessionSecurityMiddleware',
]
# The cache connection to use for the cache middleware.
#CACHE_MIDDLEWARE_ALIAS='default'
Expand Down Expand Up @@ -407,6 +410,13 @@ def make_secret_key():
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY' # don't allow site to be embedded in iframes

# Session security and inactivity timeout. Logout user after certain period of inactivity.
# By default user is warned at 20 minutes that session is about to expire and if user does not perform any mouse/keyboard activity
# the session expires 10 minutes later (total of 30 minutes).
SESSION_EXPIRE_AT_BROWSER_CLOSE = environment['session_security_expire_at_browser_close'] if not DEBUG else True
SESSION_SECURITY_WARN_AFTER = environment['session_security_warn_after'] if not DEBUG else 85800
SESSION_SECURITY_EXPIRE_AFTER = environment['session_security_expire_after'] if not DEBUG else 86400

# Put static files in the virtual path "/static/". When the "static"
# environment setting is present, then it's a local directory path
# where "collectstatic" will put static files.
Expand Down
12 changes: 12 additions & 0 deletions siteapp/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from django.test.client import RequestFactory

import selenium.webdriver
from selenium.webdriver.remote.command import Command
from django.urls import reverse
from selenium.common.exceptions import WebDriverException
from django.contrib.auth.models import Permission
Expand Down Expand Up @@ -262,6 +263,9 @@ def test_supportpage_customize(self):
self.assertInNodeText("support@govready.com", "#support_content")

class LandingSiteFunctionalTests(SeleniumTest):
def setUp(self):
super().setUp()

def test_homepage(self):
self.browser.get(self.url("/"))
self.assertRegex(self.browser.title, "Welcome to Compliance Automation")
Expand Down Expand Up @@ -502,6 +506,14 @@ def test_static_pages(self):
wait_for_sleep_after(lambda: self.browser.get(self.url("/love-assessments")))
wait_for_sleep_after(lambda: self.assertRegex(self.browser.title, "Love Assessments"))

def test_session_timeout(self):
self._login()
ping_url = self.url("/session_security/ping/?idleFor=0")
response = self.client_get(ping_url)

self.assertTrue(response.status_code==200)
self.assertTrue(response.content==b'0')

def test_simple_module(self):
# Log in and create a new project and start its task.
self._login()
Expand Down
3 changes: 3 additions & 0 deletions siteapp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@
url(r'^tags/_save$', views.create_tag),
url(r'^tags/(\d+)/_delete$', views.delete_tag),
url(r'^tags/$', views.list_tags),

# Session
url(r'session_security/', include('session_security.urls')),
]

if 'django.contrib.auth.backends.ModelBackend' in settings.AUTHENTICATION_BACKENDS:
Expand Down
2 changes: 1 addition & 1 deletion templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ <h4 class="modal-title" id="invitation_modal_title">...</h4>
}
</script>
{% endif %}

{% include 'session_security/all.html' %}
{% block scripts %}
{% endblock %}
</body>
Expand Down

0 comments on commit 8299b1e

Please sign in to comment.