Commit ea337ad7 by Waheed Ahmed

Added Top level Object Access.

ECOM-4978
parent 9983c7a9
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
import ddt import ddt
from mock import patch
from django.conf import settings from django.conf import settings
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.forms import model_to_dict from django.forms import model_to_dict
from django.test import TestCase from django.test import TestCase
from guardian.shortcuts import assign_perm
from course_discovery.apps.core.tests.factories import UserFactory, USER_PASSWORD from course_discovery.apps.core.tests.factories import UserFactory, USER_PASSWORD
from course_discovery.apps.publisher.models import Course, CourseRun, Seat, State from course_discovery.apps.publisher.models import Course, CourseRun, Seat, State
from course_discovery.apps.publisher.tests import factories from course_discovery.apps.publisher.tests import factories
from course_discovery.apps.publisher.tests.utils import create_non_staff_user_and_login
from course_discovery.apps.publisher.views import CourseRunDetailView
from course_discovery.apps.publisher.wrappers import CourseRunWrapper from course_discovery.apps.publisher.wrappers import CourseRunWrapper
from course_discovery.apps.publisher_comments.tests.factories import CommentFactory from course_discovery.apps.publisher_comments.tests.factories import CommentFactory
...@@ -46,8 +50,8 @@ class CreateUpdateCourseViewTests(TestCase): ...@@ -46,8 +50,8 @@ class CreateUpdateCourseViewTests(TestCase):
self.assertNotContains(response, 'Add new comment') self.assertNotContains(response, 'Add new comment')
self.assertNotContains(response, 'Total Comments') self.assertNotContains(response, 'Total Comments')
def test_update_course(self): def test_update_course_with_staff(self):
""" Verify that we can update an existing course. """ """ Verify that staff user can update an existing course. """
course_dict = model_to_dict(self.course) course_dict = model_to_dict(self.course)
updated_course_title = 'Updated {}'.format(self.course.title) updated_course_title = 'Updated {}'.format(self.course.title)
course_dict['title'] = updated_course_title course_dict['title'] = updated_course_title
...@@ -75,6 +79,73 @@ class CreateUpdateCourseViewTests(TestCase): ...@@ -75,6 +79,73 @@ class CreateUpdateCourseViewTests(TestCase):
self.assertContains(response, 'Add new comment') self.assertContains(response, 'Add new comment')
self.assertContains(response, comment.comment) self.assertContains(response, comment.comment)
def test_course_edit_page_with_non_staff(self):
""" Verify that non staff user can't access course edit page without permission. """
non_staff_user, group = create_non_staff_user_and_login(self)
course_dict = model_to_dict(self.course)
updated_course_title = 'Updated {}'.format(self.course.title)
course_dict['title'] = updated_course_title
self.assertNotEqual(self.course.title, updated_course_title)
response = self.client.get(
reverse('publisher:publisher_courses_edit', kwargs={'pk': self.course.id})
)
self.assertEqual(response.status_code, 403)
# assign user a group and assign view permission on that group
non_staff_user.groups.add(group)
assign_perm(Course.VIEW_PERMISSION, group, self.course)
response = self.client.get(
reverse('publisher:publisher_courses_edit', kwargs={'pk': self.course.id})
)
self.assertEqual(response.status_code, 200)
def test_update_course_with_non_staff(self):
""" Tests for update course with non staff user. """
non_staff_user, group = create_non_staff_user_and_login(self)
course_dict = model_to_dict(self.course)
updated_course_title = 'Updated {}'.format(self.course.title)
course_dict['title'] = updated_course_title
self.assertNotEqual(self.course.title, updated_course_title)
response = self.client.post(
reverse('publisher:publisher_courses_edit', kwargs={'pk': self.course.id}),
course_dict
)
# verify that non staff user can't update course without permission
self.assertEqual(response.status_code, 403)
# assign user a group and assign view permission on that group
non_staff_user.groups.add(group)
assign_perm(Course.VIEW_PERMISSION, group, self.course)
response = self.client.post(
reverse('publisher:publisher_courses_edit', kwargs={'pk': self.course.id}),
course_dict
)
self.assertRedirects(
response,
expected_url=reverse('publisher:publisher_courses_edit', kwargs={'pk': self.course.id}),
status_code=302,
target_status_code=200
)
course = Course.objects.get(id=self.course.id)
# Assert that course is updated.
self.assertEqual(course.title, updated_course_title)
# add new and check the comment on edit page.
comment = CommentFactory(content_object=self.course, user=self.user, site=self.site)
response = self.client.get(reverse('publisher:publisher_courses_edit', kwargs={'pk': self.course.id}))
self.assertContains(response, 'Total Comments 1')
self.assertContains(response, 'Add new comment')
self.assertContains(response, comment.comment)
class CreateUpdateCourseRunViewTests(TestCase): class CreateUpdateCourseRunViewTests(TestCase):
""" Tests for the publisher `CreateCourseRunView` and `UpdateCourseRunView`. """ """ Tests for the publisher `CreateCourseRunView` and `UpdateCourseRunView`. """
...@@ -115,11 +186,78 @@ class CreateUpdateCourseRunViewTests(TestCase): ...@@ -115,11 +186,78 @@ class CreateUpdateCourseRunViewTests(TestCase):
self.assertNotContains(response, 'Add new comment') self.assertNotContains(response, 'Add new comment')
self.assertNotContains(response, 'Total Comments') self.assertNotContains(response, 'Total Comments')
def test_update_course_run(self): def test_update_course_run_with_staff(self):
""" Verify that we can update an existing course run. """ """ Verify that staff user can update an existing course run. """
updated_lms_course_id = 'course-v1:testX+AS121+2018_q1'
self.course_run_dict['lms_course_id'] = updated_lms_course_id
self.assertNotEqual(self.course_run.lms_course_id, updated_lms_course_id)
response = self.client.post(
reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.course_run.id}),
self.course_run_dict
)
self.assertRedirects(
response,
expected_url=reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.course_run.id}),
status_code=302,
target_status_code=200
)
course_run = CourseRun.objects.get(id=self.course_run.id)
# Assert that course run is updated.
self.assertEqual(course_run.lms_course_id, updated_lms_course_id)
# add new and check the comment on edit page.
comment = CommentFactory(content_object=self.course_run, user=self.user, site=self.site)
response = self.client.get(reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.course_run.id}))
self.assertContains(response, 'Total Comments 1')
self.assertContains(response, 'Add new comment')
self.assertContains(response, comment.comment)
def test_edit_course_run_page_with_non_staff(self):
""" Verify that non staff user can't access course run edit page without permission. """
non_staff_user, group = create_non_staff_user_and_login(self)
updated_lms_course_id = 'course-v1:testX+AS121+2018_q1' updated_lms_course_id = 'course-v1:testX+AS121+2018_q1'
self.course_run_dict['lms_course_id'] = updated_lms_course_id self.course_run_dict['lms_course_id'] = updated_lms_course_id
self.assertNotEqual(self.course_run.lms_course_id, updated_lms_course_id) self.assertNotEqual(self.course_run.lms_course_id, updated_lms_course_id)
response = self.client.get(
reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.course_run.id})
)
self.assertEqual(response.status_code, 403)
# assign user a group and assign view permission on that group
non_staff_user.groups.add(group)
assign_perm(Course.VIEW_PERMISSION, group, self.course_run.course)
response = self.client.get(
reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.course_run.id})
)
self.assertEqual(response.status_code, 200)
def test_update_course_run_with_non_staff(self):
""" Test for course run with non staff user. """
non_staff_user, group = create_non_staff_user_and_login(self)
updated_lms_course_id = 'course-v1:testX+AS121+2018_q1'
self.course_run_dict['lms_course_id'] = updated_lms_course_id
self.assertNotEqual(self.course_run.lms_course_id, updated_lms_course_id)
response = self.client.post(
reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.course_run.id}),
self.course_run_dict
)
# verify that non staff user can't update course run without permission
self.assertEqual(response.status_code, 403)
# assign user a group and assign view permission on that group
non_staff_user.groups.add(group)
assign_perm(Course.VIEW_PERMISSION, group, self.course_run.course)
response = self.client.post( response = self.client.post(
reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.course_run.id}), reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.course_run.id}),
self.course_run_dict self.course_run_dict
...@@ -155,6 +293,7 @@ class SeatsCreateUpdateViewTests(TestCase): ...@@ -155,6 +293,7 @@ class SeatsCreateUpdateViewTests(TestCase):
self.user = UserFactory(is_staff=True, is_superuser=True) self.user = UserFactory(is_staff=True, is_superuser=True)
self.site = Site.objects.get(pk=settings.SITE_ID) self.site = Site.objects.get(pk=settings.SITE_ID)
self.client.login(username=self.user.username, password=USER_PASSWORD) self.client.login(username=self.user.username, password=USER_PASSWORD)
self.seat_edit_url = reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id})
def test_seat_view_page(self): def test_seat_view_page(self):
""" Verify that we can open new seat page. """ """ Verify that we can open new seat page. """
...@@ -177,8 +316,8 @@ class SeatsCreateUpdateViewTests(TestCase): ...@@ -177,8 +316,8 @@ class SeatsCreateUpdateViewTests(TestCase):
self.assertEqual(seat.price, seat_price) self.assertEqual(seat.price, seat_price)
def test_update_seat(self): def test_update_seat_with_staff(self):
""" Verify that we can update an existing seat. """ """ Verify that staff user can update an existing seat. """
self.assertEqual(self.seat.type, Seat.PROFESSIONAL) self.assertEqual(self.seat.type, Seat.PROFESSIONAL)
updated_seat_price = 470.00 updated_seat_price = 470.00
self.seat_dict['price'] = updated_seat_price self.seat_dict['price'] = updated_seat_price
...@@ -191,7 +330,7 @@ class SeatsCreateUpdateViewTests(TestCase): ...@@ -191,7 +330,7 @@ class SeatsCreateUpdateViewTests(TestCase):
self.assertRedirects( self.assertRedirects(
response, response,
expected_url=reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}), expected_url=self.seat_edit_url,
status_code=302, status_code=302,
target_status_code=200 target_status_code=200
) )
...@@ -202,28 +341,94 @@ class SeatsCreateUpdateViewTests(TestCase): ...@@ -202,28 +341,94 @@ class SeatsCreateUpdateViewTests(TestCase):
self.assertEqual(seat.type, Seat.VERIFIED) self.assertEqual(seat.type, Seat.VERIFIED)
self.seat_dict['type'] = Seat.HONOR self.seat_dict['type'] = Seat.HONOR
response = self.client.post( response = self.client.post(self.seat_edit_url, self.seat_dict)
reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}),
self.seat_dict
)
seat = Seat.objects.get(id=self.seat.id) seat = Seat.objects.get(id=self.seat.id)
# Assert that we can change seat type. # Assert that we can change seat type.
self.assertEqual(seat.type, Seat.HONOR) self.assertEqual(seat.type, Seat.HONOR)
self.assertRedirects( self.assertRedirects(
response, response,
expected_url=reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}), expected_url=self.seat_edit_url,
status_code=302, status_code=302,
target_status_code=200 target_status_code=200
) )
# add new and check the comment on edit page. # add new and check the comment on edit page.
comment = CommentFactory(content_object=self.seat, user=self.user, site=self.site) comment = CommentFactory(content_object=self.seat, user=self.user, site=self.site)
response = self.client.get(reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id})) response = self.client.get(self.seat_edit_url)
self.assertContains(response, 'Total Comments 1') self.assertContains(response, 'Total Comments 1')
self.assertContains(response, 'Add new comment') self.assertContains(response, 'Add new comment')
self.assertContains(response, comment.comment) self.assertContains(response, comment.comment)
def test_edit_seat_page_with_non_staff(self):
""" Verify that non staff user can't access seat edit page without permission. """
non_staff_user, group = create_non_staff_user_and_login(self)
response = self.client.get(reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}))
self.assertEqual(response.status_code, 403)
# assign user a group and assign view permission on that group
non_staff_user.groups.add(group)
assign_perm(Course.VIEW_PERMISSION, group, self.seat.course_run.course)
response = self.client.get(reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}))
self.assertEqual(response.status_code, 200)
def test_update_seat_with_non_staff(self):
""" Tests update seat for non staff user. """
non_staff_user, group = create_non_staff_user_and_login(self)
self.assertEqual(self.seat.type, Seat.PROFESSIONAL)
updated_seat_price = 470.00
self.seat_dict['price'] = updated_seat_price
self.seat_dict['type'] = Seat.VERIFIED
self.assertNotEqual(self.seat.price, updated_seat_price)
response = self.client.post(
reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}),
self.seat_dict
)
# verify that non staff user can't update course seat without permission
self.assertEqual(response.status_code, 403)
# assign user a group and assign view permission on that group
non_staff_user.groups.add(group)
assign_perm(Course.VIEW_PERMISSION, group, self.seat.course_run.course)
response = self.client.post(
reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}),
self.seat_dict
)
self.assertRedirects(
response,
expected_url=reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}),
status_code=302,
target_status_code=200
)
seat = Seat.objects.get(id=self.seat.id)
# Assert that seat is updated.
self.assertEqual(seat.price, updated_seat_price)
self.assertEqual(seat.type, Seat.VERIFIED)
self.seat_dict['type'] = Seat.HONOR
response = self.client.post(
reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}),
self.seat_dict
)
seat = Seat.objects.get(id=self.seat.id)
# Assert that we can change seat type.
self.assertEqual(seat.type, Seat.HONOR)
self.assertRedirects(
response,
expected_url=reverse('publisher:publisher_seats_edit', kwargs={'pk': self.seat.id}),
status_code=302,
target_status_code=200
)
@ddt.ddt @ddt.ddt
class CourseRunDetailTests(TestCase): class CourseRunDetailTests(TestCase):
...@@ -232,6 +437,8 @@ class CourseRunDetailTests(TestCase): ...@@ -232,6 +437,8 @@ class CourseRunDetailTests(TestCase):
def setUp(self): def setUp(self):
super(CourseRunDetailTests, self).setUp() super(CourseRunDetailTests, self).setUp()
self.course = factories.CourseFactory() self.course = factories.CourseFactory()
self.user = UserFactory(is_staff=True)
self.client.login(username=self.user.username, password=USER_PASSWORD)
self.course_run = factories.CourseRunFactory(course=self.course) self.course_run = factories.CourseRunFactory(course=self.course)
self._generate_seats([Seat.AUDIT, Seat.HONOR, Seat.VERIFIED, Seat.PROFESSIONAL]) self._generate_seats([Seat.AUDIT, Seat.HONOR, Seat.VERIFIED, Seat.PROFESSIONAL])
self._generate_credit_seat() self._generate_credit_seat()
...@@ -239,13 +446,35 @@ class CourseRunDetailTests(TestCase): ...@@ -239,13 +446,35 @@ class CourseRunDetailTests(TestCase):
self.wrapped_course_run = CourseRunWrapper(self.course_run) self.wrapped_course_run = CourseRunWrapper(self.course_run)
self.date_format = '%b %d, %Y, %H:%M:%S %p' self.date_format = '%b %d, %Y, %H:%M:%S %p'
def test_page_without_data(self): def test_page_without_data_staff(self):
""" Verify that detail page without any data available for that course-run. """ """ Verify that staff user can access detail page without any data
available for that course-run.
"""
course_run = factories.CourseRunFactory(course=self.course) course_run = factories.CourseRunFactory(course=self.course)
page_url = reverse('publisher:publisher_course_run_detail', args=[course_run.id]) page_url = reverse('publisher:publisher_course_run_detail', args=[course_run.id])
response = self.client.get(page_url) response = self.client.get(page_url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_page_with_invalid_id(self):
""" Verify that invalid course run id return 404. """
page_url = reverse('publisher:publisher_course_run_detail', args=[3434])
response = self.client.get(page_url)
self.assertEqual(response.status_code, 404)
def test_details_page_non_staff(self):
""" Verify that non staff user can't access detail page. """
non_staff_user, group = create_non_staff_user_and_login(self)
response = self.client.get(self.page_url)
self.assertEqual(response.status_code, 403)
non_staff_user.groups.add(group)
assign_perm(Course.VIEW_PERMISSION, group, self.course)
response = self.client.get(self.page_url)
self.assertEqual(response.status_code, 200)
def _generate_seats(self, modes): def _generate_seats(self, modes):
""" Helper method to add seats for a course-run. """ """ Helper method to add seats for a course-run. """
for mode in modes: for mode in modes:
...@@ -255,9 +484,9 @@ class CourseRunDetailTests(TestCase): ...@@ -255,9 +484,9 @@ class CourseRunDetailTests(TestCase):
""" Helper method to add credit seat for a course-run. """ """ Helper method to add credit seat for a course-run. """
factories.SeatFactory(type='credit', course_run=self.course_run, credit_provider='ASU', credit_hours=9) factories.SeatFactory(type='credit', course_run=self.course_run, credit_provider='ASU', credit_hours=9)
def test_course_run_detail_page(self): def test_course_run_detail_page_staff(self):
""" Verify that detail page contains all the data for drupal, studio and """ Verify that detail page contains all the data for drupal, studio and
cat. cat with staff user.
""" """
response = self.client.get(self.page_url) response = self.client.get(self.page_url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
...@@ -382,6 +611,16 @@ class CourseRunDetailTests(TestCase): ...@@ -382,6 +611,16 @@ class CourseRunDetailTests(TestCase):
self.assertContains(response, 'Total Comments 1') self.assertContains(response, 'Total Comments 1')
self.assertContains(response, comment.comment) self.assertContains(response, comment.comment)
def test_get_course_return_none(self):
""" Verify that `ViewPermissionMixin.get_course` return none
if `publisher_object` doesn't have `course` attr.
"""
non_staff_user, group = create_non_staff_user_and_login(self)
page_url = reverse('publisher:publisher_course_run_detail', args=[self.course_run.id])
with patch.object(CourseRunDetailView, 'get_object', return_value=non_staff_user):
response = self.client.get(page_url)
self.assertEqual(response.status_code, 403)
class ChangeStateViewTests(TestCase): class ChangeStateViewTests(TestCase):
""" Tests for the `ChangeStateView`. """ """ Tests for the `ChangeStateView`. """
...@@ -389,12 +628,14 @@ class ChangeStateViewTests(TestCase): ...@@ -389,12 +628,14 @@ class ChangeStateViewTests(TestCase):
def setUp(self): def setUp(self):
super(ChangeStateViewTests, self).setUp() super(ChangeStateViewTests, self).setUp()
self.course = factories.CourseFactory() self.course = factories.CourseFactory()
self.user = UserFactory(is_staff=True)
self.client.login(username=self.user.username, password=USER_PASSWORD)
self.course_run = factories.CourseRunFactory(course=self.course) self.course_run = factories.CourseRunFactory(course=self.course)
self.page_url = reverse('publisher:publisher_course_run_detail', args=[self.course_run.id]) self.page_url = reverse('publisher:publisher_course_run_detail', args=[self.course_run.id])
self.change_state_url = reverse('publisher:publisher_change_state', args=[self.course_run.id]) self.change_state_url = reverse('publisher:publisher_change_state', args=[self.course_run.id])
def test_detail_page_change_state(self): def test_change_state_with_staff(self):
""" Verify that we can change workflow state from detail page. """ """ Verify that staff user can change workflow state from detail page. """
response = self.client.get(self.page_url) response = self.client.get(self.page_url)
self.assertContains(response, 'Status:') self.assertContains(response, 'Status:')
self.assertContains(response, State.DRAFT.title()) self.assertContains(response, State.DRAFT.title())
...@@ -404,14 +645,34 @@ class ChangeStateViewTests(TestCase): ...@@ -404,14 +645,34 @@ class ChangeStateViewTests(TestCase):
# assert that state is changed to `NEEDS_REVIEW` # assert that state is changed to `NEEDS_REVIEW`
self.assertContains(response, State.NEEDS_REVIEW.title().replace('_', ' ')) self.assertContains(response, State.NEEDS_REVIEW.title().replace('_', ' '))
def test_detail_page_change_state_not_allowed(self): def test_change_state_not_allowed_with_staff(self):
""" Verify that we can't change workflow state from `DRAFT` to `PUBLISHED`. """ """ Verify that staff user can't change workflow state from `DRAFT` to `PUBLISHED`. """
response = self.client.get(self.page_url) response = self.client.get(self.page_url)
self.assertContains(response, 'Status:') self.assertContains(response, 'Status:')
self.assertContains(response, State.DRAFT.title()) self.assertContains(response, State.DRAFT.title())
# change workflow state from `DRAFT` to `PUBLISHED` # change workflow state from `DRAFT` to `PUBLISHED`
response = self.client.post(self.change_state_url, data={'state': State.PUBLISHED}, follow=True) response = self.client.post(self.change_state_url, data={'state': State.PUBLISHED}, follow=True)
# assert that state is not changed to `PUBLISHED` # assert that state is not changed to `PUBLISHED`
self.assertNotContains(response, State.PUBLISHED.title()) self.assertNotContains(response, State.PUBLISHED.title())
self.assertContains(response, 'There was an error in changing state.') self.assertContains(response, 'There was an error in changing state.')
def test_change_state_with_no_staff(self):
""" Tests change state for non staff user. """
non_staff_user, group = create_non_staff_user_and_login(self)
response = self.client.post(self.change_state_url, data={'state': State.NEEDS_REVIEW}, follow=True)
# verify that non staff user can't change workflow state without permission
self.assertEqual(response.status_code, 403)
# assign user a group and assign view permission on that group
non_staff_user.groups.add(group)
assign_perm(Course.VIEW_PERMISSION, group, self.course)
response = self.client.get(self.page_url)
self.assertContains(response, 'Status:')
self.assertContains(response, State.DRAFT.title())
# change workflow state from `DRAFT` to `NEEDS_REVIEW`
response = self.client.post(self.change_state_url, data={'state': State.NEEDS_REVIEW}, follow=True)
# assert that state is changed to `NEEDS_REVIEW`
self.assertContains(response, State.NEEDS_REVIEW.title().replace('_', ' '))
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