From: Yoan Le Clanche Date: Wed, 23 Sep 2020 08:52:47 +0000 (+0200) Subject: Use restricted field on student to forbide some pages X-Git-Tag: 1.4.3~41 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=579fc45f634ad6243b91f17d36429767c6ce0f1f;p=teleforma.git Use restricted field on student to forbide some pages --- diff --git a/teleforma/admin.py b/teleforma/admin.py index c8ae9b7a..04c55d8f 100644 --- a/teleforma/admin.py +++ b/teleforma/admin.py @@ -112,10 +112,10 @@ class StudentAdmin(admin.ModelAdmin): filter_horizontal = ['trainings'] inlines = [PaymentInline, OptionalFeeInline, DiscountInline, PaybackInline] search_fields = ['user__first_name', 'user__last_name', 'user__username'] - list_filter = ['user__is_active', 'is_subscribed', 'platform_only', PeriodListFilter, + list_filter = ['user__is_active', 'restricted', 'is_subscribed', 'platform_only', PeriodListFilter, 'trainings', 'iej', 'procedure', 'written_speciality', 'oral_speciality', 'oral_1', 'oral_2', 'fascicule', BalanceFilter ] - list_display = ['student_name', 'get_trainings', 'platform_only', + list_display = ['student_name', 'restricted', 'get_trainings', 'platform_only', 'total_payments', 'total_fees', 'balance', 'balance_intermediary'] readonly_fields = [ 'balance', 'balance_intermediary' ] actions = ['export_xls', 'write_message', 'add_to_group'] diff --git a/teleforma/decorators.py b/teleforma/decorators.py new file mode 100644 index 00000000..cdeb87a0 --- /dev/null +++ b/teleforma/decorators.py @@ -0,0 +1,102 @@ +import urlparse +from functools import wraps +from django.conf import settings +from django.contrib.auth import REDIRECT_FIELD_NAME +from django.core.exceptions import PermissionDenied +from django.utils.decorators import available_attrs +from django.shortcuts import redirect +from teleforma.models.crfpa import Student + +def user_passes_test(login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): + """ + Decorator for views that checks that the user passes the given test, + redirecting to the log-in page if necessary. The test should be a callable + that takes the user object and returns True if the user passes. + """ + + def decorator(view_func): + @wraps(view_func, assigned=available_attrs(view_func)) + def _wrapped_view(request, *args, **kwargs): + user = request.user + restricted = False + if user.is_authenticated(): + try: + student = user.student.get() + except Student.DoesNotExist: + student = None + if student: + restricted = student.restricted + if not restricted: + return view_func(request, *args, **kwargs) + + if restricted: + return redirect('teleforma-unauthorized') + + path = request.build_absolute_uri() + # If the login url is the same scheme and net location then just + # use the path as the "next" url. + login_scheme, login_netloc = urlparse.urlparse(login_url or + settings.LOGIN_URL)[:2] + current_scheme, current_netloc = urlparse.urlparse(path)[:2] + if ((not login_scheme or login_scheme == current_scheme) and + (not login_netloc or login_netloc == current_netloc)): + path = request.get_full_path() + from django.contrib.auth.views import redirect_to_login + return redirect_to_login(path, login_url, redirect_field_name) + return _wrapped_view + return decorator + + +def access_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None): + """ + Decorator for views that checks that the user is logged in, redirecting + to the log-in page if necessary. + """ + actual_decorator = user_passes_test( + login_url=login_url, + redirect_field_name=redirect_field_name + ) + if function: + return actual_decorator(function) + return actual_decorator + + + + +# def access_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None): +# """ +# Decorator for views that checks that the user is logged in, redirecting +# to the log-in page if necessary. +# """ +# def can_access(user): +# student = user.student.get() +# if student: +# return user.is_authenticated() and not student.restricted +# return user.is_authenticated() + + +# student = user.student.get() +# if student: +# if student.restricted: +# redirect('user-restricted') + +# path = request.build_absolute_uri() +# # If the login url is the same scheme and net location then just +# # use the path as the "next" url. +# login_scheme, login_netloc = urlparse.urlparse(login_url or +# settings.LOGIN_URL)[:2] +# current_scheme, current_netloc = urlparse.urlparse(path)[:2] +# if ((not login_scheme or login_scheme == current_scheme) and +# (not login_netloc or login_netloc == current_netloc)): +# path = request.get_full_path() +# from django.contrib.auth.views import redirect_to_login +# return redirect_to_login(path, None, redirect_field_name) + +# actual_decorator = user_passes_test( +# lambda u: can_access(u), +# login_url=login_url, +# redirect_field_name=redirect_field_name +# ) +# if function: +# return actual_decorator(function) +# return actual_decorator diff --git a/teleforma/exam/views.py b/teleforma/exam/views.py index 46a7bbf9..bb8ab050 100755 --- a/teleforma/exam/views.py +++ b/teleforma/exam/views.py @@ -5,6 +5,7 @@ from teleforma.exam.models import * from teleforma.exam.forms import * from teleforma.views.core import * +from teleforma.decorators import access_required from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.core.urlresolvers import reverse_lazy, reverse @@ -136,7 +137,7 @@ class ScriptView(ScriptMixinView, CourseAccessMixin, UpdateView): return context - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(ScriptView, self).dispatch(*args, **kwargs) @@ -196,7 +197,7 @@ class ScriptsView(ScriptsListMixinView, ListView): base_qs = base_qs.order_by('-date_submitted') return base_qs - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(ScriptsView, self).dispatch(*args, **kwargs) @@ -271,7 +272,7 @@ class ScriptCreateView(ScriptMixinView, CreateView): context['form'].fields['course'].queryset = context['courses'] return context - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): self.period = Period.objects.get(id=kwargs['period_id']) return super(ScriptCreateView, self).dispatch(*args, **kwargs) @@ -294,7 +295,7 @@ class QuotasView(ListView): model = Quota template_name='exam/quotas.html' - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(QuotasView, self).dispatch(*args, **kwargs) @@ -412,7 +413,7 @@ class ScoreCreateView(ScriptCreateView): context['create_fields'] = ['course', 'session', 'type', 'score' ] return context - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(ScoreCreateView, self).dispatch(*args, **kwargs) diff --git a/teleforma/templates/teleforma/courses.html b/teleforma/templates/teleforma/courses.html index 2f1668e7..1ef1fbe5 100644 --- a/teleforma/templates/teleforma/courses.html +++ b/teleforma/templates/teleforma/courses.html @@ -78,7 +78,7 @@
- {% if appointments %} + {% if appointments and not restricted %}
{% if current_appointement %}

@@ -129,7 +129,7 @@

{% endif %} - {% if webclass_slots or webclass_to_subscribe %} + {% if webclass_slots or webclass_to_subscribe and not restricted %}
Webclasse
@@ -170,47 +170,48 @@
{% endif %} - - {% for c in courses %} - {% with c.course as course %} - {% for type in c.types %} -
-
- {{ course.title }} - - {{ type }}{% if course.description %} - {{ course.description }}{% endif %} + {% if not restricted %} + {% for c in courses %} + {% with c.course as course %} + {% for type in c.types %} +
+ + + {% if show_media %} + + {% block conference %} + {% include "teleforma/inc/conference_list.html" %} + {% endblock %} + + {% block media %} + {% with "Passed conferences" as title %} + {% include "teleforma/inc/media_list.html" with show_only=1 %} + {% endwith %} + {% endblock %} + + {% comment %} + {% block webclass %} + {% with "Web class" as title %} + {% include "teleforma/inc/media_list.html" with show_only=1 %} + {% endwith %} + {% endblock %} + {% endcomment %} + + {% endif %} + + {% block document %} + {% with forloop.counter as type_counter %} + {% include "teleforma/inc/document_list.html" %} + {% endwith %} + {% endblock %}
- - {% if show_media %} - - {% block conference %} - {% include "teleforma/inc/conference_list.html" %} - {% endblock %} - - {% block media %} - {% with "Passed conferences" as title %} - {% include "teleforma/inc/media_list.html" with show_only=1 %} - {% endwith %} - {% endblock %} - - {% comment %} - {% block webclass %} - {% with "Web class" as title %} - {% include "teleforma/inc/media_list.html" with show_only=1 %} - {% endwith %} - {% endblock %} - {% endcomment %} - - {% endif %} - - {% block document %} - {% with forloop.counter as type_counter %} - {% include "teleforma/inc/document_list.html" %} + {% endfor %} {% endwith %} - {% endblock %} -
- {% endfor %} - {% endwith %} - {% endfor %} + {% endfor %} + {% endif %}
{% endblock course %} diff --git a/teleforma/templates/teleforma/unauthorized.html b/teleforma/templates/teleforma/unauthorized.html new file mode 100644 index 00000000..01d42a61 --- /dev/null +++ b/teleforma/templates/teleforma/unauthorized.html @@ -0,0 +1,5 @@ +{% extends "telemeta/base.html" %} + +{% block content %} +

Vous n'êtes pas autorisé à voir cette page car votre compte est restreint.

+{% endblock %} \ No newline at end of file diff --git a/teleforma/templates/telemeta/base.html b/teleforma/templates/telemeta/base.html index 9c1a3710..a307db64 100644 --- a/teleforma/templates/telemeta/base.html +++ b/teleforma/templates/telemeta/base.html @@ -112,39 +112,41 @@ alt="logo" />
  • {% trans "Messaging" %}{% if postman_unread_count %} ({{ postman_unread_count }}){% endif %}
  • -
  • {% trans "Annals" %}
  • - - {% if periods|length == 1 %} -
  •  {% trans "Scripts" %} + {% if not user.student or not user.student.get.restricted %} +
  • {% trans "Annals" %}
  • + + {% if periods|length == 1 %} +
  •  {% trans "Scripts" %} + {% if user.is_staff or user.quotas.all %}{% untreated_scripts_count user periods.0.id %} + {% else %}{% treated_scripts_count user periods.0.id %}{% endif %} +
  • + {% else %} +
  •  {% trans "Scripts" %} {% if user.is_staff or user.quotas.all %}{% untreated_scripts_count user periods.0.id %} - {% else %}{% treated_scripts_count user periods.0.id %}{% endif %} -
  • - {% else %} -
  •  {% trans "Scripts" %} - {% if user.is_staff or user.quotas.all %}{% untreated_scripts_count user periods.0.id %} - {% else %}{% treated_scripts_count user periods.0.id %}{% endif %} - -
  • - {% endif %} - - {% if user.professor.count %} -
  • Webclass
  • - {% endif %} - - {% if periods|length == 1 %} -
  •  {% trans "Scores" %}
  • - {% else %} -
  •  {% trans "Scores" %} - +
  • + {% endif %} + + {% if user.professor.count %} +
  • Webclass
  • + {% endif %} + + {% if periods|length == 1 %} +
  •  {% trans "Scores" %}
  • + {% else %} +
  •  {% trans "Scores" %} + +
  • + {% endif %} {% endif %} {% if user.is_authenticated %} diff --git a/teleforma/urls.py b/teleforma/urls.py index 6b94e52c..c2f63cf7 100644 --- a/teleforma/urls.py +++ b/teleforma/urls.py @@ -35,7 +35,7 @@ import os.path from django.conf.urls import patterns, url, include from django.conf import settings -from django.views.generic.base import RedirectView +from django.views.generic.base import RedirectView, TemplateView from django.views.generic.list import ListView from teleforma.models import * from teleforma.views import * @@ -78,6 +78,9 @@ urlpatterns = patterns('', # Home url(r'^$', HomeRedirectView.as_view(), name="teleforma-home"), + # Unauthorized + url(r'^unauthorized/$', TemplateView.as_view(template_name="teleforma/unauthorized.html"), name="teleforma-unauthorized"), + # Telemeta url(r'^', include('telemeta.urls')), diff --git a/teleforma/views/core.py b/teleforma/views/core.py index 3ef258d2..03417125 100644 --- a/teleforma/views/core.py +++ b/teleforma/views/core.py @@ -64,7 +64,6 @@ from django.contrib.auth.forms import UserChangeForm from django.core.exceptions import ObjectDoesNotExist from django.contrib.syndication.views import Feed from django.core.paginator import Paginator -from django.contrib.auth.decorators import login_required from django.contrib.contenttypes.models import ContentType from django.views.generic.edit import FormView from django.core.urlresolvers import reverse, reverse_lazy @@ -74,6 +73,7 @@ from teleforma.models import * from teleforma.forms import * from teleforma.models.appointment import AppointmentPeriod from teleforma.webclass.models import Webclass, WebclassSlot, WebclassRecord +from teleforma.decorators import access_required from telemeta.views import * import jqchat.models from xlwt import Workbook @@ -89,6 +89,7 @@ except: pass + def render(request, template, data = None, mimetype = None): return render_to_response(template, data, context_instance=RequestContext(request), mimetype=mimetype) @@ -389,6 +390,7 @@ class CourseListView(CourseAccessMixin, ListView): to_subscribe.append(webclass) context['webclass_slots'] = slots context['webclass_to_subscribe'] = to_subscribe + context['restricted'] = student.restricted return context @@ -471,7 +473,7 @@ class CourseView(CourseAccessMixin, DetailView): context['webclass_error'] = True return context - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(CourseView, self).dispatch(*args, **kwargs) @@ -572,7 +574,7 @@ class MediaPendingView(ListView): return context @method_decorator(permission_required('is_superuser')) - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(MediaPendingView, self).dispatch(*args, **kwargs) @@ -600,7 +602,7 @@ class DocumentView(CourseAccessMixin, DetailView): context['periods'] = get_periods(self.request.user) return context - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(DocumentView, self).dispatch(*args, **kwargs) @@ -681,7 +683,7 @@ class ConferenceView(CourseAccessMixin, DetailView): except: pass - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(ConferenceView, self).dispatch(*args, **kwargs) @@ -808,7 +810,7 @@ class ConferenceRecordView(FormView): command = 'dwebp ' + path + ' -o ' + dir + os.sep + 'preview.png &' os.system(command) - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(ConferenceRecordView, self).dispatch(*args, **kwargs) diff --git a/teleforma/views/crfpa.py b/teleforma/views/crfpa.py index 4ff8dc7c..87c5a6b8 100644 --- a/teleforma/views/crfpa.py +++ b/teleforma/views/crfpa.py @@ -37,6 +37,7 @@ from teleforma.models.core import Period from teleforma.views.core import * from teleforma.forms import WriteForm from telemeta.views import ProfileView +from teleforma.decorators import access_required from registration.views import * from extra_views import CreateWithInlinesView, UpdateWithInlinesView, InlineFormSet from postman.views import WriteView as PostmanWriteView @@ -525,7 +526,7 @@ class AnnalsView(ListView): context['period'] = periods[0] return context - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(AnnalsView, self).dispatch(*args, **kwargs) diff --git a/teleforma/views/pro.py b/teleforma/views/pro.py index 7589c5dd..4f738a27 100644 --- a/teleforma/views/pro.py +++ b/teleforma/views/pro.py @@ -35,14 +35,14 @@ from teleforma.views.core import * - +from teleforma.decorators import access_required class SeminarView(DetailView): model = Seminar template_name='teleforma/seminar_detail.html' - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(SeminarView, self).dispatch(*args, **kwargs) diff --git a/teleforma/webclass/views.py b/teleforma/webclass/views.py index c516f7c7..077fb7b7 100644 --- a/teleforma/webclass/views.py +++ b/teleforma/webclass/views.py @@ -16,6 +16,7 @@ from django.core.cache import cache from teleforma.webclass.models import Webclass, WebclassSlot from teleforma.webclass.forms import WebclassRecordsForm +from teleforma.decorators import access_required from teleforma.views.core import get_periods, get_courses @@ -159,12 +160,12 @@ class WebclassRecordsFormView(FormView): return super(WebclassRecordsFormView, self).form_valid(form) @method_decorator(permission_required('is_superuser')) - @method_decorator(login_required) + @method_decorator(access_required) def dispatch(self, *args, **kwargs): return super(WebclassRecordsFormView, self).dispatch(*args, **kwargs) -@login_required +@access_required def join_webclass(request, pk): webclass_slot = WebclassSlot.published.get(pk=int(pk)) # webclass = webclass_slot.webclass