Skip to content

Commit

Permalink
Fix so that MULTIPLE_REQUESTS_ALLOWED is obeyed.
Browse files Browse the repository at this point in the history
  • Loading branch information
amanning9 committed Mar 27, 2024
1 parent 36f84af commit 76fed67
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 56 deletions.
19 changes: 13 additions & 6 deletions jasmin_services/models/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,21 @@ def approvers(self):
)

def user_may_apply(self, user):
"""Helper for if the user is allowed to apply for this role."""
"""Return true if user is allowed to apply for this role."""
# If multiple requests are allowed, they are always allowed to apply.
if settings.MULTIPLE_REQUESTS_ALLOWED:
return True
return self.accesses.filter(
Q(grant__revoked=True)
| Q(grant__expires__lt=(django.utils.timezone.localdate() + dt.timedelta(days=60))),
user=user,
).exists()
# Otherwise get the valid (and not expiring soon) grants and requests the user has.
# If they have any, they are not allowed to apply.
valid_grants_requests = self.accesses.filter(user=user).filter(
Q(
Q(grant__revoked=False) # Valid grants are not revoked.
& Q(grant__expires__gt=(django.utils.timezone.localdate() + dt.timedelta(days=60)))
)
| Q(request__state="PENDING")
| Q(request__incomplete=True)
)
return not valid_grants_requests.exists()

def enable(self, user):
"""Enable this role for the given user."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
</thead>
<tbody>
{% for access in accesses %}
{{ access.frontend.may_apply }}
{% if access.status == "REVOKED" or access.status == "REJECTED" or access.status == "INCOMPLETE" %}
<tr class="table-danger">
<td class="text-danger" style="width: 1%;"><i class="fa fa-fw fa-ban"></i></td>
Expand All @@ -34,10 +33,12 @@
<td>{{ access.frontend.start|date:"DATE_FORMAT" }}</td>
<td>{{ access.expires|date:"DATE_FORMAT"|default:"-" }}</td>
<td>
{% if access.status == "EXPIRING" or access.status == "EXPIRED" %}
{% if access.status == "EXPIRING" or access.status == "EXPIRED" %}
{% if access.frontend.may_apply %}
<a class="btn btn-warning btn-sm" href="{{ access.frontend.apply_url }}">
Extend
</a>
{% endif %}
{% elif access.status == "REVOKED" or access.status == "REJECTED" or access.status == "INCOMPLETE" %}
<button class="btn btn-warning btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#access-collapse-{{ access.frontend.id }}">
See Reason
Expand All @@ -57,19 +58,21 @@
{% if access.status == "REVOKED" or access.status == "REJECTED" or access.status == "INCOMPLETE" %}
<p>This {{ access.frontend.type|lower }} was {{ access.status|lower }} for the following reason:</p>
<p>{{ access.user_reason|markdown }} </p>
{% if access.status == "INCOMPLETE"%}
{% if access.frontend.may_apply and access.status == "INCOMPLETE"%}
<a class="btn btn-warning btn-sm" href="{{ access.frontend.apply_url }}">Add Info</a>
{% elif access.status == "REVOKED" or access.status == "REJECTED" %}
{% if access.frontend.may_apply %}
<a class="btn btn-warning btn-sm" href="{{ access.frontend.apply_url }}">Reapply</a>
{% endif %}
{% endif %}
<hr />
{% endif %}
{% if access.status == "EXPIRING" %}
{% if access.frontend.may_apply and access.status == "EXPIRING" %}
<p>This grant is expiring soon.</p>
<a class="btn btn-warning btn-sm" href="{{ access.frontend.apply_url }}">Extend</a>
<hr />
{% endif %}
{% if access.status == "EXPIRED" %}
{% if access.frontend.may_apply and access.status == "EXPIRED" %}
<p>This grant is has expired.</p>
<a class="btn btn-warning btn-sm" href="{{ access.frontend.apply_url }}">Extend</a>
<hr />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@
</div>
<div class="col-md-6">
{% block service_access %}
{% if grants or requests%}
{% if accesses %}
<div class="card">
<div class="card-header">
<h3 class="card-title">Your Requests or Grants</h3>
</div>
<table class="table table-striped">
{% display_accesses auth.user grants requests %}
{% display_accesses accesses %}
</table>
</div>
{% endif %}
Expand Down Expand Up @@ -82,7 +82,7 @@ <h3 class="card-title">Your Requests or Grants</h3>
{% endif %}
{% endblock service_roles %}
{% block managers_deputies %}
{% if grants %}
{% if managers or deputies %}
<div class="card">
<div class="card-header">
<h3 class="card-title">Managers & Deputies</h3>
Expand Down
32 changes: 2 additions & 30 deletions jasmin_services/templatetags/service_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,34 +45,6 @@ def pending_req_count(context, service):


@register.inclusion_tag("jasmin_services/includes/display_accesses.html")
def display_accesses(user, *all_accesses):
"""Process a list of either requests or grants for display."""

accesses = list(itertools.chain.from_iterable(all_accesses))

# This ID is used to create CSS ids. Must be unique per access.
id_part = "".join(random.choice(string.ascii_lowercase) for i in range(5))
id_ = 0
# We loop through the list, and add some information which is not otherwise available.
for access in accesses:
access.frontend = {
"start": (access.requested_at if isinstance(access, Request) else access.granted_at),
"id": f"{id_part}_{id_}",
"type": ("REQUEST" if isinstance(access, Request) else "GRANT"),
"apply_url": django.urls.reverse(
"jasmin_services:role_apply",
kwargs={
"category": access.access.role.service.category.name,
"service": access.access.role.service.name,
"role": access.access.role.name,
"bool_grant": 0 if isinstance(access, Request) else 1,
"previous": access.id,
},
),
"may_apply": access.access.role.user_may_apply(user),
}
id_ += 1

accesses = sorted(accesses, key=lambda x: x.frontend["start"], reverse=True)

def display_accesses(accesses):
"""Template tag to display a list of accesses (requests and or grants)."""
return {"accesses": accesses}
57 changes: 45 additions & 12 deletions jasmin_services/views/service_details.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import itertools
import random
import string
from datetime import date

import django.views.generic
Expand Down Expand Up @@ -35,14 +38,43 @@ def get_service_roleholders(service, role_name):
)
return [x.access.user for x in holders]

@staticmethod
def display_accesses(user, *all_accesses):
"""Process a list of either requests or grants for display."""
accesses = list(itertools.chain.from_iterable(all_accesses))

# This ID is used to create CSS ids. Must be unique per access.
id_part = "".join(random.choice(string.ascii_lowercase) for i in range(5))
id_ = 0
# We loop through the list, and add some information which is not otherwise available.
for access in accesses:
access.frontend = {
"start": (
access.requested_at if isinstance(access, models.Request) else access.granted_at
),
"id": f"{id_part}_{id_}",
"type": ("REQUEST" if isinstance(access, models.Request) else "GRANT"),
"apply_url": django.urls.reverse(
"jasmin_services:role_apply",
kwargs={
"category": access.access.role.service.category.name,
"service": access.access.role.service.name,
"role": access.access.role.name,
"bool_grant": 0 if isinstance(access, models.Request) else 1,
"previous": access.id,
},
),
"may_apply": access.access.role.user_may_apply(user),
}
id_ += 1

accesses = sorted(accesses, key=lambda x: x.frontend["start"], reverse=True)
return accesses

def get_context_data(self, **kwargs):
"""Add information about service to the context."""
context = super().get_context_data(**kwargs)

roles = self.service.get_user_active_roles(self.request.user)
for role in roles:
print(role.id)

# Get the active grants and requests for the service as a whole
grants = (
models.Grant.objects.filter(
Expand All @@ -59,17 +91,19 @@ def get_context_data(self, **kwargs):
.prefetch_related("metadata")
)

# Get the roles the user is able to see.
# Get the roles the user is able to apply for.
# This is any roles which aren't hidden, or any role the user
# Has an access (request or grant) for.
visible_roles = self.service.roles.filter(
Q(hidden=False) | Q(access__user=self.request.user)
)
may_apply_roles = [
x
for x in self.service.roles.filter(Q(hidden=False) | Q(access__user=self.request.user))
if x.user_may_apply(self.request.user)
]

# If the user holds an active grant in the service
# get all the current managers and deputies of a services so that
# we can display this information to users of the service.
if grants:
if grants.exists():
managers = self.get_service_roleholders(self.service, "MANAGER")
deputies = self.get_service_roleholders(self.service, "DEPUTY")
else:
Expand All @@ -82,12 +116,11 @@ def get_context_data(self, **kwargs):

context |= {
"service": self.service,
"requests": requests,
"grants": grants,
"roles": visible_roles,
"roles": may_apply_roles,
"managers": managers,
"deputies": deputies,
"user_may_apply": common.user_may_apply(self.request.user, self.service),
"accesses": self.display_accesses(self.request.user, grants, requests),
}
return context

Expand Down

0 comments on commit 76fed67

Please sign in to comment.