Skip to content

Commit

Permalink
Merge pull request #330 from fasrc/cp_piprojuserrole
Browse files Browse the repository at this point in the history
Integrate PI projectuserrolechoice
  • Loading branch information
claire-peters authored Aug 23, 2024
2 parents 9634063 + 332eca3 commit 6f28d4e
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 49 deletions.
6 changes: 3 additions & 3 deletions coldfront/config/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
INACTIVE_ALLOCATION_STATUSES = ['Denied', 'Expired', 'Inactive', 'Pending Deactivation']

# Categorization of project manager permissions
MANAGERS = ['General Manager', 'Access Manager', 'Storage Manager']
ACCESS_MANAGERS = ['General Manager', 'Access Manager']
DATA_MANAGERS = ['General Manager', 'Storage Manager']
MANAGERS = ['PI', 'General Manager', 'Access Manager', 'Storage Manager']
ACCESS_MANAGERS = ['PI', 'General Manager', 'Access Manager']
DATA_MANAGERS = ['PI', 'General Manager', 'Storage Manager']

#------------------------------------------------------------------------------
# DjangoQ settings
Expand Down
2 changes: 1 addition & 1 deletion coldfront/core/allocation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ def user_permissions(self, user):

project_perms = self.project.user_permissions(user)

if ProjectPermission.PI in project_perms or ProjectPermission.DATA_MANAGER in project_perms:
if ProjectPermission.DATA_MANAGER in project_perms:
return [AllocationPermission.USER, AllocationPermission.MANAGER]

if self.project.projectuser_set.filter(user=user, status__name='Active').exists():
Expand Down
20 changes: 11 additions & 9 deletions coldfront/core/portal/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ def home(request):
Q(status__name__in=['Active', 'New', 'Renewal Requested', ]) &
Q(project__status__name__in=['Active', 'New']) &
(
Q(project__projectuser__user=request.user) &
Q(project__projectuser__status__name__in=['Active', ]) &
(Q(project__projectuser__role__name__in=MANAGERS) |
Q(allocationuser__user=request.user) &
Q(allocationuser__status__name='Active'))
) | Q(project__pi=request.user)
(
Q(project__projectuser__user=request.user) &
Q(project__projectuser__status__name__in=['Active', ]) &
(Q(project__projectuser__role__name__in=MANAGERS) |
Q(allocationuser__user=request.user) &
Q(allocationuser__status__name='Active'))
) | Q(project__pi=request.user)
)
).distinct().order_by('-created')

managed_allocations = Allocation.objects.filter(
Expand All @@ -61,14 +63,14 @@ def home(request):
)

if managed_allocations:
allocation_request_list = AllocationChangeRequest.objects.filter(
allocation_change_request_list = AllocationChangeRequest.objects.filter(
Q(allocation__in=managed_allocations) & (
Q(status__name='Pending') |
Q(modified__gt=timezone.now()-timezone.timedelta(days=30))
)
).distinct().order_by('-created')
else:
allocation_request_list = None
allocation_change_request_list = None

user_depts = DepartmentMember.objects.filter(user=request.user)
department_list = Department.objects.filter(
Expand All @@ -78,7 +80,7 @@ def home(request):
context['department_list'] = department_list
context['project_list'] = project_list
context['allocation_list'] = allocation_list
context['allocation_request_list'] = allocation_request_list
context['allocation_request_list'] = allocation_change_request_list

try:
context['ondemand_url'] = settings.ONDEMAND_URL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ <h3>Project: {{project.title}}</h3>
<b>Access Managers</b> have the permissions to manage group membership.<br/>
<b>Storage Managers</b> have the permissions to make allocation requests.<br/>
<b>General Managers</b> have the permissions of a PI, save the ability to assign other General Managers.<br/>
<b>PIs</b> have permissions to manage the project, its users, and its related allocations regardless of their assigned projectuser role.<br/>
<b>PIs</b> have permissions to manage the project, its users, and its related allocations.<br/>
</td>
</tr>
<tr>
Expand Down
20 changes: 0 additions & 20 deletions coldfront/core/project/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,6 @@
from coldfront.plugins.ifx.models import ProjectOrganization


def add_project_status_choices(apps, schema_editor):
ProjectStatusChoice = apps.get_model('project', 'ProjectStatusChoice')

for choice in ['New', 'Active', 'Archived', ]:
ProjectStatusChoice.objects.get_or_create(name=choice)


def add_project_user_role_choices(apps, schema_editor):
ProjectUserRoleChoice = apps.get_model('project', 'ProjectUserRoleChoice')

for choice in ['User', 'Storage Manager', 'General Manager', 'Access Manager']:
ProjectUserRoleChoice.objects.get_or_create(name=choice)


def add_project_user_status_choices(apps, schema_editor):
ProjectUserStatusChoice = apps.get_model('project', 'ProjectUserStatusChoice')

for choice in ['Active', 'Pending - Remove', 'Denied', 'Removed', ]:
ProjectUserStatusChoice.objects.get_or_create(name=choice)

def generate_usage_history_graph(project):
"""Create a Project billing record graph.
Expand Down
2 changes: 1 addition & 1 deletion coldfront/core/test_helpers/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
### Default values and Faker provider setup ###

project_status_choice_names = ['New', 'Active', 'Archived']
project_user_role_choice_names = ['User', 'Access Manager', 'General Manager', 'Storage Manager']
project_user_role_choice_names = ['User', 'Access Manager', 'Storage Manager', 'General Manager', 'PI']
field_of_science_names = ['Physics', 'Chemistry', 'Economics', 'Biology', 'Sociology']
attr_types = ['Date', 'Int', 'Float', 'Text', 'Boolean']

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def handle(self, *args, **options):
project_status_choices['New'] = ProjectStatusChoice.objects.get(name='New')

project_user_role_choices = {}
project_user_role_choices['PI'] = ProjectUserRoleChoice.objects.get(name='General Manager')
project_user_role_choices['PI'] = ProjectUserRoleChoice.objects.get(name='PI')
project_user_role_choices['U'] = ProjectUserRoleChoice.objects.get(name='User')
project_user_role_choices['M'] = ProjectUserRoleChoice.objects.get(name='General Manager')
project_user_role_choices['Manager'] = ProjectUserRoleChoice.objects.get(name='General Manager')
Expand Down
4 changes: 2 additions & 2 deletions coldfront/core/utils/management/commands/load_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def handle(self, *args, **options):
ProjectUser.objects.get_or_create(
user=pi1,
project=project_obj,
role=ProjectUserRoleChoice.objects.get(name='General Manager'),
role=ProjectUserRoleChoice.objects.get(name='PI'),
status=ProjectUserStatusChoice.objects.get(name='Active')
)

Expand Down Expand Up @@ -399,7 +399,7 @@ def handle(self, *args, **options):
project_user_obj, _ = ProjectUser.objects.get_or_create(
user=pi2,
project=project_obj,
role=ProjectUserRoleChoice.objects.get(name='General Manager'),
role=ProjectUserRoleChoice.objects.get(name='PI'),
status=ProjectUserStatusChoice.objects.get(name='Active')
)

Expand Down
23 changes: 12 additions & 11 deletions coldfront/plugins/ldap/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,13 +431,13 @@ def collect_update_project_status_membership():
[(pi.project.title, pi.user.username) for pi in pis_to_deactivate])

### identify PIs with incorrect roles and change their status ###
projectuser_role_manager = ProjectUserRoleChoice.objects.get(name='General Manager')
projectuser_role_pi = ProjectUserRoleChoice.objects.get(name='PI')

pis_mislabeled = ProjectUser.objects.filter(
reduce(operator.or_,
(( Q(project=group.project) &
Q(user__username=group.pi['sAMAccountName']) &
~Q(role=projectuser_role_manager))
Q(user__username=group.pi['sAMAccountName'][0]) &
~Q(role=projectuser_role_pi))
for group in active_pi_groups)
)
)
Expand All @@ -446,7 +446,7 @@ def collect_update_project_status_membership():
logger.info('Project PIs with incorrect labeling: %s',
[(pi.project.title, pi.user.username) for pi in pis_mislabeled])
ProjectUser.objects.bulk_update([
ProjectUser(id=pi.id, role=projectuser_role_manager)
ProjectUser(id=pi.id, role=projectuser_role_pi)
for pi in pis_mislabeled
], ['role'])

Expand Down Expand Up @@ -478,7 +478,7 @@ def collect_update_project_status_membership():
)
if present_projectusers:
logger.warning('found reactivated ADUsers for project %s: %s',
group.project.title, [user.user.username for user in present_projectusers])
group.project.title, [u.user.username for u in present_projectusers])

present_projectusers.update(
role=projectuser_role_user, status=projectuserstatus_active
Expand Down Expand Up @@ -644,16 +644,16 @@ def add_new_projects(groupusercollections, errortracker):
logger.debug('adding manager status to ProjectUser %s for Project %s',
group.pi['sAMAccountName'][0], group.name)
try:
manager = group.project.projectuser_set.get(
pi_projuser = group.project.projectuser_set.get(
user__username=group.pi['sAMAccountName'][0]
)
except ProjectUser.DoesNotExist:
logger.warning('PI %s not found in ProjectUser for Project %s',
logger.warning('PI %s not found in %s AD Group Members',
group.pi['sAMAccountName'][0], group.name)
errortracker['pi_not_projectuser'].append(group.name)
continue
manager.role = ProjectUserRoleChoice.objects.get(name='General Manager')
manager.save()
pi_projuser.role = ProjectUserRoleChoice.objects.get(name='PI')
pi_projuser.save()
added_projects.append([group.name, group.project])

for errortype in errortracker:
Expand All @@ -674,7 +674,6 @@ def identify_ad_group(sender, **kwargs):
ifx_pi = get_user_model().objects.get(username=manager['sAMAccountName'][0])
except Exception as e:
raise ValueError(f"issue retrieving pi's ifxuser entry: {e}")

return ifx_pi

@receiver(project_post_create)
Expand Down Expand Up @@ -702,10 +701,12 @@ def update_new_project(sender, **kwargs):
project.pi = get_user_model().objects.get(username=manager['sAMAccountName'][0])
project.save()
for member in members:
role_name = "User" if member['sAMAccountName'][0] != manager['sAMAccountName'][0] else "General Manager"
role_name = "User" if member['sAMAccountName'][0] != manager['sAMAccountName'][0] else "PI"
try:
user_obj = get_user_model().objects.get(username=member['sAMAccountName'][0])
except get_user_model().DoesNotExist:
logger.warning('User %s not found when trying to add to Project %s',
member['sAMAccountName'][0], project.title)
continue
ProjectUser.objects.create(
project=project,
Expand Down

0 comments on commit 6f28d4e

Please sign in to comment.