Skip to content

Commit

Permalink
YDA-6198: add all users internal option
Browse files Browse the repository at this point in the history
Add a way to make the ruleset consider all users to
be internal, by setting the external domain filter to "*".
This is useful in situations where all users are to be authenticated
using OIDC.

This also makes the is-user-external script use the ruleset
function for determining whether a user is external, so that the
PAM stack and ruleset use exactly the same logic.
  • Loading branch information
stsnel committed Feb 18, 2025
1 parent 72305cf commit c58ce7b
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
16 changes: 16 additions & 0 deletions integration_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import time
import traceback
import uuid
from subprocess import PIPE, Popen

import data_access_token
import folder
Expand Down Expand Up @@ -769,6 +770,12 @@ def _test_folder_secure_func(ctx, func):
{"name": "util.user.usertype.rodsuser",
"test": lambda ctx: user.user_type(ctx, "researcher"),
"check": lambda x: x == "rodsuser"},
{"name": "is_user_external.internal",
"test": lambda ctx: _test_is_user_external(ctx, "researcher@yoda.dev"),
"check": lambda x: x == "1"},
{"name": "is_user_external.external",
"test": lambda ctx: _test_is_user_external(ctx, "researcher@externaldomain.nl"),
"check": lambda x: x == "0"}
]


Expand Down Expand Up @@ -862,6 +869,15 @@ def _call_dir_list(ctx, dirname, resc_name):
return json.loads(ret['arguments'][2])


def _test_is_user_external(ctx, username):
command = ["/etc/irods/yoda-ruleset/tools/is-user-external.py"]
environment = dict(os.environ)
environment["PAM_USER"] = username
process = Popen(command, stdout=PIPE, env=environment)
process.communicate()
return process.wait()


def _call_dir_list_check_exc(ctx, dirname, resc_name):
try:
msi.dir_list(ctx, dirname, resc_name, "")
Expand Down
18 changes: 18 additions & 0 deletions tools/is-user-external.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
"""This script is used by the PAM stack to verify whether
a user is external, based on the username."""

__copyright__ = 'Copyright (c) 2025, Utrecht University'
__license__ = 'GPLv3, see LICENSE'

import os
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(os.path.join(os.path.dirname(__file__), "../util"))

from yoda_names import is_internal_user

username = os.environ.get("PAM_USER", "")
exit_code = 1 if is_internal_user(username) else 0
sys.exit(exit_code)
2 changes: 2 additions & 0 deletions unit-tests/test_util_yoda_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ def test_is_internal_user(self):
self.assertEqual(_is_internal_user("peter@cs.uu.nl", ["*.uu.nl"]), True)
self.assertEqual(_is_internal_user("peter@ai.cs.uu.nl", ["*.cs.uu.nl"]), True)
self.assertEqual(_is_internal_user("peter@ai.hum.uu.nl", ["*.cs.uu.nl"]), False)
self.assertEqual(_is_internal_user("peter@uu.nl", ["*"]), True)
self.assertEqual(_is_internal_user("peter@vu.nl", ["*"]), True)
4 changes: 3 additions & 1 deletion util/yoda_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ def _is_internal_user(username: str, external_domain_filter: List) -> bool:
return True

for domain in external_domain_filter:
if domain.startswith("*."):
if domain == "*":
return True
elif domain.startswith("*."):
if username.endswith(domain[1:]) or username.endswith("@" + domain[2:]):
return True
else:
Expand Down

0 comments on commit c58ce7b

Please sign in to comment.