Skip to content
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
1 change: 1 addition & 0 deletions coldfront/config/plugins/ldap_fasrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
AUTH_LDAP_USER_SEARCH_BASE = ENV.str('AUTH_LDAP_USER_SEARCH_BASE')
AUTH_LDAP_GROUP_SEARCH_BASE = ENV.str('AUTH_LDAP_GROUP_SEARCH_BASE')
CF_LDAP_PROJECT_GROUP_SAM = ENV.str('CF_LDAP_PROJECT_GROUP_SAM', default=None)
CF_LDAP_FASSE_GROUP = ENV.str('CF_LDAP_FASSE_GROUP', default=None)


LOGGING['handlers']['ldap_fasrc'] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def handle(self, *args, **options):

for name, attribute_type, has_usage, is_private in (
('Starfish Zone', 'Int', False, False),
('is_fasse', 'Yes/No', False, False),
# UBCCR defaults
# ('Project ID', 'Text', False, False),
# ('Account Number', 'Int', False, True),
Expand Down
5 changes: 5 additions & 0 deletions coldfront/core/project/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ def latest_publication(self):
def sf_zone(self):
return self.get_attribute('Starfish Zone')

@property
def is_fasse(self):
"""Return True if the project has an is_fasse attribute set to 'True', False otherwise."""
return self.get_attribute('is_fasse') == 'True'

@property
def needs_review(self):
"""
Expand Down
33 changes: 33 additions & 0 deletions coldfront/plugins/ldap/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from coldfront.core.allocation.models import AllocationUserStatusChoice, AllocationUser
from coldfront.core.project.models import (
Project,
ProjectAttribute,
ProjectAttributeType,
ProjectStatusChoice,
ProjectUserRoleChoice,
ProjectUserStatusChoice,
Expand Down Expand Up @@ -559,6 +561,22 @@ def collect_update_project_status_membership():

ad_conn = LDAPConn()

# Resolve the set of project AD group SAMAccountNames that are MemberOf the fasse group.
CF_LDAP_FASSE_GROUP = import_from_settings('CF_LDAP_FASSE_GROUP', None)
fasse_project_titles = set()
if CF_LDAP_FASSE_GROUP:
fasse_entries = ad_conn.search_groups(
{'sAMAccountName': CF_LDAP_FASSE_GROUP}, attributes=['member']
)
if fasse_entries:
fasse_member_dns = fasse_entries[0].get('member', [])
if fasse_member_dns:
fasse_member_groups = ad_conn.search_groups(
{'distinguishedName': fasse_member_dns}, attributes=['sAMAccountName']
)
fasse_project_titles = {g['sAMAccountName'][0] for g in fasse_member_groups}
logger.debug('fasse project titles resolved from AD: %s', fasse_project_titles)

proj_membs_mans = {p: ad_conn.return_group_members_manager(p.title) for p in active_projects}
proj_membs_mans, _ = cleaned_membership_query(proj_membs_mans)
groupusercollections = [
Expand Down Expand Up @@ -633,8 +651,23 @@ def collect_update_project_status_membership():
)
logger.info("Reactivating projects: %s", [p.title for p in active_pi_group_projs_statuschange])
active_pi_group_projs_statuschange.update(status=project_active_status)
is_fasse_attr_type = ProjectAttributeType.objects.filter(name='is_fasse').first()

for group in active_pi_groups:

# Update is_fasse ProjectAttribute based on fasse group membership in AD.
if CF_LDAP_FASSE_GROUP and is_fasse_attr_type:
is_fasse = group.name in fasse_project_titles
ProjectAttribute.objects.update_or_create(
project=group.project,
proj_attr_type=is_fasse_attr_type,
defaults={'value': str(is_fasse)},
)
else:
logger.warning(
'Skipping is_fasse ProjectAttribute update. CF_LDAP_FASSE_GROUP or is_fasse ProjectAttributeType not found.'
)

ad_users_not_added, remove_projuser_names = group.compare_members_projectusers()
group_storage_allocations = group.project.allocation_set.filter(
resources__resource_type__name='Storage', status__name='Active'
Expand Down
Loading