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

feat: Adding whitelisting via usernames (onyens for UNC SAML) #351

Merged
merged 1 commit into from
May 15, 2024
Merged
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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ appstore:
tag: <branchname>
pullPolicy: Always
django:
AUTHORIZED_USERS: <a list emails of authorized users>
AUTHORIZED_USERS: <a list emails or usernames of authorized users>
EMAIL_HOST_USER: "[email protected]"
EMAIL_HOST_PASSWORD: <secret>
DOCKSTORE_APPS_BRANCH: <appstore branch>
Expand Down
4 changes: 2 additions & 2 deletions appstore/core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@


class AuthorizedUserAdmin(admin.ModelAdmin):
fields = ['email']
list_display = 'email'
fields = ['email', 'username']
list_display = ['email', 'username']


admin.site.register(AuthorizedUser)
3 changes: 2 additions & 1 deletion appstore/core/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class Migration(migrations.Migration):
name='AuthorizedUsers',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.EmailField(max_length=254)),
('email', models.EmailField(max_length=254, verbose_name='Email')),
('username', models.CharField(max_length=128, verbose_name='Username')),
],
),
]
12 changes: 9 additions & 3 deletions appstore/core/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.db import models
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django_saml2_auth.user import get_user

def update_user(user):
Expand All @@ -14,14 +15,19 @@ def update_user(user):
return _user

class AuthorizedUser(models.Model):
email = models.EmailField(max_length=254)
email = models.EmailField(max_length=254, blank=True)
username = models.CharField(max_length=128, blank=True)

def __str__(self):
return self.email
return f"{self.email}, {self.username}"

def clean(self):
if not self.email and not self.username:
raise ValidationError("Please enter a value for either email and/or username. Both cannot be empty.")

class IrodAuthorizedUser(models.Model):
user = models.TextField(max_length=254)
uid = models.IntegerField()

def __str__(self):
return (self.user,self.uid)
return f"{self.user}, {self.uid}"
10 changes: 10 additions & 0 deletions appstore/middleware/filter_whitelist_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ def is_auto_whitelisted_email(user):
if re.match(pattern, email) is not None:
return True
return False

@staticmethod
def is_whitelisted_username(user):
username = user.username


@staticmethod
def is_authorized(user):
Expand All @@ -96,6 +101,9 @@ def is_authorized(user):
# authorize the user automatically, and allow them through.
AuthorizedUser.objects.create(email=user.email)
return True
if AuthorizedUser.objects.filter(username=user.username).exists():
logger.debug(f"found user with username {user.username} in AuthorizedUser")
return True
logger.debug(f"user email {user.email} not found in AuthorizedUser")
return False

Expand All @@ -115,6 +123,8 @@ def send_whitelist_email(request, user):
msg = (
"A user "
+ user.email
+ "/"
+ user.username
+ " is requesting access to AppStore on "
+ settings.APPLICATION_BRAND
+ " and needs to be reviewed for whitelisting. Upon successful review, kindly add the user to"
Expand Down
15 changes: 15 additions & 0 deletions appstore/middleware/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ def test_login_whitelisted_user(self):
self.groups.name,
)

def test_login_whitelisted_username(self):
print("---- TESTING FOR WHITELISTED USERNAME (steve_whitelist) ----- ")
user = self._create_user_and_login(
username="Steve_whitelist", email="[email protected]", password="admin"
)
AuthorizedUser.objects.create(username=user.username)
self.request.user = user
self.request.session = self.client.session
response = self.middleware.process_request(self.request)
self.assertFalse(isinstance(response, HttpResponseRedirect))
self.assertEqual(
list(self.request.user.groups.values_list("name", flat=True))[0],
self.groups.name,
)

def test_redirect_non_whitelisted_user(self):
user = self._create_user_and_login(
username="Steve_nonwhitelist",
Expand Down
16 changes: 8 additions & 8 deletions bin/authorizeuser.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,27 +43,27 @@ def irods_user_create(username,uid):
if AUTH_USERS:
users = re.split(r'[\s,]+',AUTH_USERS)
for user in users:
if AuthorizedUser.objects.filter(email=user):
print(f'{"User already in Authorized Users list ----> add skipping"}')
is_email = re.match(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$',user) is not None
is_authorized_user = AuthorizedUser.objects.filter(email=user) if is_email else AuthorizedUser.objects.filter(username=user)
if is_authorized_user:
print(f"User {user} already in Authorized Users list ----> add skipping")
else:
u = AuthorizedUser(email=user)
u = AuthorizedUser(email=user) if is_email else AuthorizedUser(username=user)
u.save()
print(f"Added {user} to the Authorized Users list ----> add success")
print(f"Added {user} to the Authorized Users list ----> add success")

if IROD_AUTH_USERS:
print("IRODS USERS ENABLED")
with open('/etc/iroduserdata/iroduserdata','r') as f:
for line in f:
user,uid = line.split("::")
irods_user_create(user,uid)




if REMOVE_AUTH_USERS:
users = re.split(r'[\s,]+',REMOVE_AUTH_USERS)
for user in users:
a_user = AuthorizedUser.objects.filter(email=user)
is_email = re.match(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$',user) is not None
a_user = AuthorizedUser.objects.filter(email=user) if is_email else AuthorizedUser.objects.filter(username=user)
if a_user:
a_user.delete()
print(f"Removed {user} from Authorized Users list ----> remove success")
Expand Down
17 changes: 10 additions & 7 deletions bin/authorizeuser.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ manageauthorizedusers () {
for user in "${USERS[@]}"; do
cat <<EOF | appstore shell --settings=${BRAND_MODULE}
from core.models import AuthorizedUser
if AuthorizedUser.objects.filter(email="$user"):
print(f"User already in Authorized Users list ----> add skipping")
is_email = re.match(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$',user) is not None
is_authorized_user = AuthorizedUser.objects.filter(email="$user") if is_email else AuthorizedUser.objects.filter(username="$user")
if is_authorized_user:
print(f"User {"$user"} already in Authorized Users list ----> add skipping")
else:
u = AuthorizedUser(email="$user")
u = AuthorizedUser(email="$user") if is_email else AuthorizedUser(username="$user")
u.save()
print(f"Added {'$user'} to the Authorized Users list ----> add success")
print(f"Added {"$user"} to the Authorized Users list ----> add success")
EOF
done
fi
Expand All @@ -38,12 +40,13 @@ EOF
for user in "${USERS[@]}"; do
cat <<EOF | appstore shell --settings=appstore.settings.${brand}_settings
from core.models import AuthorizedUser
a_user = AuthorizedUser.objects.filter(email="$user")
is_email = re.match(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$',user) is not None
a_user = AuthorizedUser.objects.filter(email=$user) if is_email else AuthorizedUser.objects.filter(username=$user)
if a_user:
a_user.delete()
print(f"Removed {'$user'} from Authorized Users list ----> remove success")
print(f"Removed {user} from Authorized Users list ----> remove success")
else:
print(f"{'$user'} not in Authorized Users list ----> remove skipping")
print(f"{$user} not in Authorized Users list ----> remove skipping")
EOF
done
fi
Expand Down
4 changes: 3 additions & 1 deletion bin/createtestusers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
django_user.save()
if AuthorizedUser.objects.filter(email=email):
print(f'{"User already in Authorized Users list ----> add skipping"}')
elif AuthorizedUser.objects.filter(username=username):
print(f'{"User already in Authorized Users list ----> add skipping"}')
else:
u = AuthorizedUser(email=email)
u = AuthorizedUser(email=email, username=username)
u.save()
print(f"Added {username} to the Authorized Users list ----> add success")
else:
Expand Down
Loading