]> git.parisson.com Git - teleforma.git/commitdiff
Use restricted field on student to forbide some pages
authorYoan Le Clanche <yoanl@pilotsystems.net>
Wed, 23 Sep 2020 08:52:47 +0000 (10:52 +0200)
committerYoan Le Clanche <yoanl@pilotsystems.net>
Wed, 23 Sep 2020 08:52:47 +0000 (10:52 +0200)
teleforma/admin.py
teleforma/decorators.py [new file with mode: 0644]
teleforma/exam/views.py
teleforma/templates/teleforma/courses.html
teleforma/templates/teleforma/unauthorized.html [new file with mode: 0644]
teleforma/templates/telemeta/base.html
teleforma/urls.py
teleforma/views/core.py
teleforma/views/crfpa.py
teleforma/views/pro.py
teleforma/webclass/views.py

index c8ae9b7a9ebfe71e8b6d55c204ca1f906608102a..04c55d8fc0bb39e326994c10667aeffe43e3132e 100644 (file)
@@ -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 (file)
index 0000000..cdeb87a
--- /dev/null
@@ -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
index 46a7bbf9f1688c47f6a2ca9a487b8c2006a2b5f2..bb8ab0507dff93db1311af6e6d218dc37b276b8f 100755 (executable)
@@ -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)
 
index 2f1668e7abd80025e3eb89945905119173808827..1ef1fbe59ce40d0234f5e796ba36022b5343474f 100644 (file)
@@ -78,7 +78,7 @@
 
 <div class="desk_center home">
 
-  {% if appointments %}
+  {% if appointments and not restricted %}
   <div class="appointment">
     {% if current_appointement %}
       <p>
   </div>
   {% endif %}
 
-  {% if webclass_slots or webclass_to_subscribe %}
+  {% if webclass_slots or webclass_to_subscribe and not restricted %}
   <div class="course_title">
     Webclasse
   </div>
   </div>
   {% endif %}
 
-
-  {% for c in courses %}
-  {% with c.course as course %}
-  {% for type in c.types %}
-  <div class="course">
-    <div class="course_title">
-      <a href="{% url teleforma-desk-period-course period.id course.id %}">{{ course.title }} -
-        {{ type }}{% if course.description %} - {{ course.description }}{% endif %}</a>
+  {% if not restricted %}
+    {% for c in courses %}
+    {% with c.course as course %}
+    {% for type in c.types %}
+    <div class="course">
+      <div class="course_title">
+        <a href="{% url teleforma-desk-period-course period.id course.id %}">{{ course.title }} -
+          {{ type }}{% if course.description %} - {{ course.description }}{% endif %}</a>
+      </div>
+
+      {% 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 %}
     </div>
-
-    {% 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 %}
-  </div>
-  {% endfor %}
-  {% endwith %}
-  {% endfor %}
+    {% endfor %}
+  {% endif %}
 </div>
 {% endblock course %}
 
diff --git a/teleforma/templates/teleforma/unauthorized.html b/teleforma/templates/teleforma/unauthorized.html
new file mode 100644 (file)
index 0000000..01d42a6
--- /dev/null
@@ -0,0 +1,5 @@
+{% extends "telemeta/base.html" %}
+
+{% block content %}
+<p>Vous n'êtes pas autorisé à voir cette page car votre compte est restreint.</p>
+{% endblock %}
\ No newline at end of file
index 9c1a37102e2cc2dab730b13fc4af94633606b01b..a307db64ed045ecb1b9fecfc3a5340a91b51fedf 100644 (file)
@@ -112,39 +112,41 @@ alt="logo" />
 
  <li><a href="{% url postman_inbox %}" class="orange">{% trans "Messaging" %}{% if postman_unread_count %} ({{ postman_unread_count }}){% endif %}</a></li>
 
-  <li><a href="{% url teleforma-annals %}" class="yellow">{% trans "Annals" %}</a></li>
-
-  {% if periods|length == 1 %}
-      <li><a href="{% url teleforma-exam-scripts-pending periods.0.id %}" class="green">&nbsp;{% trans "Scripts" %}
+  {% if not user.student or not user.student.get.restricted %}
+    <li><a href="{% url teleforma-annals %}" class="yellow">{% trans "Annals" %}</a></li>
+
+    {% if periods|length == 1 %}
+        <li><a href="{% url teleforma-exam-scripts-pending periods.0.id %}" class="green">&nbsp;{% 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 %}</a>
+      </li>
+    {% else %}
+      <li><a href="#scripts#" class="green">&nbsp;{% 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 %}</a>
-     </li>
-  {% else %}
-    <li><a href="#scripts#" class="green">&nbsp;{% 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 %}</a>
-      <ul>
-       {% for period in periods %}
-        <li><a href="{% url teleforma-exam-scripts-pending period.id %}" class="green">{{ period.name }}</a></li>
-       {% endfor %}
-      </ul>
-    </li>
-  {% endif %}
-
-  {% if user.professor.count %}
-    <li><a href="{% url teleforma-webclass-professor %}" class="yellow">Webclass</a></li>
-  {% endif %}
-
-  {% if periods|length == 1 %}
-      <li><a href="{% url teleforma-exam-scripts-scores-all periods.0.id %}" class="green">&nbsp;{% trans "Scores" %}</a></li>
-  {% else %}
-    <li><a href="#scores#" class="green">&nbsp;{% trans "Scores" %}</a>
-      <ul>
+      {% else %}{% treated_scripts_count user periods.0.id %}{% endif %}</a>
+        <ul>
         {% for period in periods %}
-        <li><a href="{% url teleforma-exam-scripts-scores-all period.id %}" class="green">{{ period.name }}</a></li>
+          <li><a href="{% url teleforma-exam-scripts-pending period.id %}" class="green">{{ period.name }}</a></li>
         {% endfor %}
-      </ul>
-    </li>
+        </ul>
+      </li>
+    {% endif %}
+
+    {% if user.professor.count %}
+      <li><a href="{% url teleforma-webclass-professor %}" class="yellow">Webclass</a></li>
+    {% endif %}
+
+    {% if periods|length == 1 %}
+        <li><a href="{% url teleforma-exam-scripts-scores-all periods.0.id %}" class="green">&nbsp;{% trans "Scores" %}</a></li>
+    {% else %}
+      <li><a href="#scores#" class="green">&nbsp;{% trans "Scores" %}</a>
+        <ul>
+          {% for period in periods %}
+          <li><a href="{% url teleforma-exam-scripts-scores-all period.id %}" class="green">{{ period.name }}</a></li>
+          {% endfor %}
+        </ul>
+      </li>
+    {% endif %}
   {% endif %}
 
  {% if user.is_authenticated %}
index 6b94e52cd1d5d007309befb34863d38714b27aa2..c2f63cf7501766aaca8c70642f132d9b845c3637 100644 (file)
@@ -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')),
 
index 3ef258d21212178d2837c7d94bba487e2ee0ad60..0341712577cb9b269a7758621411f175c67f559d 100644 (file)
@@ -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)
 
index 4ff8dc7ce3522a1fd9ec89cd36ae28efbedb1993..87c5a6b813ed806c98614bfc8514f85213cb684d 100644 (file)
@@ -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)
 
index 7589c5dd4abaa4cdc746f5d2d5eecdf1b9977745..4f738a27417a0af39adf700f3733cd0fa7174f42 100644 (file)
 
 
 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)
 
index c516f7c72bd5177352f788c1f6c38ef908a70f62..077fb7b7d493e9557685c1c50457c449532dc700 100644 (file)
@@ -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