Files
soc-fortress/iris-web/source/app/blueprints/login/login_routes.py
hcornet 506716e703
Some checks failed
Deployment Verification / deploy-and-test (push) Failing after 29s
first sync
2025-03-04 07:59:21 +01:00

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)