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

Add eula enforcement #609

Open
wants to merge 61 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
cb60d7c
started eula user functionality
rg663 Jun 27, 2023
90d9b5e
made it so user status is pending when allocation has eula
rg663 Jun 27, 2023
d9f6bf3
added email functionality
rg663 Jun 27, 2023
47f2f3f
line deletion
rg663 Jun 27, 2023
0c361d2
add config variable check to each part
rg663 Jun 27, 2023
6f26dcf
working through user statuses
rg663 Jun 29, 2023
1ca566d
enabling checkbox functionality
rg663 Jun 29, 2023
a7f6c7c
started selection functionality
rg663 Jul 1, 2023
ba9ccf0
working on agree button
rg663 Jul 5, 2023
e21f12a
users can now accept/decline eulas
rg663 Jul 5, 2023
019d7a5
small change
rg663 Jul 5, 2023
2e9c468
fixed email
rg663 Jul 5, 2023
913594b
code cleanup
rg663 Jul 5, 2023
2701732
email functionality close to working
rg663 Jul 5, 2023
edd4d13
functionality near complete
rg663 Jul 5, 2023
4a8a14f
email functionality almost done
rg663 Jul 6, 2023
9a3dd2d
fixed functionality for when config is false
rg663 Jul 6, 2023
a8c1667
bug fix
rg663 Jul 6, 2023
99825f4
emails work
rg663 Jul 7, 2023
e023f7e
email updates
rg663 Jul 7, 2023
850a223
config fix
rg663 Jul 7, 2023
6d40263
small fixes
rg663 Jul 8, 2023
2c1b66e
Update add_scheduled_tasks.py
rg663 Jul 8, 2023
5a32cf4
Update allocation_agree_to_eula.txt
rg663 Jul 8, 2023
d314048
refactored eula reminder emails
rg663 Jul 13, 2023
fcc451c
Update .gitignore
rg663 Jul 25, 2023
40beb99
Update add_allocation_defaults.py
rg663 Jul 27, 2023
8aec097
Update add_allocation_defaults.py
rg663 Jul 27, 2023
6ed7dd4
added ability to prompt users when adding to allocation and have eula…
rg663 Jun 14, 2023
d23c4be
commit with comments
rg663 Jun 18, 2023
3f47066
done
rg663 Jun 18, 2023
ae2cb8f
fixed formatting and removed comments
rg663 Jun 18, 2023
a78cb0f
fixed functionality when adding 0 users to allocation
rg663 Jun 18, 2023
131b361
fixed display for allocations without eula
rg663 Jun 18, 2023
67f62a6
fixed checkbox functionality
rg663 Jun 26, 2023
709e8c1
code cleanup
rg663 Jun 27, 2023
6627fe8
fixed bug in eula display
rg663 Jul 5, 2023
76d1d98
fixed html side of bug
rg663 Jul 5, 2023
db0f320
add EULA_AGREEMENT to resource view
jrlagrone Apr 10, 2024
679e261
changing pending -> pendingeula for clarity
jrlagrone Apr 10, 2024
a79ba7f
change denied -> deniedeula for clarity
jrlagrone Apr 10, 2024
d35f8f3
only show eula approval to current user
jrlagrone Apr 10, 2024
7be2046
handled pending eula differently than other cases
jrlagrone Apr 11, 2024
c7caf60
fix user in allocation check
jrlagrone Apr 11, 2024
6a6ed57
don't ask a PI to accept EULA for user
jrlagrone Apr 11, 2024
da0d7f5
remove more PI prompts to accept user EULA
jrlagrone Apr 11, 2024
ca141eb
don't default to users being active. They may not have agreed to the …
jrlagrone Apr 11, 2024
dca5baa
refactor to not redfine the same function many times
jrlagrone Apr 11, 2024
a6334f0
remove unused pending allocations
jrlagrone Apr 11, 2024
bf9ee30
default new users on allocations to pending eula not active
jrlagrone Apr 11, 2024
3d44d76
remove another instance of get_eula def
jrlagrone Apr 11, 2024
0b363b1
add more helpful messaging and links for pending allocations
jrlagrone Apr 11, 2024
1d55c0b
remove debug prints
jrlagrone Apr 11, 2024
8556e5a
remove debugging / handle reject eula better
jrlagrone Apr 12, 2024
3546808
start breaking out some eula logic to it's own page
jrlagrone Apr 12, 2024
0a43c0d
finish moving EULA acceptance /review to it's own page
jrlagrone Apr 12, 2024
7980662
fix some links and remove unused form
jrlagrone Apr 12, 2024
b248fed
remove import of unused form
jrlagrone Apr 12, 2024
8b458f9
only get user status if user is in allocation
jrlagrone Apr 30, 2024
5545cd3
remove white space
jrlagrone May 10, 2024
a4d5ac5
remove site specific .gitignore
jrlagrone May 10, 2024
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
9 changes: 7 additions & 2 deletions coldfront/config/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#------------------------------------------------------------------------------
PROJECT_ENABLE_PROJECT_REVIEW = ENV.bool('PROJECT_ENABLE_PROJECT_REVIEW', default=True)

#------------------------------------------------------------------------------
# Enable EULA force agreement
#------------------------------------------------------------------------------
EULA_AGREEMENT = ENV.bool('EULA_AGREEMENT', default=True)

#------------------------------------------------------------------------------
# Allocation related
#------------------------------------------------------------------------------
Expand All @@ -29,7 +34,6 @@
# This is in days
ALLOCATION_DEFAULT_ALLOCATION_LENGTH = ENV.int('ALLOCATION_DEFAULT_ALLOCATION_LENGTH', default=365)


#------------------------------------------------------------------------------
# Allow user to select account name for allocation
#------------------------------------------------------------------------------
Expand All @@ -38,7 +42,8 @@

SETTINGS_EXPORT += [
'ALLOCATION_ACCOUNT_ENABLED',
'CENTER_HELP_URL'
'CENTER_HELP_URL',
'EULA_AGREEMENT'
]

ADMIN_COMMENTS_SHOW_EMPTY = ENV.bool('ADMIN_COMMENTS_SHOW_EMPTY', default=True)
Expand Down
1 change: 1 addition & 0 deletions coldfront/config/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@
EMAIL_ALLOCATION_EXPIRING_NOTIFICATION_DAYS = ENV.list('EMAIL_ALLOCATION_EXPIRING_NOTIFICATION_DAYS', cast=int, default=[7, 14, 30])
EMAIL_SIGNATURE = ENV.str('EMAIL_SIGNATURE', default='', multiline=True)
EMAIL_ADMINS_ON_ALLOCATION_EXPIRE = ENV.bool('EMAIL_ADMINS_ON_ALLOCATION_EXPIRE', default=False)
EMAIL_EULA_REMINDERS = ENV.bool('EMAIL_EULA_REMINDERS', default=True)
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def handle(self, *args, **options):
for choice in ('Pending', 'Approved', 'Denied',):
AllocationChangeStatusChoice.objects.get_or_create(name=choice)

for choice in ('Active', 'Error', 'Removed', ):
for choice in ('Active', 'Error', 'Removed', 'PendingEULA', 'DeclinedEULA'):
AllocationUserStatusChoice.objects.get_or_create(name=choice)

for name, attribute_type, has_usage, is_private in (
Expand Down
12 changes: 10 additions & 2 deletions coldfront/core/allocation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
['-is_allocatable', 'name'])

class AllocationPermission(Enum):
""" A project permission stores the user and manager fields of a project. """
""" An allocation permission stores the user and manager fields of a project. """

USER = 'USER'
MANAGER = 'MANAGER'
Expand Down Expand Up @@ -321,7 +321,7 @@ def user_permissions(self, user):
if ProjectPermission.PI in project_perms or ProjectPermission.MANAGER in project_perms:
return [AllocationPermission.USER, AllocationPermission.MANAGER]

if self.allocationuser_set.filter(user=user, status__name__in=['Active', 'New', ]).exists():
if self.allocationuser_set.filter(user=user, status__name__in=['Active', 'New', 'PendingEULA']).exists():
return [AllocationPermission.USER]

return []
Expand All @@ -341,6 +341,14 @@ def has_perm(self, user, perm):

def __str__(self):
return "%s (%s)" % (self.get_parent_resource.name, self.project.pi)

def get_eula(self):
if self.get_resources_as_list:
for res in self.get_resources_as_list:
if res.get_attribute(name='eula'):
return res.get_attribute(name='eula')
else:
return None

class AllocationAdminNote(TimeStampedModel):
""" An allocation admin note is a note that an admin makes on an allocation.
Expand Down
22 changes: 21 additions & 1 deletion coldfront/core/allocation/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import logging

from coldfront.core.allocation.models import (Allocation,
AllocationStatusChoice)
AllocationStatusChoice, AllocationUserStatusChoice)
from coldfront.core.allocation.utils import get_user_resources
from coldfront.core.user.models import User
from coldfront.core.utils.common import import_from_settings
from coldfront.core.utils.mail import send_email_template
Expand Down Expand Up @@ -39,6 +40,25 @@ def update_statuses():
logger.info('Allocations set to expired: {}'.format(
allocations_to_expire.count()))

def send_eula_reminders():
for allocation in Allocation.objects.all():
if allocation.get_eula():
email_receiver_list = []
for allocation_user in allocation.allocationuser_set.all():
if allocation_user.status == AllocationUserStatusChoice.objects.get(name='PendingEULA'):
if allocation_user.user.email not in email_receiver_list:
email_receiver_list.append(allocation_user.user.email)

template_context = {
'center_name': CENTER_NAME,
'resource': allocation.get_parent_resource,
'url': f'{CENTER_BASE_URL.strip("/")}/{"allocation"}/{allocation.pk}/review-eula',
'signature': EMAIL_SIGNATURE
}

if email_receiver_list:
send_email_template(f'Reminder: Agree to EULA for {allocation}', 'email/allocation_eula_reminder.txt', template_context, EMAIL_SENDER, email_receiver_list)
logger.debug(f'Allocation(s) EULA reminder sent to users {email_receiver_list}.')

def send_expiry_emails():
#Allocations expiring soon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ <h2>Add users to allocation for project: {{allocation.project.title}}</h2>
</div>
{{ formset.management_form }}
<div>
<button type="submit" class="btn btn-primary"><i class="fas
<button type="submit" class="btn btn-primary confirm-add"><i class="fas
fa-user-plus"></i> Add Selected Users to Allocation</button>
<a class="btn btn-secondary" href="{% url 'allocation-detail' allocation.pk %}" role="button"><i class="fas fa-long-arrow-left" aria-hidden="true"></i>
Back to Allocation</a>
Expand Down Expand Up @@ -75,4 +75,4 @@ <h2>Add users to allocation for project: {{allocation.project.title}}</h2>
}
});
</script>
{% endblock %}
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ <h3><i class="fas fa-list" aria-hidden="true"></i> Allocation Information</h3>
{% for resource in allocation.get_resources_as_list %}
<a href="{% url 'resource-detail' resource.pk %}">{{ resource }}</a> <br>
{% endfor %}
{% else %}
None
{% endif %}
{% else %}
None
{% endif %}
</td>
</tr>
{% if request.user.is_superuser %}
Expand Down Expand Up @@ -173,6 +173,41 @@ <h3><i class="fas fa-list" aria-hidden="true"></i> Allocation Information</h3>
</div>
</div>

{% if eulas %}
<div class="card mb-3">
<div class="card-header">
<h3 class="d-inline"><i class="fas fa-info-circle" aria-hidden="true"></i> EULA Agreements </h3>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-sm">
<thead>
<tr>
<th scope="col">Resource</th>
<th scope="col">EULA</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<a href="{% url 'resource-detail' res %}">{{res_obj}}</a><br>
</td>
<td>
{{eulas}}
</td>
</tr>
</tbody>
</table>
{% if user_in_allocation %}
<div class="d-inline-flex">
<a href="{% url 'allocation-review-eula' allocation.pk %}">Review EULA Agreement</a>
</div>
{% endif %}
</div>
</div>
</div>
{% endif %}

{% if attributes or attributes_with_usage or request.user.is_superuser %}
<div class="card mb-3">
<div class="card-header">
Expand Down Expand Up @@ -234,6 +269,7 @@ <h4 class="card-title">{{attribute}}</h4>
</div>
{% endif %}

{% if not user_is_pending %}
<!-- Start Allocation Change Requests -->
<div class="card mb-3">
<div class="card-header">
Expand Down Expand Up @@ -322,7 +358,9 @@ <h3 class="d-inline"><i class="fas fa-users" aria-hidden="true"></i> Users in Al
<td>{{ user.user.email }}</td>
{% if user.status.name == 'Active' %}
<td class="text-success">{{ user.status.name }}</td>
{% elif user.status.name == 'Denied' or user.status.name == 'Error' %}
{% elif user.status.name == 'PendingEULA' %}
<td class="text-info">{{ user.status.name }}</td>
{% elif user.status.name == 'Denied' or user.status.name == 'Error' or user.status.name == 'DeclinedEULA' %}
<td class="text-danger">{{ user.status.name }}</td>
{% else %}
<td class="text-info">{{ user.status.name }}</td>
Expand Down Expand Up @@ -380,6 +418,7 @@ <h3 class="d-inline"><i class="fas fa-users" aria-hidden="true"></i> Notificatio
{% endif %}
</div>
</div>
{% endif %}

<script>
$(document).ready(function () {
Expand Down Expand Up @@ -431,4 +470,4 @@ <h3 class="d-inline"><i class="fas fa-users" aria-hidden="true"></i> Notificatio
}
})
</script>
{% endblock %}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{% extends "common/base.html" %}
{% load crispy_forms_tags %}
{% load static %}


{% block title %}
Review Allocation EULA
{% endblock %}


{% block content %}
{% if allocation.project.status.name == 'Archived' %}
<div class="alert alert-warning" role="alert">
This is a allocation from an archived project! You cannot make any changes.
</div>
{% endif %}


{% if form.non_field_errors %}
<div class="alert alert-danger" role="alert">
{{ form.non_field_errors }}
</div>
{% endif %}

{% if eulas %}
<div class="card mb-3">
<div class="card-header">
<h3 class="d-inline"><i class="fas fa-info-circle" aria-hidden="true"></i> EULA Agreements </h3>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-sm">
<thead>
<tr>
<th scope="col">Resource</th>
<th scope="col">EULA</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<a href="{% url 'resource-detail' res %}">{{res_obj}}</a><br>
</td>
<td>
{{eulas}}
</td>
</tr>
</tbody>
</table>
{% if allocation_user_status %}
{% if allocation_user_status == 'PendingEULA' %}
<form method="post">
{% csrf_token %}
<h4 class="d-inline">In order to access <a href="{% url 'allocation-detail' allocation %}">this allocation</a> you must agree to the EULA</h4>
<div style="padding-top:1em">
<button type="submit" name="action" value="accepted_eula" class="btn btn-success mr-1 confirm-eula">I Agree</button>
<button type="submit" name="action" value="declined_eula" class="btn btn-danger mr-1 confirm-deny-eula">I Disagree</button>
</div>
</form>
{% elif allocation_user_status == 'DeclinedEULA' %}
<h4 class="d-inline">You declined the EULA for <a href="{% url 'allocation-detail' allocation %}">this allocation</a> on {{last_updated}}</h4>
{% elif allocation_user_status == 'Active' %}
<h4 class="d-inline">You accepted the EULA for <a href="{% url 'allocation-detail' allocation %}">this allocation</a> on {{last_updated}}</h4>
{% endif %}
{% endif %}
</div>
</div>
</div>
{% endif %}
{% endblock %}
2 changes: 2 additions & 0 deletions coldfront/core/allocation/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
allocation_views.AllocationCreateView.as_view(), name='allocation-create'),
path('<int:pk>/', allocation_views.AllocationDetailView.as_view(),
name='allocation-detail'),
path('<int:pk>/review-eula', allocation_views.AllocationEULAView.as_view(),
name='allocation-review-eula'),
path('change-request/<int:pk>/', allocation_views.AllocationChangeDetailView.as_view(),
name='allocation-change-detail'),
path('<int:pk>/delete-attribute-change', allocation_views.AllocationChangeDeleteAttributeView.as_view(),
Expand Down
Loading