Some checks failed
Deployment Verification / deploy-and-test (push) Failing after 29s
164 lines
6.0 KiB
Python
164 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# IRIS Source Code
|
|
# Copyright (C) 2021 - Airbus CyberSecurity (SAS)
|
|
# ir@cyberactionlab.net
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 3 of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with this program; if not, write to the Free Software Foundation,
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
from urllib.parse import urlsplit
|
|
|
|
# IMPORTS ------------------------------------------------
|
|
|
|
from flask import Blueprint
|
|
from flask import redirect
|
|
from flask import render_template
|
|
from flask import request
|
|
from flask import session
|
|
from flask import url_for
|
|
from flask_login import current_user
|
|
from flask_login import login_user
|
|
|
|
from app import app
|
|
from app import bc
|
|
from app import db
|
|
|
|
from app.forms import LoginForm
|
|
from app.iris_engine.access_control.ldap_handler import ldap_authenticate
|
|
from app.iris_engine.access_control.utils import ac_get_effective_permissions_of_user
|
|
from app.iris_engine.utils.tracker import track_activity
|
|
from app.models.cases import Cases
|
|
from app.util import is_authentication_ldap
|
|
from app.datamgmt.manage.manage_users_db import get_active_user_by_login
|
|
|
|
|
|
login_blueprint = Blueprint(
|
|
'login',
|
|
__name__,
|
|
template_folder='templates'
|
|
)
|
|
|
|
log = app.logger
|
|
|
|
|
|
# filter User out of database through username
|
|
def _retrieve_user_by_username(username):
|
|
user = get_active_user_by_login(username)
|
|
if not user:
|
|
track_activity("someone tried to log in with user '{}', which does not exist".format(username),
|
|
ctx_less=True, display_in_ui=False)
|
|
return user
|
|
|
|
|
|
def _render_template_login(form, msg):
|
|
organisation_name = app.config.get('ORGANISATION_NAME')
|
|
login_banner = app.config.get('LOGIN_BANNER_TEXT')
|
|
ptfm_contact = app.config.get('LOGIN_PTFM_CONTACT')
|
|
|
|
return render_template('login.html', form=form, msg=msg, organisation_name=organisation_name,
|
|
login_banner=login_banner, ptfm_contact=ptfm_contact)
|
|
|
|
|
|
def _authenticate_ldap(form, username, password, local_fallback=True):
|
|
try:
|
|
if ldap_authenticate(username, password) is False:
|
|
if local_fallback is True:
|
|
track_activity("wrong login password for user '{}' using LDAP auth - falling back to local based on settings".format(username),
|
|
ctx_less=True, display_in_ui=False)
|
|
|
|
return _authenticate_password(form, username, password)
|
|
|
|
track_activity("wrong login password for user '{}' using LDAP auth".format(username),
|
|
ctx_less=True, display_in_ui=False)
|
|
return _render_template_login(form, 'Wrong credentials. Please try again.')
|
|
|
|
user = _retrieve_user_by_username(username)
|
|
if not user:
|
|
return _render_template_login(form, 'Wrong credentials. Please try again.')
|
|
|
|
return wrap_login_user(user)
|
|
except Exception as e:
|
|
log.error(e.__str__())
|
|
return _render_template_login(form, 'LDAP authentication unavailable. Check server logs')
|
|
|
|
|
|
def _authenticate_password(form, username, password):
|
|
user = _retrieve_user_by_username(username)
|
|
if not user or user.is_service_account:
|
|
return _render_template_login(form, 'Wrong credentials. Please try again.')
|
|
|
|
if bc.check_password_hash(user.password, password):
|
|
return wrap_login_user(user)
|
|
|
|
track_activity("wrong login password for user '{}' using local auth".format(username), ctx_less=True,
|
|
display_in_ui=False)
|
|
return _render_template_login(form, 'Wrong credentials. Please try again.')
|
|
|
|
|
|
# CONTENT ------------------------------------------------
|
|
# Authenticate user
|
|
if app.config.get("AUTHENTICATION_TYPE") in ["local", "ldap"]:
|
|
@login_blueprint.route('/login', methods=['GET', 'POST'])
|
|
def login():
|
|
session.permanent = True
|
|
|
|
if current_user.is_authenticated:
|
|
return redirect(url_for('index.index'))
|
|
|
|
form = LoginForm(request.form)
|
|
|
|
# check if both http method is POST and form is valid on submit
|
|
if not form.is_submitted() and not form.validate():
|
|
return _render_template_login(form, None)
|
|
|
|
# assign form data to variables
|
|
username = request.form.get('username', '', type=str)
|
|
password = request.form.get('password', '', type=str)
|
|
|
|
if is_authentication_ldap() is True:
|
|
return _authenticate_ldap(form, username, password, app.config.get('AUTHENTICATION_LOCAL_FALLBACK'))
|
|
|
|
return _authenticate_password(form, username, password)
|
|
|
|
|
|
def wrap_login_user(user):
|
|
login_user(user)
|
|
|
|
track_activity("user '{}' successfully logged-in".format(user.user), ctx_less=True, display_in_ui=False)
|
|
caseid = user.ctx_case
|
|
session['permissions'] = ac_get_effective_permissions_of_user(user)
|
|
|
|
if caseid is None:
|
|
case = Cases.query.order_by(Cases.case_id).first()
|
|
user.ctx_case = case.case_id
|
|
user.ctx_human_case = case.name
|
|
db.session.commit()
|
|
|
|
session['current_case'] = {
|
|
'case_name': user.ctx_human_case,
|
|
'case_info': "",
|
|
'case_id': user.ctx_case
|
|
}
|
|
|
|
track_activity("user '{}' successfully logged-in".format(user), ctx_less=True, display_in_ui=False)
|
|
|
|
next_url = None
|
|
if request.args.get('next'):
|
|
next_url = request.args.get('next') if 'cid=' in request.args.get('next') else request.args.get('next') + '?cid=' + str(user.ctx_case)
|
|
|
|
if not next_url or urlsplit(next_url).netloc != '':
|
|
next_url = url_for('index.index', cid=user.ctx_case)
|
|
|
|
return redirect(next_url)
|