Skip to content
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: 1 addition & 1 deletion .env.model
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ IRIS_AUTHENTICATION_TYPE=local
#IRIS_ADM_API_KEY=B8BA5D730210B50F41C06941582D7965D57319D5685440587F98DFDC45A01594
#IRIS_ADM_EMAIL=admin@localhost
#IRIS_ADM_USERNAME=administrator
# requests the just-in-time creation of users with ldap authentification (see https://github.com/dfir-iris/iris-web/issues/203)
# requests the just-in-time creation of users with ldap / oidc authentification (see https://github.com/dfir-iris/iris-web/issues/203)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the authentication spelling.

The changed comment still uses authentification. Replace it with authentication.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.env.model at line 52, Update the comment describing just-in-time LDAP/OIDC
user creation to replace “authentification” with “authentication,” without
changing its meaning or surrounding content.

#IRIS_AUTHENTICATION_CREATE_USER_IF_NOT_EXIST=True
# the group to which newly created users are initially added, default value is Analysts
#IRIS_NEW_USERS_DEFAULT_GROUP=
Expand Down
6 changes: 6 additions & 0 deletions source/app/blueprints/pages/login/login_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
from app.business.auth import validate_ldap_login, _retrieve_user_by_username, wrap_login_user
from app.datamgmt.manage.manage_users_db import create_user
from app.datamgmt.manage.manage_users_db import get_user
from app.datamgmt.manage.manage_users_db import add_user_to_group
from app.datamgmt.manage.manage_groups_db import get_group_by_name
from app.forms import LoginForm, MFASetupForm
from app.iris_engine.utils.tracker import track_activity

Expand Down Expand Up @@ -215,6 +217,10 @@ def oidc_authorise():
user_is_service_account=False
)

initial_group = get_group_by_name(app.config.get('IRIS_NEW_USERS_DEFAULT_GROUP'))
add_user_to_group(user.id, initial_group.group_id)
Comment on lines +220 to +221

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate the configured group before dereferencing it.

If IRIS_NEW_USERS_DEFAULT_GROUP does not match a database row, get_group_by_name returns None (source/app/datamgmt/manage/manage_groups_db.py:81-83). Line 221 then raises AttributeError, and OIDC just-in-time user creation fails. Resolve and validate initial_group before create_user, then return a clear configuration error when the group is missing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/app/blueprints/pages/login/login_routes.py` around lines 220 - 221,
The get_group_by_name function can return None when the configured group does
not exist in the database, but the code immediately dereferences
initial_group.group_id without validation, causing an AttributeError during OIDC
just-in-time user creation. Add a None-check after the get_group_by_name call to
validate that initial_group is not None before accessing its group_id attribute.
If initial_group is None, return a clear configuration error message indicating
that the group specified in IRIS_NEW_USERS_DEFAULT_GROUP does not exist in the
database. Only proceed with the add_user_to_group call once initial_group has
been validated as non-None.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 20 'def create_user|def add_user_to_group|db\.session\.(commit|rollback)' source/app

Repository: dfir-iris/iris-web

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== target file outline/sections =="
wc -l source/app/blueprints/pages/login/login_routes.py source/app/datamgmt/manage/manage_users_db.py || true
sed -n '180,250p' source/app/blueprints/pages/login/login_routes.py
printf '\n== manage_users_db relevant sections ==\n'
sed -n '240,355p' source/app/datamgmt/manage/manage_users_db.py
printf '\n== precise function definitions/callers/usages in relevant datamgmt files ==\n'
rg -n -C 12 'def create_user|def add_user_to_group|get_group_by_name|create_user\s*\(|add_user_to_group\s*\(' source/app/datamgmt/manage source/app/blueprints/pages/login/login_routes.py
printf '\n== db transaction declarations in relevant files ==\n'
rg -n 'db\.session\.(commit|rollback)|before_request|atexit|`@app`\.(teardown|before)|after_request|sessionmaker|scoped_session|transaction' source/app/datamgmt/manage/manage_users_db.py source/app/blueprints/pages/login/login_routes.py

Repository: dfir-iris/iris-web

Length of output: 18844


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== create_user implementation =="
sed -n '673,730p' source/app/datamgmt/manage/manage_users_db.py

echo "== User.save definition candidates =="
rg -n -C 8 'class User|def save\(' source/app source -g '*.py' | head -n 120

echo "== OIDC login route full function =="
sed -n '130,230p' source/app/blueprints/pages/login/login_routes.py

echo "== search for session rollback handling in OIDC path =="
rg -n -C 6 'add_user_to_group|create_user\(|IRIS_NEW_USERS_DEFAULT_GROUP|db\.session\.rollback|rollback\(\)' source/app/blueprints/pages/login source/app/datamgmt -g '*.py'

Repository: dfir-iris/iris-web

Length of output: 23104


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== User save implementation =="
sed -n '199,250p' source/app/models/authorization.py

echo "== ac_auto_update_user_effective_access implementation =="
rg -n -C 12 'def ac_auto_update_user_effective_access|_auto_update_user_effective_access' source/app/datamgmt -g '*.py'

Repository: dfir-iris/iris-web

Length of output: 24376


Make OIDC user creation and default-group assignment atomic.

create_user() commits the user after User.save(), and add_user_to_group() commits membership separately. If default-group assignment fails, the OIDC user remains persisted without the configured membership. Wrap the creation sequence in one transaction, or roll back create_user() changes if assignment fails.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/app/blueprints/pages/login/login_routes.py` around lines 220 - 221,
Update the OIDC user-creation flow around create_user(), get_group_by_name(),
and add_user_to_group() so user persistence and default-group membership share
one transaction. Ensure any failure during group lookup or assignment rolls back
the newly created user and membership changes, preventing a persisted user
without the configured default group.

log.info(f"Adding new user {user_name} to default initial group {initial_group}.")

if user and not user.active:
return response_error("User not active in IRIS", 403)

Expand Down