Skip to content

Commit

Permalink
[Institution Rework] [ENG-3696] Project PR - Backend Part (#10254)
Browse files Browse the repository at this point in the history
- [Institution Rework] [ENG-4229] Add unit tests to cover reworked SSO flow with identity and affiliation (#10313)
- [Institution Rework] [ENG-4202] Another follow-up: Fix/Improve email templates (#10311)
- [Institution Rework] [ENG-4202] Follow-up: Add email templates (#10308)
- [Institution Rework] [ENG-4204] Part 2: Minor tweak SSO exceptions for CAS (#10299)
- [Institution Rework] [ENG-4198] Fix/Improve Migration Command (#10293)
- [Institution Rework] [Bug Fix] Remove user from institution metrics admin when affiliation is removed (#10290)
- [Institution Rework] [Bug Fix] Exclude banner_name and logo_name from form fields (#10289)
- [Institution Rework] [Bug Fix] Fix admin asset and institution filter (#10283)
- [Institution Rework] [Bug Fix] Return placeholder images as fallback (#10282)
- [Institution Rework] [ENG-4202] [ENG-4204] Rework Institution SSO flow with identity and affiliation - API Part (#10260)
- [Institution Rework] [ENG-4216] [ENG-4217] Change asset references (#10247)
- [Institution Rework] [ENG-4206] [ENG-4207] Institution assets rework (#10240)
- [Institution Rework] [ENG-4199] [ENG-4200] Update user-institution affiliation references (#10236)
- [Institution Rework] [ENG-4197] [ENG-4198] Add a new model for user-institution affiliation (#10227)
  • Loading branch information
cslzchen committed Jan 25, 2023
1 parent 68d23f9 commit 5fa3c49
Show file tree
Hide file tree
Showing 74 changed files with 1,415 additions and 434 deletions.
3 changes: 2 additions & 1 deletion admin/base/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
include([
re_path(r'^$', views.home, name='home'),
re_path(r'^admin/', admin.site.urls),
re_path(r'^asset_files/', include('admin.asset_files.urls', namespace='asset_files')),
re_path(r'^provider_asset_files/', include('admin.provider_asset_files.urls', namespace='provider_asset_files')),
re_path(r'^institution_asset_files/', include('admin.institution_asset_files.urls', namespace='institution_asset_files')),
re_path(r'^banners/', include('admin.banners.urls', namespace='banners')),
re_path(r'^brands/', include('admin.brands.urls', namespace='brands')),
re_path(r'^comments/', include('admin.comments.urls', namespace='comments')),
Expand Down
File renamed without changes.
20 changes: 20 additions & 0 deletions admin/institution_asset_files/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django import forms

from osf.models.storage import InstitutionAssetFile
from osf.models.institution import Institution

class InstitutionAssetFileForm(forms.ModelForm):
class Meta:
model = InstitutionAssetFile
fields = ['name', 'file', 'institutions', 'id']

id = forms.IntegerField(required=False, widget=forms.HiddenInput())
institutions = forms.ModelMultipleChoiceField(Institution.objects.all(), widget=forms.CheckboxSelectMultiple(), required=False)

def clean(self):
cleaned_data = super(InstitutionAssetFileForm, self).clean()
obj_id = int(cleaned_data.get('id', None) or 0)
for institution in cleaned_data.get('institutions', []):
if institution.asset_files.exclude(id=obj_id).filter(name=cleaned_data.get('name', '')).exists():
raise forms.ValidationError('Naming conflict detected on Institution "{}"'.format(institution.name))
return cleaned_data
11 changes: 11 additions & 0 deletions admin/institution_asset_files/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.conf.urls import re_path
from . import views

app_name = 'admin'

urlpatterns = [
re_path(r'^$', views.InstitutionAssetFileList.as_view(), name='list'),
re_path(r'^create/$', views.InstitutionAssetFileCreate.as_view(), name='create'),
re_path(r'^(?P<asset_id>[0-9]+)/$', views.InstitutionAssetFileDetail.as_view(), name='detail'),
re_path(r'^(?P<asset_id>[0-9]+)/delete/$', views.InstitutionAssetFileDelete.as_view(), name='delete'),
]
92 changes: 92 additions & 0 deletions admin/institution_asset_files/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.urls import reverse_lazy
from django.forms.models import model_to_dict
from django.views.generic import ListView, DetailView, View, CreateView, DeleteView, UpdateView

from admin.institution_asset_files.forms import InstitutionAssetFileForm
from osf.models.storage import InstitutionAssetFile
from osf.models.institution import Institution

class InstitutionAssetFileList(PermissionRequiredMixin, ListView):
paginate_by = 25
template_name = 'osf/assetfile_list.html'
ordering = 'name'
permission_required = 'osf.view_institutionassetfile'
raise_exception = True
model = InstitutionAssetFile

def get_queryset(self):
filtered_institution_id = self.request.GET.get('institution_id', None)
qs = InstitutionAssetFile.objects.all().order_by(self.ordering)
if filtered_institution_id and Institution.objects.filter(id=filtered_institution_id).exists():
qs = qs.filter(institutions__id=filtered_institution_id)
return qs

def get_context_data(self, **kwargs):
query_set = kwargs.pop('object_list', self.object_list)
page_size = self.get_paginate_by(query_set)
paginator, page, query_set, is_paginated = self.paginate_queryset(
query_set, page_size)
rv = {
'on_institution_route': True,
'asset_files': query_set,
'page': page,
'filterable_target_ids': dict({'': '---'}, **{str(id): ' '.join([name]) for id, name in Institution.objects.all().values_list('id', 'name')}),
}
return rv

class AssetFileMixin(object):
def get_object(self, queryset=None):
return InstitutionAssetFile.objects.get(id=self.kwargs.get('asset_id'))

class InstitutionAssetFileDisplay(AssetFileMixin, PermissionRequiredMixin, DetailView):
permission_required = 'osf.view_institutionassetfile'
template_name = 'osf/assetfile_form.html'
form_class = InstitutionAssetFileForm
raise_exception = True
model = InstitutionAssetFile

def get_context_data(self, **kwargs):
instance = self.get_object()
kwargs['form'] = self.form_class(model_to_dict(instance), instance=instance)
# Assumption: only css files will not be images. This may be incorrect in the future, but currently is not.
kwargs['embed_file'] = instance.file and not instance.file.url.endswith('.css')
kwargs['on_institution_route'] = True
return kwargs

class InstitutionAssetFileChangeForm(AssetFileMixin, PermissionRequiredMixin, UpdateView):
permission_required = 'osf.change_institutionassetfile'
raise_exception = True
model = InstitutionAssetFile
form_class = InstitutionAssetFileForm

def get_success_url(self, *args, **kwargs):
return reverse_lazy('institution_asset_files:detail', kwargs={'asset_id': self.kwargs.get('asset_id')})

class InstitutionAssetFileDelete(AssetFileMixin, PermissionRequiredMixin, DeleteView):
permission_required = 'osf.delete_institutionassetfile'
raise_exception = True
template_name = 'osf/assetfile_confirm_delete.html'
success_url = reverse_lazy('institution_asset_files:list')


class InstitutionAssetFileDetail(PermissionRequiredMixin, View):
permission_required = 'osf.view_institutionassetfile'
raise_exception = True
form_class = InstitutionAssetFileForm

def get(self, request, *args, **kwargs):
view = InstitutionAssetFileDisplay.as_view()
return view(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
view = InstitutionAssetFileChangeForm.as_view()
return view(request, *args, **kwargs)

class InstitutionAssetFileCreate(PermissionRequiredMixin, CreateView):
permission_required = 'osf.change_institutionassetfile'
raise_exception = True
template_name = 'osf/assetfile_create.html'
success_url = reverse_lazy('institution_asset_files:list')
model = InstitutionAssetFile
form_class = InstitutionAssetFileForm
2 changes: 1 addition & 1 deletion admin/institutions/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Meta:
model = Institution

exclude = [
'is_deleted', 'contributors'
'is_deleted', 'contributors', 'banner_name', 'logo_name'
]

class InstitutionalMetricsAdminRegisterForm(forms.Form):
Expand Down
3 changes: 2 additions & 1 deletion admin/institutions/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ def get_context_data(self, *args, **kwargs):
institution_dict = model_to_dict(institution)
kwargs.setdefault('page_number', self.request.GET.get('page', '1'))
kwargs['institution'] = institution_dict
kwargs['logohost'] = settings.OSF_URL
kwargs['logo_path'] = institution.logo_path
kwargs['banner_path'] = institution.banner_path
fields = institution_dict
kwargs['change_form'] = InstitutionForm(initial=fields)
kwargs['import_form'] = ImportFileForm()
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from osf.models.storage import ProviderAssetFile
from osf.models.provider import AbstractProvider


class ProviderAssetFileForm(forms.ModelForm):
class Meta:
model = ProviderAssetFile
Expand Down
File renamed without changes.
26 changes: 14 additions & 12 deletions admin/asset_files/views.py → admin/provider_asset_files/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
from django.forms.models import model_to_dict
from django.views.generic import ListView, DetailView, View, CreateView, DeleteView, UpdateView

from admin.asset_files.forms import ProviderAssetFileForm
from admin.provider_asset_files.forms import ProviderAssetFileForm
from osf.models.provider import AbstractProvider
from osf.models.storage import ProviderAssetFile

class ProviderAssetFileList(PermissionRequiredMixin, ListView):
paginate_by = 25
template_name = 'osf/providerassetfile_list.html'
template_name = 'osf/assetfile_list.html'
ordering = 'name'
permission_required = 'osf.view_providerassetfile'
raise_exception = True
model = ProviderAssetFile

def get_queryset(self):
filtered_provider_id = self.request.GET.get('provider_id', None)
filtered_target_id = self.request.GET.get('provider_id', None)
qs = ProviderAssetFile.objects.all().order_by(self.ordering)
if filtered_provider_id and AbstractProvider.objects.filter(id=filtered_provider_id).exists():
qs = qs.filter(providers__id=filtered_provider_id)
if filtered_target_id and AbstractProvider.objects.filter(id=filtered_target_id).exists():
qs = qs.filter(providers__id=filtered_target_id)
return qs

def get_context_data(self, **kwargs):
Expand All @@ -29,9 +29,10 @@ def get_context_data(self, **kwargs):
paginator, page, query_set, is_paginated = self.paginate_queryset(
query_set, page_size)
rv = {
'on_provider_route': True,
'asset_files': query_set,
'page': page,
'filterable_provider_ids': dict({'': '---'}, **{str(id): ' '.join([type_, name]) for id, name, type_ in AbstractProvider.objects.annotate(
'filterable_target_ids': dict({'': '---'}, **{str(id): ' '.join([type_, name]) for id, name, type_ in AbstractProvider.objects.annotate(
type_=Case(
When(type='osf.preprintprovider', then=Value('[preprint]')),
When(type='osf.collectionprovider', then=Value('[collection]')),
Expand All @@ -48,7 +49,7 @@ def get_object(self, queryset=None):

class ProviderAssetFileDisplay(AssetFileMixin, PermissionRequiredMixin, DetailView):
permission_required = 'osf.view_providerassetfile'
template_name = 'osf/providerassetfile_form.html'
template_name = 'osf/assetfile_form.html'
form_class = ProviderAssetFileForm
raise_exception = True
model = ProviderAssetFile
Expand All @@ -58,6 +59,7 @@ def get_context_data(self, **kwargs):
kwargs['form'] = self.form_class(model_to_dict(instance), instance=instance)
# Assumption: only css files will not be images. This may be incorrect in the future, but currently is not.
kwargs['embed_file'] = instance.file and not instance.file.url.endswith('.css')
kwargs['on_provider_route'] = True
return kwargs

class ProviderAssetFileChangeForm(AssetFileMixin, PermissionRequiredMixin, UpdateView):
Expand All @@ -67,13 +69,13 @@ class ProviderAssetFileChangeForm(AssetFileMixin, PermissionRequiredMixin, Updat
form_class = ProviderAssetFileForm

def get_success_url(self, *args, **kwargs):
return reverse_lazy('asset_files:detail', kwargs={'asset_id': self.kwargs.get('asset_id')})
return reverse_lazy('provider_asset_files:detail', kwargs={'asset_id': self.kwargs.get('asset_id')})

class ProviderAssetFileDelete(AssetFileMixin, PermissionRequiredMixin, DeleteView):
permission_required = 'osf.delete_providerassetfile'
raise_exception = True
template_name = 'osf/providerassetfile_confirm_delete.html'
success_url = reverse_lazy('asset_files:list')
template_name = 'osf/assetfile_confirm_delete.html'
success_url = reverse_lazy('provider_asset_files:list')


class ProviderAssetFileDetail(PermissionRequiredMixin, View):
Expand All @@ -92,7 +94,7 @@ def post(self, request, *args, **kwargs):
class ProviderAssetFileCreate(PermissionRequiredMixin, CreateView):
permission_required = 'osf.change_providerassetfile'
raise_exception = True
template_name = 'osf/providerassetfile_create.html'
success_url = reverse_lazy('asset_files:list')
template_name = 'osf/assetfile_create.html'
success_url = reverse_lazy('provider_asset_files:list')
model = ProviderAssetFile
form_class = ProviderAssetFileForm
21 changes: 17 additions & 4 deletions admin/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,19 @@
</ul>
</div>
{% endif %}
{% if perms.osf.view_institutionassetfile %}
<li><a role="button" data-toggle="collapse" href="#collapseInstitutionAssetFiles">
<i class='fa fa-caret-down'></i> Institution Assets
</a></li>
<div class="collapse" id="collapseInstitutionAssetFiles">
<ul class="sidebar-menu sidebar-menu-inner">
<li><a href="{% url 'institution_asset_files:list' %}"><i class='fa fa-link'></i><span> List</span> </a></li>
{% if perms.osf.change_institutionassetfile %}
<li><a href="{% url 'institution_asset_files:create' %}"><i class='fa fa-link'></i><span> Create</span> </a></li>
{% endif %}
</ul>
</div>
{% endif %}
{% if perms.osf.view_brand %}
<li><a role="button" data-toggle="collapse" href="#collapseBrands">
<i class='fa fa-caret-down'></i> Brands
Expand Down Expand Up @@ -204,14 +217,14 @@
</div>
{% endif %}
{% if perms.osf.view_providerassetfile %}
<li><a role="button" data-toggle="collapse" href="#collapseAssetFiles">
<li><a role="button" data-toggle="collapse" href="#collapseProviderAssetFiles">
<i class='fa fa-caret-down'></i> Provider Assets
</a></li>
<div class="collapse" id="collapseAssetFiles">
<div class="collapse" id="collapseProviderAssetFiles">
<ul class="sidebar-menu sidebar-menu-inner">
<li><a href="{% url 'asset_files:list' %}"><i class='fa fa-link'></i><span> List</span> </a></li>
<li><a href="{% url 'provider_asset_files:list' %}"><i class='fa fa-link'></i><span> List</span> </a></li>
{% if perms.osf.change_providerassetfile %}
<li><a href="{% url 'asset_files:create' %}"><i class='fa fa-link'></i><span> Create</span> </a></li>
<li><a href="{% url 'provider_asset_files:create' %}"><i class='fa fa-link'></i><span> Create</span> </a></li>
{% endif %}
</ul>
</div>
Expand Down
4 changes: 2 additions & 2 deletions admin/templates/institutions/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ <h2>{{ institution.name }}</h2>
<h4>Logo:</h4>
</div>
<div class="col-md-2">
<img class="institution-logo" src="{{ logohost }}/static/img/institutions/shields/{{ institution.logo_name }}">
<img class="institution-logo" src="{{ logo_path }}">
</div>
<div class="col-md-2">
<h4>Banner:</h4>
</div>
<div class="col-md-6">
<img class="institution-banner" src="{{ logohost }}/static/img/institutions/banners/{{ institution.banner_name }}">
<img class="institution-banner" src="{{ banner_path }}">
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion admin/templates/institutions/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ <h2>List of Institutions</h2>
<tr>
<td>
<a href="{% url 'institutions:detail' institution_id=institution.id %}">
<img class="institution-logo" src="{{ logohost }}/static/img/institutions/shields/{{ institution.logo_name }}">
<img class="institution-logo" src="{{ institution.logo_path }}">
</a>
</td>
<td><a href="{% url 'institutions:detail' institution_id=institution.id %}">{{ institution.name }}</a></td>
Expand Down
2 changes: 1 addition & 1 deletion admin/templates/institutions/node_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{% endblock title %}
{% block content %}
<h2>List of Nodes for {{ institution.name }}
<img class="institution-logo" src="{{ logohost }}/static/img/institutions/shields/{{ institution.logo_name }}">
<img class="institution-logo" src="{{ institution.logo_path }}">
</h2>
{% include 'nodes/node_list.html' %}
{% endblock content %}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% load render_bundle from webpack_loader %}
{% load static %}
{% block title %}
<title>Provider Asset File</title>
<title>Asset File</title>
{% endblock title %}
{% block content %}
<form action="" method="post" enctype="multipart/form-data">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
{% load render_bundle from webpack_loader %}
{% load static %}
{% block title %}
<title>Provider Asset File</title>
<title>Asset File</title>
{% endblock title %}
{% block content %}
<div class="row">
<div class="col-md-12">
{% if perms.osf.delete_providerassetfile %}
<a class="btn btn-danger" href={% url 'asset_files:delete' object.id %}>Delete asset</a>
{% if perms.osf.delete_providerassetfile and on_provider_route %}
<a class="btn btn-danger" href={% url 'provider_asset_files:delete' object.id %}>Delete asset</a>
{% endif %}
{% if perms.osf.delete_institutionassetfile and on_institution_route %}
<a class="btn btn-danger" href={% url 'institution_asset_files:delete' object.id %}>Delete asset</a>
{% endif %}
</div>
</div>
Expand Down
Loading

0 comments on commit 5fa3c49

Please sign in to comment.