Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session management rewrite using Flask-Session #563

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ BASE_URL=<BASE URL FOR DEPLOYED APP>
VIEW_REQUEST_ENDPOINT=<ENDPOINT FOR VIEWING A REQUEST>
APP_TIMEZONE=<LOCAL APPLICATION TIMEZONE>
SESSION_COOKIE_SECURE=True
SESSION_TYPE=<FLASK-SESSION SESSION TYPE>
SESSION_REFRESH_EACH_REQUEST=True
ERROR_RECIPIENTS=

# Log Settings
Expand Down
13 changes: 6 additions & 7 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@
from flask import (Flask, abort, render_template, request as flask_request)
from flask_bootstrap import Bootstrap
from flask_elasticsearch import FlaskElasticsearch
from flask_kvsession import KVSessionExtension
from flask_login import LoginManager, current_user
from flask_mail import Mail
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
from flask_tracy import Tracy
from flask_wtf import CsrfProtect
from flask_session import Session
from raven.contrib.flask import Sentry
from simplekv.decorator import PrefixDecorator
from simplekv.memory.redisstore import RedisStore

from app import celery_config
from app.constants import OPENRECORDS_DL_EMAIL
Expand All @@ -36,11 +34,12 @@
mail = Mail()
tracy = Tracy()
login_manager = LoginManager()
store = RedisStore(redis.StrictRedis(db=Config.SESSION_REDIS_DB,
host=Config.REDIS_HOST, port=Config.REDIS_PORT))
session_redis = PrefixDecorator('session_', store)
store = redis.StrictRedis(db=Config.SESSION_REDIS_DB,
host=Config.REDIS_HOST,
port=Config.REDIS_PORT)
celery = Celery(__name__, broker=Config.CELERY_BROKER_URL)
sentry = Sentry()
sess = Session()

upload_redis = redis.StrictRedis(
db=Config.UPLOAD_REDIS_DB, host=Config.REDIS_HOST, port=Config.REDIS_PORT)
Expand Down Expand Up @@ -113,6 +112,7 @@ def create_app(config_name='default'):
celery.conf.update(app.config)
celery.config_from_object(celery_config)
sentry.init_app(app, logging=app.config["USE_SENTRY"], level=logging.INFO)
sess.init_app(app)

with app.app_context():
from app.models import Anonymous
Expand All @@ -121,7 +121,6 @@ def create_app(config_name='default'):
if app.config['USE_SAML']:
login_manager.login_message = None
login_manager.login_message_category = None
KVSessionExtension(session_redis, app)

# Error Handlers
@app.errorhandler(400)
Expand Down
10 changes: 7 additions & 3 deletions app/auth/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ def saml_sls(saml_sp, user_guid):
Response Object: Redirect the user to the Home Page.

"""
dscb = session.destroy()
dscb = session.clear()
url = saml_sp.process_slo(delete_session_cb=dscb)
errors = saml_sp.get_errors()
logout_user()
Expand All @@ -420,7 +420,9 @@ def saml_sls(saml_sp, user_guid):
'type': current_app.config['AUTH_TYPE']
}
)
return redirect(url) if url else redirect(url_for('main.index'))
redir = redirect(url) if url else redirect(url_for('main.index'))
redir.headers['Clear-Site-Data'] = '"*"'
return redir
else:
error_message = "Errors on SAML Logout:\n{errors}".format(errors='\n'.join(errors))
current_app.logger.exception(error_message)
Expand All @@ -433,8 +435,10 @@ def saml_sls(saml_sp, user_guid):
'errors': error_message
}
)
redir = redirect(url_for('main.index'))
redir.headers['Clear-Site-Data'] = '"*"'
flash("Sorry! An unexpected error has occurred. Please try again later.", category='danger')
return redirect(url_for('main.index'))
return redir


def saml_slo(saml_sp):
Expand Down
8 changes: 3 additions & 5 deletions app/auth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def logout():

elif current_app.config["USE_LOCAL_AUTH"]:
logout_user()
session.destroy()
session.clear()
if timeout:
flash("Your session timed out. Please login again", category="info")
return redirect(url_for("main.index"))
Expand Down Expand Up @@ -259,7 +259,6 @@ def ldap_login():

if authenticated:
login_user(user)
session.regenerate()
session["user_id"] = current_user.get_id()

create_auth_event(
Expand Down Expand Up @@ -332,7 +331,7 @@ def ldap_logout():
'timed_out': timed_out
}
)
session.destroy()
session.clear()
if timed_out:
flash("Your session timed out. Please login again", category="info")
return redirect(url_for("main.index"))
Expand Down Expand Up @@ -360,7 +359,6 @@ def local_login():

if user is not None:
login_user(user)
session.regenerate()
session["user_id"] = current_user.get_id()

create_auth_event(
Expand Down Expand Up @@ -411,7 +409,7 @@ def local_logout(timed_out=False):
'type': current_app.config['AUTH_TYPE']
}
)
session.destroy()
session.clear()
if timed_out:
flash("Your session timed out. Please login again", category="info")
return redirect(url_for("main.index"))
22 changes: 20 additions & 2 deletions app/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
from psycopg2 import OperationalError
from sqlalchemy.exc import SQLAlchemyError

from app import calendar, sentry, db
from app import calendar, db, store
from app.constants import OPENRECORDS_DL_EMAIL, request_status
from app.constants.event_type import EMAIL_NOTIFICATION_SENT, REQ_STATUS_CHANGED
from app.constants.response_privacy import PRIVATE
from app.lib.db_utils import create_object, update_object
from app.lib.email_utils import send_email
from app.models import Agencies, Emails, Events, Requests
from app.models import Agencies, Emails, Events, Requests, Users

# NOTE: (For Future Reference)
# If we find ourselves in need of a request context, app.test_request_context() might come in handy.
Expand Down Expand Up @@ -174,3 +174,21 @@ def update_next_request_number():
db.session.commit()
except SQLAlchemyError:
db.session.rollback()


def _clear_expired_session_ids():
"""
Celery task to clear session ids that are no longer valid.
:return:
"""
users = Users.query.with_entities(Users.guid, Users.session_id).filter(Users.session_id.isnot(None)).all()
if users:
for user in users:
if store.get("session:" + user[1]) is None:
update_object(
{
'session_id': None
},
Users,
user[0]
)
27 changes: 0 additions & 27 deletions app/lib/redis_utils.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import os
from app import sentry

try:
import cPickle as pickle
except ImportError:
import pickle

from flask import current_app
from app import upload_redis as redis
from app.lib.file_utils import (
os_get_hash,
os_get_mime_type
)
from flask_kvsession import (
KVSession
)


# Redis File Utilities
Expand Down Expand Up @@ -58,25 +53,3 @@ def _get_file_metadata_key(request_or_response_id, filepath, is_update):
return '|'.join((str(request_or_response_id),
os.path.basename(filepath),
'update' if is_update else 'new'))


# Redis Session Utilities
def redis_get_user_session(session_id):
serialization_method = pickle
session_class = KVSession

try:
s = session_class(serialization_method.loads(
current_app.kvsession_store.get(session_id)
))
s.sid_s = session_id

return s

except KeyError:
sentry.captureException()
return None


def redis_delete_user_session(session_id):
redis.delete(session_id)
2 changes: 1 addition & 1 deletion app/main/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def index():
return render_template('main/home.html', duplicate_session=True)
update_object(
{
'session_id': session.sid_s
'session_id': session.sid
},
Users,
current_user.guid
Expand Down
1 change: 0 additions & 1 deletion app/static/js/plugins/bootstrap-session-timeout.min.js

This file was deleted.

Loading