def override_other_acl(self, acl): other_category_acl = self.user.acl_cache['categories'][self.category.pk].copy() other_category_acl.update({ 'can_see': 1, 'can_browse': 1, 'can_see_all_threads': 1, 'can_see_own_threads': 0, 'can_hide_threads': 0, 'can_approve_content': 0, }) other_category_acl.update(acl) categories_acl = self.user.acl_cache['categories'] categories_acl[self.category_b.pk] = other_category_acl visible_categories = [self.category.pk] if other_category_acl['can_see']: visible_categories.append(self.category_b.pk) override_acl( self.user, { 'visible_categories': visible_categories, 'categories': categories_acl, } )
def test_cant_invite_followers_only(self): """api validates that you cant invite followers-only user to thread""" user_constant = UserModel.LIMIT_INVITES_TO_FOLLOWED self.other_user.limits_private_thread_invites_to = user_constant self.other_user.save() response = self.client.post( self.api_link, data={ 'to': [self.other_user.username], 'title': "Lorem ipsum dolor met", 'post': "Lorem ipsum dolor.", } ) self.assertEqual(response.status_code, 400) self.assertEqual( response.json(), { 'to': ["BobBoberson limits invitations to private threads to followed users."], } ) # allow us to bypass following check override_acl(self.user, {'can_add_everyone_to_private_threads': 1}) response = self.client.post( self.api_link, data={ 'to': [self.other_user.username], 'title': "-----", 'post': "Lorem ipsum dolor.", } ) self.assertEqual(response.status_code, 400) self.assertEqual( response.json(), { 'title': ["Thread title should contain alpha-numeric characters."], } ) # make user follow us override_acl(self.user, {'can_add_everyone_to_private_threads': 0}) self.other_user.follows.add(self.user) response = self.client.post( self.api_link, data={ 'to': [self.other_user.username], 'title': "-----", 'post': "Lorem ipsum dolor.", } ) self.assertEqual(response.status_code, 400) self.assertEqual( response.json(), { 'title': ["Thread title should contain alpha-numeric characters."], } )
def test_user_moderation_queue_bypass(self): """bypass moderation queue due to user's acl""" override_acl(self.user, {'can_approve_content': 1}) self.override_acl({'require_threads_approval': 1}) response = self.client.post( self.api_link, data={ 'category': self.category.pk, 'title': "Hello, I am test thread!", 'post': "Lorem ipsum dolor met!", } ) self.assertEqual(response.status_code, 200) thread = self.user.thread_set.all()[:1][0] self.assertFalse(thread.is_unapproved) self.assertFalse(thread.has_unapproved_posts) post = self.user.post_set.all()[:1][0] self.assertFalse(post.is_unapproved) category = Category.objects.get(slug='first-category') self.assertEqual(category.threads, self.category.threads + 1) self.assertEqual(category.posts, self.category.posts + 1) self.assertEqual(category.last_thread_id, thread.id)
def test_field_display_json(self): """field is included in display json""" test_link = reverse('misago:api:user-details', kwargs={'pk': self.user.pk}) response = self.client.get(test_link) self.assertEqual( response.json()['groups'], [ { 'name': 'IP address', 'fields': [ { 'fieldname': 'join_ip', 'name': 'Join IP', 'text': '127.0.0.1', }, { 'fieldname': 'last_ip', 'name': 'Last IP', 'text': '127.0.0.1', }, ], }, ] ) # IP fields tests ACL before displaying override_acl(self.user, { 'can_see_users_ips': 0 }) response = self.client.get(test_link) self.assertEqual(response.json()['groups'], [])
def test_no_permission(self): """api validates permission to search""" override_acl(self.user, {'can_search': 0}) response = self.client.get(self.test_link) self.assertContains(response, "have permission to search site", status_code=403)
def override_acl(self, allow_download=True): acl = self.user.acl.copy() acl.update({ 'max_attachment_size': 1000, 'can_download_other_users_attachments': allow_download }) override_acl(self.user, acl)
def test_category_moderation_queue_bypass(self): """bypass moderation queue due to user's acl""" override_acl(self.user, {'can_approve_content': 1}) self.category.require_replies_approval = True self.category.save() response = self.client.post( self.api_link, data={ 'post': "Lorem ipsum dolor met!", } ) self.assertEqual(response.status_code, 200) thread = Thread.objects.get(pk=self.thread.pk) self.assertFalse(thread.is_unapproved) self.assertFalse(thread.has_unapproved_posts) self.assertEqual(thread.replies, self.thread.replies + 1) post = self.user.post_set.all()[:1][0] self.assertFalse(post.is_unapproved) category = Category.objects.get(slug='first-category') self.assertEqual(category.threads, self.category.threads) self.assertEqual(category.posts, self.category.posts + 1)
def override_acl(self, acl=None): category_acl = self.user.acl['categories'][self.category.pk] category_acl.update({ 'can_see': 1, 'can_browse': 1, 'can_see_all_threads': 1, 'can_see_own_threads': 0, 'can_hide_threads': 0, 'can_approve_content': 0, 'can_edit_posts': 0, 'can_hide_posts': 0, 'can_hide_own_posts': 0, 'can_close_threads': 0, 'post_edit_time': 0, 'can_hide_events': 0, }) if acl: category_acl.update(acl) override_acl(self.user, { 'categories': { self.category.pk: category_acl } })
def test_cant_invite_anyone(self): """api validates that you cant invite nobody user to thread""" self.other_user.limits_private_thread_invites_to = LIMITS_PRIVATE_THREAD_INVITES_TO_NOBODY self.other_user.save() response = self.client.post(self.api_link, data={ 'to': [self.other_user.username], 'title': "Lorem ipsum dolor met", 'post': "Lorem ipsum dolor.", }) self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), { 'to': [ "BobBoberson is not allowing invitations to private threads." ] }) # allow us to bypass user preference check override_acl(self.user, {'can_add_everyone_to_private_threads': 1}) response = self.client.post(self.api_link, data={ 'to': [self.other_user.username], 'title': "-----", 'post': "Lorem ipsum dolor.", }) self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), { 'title': [ "Thread title should contain alpha-numeric characters." ] })
def test_participant_leave_thread(self): """ leave thread view makes user leave thread """ User = get_user_model() users = ( User.objects.create_user("Bob", "*****@*****.**", "pass123"), User.objects.create_user("Dam", "*****@*****.**", "pass123"), ) ThreadParticipant.objects.set_owner(self.thread, users[0]) ThreadParticipant.objects.add_participant(self.thread, users[1]) ThreadParticipant.objects.add_participant(self.thread, self.user) override_acl(self.user, {"can_use_private_threads": True, "can_moderate_private_threads": True}) link = reverse( "misago:private_thread_leave", kwargs={"thread_id": self.thread.id, "thread_slug": self.thread.slug} ) response = self.client.post(link, **self.ajax_header) self.assertEqual(response.status_code, 302) self.assertEqual(self.thread.threadparticipant_set.count(), 2) owner = self.thread.threadparticipant_set.get(is_owner=True) self.assertEqual(owner.user, users[0]) for participants in self.thread.threadparticipant_set.all(): self.assertIn(participants.user, users) Thread.objects.get(pk=self.thread.pk) with self.assertRaises(ThreadParticipant.DoesNotExist): self.thread.threadparticipant_set.get(user=self.user)
def override_acl(self, acl=None): final_acl = self.user.acl['categories'][self.category.pk] final_acl.update({ 'can_see': 1, 'can_browse': 1, 'can_see_all_threads': 1, 'can_see_own_threads': 0, 'can_hide_threads': 0, 'can_approve_content': 0, 'can_edit_posts': 0, 'can_hide_posts': 0, 'can_hide_own_posts': 0, 'can_merge_threads': 0 }) if acl: final_acl.update(acl) visible_categories = self.user.acl['visible_categories'] browseable_categories = self.user.acl['browseable_categories'] if not final_acl['can_see'] and self.category.pk in visible_categories: visible_categories.remove(self.category.pk) browseable_categories.remove(self.category.pk) if not final_acl['can_browse'] and self.category.pk in browseable_categories: browseable_categories.remove(self.category.pk) override_acl(self.user, { 'visible_categories': visible_categories, 'browseable_categories': browseable_categories, 'categories': { self.category.pk: final_acl } })
def test_edit_participants(self): """edit participants view displays thread participants""" User = get_user_model() users = ( User.objects.create_user("Bob", "*****@*****.**", "pass123"), User.objects.create_user("Dam", "*****@*****.**", "pass123"), ) ThreadParticipant.objects.set_owner(self.thread, self.user) ThreadParticipant.objects.add_participant(self.thread, users[0]) ThreadParticipant.objects.add_participant(self.thread, users[1]) override_acl(self.user, {"can_use_private_threads": True, "can_moderate_private_threads": True}) link = reverse( "misago:private_thread_edit_participants", kwargs={"thread_id": self.thread.id, "thread_slug": self.thread.slug}, ) response = self.client.get(link, **self.ajax_header) self.assertEqual(response.status_code, 200) owner_pos = response.content.find(self.user.get_absolute_url()) for user in users: participant_pos = response.content.find(user.get_absolute_url()) self.assertTrue(owner_pos < participant_pos)
def test_user_ban(self): """user ban details page has no showstoppers""" override_acl(self.user, { 'can_see_ban_details': 0, }) User = get_user_model() test_user = User.objects.create_user("Bob", "*****@*****.**", 'pass.123') link_kwargs = {'user_slug': test_user.slug, 'user_id': test_user.pk} response = self.client.get(reverse('misago:user_ban', kwargs=link_kwargs)) self.assertEqual(response.status_code, 404) override_acl(self.user, { 'can_see_ban_details': 1, }) Ban.objects.create(banned_value=test_user.username, user_message="User m3ss4ge.", staff_message="Staff m3ss4ge.") response = self.client.get(reverse('misago:user_ban', kwargs=link_kwargs)) self.assertEqual(response.status_code, 200) self.assertIn('User m3ss4ge', response.content) self.assertIn('Staff m3ss4ge', response.content)
def test_no_permission(self): """api respects permission to search users""" override_acl(self.user, {'can_search_users': 0}) response = self.client.get(self.api_link) self.assertEqual(response.status_code, 200) self.assertNotIn('users', [p['id'] for p in response.json()])
def test_add_user_to_other_user_thread_moderator(self): """moderators can add users to other users threads""" ThreadParticipant.objects.set_owner(self.thread, self.other_user) self.thread.has_reported_posts = True self.thread.save() override_acl(self.user, {'can_moderate_private_threads': 1}) self.patch( self.api_link, [ { 'op': 'add', 'path': 'participants', 'value': self.user.username, }, ] ) # event was set on thread event = self.thread.post_set.order_by('id').last() self.assertTrue(event.is_event) self.assertTrue(event.event_type, 'entered_thread') # notification about new private thread wasn't send because we invited ourselves self.assertEqual(len(mail.outbox), 0)
def test_thread_visibility(self): """only participated threads are returned by private threads api""" visible = testutils.post_thread(category=self.category, poster=self.user) reported = testutils.post_thread(category=self.category, poster=self.user) # hidden thread testutils.post_thread(category=self.category, poster=self.user) ThreadParticipant.objects.add_participants(visible, [self.user]) reported.has_reported_posts = True reported.save() response = self.client.get(self.api_link) self.assertEqual(response.status_code, 200) response_json = response.json() self.assertEqual(response_json['count'], 1) self.assertEqual(response_json['results'][0]['id'], visible.id) # threads with reported posts will also show to moderators override_acl(self.user, {'can_moderate_private_threads': 1}) response = self.client.get(self.api_link) self.assertEqual(response.status_code, 200) response_json = response.json() self.assertEqual(response_json['count'], 2) self.assertEqual(response_json['results'][0]['id'], reported.id) self.assertEqual(response_json['results'][1]['id'], visible.id)
def test_add_user_to_closed_moderator(self): """moderators can add users to closed threads""" ThreadParticipant.objects.set_owner(self.thread, self.user) self.thread.is_closed = True self.thread.save() override_acl(self.user, { 'can_moderate_private_threads': 1 }) response = self.patch(self.api_link, [ {'op': 'add', 'path': 'participants', 'value': self.other_user.username} ]) # event was set on thread event = self.thread.post_set.order_by('id').last() self.assertTrue(event.is_event) self.assertTrue(event.event_type, 'added_participant') # notification about new private thread was sent to other user self.assertEqual(len(mail.outbox), 1) email = mail.outbox[-1] self.assertIn(self.user.username, email.subject) self.assertIn(self.thread.title, email.subject)
def test_owner_add_participant(self): """owner can add participants""" User = get_user_model() users = ( User.objects.create_user("Bob", "*****@*****.**", "pass123"), User.objects.create_user("Dam", "*****@*****.**", "pass123"), ) ThreadParticipant.objects.set_owner(self.thread, self.user) ThreadParticipant.objects.add_participant(self.thread, users[0]) override_acl(self.user, {"can_use_private_threads": True, "can_moderate_private_threads": True}) link = reverse( "misago:private_thread_add_participants", kwargs={"thread_id": self.thread.id, "thread_slug": self.thread.slug}, ) response = self.client.post(link, data={"users": "Bob, Dam"}, **self.ajax_header) self.assertEqual(response.status_code, 200) self.assertEqual(self.thread.threadparticipant_set.count(), 3) for participant in self.thread.threadparticipant_set.all(): if participant.is_owner: self.assertEqual(participant.user, self.user) else: self.assertIn(participant.user, users) Thread.objects.get(pk=self.thread.pk) self.thread.threadparticipant_set.get(user=self.user)
def test_cant_invite_blocking(self): """api validates that you cant invite blocking user to thread""" self.other_user.blocks.add(self.user) response = self.client.post(self.api_link, data={ 'to': [self.other_user.username], 'title': "Lorem ipsum dolor met", 'post': "Lorem ipsum dolor.", }) self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), { 'to': [ "BobBoberson is blocking you." ] }) # allow us to bypass blocked check override_acl(self.user, {'can_add_everyone_to_private_threads': 1}) response = self.client.post(self.api_link, data={ 'to': [self.other_user.username], 'title': "-----", 'post': "Lorem ipsum dolor.", }) self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), { 'title': [ "Thread title should contain alpha-numeric characters." ] })
def override_other_acl(self, acl=None): other_category_acl = self.user.acl['categories'][self.category.pk].copy() other_category_acl.update({ 'can_see': 1, 'can_browse': 1, 'can_start_threads': 0, 'can_reply_threads': 0, 'can_edit_posts': 1, 'can_approve_content': 0, 'can_move_posts': 1 }) if acl: other_category_acl.update(acl) categories_acl = self.user.acl['categories'] categories_acl[self.category_b.pk] = other_category_acl visible_categories = [self.category.pk] if other_category_acl['can_see']: visible_categories.append(self.category_b.pk) override_acl(self.user, { 'visible_categories': visible_categories, 'categories': categories_acl, })
def test_other_user(self): """api handles scenario when its other user looking at profile""" test_user = UserModel.objects.create_user('BobBoberson', '*****@*****.**', 'bob123456') api_link = reverse( 'misago:api:user-edit-details', kwargs={ 'pk': test_user.pk, } ) # moderator has permission to edit details override_acl(self.user, { 'can_moderate_profile_details': True, }) response = self.client.get(api_link) self.assertEqual(response.status_code, 200) # non-moderator has no permission to edit details override_acl(self.user, { 'can_moderate_profile_details': False, }) response = self.client.get(api_link) self.assertEqual(response.status_code, 403)
def test_moderator_closed_thread_takeover(self): """moderator can takeover closed thread thread""" ThreadParticipant.objects.set_owner(self.thread, self.other_user) ThreadParticipant.objects.add_participants(self.thread, [self.user]) self.thread.is_closed = True self.thread.save() override_acl(self.user, { 'can_moderate_private_threads': 1 }) response = self.patch(self.api_link, [ {'op': 'replace', 'path': 'owner', 'value': self.user.pk} ]) self.assertEqual(response.status_code, 200) # valid users were flagged for sync User = get_user_model() self.assertFalse(User.objects.get(pk=self.user.pk).sync_unread_private_threads) self.assertTrue(User.objects.get(pk=self.other_user.pk).sync_unread_private_threads) # ownership was transfered self.assertEqual(self.thread.participants.count(), 2) self.assertTrue(ThreadParticipant.objects.get(user=self.user).is_owner) self.assertFalse(ThreadParticipant.objects.get(user=self.other_user).is_owner) # change was recorded in event event = self.thread.post_set.order_by('id').last() self.assertTrue(event.is_event) self.assertTrue(event.event_type, 'tookover')
def test_moderator_change_owner(self): """moderator can change thread owner to other user""" User = get_user_model() new_owner = User.objects.create_user( 'NewOwner', '*****@*****.**', 'pass123') ThreadParticipant.objects.set_owner(self.thread, self.other_user) ThreadParticipant.objects.add_participants(self.thread, [self.user, new_owner]) override_acl(self.user, { 'can_moderate_private_threads': 1 }) response = self.patch(self.api_link, [ {'op': 'replace', 'path': 'owner', 'value': new_owner.pk} ]) self.assertEqual(response.status_code, 200) # valid users were flagged for sync self.assertTrue(User.objects.get(pk=new_owner.pk).sync_unread_private_threads) self.assertFalse(User.objects.get(pk=self.user.pk).sync_unread_private_threads) self.assertTrue(User.objects.get(pk=self.other_user.pk).sync_unread_private_threads) # ownership was transfered self.assertEqual(self.thread.participants.count(), 3) self.assertTrue(ThreadParticipant.objects.get(user=new_owner).is_owner) self.assertFalse(ThreadParticipant.objects.get(user=self.user).is_owner) self.assertFalse(ThreadParticipant.objects.get(user=self.other_user).is_owner) # change was recorded in event event = self.thread.post_set.order_by('id').last() self.assertTrue(event.is_event) self.assertTrue(event.event_type, 'changed_owner')
def test_list_handles_nonexisting_user(self): """list raises 404 for invalid user id""" self.user.set_username("NewUsername", self.user) override_acl(self.user, {"can_see_users_name_history": True}) response = self.client.get("%s?user=142141" % self.link) self.assertEqual(response.status_code, 404)
def test_list_handles_invalid_filter(self): """list raises 404 for invalid filter""" self.user.set_username('NewUsername', self.user) override_acl(self.user, {'can_see_users_name_history': True}) response = self.client.get('%s?user=abcd' % self.link) self.assertEqual(response.status_code, 404)
def test_signature_no_permission(self): """edit signature view with no ACL returns 404""" override_acl(self.user, { 'can_have_signature': 0, }) response = self.client.get(self.view_link) self.assertEqual(response.status_code, 404)
def test_protected_user(self): """fail to warn due to user's can_be_warned""" override_acl(self.user, {'can_warn_users': 1}) override_acl(self.test_user, {'can_be_warned': 0}) response = self.client.get(reverse('misago:warn_user', kwargs=self.link_kwargs)) self.assertEqual(response.status_code, 403)
def test_flood_permission(self): """middleware is respects permission to flood for team members""" override_acl(self.user, { 'can_omit_flood_protection': True }) middleware = FloodProtectionMiddleware(user=self.user) self.assertFalse(middleware.use_this_middleware())
def test_moderate_own_username(self): """moderate own username""" override_acl(self.user, { 'can_rename_users': 1, }) response = self.client.get('/api/users/%s/moderate-username/' % self.user.pk) self.assertEqual(response.status_code, 200)
def test_lander_no_permission(self): """lander returns 403 if user has no permission""" override_acl(self.user, { 'can_browse_users_list': 0, }) response = self.client.get(reverse('misago:users')) self.assertEqual(response.status_code, 403)
def test_signature_no_permission(self): """edit signature api with no ACL returns 403""" override_acl(self.user, { 'can_have_signature': 0, }) response = self.client.get(self.link) self.assertEqual(response.status_code, 403) self.assertEqual( response.json(), { "detail": "You don't have permission to change signature.", })
def test_delete_no_permission(self): """raises 403 error when no permission to delete""" override_acl( self.user, { 'can_delete_users_newer_than': 0, 'can_delete_users_with_less_posts_than': 0, } ) response = self.client.post(self.link) self.assertEqual(response.status_code, 403) self.assertContains(response, "can't delete users", status_code=403)
def test_delete_superadmin(self): """raises 403 error when attempting to delete superadmin""" override_acl(self.user, { 'can_delete_users_newer_than': 10, 'can_delete_users_with_less_posts_than': 10, }) self.other_user.is_superuser = True self.other_user.save() response = self.client.post(self.link) self.assertContains(response, "can't delete administrators", status_code=403)
def test_list_denies_permission(self): """list denies permission for other user (or all) if no access""" override_acl(self.user, {'can_see_users_name_history': False}) response = self.client.get('%s?user=%s' % (self.link, self.user.pk + 1)) self.assertEqual(response.status_code, 403) self.assertIn("don't have permission to", response.content) response = self.client.get(self.link) self.assertEqual(response.status_code, 403) self.assertIn("don't have permission to", response.content)
def test_no_permission(self): """view validates permission to search forum""" override_acl(self.user, {'can_search': 0}) response = self.client.get( reverse('misago:search', kwargs={ 'search_provider': 'users', })) self.assertContains(response, "have permission to search site", status_code=403)
def override_acl(self, acl): final_acl = { 'can_see': 1, 'can_browse': 1, 'can_see_all_threads': 1, 'can_see_own_threads': 0, 'can_hide_threads': 0, 'can_approve_content': 0, } final_acl.update(acl) override_acl(self.user, {'categories': {self.category.pk: final_acl}})
def test_delete_self(self): """raises 403 error when attempting to delete oneself""" override_acl( self.user, { 'can_delete_users_newer_than': 10, 'can_delete_users_with_less_posts_than': 10, }) response = self.client.post('/api/users/%s/delete/' % self.user.pk) self.assertEqual(response.status_code, 403) self.assertEqual(response.json(), { 'detail': "You can't delete your account.", })
def test_add_no_perm_user(self): """can't add user that has no permission to use private threads""" ThreadParticipant.objects.set_owner(self.thread, self.user) override_acl(self.other_user, { 'can_use_private_threads': 0 }) response = self.patch(self.api_link, [ {'op': 'add', 'path': 'participants', 'value': self.other_user.username} ]) self.assertContains(response, "BobBoberson can't participate", status_code=400)
def test_post_too_long_signature(self): """too long new signature errors""" override_acl(self.user, { 'can_have_signature': 1, }) self.user.is_signature_locked = False self.user.save() response = self.client.post(self.link, data={'signature': 'abcd' * 1000}) self.assertEqual(response.status_code, 400) self.assertIn('too long', response.content)
def test_delete_admin(self): """raises 403 error when attempting to delete admin""" override_acl(self.user, { 'can_delete_users_newer_than': 10, 'can_delete_users_with_less_posts_than': 10, }) self.other_user.is_staff = True self.other_user.save() response = self.client.post(self.link) self.assertEqual(response.status_code, 403) self.assertIn("can't delete administrators", response.content)
def test_get_signature(self): """GET to api returns json with no signature""" override_acl(self.user, { 'can_have_signature': 1, }) self.user.is_signature_locked = False self.user.save() response = self.client.get(self.link) self.assertEqual(response.status_code, 200) self.assertFalse(response.json()['signature'])
def test_mod_can_see_reported(self): """moderator can see private thread that has reports""" override_acl(self.user, {'can_moderate_private_threads': 1}) self.thread.has_reported_posts = True self.thread.save() response = self.client.get(self.api_link) self.assertEqual(response.status_code, 200) response_json = response.json() self.assertEqual(response_json['title'], self.thread.title) self.assertEqual(response_json['participants'], [])
def test_signature_locked(self): """locked edit signature returns 403""" override_acl(self.user, { 'can_have_signature': 1, }) self.user.is_signature_locked = True self.user.signature_lock_user_message = 'Your siggy is banned.' self.user.save() response = self.client.get(self.link) self.assertEqual(response.status_code, 403) self.assertIn('Your siggy is banned', response.content)
def override_acl(self, new_acl): new_acl.update({ 'can_see': True, 'can_browse': True, 'can_see_all_threads': True, 'can_see_own_threads': False, 'can_pin_threads': True }) forums_acl = self.user.acl forums_acl['visible_forums'].append(self.forum.pk) forums_acl['forums'][self.forum.pk] = new_acl override_acl(self.user, forums_acl)
def override_acl(self, extra_acl=None): new_acl = self.user.acl new_acl['categories'][self.category.pk].update({ 'can_see': 1, 'can_browse': 1, 'can_start_threads': 0, 'can_reply_threads': 1 }) if extra_acl: new_acl['categories'][self.category.pk].update(extra_acl) override_acl(self.user, new_acl)
def test_cant_browse(self): """has no permission to browse forum""" forums_acl = self.user.acl forums_acl['visible_forums'].append(self.forum.pk) forums_acl['forums'][self.forum.pk] = { 'can_see': 1, 'can_browse': 0, 'can_start_threads': 1, } override_acl(self.user, forums_acl) response = self.client.get(self.link, **self.ajax_header) self.assertEqual(response.status_code, 403)
def test_get_username_requirements(self): """get to API returns username requirements""" override_acl(self.user, { 'can_rename_users': 1, }) response = self.client.get(self.link) self.assertEqual(response.status_code, 200) self.assertEqual( response.json(), { 'length_min': settings.username_length_min, 'length_max': settings.username_length_max, })
def test_delete_too_many_posts(self): """raises 403 error when user has too many posts""" override_acl(self.user, { 'can_delete_users_newer_than': 0, 'can_delete_users_with_less_posts_than': 5, }) self.other_user.posts = 6 self.other_user.save() response = self.client.post(self.link) self.assertEqual(response.status_code, 403) self.assertIn("can't delete users", response.content)
def test_moderator_can_access_reported_thread(self): """moderator can see private thread with reports""" override_acl(self.user, { 'can_use_private_threads': True, 'can_moderate_private_threads': True }) self.thread.has_reported_posts = True self.thread.save() response = self.client.get(self.thread.get_absolute_url()) self.assertEqual(response.status_code, 200) self.assertIn(self.thread.title, response.content)
def test_cant_invite_followers_only(self): """api validates that you cant invite followers-only user to thread""" user_constant = UserModel.LIMIT_INVITES_TO_FOLLOWED self.other_user.limits_private_thread_invites_to = user_constant self.other_user.save() response = self.client.post(self.api_link, data={ 'to': [self.other_user.username], 'title': "Lorem ipsum dolor met", 'post': "Lorem ipsum dolor.", }) self.assertEqual(response.status_code, 400) self.assertEqual( response.json(), { 'to': [ "BobBoberson limits invitations to private threads to followed users." ], }) # allow us to bypass following check override_acl(self.user, {'can_add_everyone_to_private_threads': 1}) response = self.client.post(self.api_link, data={ 'to': [self.other_user.username], 'title': "-----", 'post': "Lorem ipsum dolor.", }) self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), { 'title': ["Thread title should contain alpha-numeric characters."], }) # make user follow us override_acl(self.user, {'can_add_everyone_to_private_threads': 0}) self.other_user.follows.add(self.user) response = self.client.post(self.api_link, data={ 'to': [self.other_user.username], 'title': "-----", 'post': "Lorem ipsum dolor.", }) self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), { 'title': ["Thread title should contain alpha-numeric characters."], })
def test_no_lift_ban_permission(self): """user with no permission fails to lift user ban""" override_acl(self.user, { 'can_lift_bans': 0, 'max_lifted_ban_length': 0, }) Ban.objects.create(banned_value=self.test_user.username) response = self.client.post( reverse('misago:lift_user_ban', kwargs=self.link_kwargs)) self.assertEqual(response.status_code, 403) self.assertIn("You can't lift bans.", response.content)
def test_delete_user(self): """user with permission deletes other user""" override_acl(self.user, { 'can_delete_users_newer_than': 5, 'can_delete_users_with_less_posts_than': 5, }) response = self.client.post( reverse('misago:delete_user', kwargs=self.link_kwargs)) self.assertEqual(response.status_code, 302) response = self.client.post(reverse('misago:index')) self.assertEqual(response.status_code, 200) self.assertIn('Bob has been deleted', response.content)
def test_post_empty_signature(self): """empty POST empties user signature""" override_acl(self.user, { 'can_have_signature': 1, }) self.user.is_signature_locked = False self.user.save() response = self.client.post(self.link, data={'signature': ''}) self.assertEqual(response.status_code, 200) response_json = json.loads(response.content) self.assertFalse(response_json['signature'])
def test_delete_too_old_member(self): """raises 403 error when user is too old""" override_acl(self.user, { 'can_delete_users_newer_than': 5, 'can_delete_users_with_less_posts_than': 0, }) self.other_user.joined_on -= timedelta(days=6) self.other_user.save() response = self.client.post(self.link) self.assertEqual(response.status_code, 403) self.assertIn("can't delete users", response.content) self.assertIn("members for more than 5 days", response.content)
def test_reply_user_moderation_queue_bypass(self): """bypass moderation queue due to user's acl""" override_acl(self.user, {'can_approve_content': 1}) self.override_acl({'require_edits_approval': 1}) response = self.put(self.api_link, data={ 'post': "Lorem ipsum dolor met!", }) self.assertEqual(response.status_code, 200) post = self.user.post_set.all()[:1][0] self.assertFalse(post.is_unapproved)
def test_ban_details(self): """api returns ban json""" override_acl(self.user, {'can_see_ban_details': 1}) Ban.objects.create(check_type=BAN_USERNAME, banned_value=self.other_user.username, user_message='Nope!') response = self.client.get(self.link) self.assertEqual(response.status_code, 200) ban_json = json.loads(smart_str(response.content)) self.assertEqual(ban_json['user_message']['plain'], 'Nope!') self.assertEqual(ban_json['user_message']['html'], '<p>Nope!</p>')
def override_other_user_acl(self, hide=False): new_acl = deepcopy(self.other_user.acl) new_acl['categories'][self.category.pk].update({ 'can_see': 1, 'can_browse': 1, 'can_start_threads': 1, 'can_reply_threads': 1, 'can_edit_posts': 1 }) if hide: new_acl['categories'][self.category.pk].update( {'can_browse': False}) override_acl(self.other_user, new_acl)
def allow_redirect_follow(self): override_acl( self.user, { 'visible_forums': [self.redirect.parent_id, self.redirect.pk], 'forums': { self.redirect.parent_id: { 'can_see': 1, 'can_browse': 1 }, self.redirect.pk: { 'can_see': 1, 'can_browse': 1 }, } })
def test_no_permission(self): """no permission to moderate avatar""" override_acl(self.user, { 'can_rename_users': 0, }) response = self.client.get(self.link) self.assertContains(response, "can't rename users", status_code=403) override_acl(self.user, { 'can_rename_users': 0, }) response = self.client.post(self.link) self.assertContains(response, "can't rename users", status_code=403)
def test_cant_invite_no_permission(self): """api validates invited user permission to private thread""" override_acl(self.other_user, {'can_use_private_threads': 0}) response = self.client.post(self.api_link, data={ 'to': [self.other_user.username], 'title': "Lorem ipsum dolor met", 'post': "Lorem ipsum dolor.", }) self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), { 'to': ["BobBoberson can't participate in private threads."], })