Commit 9f6cfaea by Waheed Ahmed Committed by GitHub

Merge pull request #294 from edx/waheed/ecom-4978-top-level-object-access

Added Top level Object Access.
parents 9983c7a9 ea337ad7
from django.http import HttpResponseForbidden
from course_discovery.apps.publisher.models import Course, Seat
class ViewPermissionMixin(object):
def get_course(self):
publisher_object = self.get_object()
if isinstance(publisher_object, Course):
return publisher_object
if isinstance(publisher_object, Seat):
return publisher_object.course_run.course
if hasattr(publisher_object, 'course'):
return publisher_object.course
return None
def check_user(self, user):
course = self.get_course()
return check_view_permission(user, course)
def permission_failed(self):
return HttpResponseForbidden()
def dispatch(self, request, *args, **kwargs):
if not self.check_user(request.user):
return self.permission_failed()
return super(ViewPermissionMixin, self).dispatch(request, *args, **kwargs)
def check_view_permission(user, course):
return user.is_staff or user.has_perm(Course.VIEW_PERMISSION, course)
...@@ -70,6 +70,7 @@ class SeatFactory(factory.DjangoModelFactory): ...@@ -70,6 +70,7 @@ class SeatFactory(factory.DjangoModelFactory):
class GroupFactory(factory.DjangoModelFactory): class GroupFactory(factory.DjangoModelFactory):
name = FuzzyText(prefix="Test Group ")
class Meta: class Meta:
model = Group model = Group
from course_discovery.apps.core.tests.factories import UserFactory, USER_PASSWORD
from course_discovery.apps.publisher.tests import factories
def create_non_staff_user_and_login(test_class):
""" Create non staff user and login and return user and group. """
non_staff_user = UserFactory()
group = factories.GroupFactory()
test_class.client.logout()
test_class.client.login(username=non_staff_user.username, password=USER_PASSWORD)
return non_staff_user, group
...@@ -3,14 +3,17 @@ Course publisher views. ...@@ -3,14 +3,17 @@ Course publisher views.
""" """
from django.contrib import messages from django.contrib import messages
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect, HttpResponseForbidden
from django.utils.translation import ugettext_lazy as _
from django.views.generic import View from django.views.generic import View
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView from django.views.generic.edit import CreateView, UpdateView
from django.views.generic.list import ListView from django.views.generic.list import ListView
from django_fsm import TransitionNotAllowed from django_fsm import TransitionNotAllowed
from guardian.shortcuts import get_objects_for_user
from course_discovery.apps.publisher.forms import CourseForm, CourseRunForm, SeatForm from course_discovery.apps.publisher.forms import CourseForm, CourseRunForm, SeatForm
from course_discovery.apps.publisher.mixins import ViewPermissionMixin, check_view_permission
from course_discovery.apps.publisher.models import Course, CourseRun, Seat from course_discovery.apps.publisher.models import Course, CourseRun, Seat
from course_discovery.apps.publisher.wrappers import CourseRunWrapper from course_discovery.apps.publisher.wrappers import CourseRunWrapper
...@@ -23,12 +26,16 @@ class CourseRunListView(ListView): ...@@ -23,12 +26,16 @@ class CourseRunListView(ListView):
template_name = 'publisher/course_runs_list.html' template_name = 'publisher/course_runs_list.html'
def get_queryset(self): def get_queryset(self):
return [ if self.request.user.is_staff:
CourseRunWrapper(course_run) for course_run in CourseRun.objects.select_related('course').all() course_runs = CourseRun.objects.select_related('course').all()
] else:
courses = get_objects_for_user(self.request.user, Course.VIEW_PERMISSION, Course)
course_runs = CourseRun.objects.filter(course__in=courses).select_related('course').all()
return [CourseRunWrapper(course_run) for course_run in course_runs]
class CourseRunDetailView(DetailView):
class CourseRunDetailView(ViewPermissionMixin, DetailView):
""" Course Run Detail View.""" """ Course Run Detail View."""
model = CourseRun model = CourseRun
template_name = 'publisher/course_run_detail.html' template_name = 'publisher/course_run_detail.html'
...@@ -57,10 +64,11 @@ class CreateCourseView(CreateView): ...@@ -57,10 +64,11 @@ class CreateCourseView(CreateView):
return reverse(self.success_url, kwargs={'pk': self.object.id}) return reverse(self.success_url, kwargs={'pk': self.object.id})
class UpdateCourseView(UpdateView): class UpdateCourseView(ViewPermissionMixin, UpdateView):
""" Update Course View.""" """ Update Course View."""
model = Course model = Course
form_class = CourseForm form_class = CourseForm
permission_required = Course.VIEW_PERMISSION
template_name = 'publisher/course_form.html' template_name = 'publisher/course_form.html'
success_url = 'publisher:publisher_courses_edit' success_url = 'publisher:publisher_courses_edit'
...@@ -92,10 +100,11 @@ class CreateCourseRunView(CreateView): ...@@ -92,10 +100,11 @@ class CreateCourseRunView(CreateView):
return reverse(self.success_url, kwargs={'pk': self.object.id}) return reverse(self.success_url, kwargs={'pk': self.object.id})
class UpdateCourseRunView(UpdateView): class UpdateCourseRunView(ViewPermissionMixin, UpdateView):
""" Update Course Run View.""" """ Update Course Run View."""
model = CourseRun model = CourseRun
form_class = CourseRunForm form_class = CourseRunForm
permission_required = Course.VIEW_PERMISSION
template_name = 'publisher/course_run_form.html' template_name = 'publisher/course_run_form.html'
success_url = 'publisher:publisher_course_runs_edit' success_url = 'publisher:publisher_course_runs_edit'
...@@ -136,10 +145,11 @@ class CreateSeatView(CreateView): ...@@ -136,10 +145,11 @@ class CreateSeatView(CreateView):
return reverse(self.success_url, kwargs={'pk': self.object.id}) return reverse(self.success_url, kwargs={'pk': self.object.id})
class UpdateSeatView(UpdateView): class UpdateSeatView(ViewPermissionMixin, UpdateView):
""" Update Seat View.""" """ Update Seat View."""
model = Seat model = Seat
form_class = SeatForm form_class = SeatForm
permission_required = Course.VIEW_PERMISSION
template_name = 'publisher/seat_form.html' template_name = 'publisher/seat_form.html'
success_url = 'publisher:publisher_seats_edit' success_url = 'publisher:publisher_seats_edit'
...@@ -164,11 +174,16 @@ class ChangeStateView(View): ...@@ -164,11 +174,16 @@ class ChangeStateView(View):
state = request.POST.get('state') state = request.POST.get('state')
try: try:
course_run = CourseRun.objects.get(id=course_run_id) course_run = CourseRun.objects.get(id=course_run_id)
if not check_view_permission(request.user, course_run.course):
return HttpResponseForbidden()
course_run.change_state(target=state) course_run.change_state(target=state)
# pylint: disable=no-member
messages.success( messages.success(
request, 'Content moved to `{state}` successfully.'.format(state=course_run.current_state), request, _('Content moved to `{state}` successfully.').format(state=course_run.current_state)
) )
return HttpResponseRedirect(reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run_id})) return HttpResponseRedirect(reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run_id}))
except (CourseRun.DoesNotExist, TransitionNotAllowed): except (CourseRun.DoesNotExist, TransitionNotAllowed):
messages.error(request, 'There was an error in changing state.') messages.error(request, _('There was an error in changing state.'))
return HttpResponseRedirect(reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run_id})) return HttpResponseRedirect(reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run_id}))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment