Skip to content

Commit

Permalink
Permissions and Registrations
Browse files Browse the repository at this point in the history
  • Loading branch information
chandra-tacc committed Feb 7, 2025
1 parent ebf3bea commit 09b64c6
Show file tree
Hide file tree
Showing 14 changed files with 170 additions and 115 deletions.
4 changes: 2 additions & 2 deletions apcd_cms/src/apps/admin_regis_table/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from django.urls import path
from apps.admin_regis_table.views import RegistrationsTable, RegistrationsApi
from apps.admin_regis_table.views import RegistrationsTable, RegistrationsApi, RegistrationsPostApi

app_name = 'admin_regis_table'
urlpatterns = [
path('list-registration-requests/', RegistrationsTable.as_view(), name='admin_regis_table'),
path('list-registration-requests/api/', RegistrationsApi.as_view(), name='admin_regis_table_api'),
path('request-to-submit/api/<int:reg_id>/', RegistrationsApi.as_view(), name='admin_regis_update_api'),
path('request-to-submit/api/<int:reg_id>/', RegistrationsPostApi.as_view(), name='admin_regis_update_api'),
]
61 changes: 61 additions & 0 deletions apcd_cms/src/apps/admin_regis_table/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

from apps.components.paginator.paginator import paginator
from apps.utils.registrations_data_formatting import (
_set_registration_for_listing,
)
from apps.utils.utils import table_filter
from datetime import date as datetimeDate


def get_registration_list_json(registrations_content, status_filter, org_filter, page_num, *args, **kwargs):
context = {}

context['header'] = ['Business Name', 'Year', 'Type', 'Location', 'Registration Status', 'Actions']
context['status_options'] = ['All', 'Received', 'Processing', 'Complete', 'Withdrawn']
context['org_options'] = ['All']

def getDate(row):
date = row[1]
return date if date is not None else datetimeDate(1, 1, 1) # put 'None' date entries all together at end of listing w/ date 1-1-0001

registrations_content = sorted(registrations_content, key=lambda row: getDate(row), reverse=True) # sort registrations by newest to oldest

registration_table_entries = []
for registration in registrations_content:
registration_table_entries.append(_set_registration_for_listing(registration))
org_name = registration[5]
if org_name not in context['org_options']:
context['org_options'].append(org_name)

queryStr = ''

context['selected_status'] = None
if status_filter is not None and status_filter != 'All':
context['selected_status'] = status_filter
queryStr += f'&status={status_filter}'
registration_table_entries = table_filter(status_filter, registration_table_entries, 'reg_status')

context['selected_org'] = None
if org_filter is not None and org_filter != 'All':
context['selected_org'] = org_filter
queryStr += f'&org={org_filter}'
registration_table_entries = table_filter(org_filter.replace("(", "").replace(")", ""), registration_table_entries, 'biz_name')

context['query_str'] = queryStr
page_info = paginator(page_num, registration_table_entries)
context['page'] = [
{
'biz_name': obj['biz_name'],
'year': obj['year'],
'type': obj['type'],
'location': obj['location'],
'reg_status': obj['reg_status'],
'reg_id': obj['reg_id'],
}
for obj in page_info['page']
]
context['page_num'] = page_num
context['total_pages'] = page_info['page'].paginator.num_pages
context['pagination_url_namespaces'] = 'administration:admin_regis_table'
return context

99 changes: 32 additions & 67 deletions apcd_cms/src/apps/admin_regis_table/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@
update_registration_contact,
update_registration_entity,
)
from apps.utils.utils import table_filter
from apps.utils.registrations_data_formatting import (
_set_registration,
_set_registration_for_listing,
)
from apps.components.paginator.paginator import paginator
from apps.base.base import BaseAPIView, APCDAdminAccessAPIMixin, APCDAdminAccessTemplateMixin
from apps.submitter_renewals_listing.utils import get_submitter_codes
from apps.utils.apcd_groups import is_apcd_admin
from apps.admin_regis_table.utils import get_registration_list_json
from apps.base.base import (
BaseAPIView,
APCDAdminAccessAPIMixin,
APCDAdminAccessTemplateMixin,
APCDSubmitterAdminAccessAPIMixin,
)
import logging
from datetime import date as datetimeDate
import json

logger = logging.getLogger(__name__)
Expand All @@ -28,15 +32,18 @@ class RegistrationsTable(APCDAdminAccessTemplateMixin, TemplateView):
template_name = 'list_registrations.html'


class RegistrationsApi(APCDAdminAccessAPIMixin, BaseAPIView):
def _get_first_registration_entry(self, reg_id):
registrations = get_registrations(reg_id=reg_id)
if len(registrations) > 0:
return registrations[0]
else:
raise Exception(f'Registration not found {reg_id}')

class RegistrationsPostApi(APCDSubmitterAdminAccessAPIMixin, BaseAPIView):
def post(self, request, reg_id):
# Important: This POST api handles both admin and submitter admin
# Check if the registration id is allowed for submitter admin access.
if not is_apcd_admin(request.user):
response = get_submitter_codes(request.user)
submitter_codes = json.loads(response.content)['submitter_codes']
registrations = get_registrations(submitter_codes=submitter_codes, reg_id=reg_id)
if len(registrations) == 0:
logger.error(f'Registration not found {reg_id}')
return JsonResponse({'error': 'NotFound'}, status=404)

form = json.loads(request.body)
reg_entities = form['entities']
reg_contacts = form['contacts']
Expand Down Expand Up @@ -92,6 +99,15 @@ def _err_msg(resp):

return response


class RegistrationsApi(APCDAdminAccessAPIMixin, BaseAPIView):
def _get_first_registration_entry(self, reg_id):
registrations = get_registrations(reg_id=reg_id)
if len(registrations) > 0:
return registrations[0]
else:
raise Exception(f'Registration not found {reg_id}')

def get(self, request, *args, **kwargs):
if request.GET.get('reg_id'):
reg_id = int(request.GET.get('reg_id'))
Expand All @@ -105,59 +121,8 @@ def get(self, request, *args, **kwargs):
page_num = int(request.GET.get('page'))
except:
page_num = 1
context = RegistrationsApi.get_registration_list_json(registrations_content, request.GET.get('status'),
request.GET.get('org'), page_num, *args, **kwargs)
context = get_registration_list_json(registrations_content, request.GET.get('status'),
request.GET.get('org'), page_num, *args, **kwargs)
return JsonResponse({'response': context})

@staticmethod
def get_registration_list_json(registrations_content, status_filter, org_filter, page_num, *args, **kwargs):
context = {}

context['header'] = ['Business Name', 'Year', 'Type', 'Location', 'Registration Status', 'Actions']
context['status_options'] = ['All', 'Received', 'Processing', 'Complete', 'Withdrawn']
context['org_options'] = ['All']

def getDate(row):
date = row[1]
return date if date is not None else datetimeDate(1, 1, 1) # put 'None' date entries all together at end of listing w/ date 1-1-0001

registrations_content = sorted(registrations_content, key=lambda row: getDate(row), reverse=True) # sort registrations by newest to oldest

registration_table_entries = []
for registration in registrations_content:
registration_table_entries.append(_set_registration_for_listing(registration))
org_name = registration[5]
if org_name not in context['org_options']:
context['org_options'].append(org_name)

queryStr = ''

context['selected_status'] = None
if status_filter is not None and status_filter != 'All':
context['selected_status'] = status_filter
queryStr += f'&status={status_filter}'
registration_table_entries = table_filter(status_filter, registration_table_entries, 'reg_status')

context['selected_org'] = None
if org_filter is not None and org_filter != 'All':
context['selected_org'] = org_filter
queryStr += f'&org={org_filter}'
registration_table_entries = table_filter(org_filter.replace("(", "").replace(")", ""), registration_table_entries, 'biz_name')

context['query_str'] = queryStr
page_info = paginator(page_num, registration_table_entries)
context['page'] = [
{
'biz_name': obj['biz_name'],
'year': obj['year'],
'type': obj['type'],
'location': obj['location'],
'reg_status': obj['reg_status'],
'reg_id': obj['reg_id'],
}
for obj in page_info['page']
]
context['page_num'] = page_num
context['total_pages'] = page_info['page'].paginator.num_pages
context['pagination_url_namespaces'] = 'administration:admin_regis_table'
return context

6 changes: 3 additions & 3 deletions apcd_cms/src/apps/base/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.http import HttpResponseRedirect, JsonResponse
from django.views import View
from apps.utils.apcd_groups import is_apcd_admin, has_apcd_group
from apps.utils.apcd_groups import is_apcd_admin, has_apcd_group, has_groups
import logging

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -41,7 +41,7 @@ class APCDSubmitterAdminAccessTemplateMixin:
""" Template Mixin to restrict access to users with Admin and Submitter Admin. """

def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated or not has_apcd_group(request.user):
if not request.user.is_authenticated or not has_groups(request.user, ['APCD_ADMIN', 'SUBMITTER_ADMIN']):
return HttpResponseRedirect('/')
return super().dispatch(request, *args, **kwargs)

Expand All @@ -68,6 +68,6 @@ class APCDSubmitterAdminAccessAPIMixin:
""" API Mixin to restrict access to users with Admin and Submitter Admin. """

def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated or not has_apcd_group(request.user):
if not request.user.is_authenticated or not has_groups(request.user, ['APCD_ADMIN', 'SUBMITTER_ADMIN']):
return JsonResponse({'error': 'Unauthorized'}, status=403)
return super().dispatch(request, *args, **kwargs)
17 changes: 9 additions & 8 deletions apcd_cms/src/apps/registrations/views.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from apps.utils.apcd_database import create_registration, create_registration_entity, create_registration_contact, get_registrations, get_registration_entities, get_registration_contacts
from apps.utils.apcd_groups import has_apcd_group
from apps.utils.registrations_data_formatting import _set_registration
from apps.submitter_renewals_listing.views import get_submitter_code
from apps.submitter_renewals_listing.utils import get_submitter_codes
from apps.utils.apcd_groups import has_groups
from django.conf import settings
from django.http import HttpResponseRedirect, JsonResponse
from django.http import JsonResponse
from django.views.generic import TemplateView
from apps.base.base import BaseAPIView, APCDSubmitterAdminAccessAPIMixin, APCDSubmitterAdminAccessTemplateMixin
from apps.base.base import BaseAPIView, APCDGroupAccessTemplateMixin, APCDGroupAccessAPIMixin
from requests.auth import HTTPBasicAuth
import logging
import rt
Expand All @@ -20,20 +20,21 @@
RT_QUEUE = getattr(settings, 'RT_QUEUE', '')


class RegistrationFormTemplate(APCDSubmitterAdminAccessTemplateMixin, TemplateView):
class RegistrationFormTemplate(APCDGroupAccessTemplateMixin, TemplateView):
template_name = 'registration_form.html'


class RegistrationFormApi(APCDSubmitterAdminAccessAPIMixin, BaseAPIView):
class RegistrationFormApi(APCDGroupAccessAPIMixin, BaseAPIView):

def get(self, request):
formatted_reg_data = []
renew = False
reg_id = request.GET.get('reg_id', None).rstrip('/') # reg_id coming from renew has trailing slash appended, need to remove to pass correct request through
# this is primarily used for renewal and restricted to admins
if reg_id and (has_groups(request.user, ['APCD_ADMIN', 'SUBMITTER_ADMIN'])):
response = get_submitter_code(request.user)
submitter_code = json.loads(response.content)['submitter_code']
submitter_registrations = get_registrations(submitter_code=submitter_code)
response = get_submitter_codes(request.user)
submitter_codes = json.loads(response.content)['submitter_codes']
submitter_registrations = get_registrations(submitter_codes=submitter_codes)
registration_content = [registration for registration in submitter_registrations if registration[0] == int(reg_id)][0]
registration_entities = get_registration_entities(reg_id=reg_id)
registration_contacts = get_registration_contacts(reg_id=reg_id)
Expand Down
12 changes: 12 additions & 0 deletions apcd_cms/src/apps/submitter_renewals_listing/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from apps.utils.apcd_database import (
get_submitter_info,
)
from django.http import JsonResponse


def get_submitter_codes(user):
submitter = get_submitter_info(str(user))
submitter_codes = []
for i in submitter:
submitter_codes.append(i[1])
return JsonResponse({'submitter_codes': submitter_codes} if submitter_codes else [], safe=False)
36 changes: 13 additions & 23 deletions apcd_cms/src/apps/submitter_renewals_listing/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.http import JsonResponse
from apps.utils.apcd_database import get_registrations, get_registration_contacts, get_submitter_info, get_registration_entities
from apps.utils.apcd_database import get_registrations, get_registration_contacts, get_registration_entities
from django.views.generic.base import TemplateView
from apps.admin_regis_table.views import RegistrationsApi
from apps.admin_regis_table.utils import get_registration_list_json
from apps.base.base import BaseAPIView, APCDSubmitterAdminAccessAPIMixin, APCDSubmitterAdminAccessTemplateMixin
from apps.utils.registrations_data_formatting import _set_registration
from apps.submitter_renewals_listing.utils import get_submitter_codes
import logging
import json

Expand All @@ -16,47 +17,36 @@ class SubmittersTable(APCDSubmitterAdminAccessTemplateMixin, TemplateView):

class SubmittersApi(APCDSubmitterAdminAccessAPIMixin, BaseAPIView):

def _get_first_registration_entry(self, submitter_code, reg_id):
registrations = get_registrations(submitter_code=submitter_code, reg_id=reg_id)
def _get_first_registration_entry(self, submitter_codes, reg_id):
registrations = get_registrations(submitter_codes=submitter_codes, reg_id=reg_id)
if len(registrations) > 0:
return registrations[0]
else:
raise Exception(f'Registration not found {reg_id}')

def get(self, request, *args, **kwargs):
response = get_submitter_code(request.user)
submitter_code = json.loads(response.content)['submitter_code']
response = get_submitter_codes(request.user)
submitter_codes = json.loads(response.content)['submitter_codes']
registrations_content = []
registrations_entities = []
registrations_contacts = []
if request.GET.get('reg_id'):
reg_id = int(request.GET.get('reg_id'))
registration = self._get_first_registration_entry(submitter_code=submitter_code, reg_id=reg_id)
registration = self._get_first_registration_entry(submitter_codes=submitter_codes, reg_id=reg_id)
registrations_entities = get_registration_entities(reg_id=reg_id)
registrations_contacts = get_registration_contacts(reg_id=reg_id)
return JsonResponse({'response': _set_registration(registration, registrations_entities, registrations_contacts)})
else:
registration_list = get_registrations(submitter_code=submitter_code)
registration_list = get_registrations(submitter_codes=submitter_codes)
for registration in registration_list:
registrations_content.append(registration)
try:
page_num = int(request.GET.get('page'))
except:
page_num = 1
response_json = RegistrationsApi.get_registration_list_json(registrations_content, request.GET.get('status'),
request.GET.get('org'), page_num, *args, **kwargs)
response_json = get_registration_list_json(registrations_content, request.GET.get('status'),
request.GET.get('org'), page_num, *args, **kwargs)
response_json['header'] = ['Business Name', 'Year', 'Type', 'Location', 'Registration Status', 'Actions']
response_json['pagination_url_namespaces'] = 'register:submitter_regis_table'
return JsonResponse({'response': response_json})

def get_registration_list_json(self, registrations_content, *args, **kwargs):
reg_data = super().get_registration_list_json(registrations_content, *args, **kwargs)
reg_data['header'] = ['Business Name', 'Year', 'Type', 'Location', 'Registration Status', 'Actions']
reg_data['pagination_url_namespaces'] = 'register:submitter_regis_table'
return reg_data


def get_submitter_code(request):
submitter = get_submitter_info(str(request))
submitter_codes = []
for i in submitter:
submitter_codes.append(i[1])
return JsonResponse({'submitter_code': submitter_codes} if submitter_codes else [], safe=False)
11 changes: 6 additions & 5 deletions apcd_cms/src/apps/utils/apcd_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ def get_submitter_users():
if conn is not None:
conn.close()

def get_registrations(reg_id=None, submitter_code=None):

def get_registrations(reg_id=None, submitter_codes=None):
cur = None
conn = None
try:
Expand All @@ -220,14 +221,14 @@ def get_registrations(reg_id=None, submitter_code=None):
registrations.zip,
registrations.registration_year
FROM registrations
{f"LEFT JOIN registration_submitters ON registrations.registration_id = registration_submitters.registration_id LEFT JOIN submitters ON registration_submitters.submitter_id = submitters.submitter_id" if submitter_code is not None else ''}
{f"LEFT JOIN registration_submitters ON registrations.registration_id = registration_submitters.registration_id LEFT JOIN submitters ON registration_submitters.submitter_id = submitters.submitter_id" if submitter_codes is not None else ''}
WHERE 1=1
{f" AND registrations.registration_id = {str(reg_id)}" if reg_id is not None else ''}
{f" AND submitters.submitter_code = ANY(%s)" if submitter_code is not None else ''}
{f" AND submitters.submitter_code = ANY(%s)" if submitter_codes is not None else ''}
ORDER BY registrations.registration_id"""
cur = conn.cursor()
if submitter_code:
cur.execute(query, (submitter_code,))
if submitter_codes:
cur.execute(query, (submitter_codes,))
else:
cur.execute(query)
return cur.fetchall()
Expand Down
Loading

0 comments on commit 09b64c6

Please sign in to comment.