def read(self, request, thread_pk, pk): thread = self.get_thread(request, get_int_or_404(thread_pk)) post = self.get_post(request, thread, get_int_or_404(pk)).model request.user.lock() return post_read_endpoint(request, thread.model, post)
def post_editor(self, request, thread_pk, pk): thread = self.get_thread( request, get_int_or_404(thread_pk), read_aware=False, subscription_aware=False ) post = self.get_post(request, thread, get_int_or_404(pk)).model allow_edit_post(request.user, post) attachments = [] for attachment in post.attachment_set.order_by('-id'): add_acl(request.user, attachment) attachments.append(attachment) attachments_json = AttachmentSerializer( attachments, many=True, context={'user': request.user}).data return Response({ 'id': post.pk, 'api': post.get_api_url(), 'post': post.original, 'attachments': attachments_json, 'can_protect': bool(thread.category.acl['can_protect_posts']), 'is_protected': post.is_protected, 'poster': post.poster_name })
def generic(request): queryset = get_user_model().objects if request.query_params.get('followers'): user_pk = get_int_or_404(request.query_params.get('followers')) queryset = get_object_or_404(queryset, pk=user_pk).followed_by elif request.query_params.get('follows'): user_pk = get_int_or_404(request.query_params.get('follows')) queryset = get_object_or_404(queryset, pk=user_pk).follows if request.query_params.get('rank'): rank_pk = get_int_or_404(request.query_params.get('rank')) rank = get_object_or_404(Rank.objects, pk=rank_pk, is_tab=True) queryset = queryset.filter(rank=rank) if request.query_params.get('name'): name_starts_with = request.query_params.get('name').strip().lower() if name_starts_with: queryset = queryset.filter(slug__startswith=name_starts_with) else: raise Http404() queryset = queryset.select_related('rank', 'ban_cache', 'online_tracker') paginator = Paginator() users = paginator.paginate_queryset(queryset.order_by('slug'), request) make_users_status_aware(users, request.user.acl) return paginator.get_paginated_response( UserSerializer(users, many=True).data)
def post_editor(self, request, thread_pk, pk): thread = self.get_thread(request, get_int_or_404(thread_pk), read_aware=False, subscription_aware=False) post = self.get_post(request, thread, get_int_or_404(pk)).model allow_edit_post(request.user, post) attachments = [] for attachment in post.attachment_set.order_by('-id'): add_acl(request.user, attachment) attachments.append(attachment) attachments_json = AttachmentSerializer(attachments, many=True, context={ 'user': request.user }).data return Response({ 'id': post.pk, 'api': post.get_api_url(), 'post': post.original, 'attachments': attachments_json, 'can_protect': bool(thread.category.acl['can_protect_posts']), 'is_protected': post.is_protected, 'poster': post.poster_name })
def data_downloads(self, request, pk=None): get_int_or_404(pk) allow_self_only(request.user, pk, _("You can't see other users data downloads.")) queryset = request.user.datadownload_set.all()[:5] serializer = DataDownloadSerializer(queryset, many=True) return Response(serializer.data)
def forum_options(self, request, pk=None): get_int_or_404(pk) allow_self_only(request.user, pk, _("You can't change other users options.")) serializer = ForumOptionsSerializer(request.user, data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(status=204)
def forum_options(self, request, pk=None): get_int_or_404(pk) allow_self_only(request.user, pk, _("You can't change other users options.")) serializer = ForumOptionsSerializer(request.user, data=request.data) if serializer.is_valid(): serializer.save() return Response({'detail': _("Your forum options have been changed.")}) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def forum_options(self, request, pk=None): get_int_or_404(pk) allow_self_only(request.user, pk, _("You can't change other users options.")) serializer = ForumOptionsSerializer(request.user, data=request.data) if serializer.is_valid(): serializer.save() return Response(status=204) else: return Response(serializer.errors, status=400)
def forum_options(self, request, pk=None): get_int_or_404(pk) allow_self_only(request.user, pk, _("You can't change other users options.")) form = ForumOptionsForm(request.data, instance=request.user) if form.is_valid(): form.save() return Response( {'detail': _("Your forum options have been changed.")}) else: return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)
def forum_options(self, request, pk=None): get_int_or_404(pk) allow_self_only(request.user, pk, _("You can't change other users options.")) form = ForumOptionsForm(request.data, instance=request.user) if form.is_valid(): form.save() return Response({ 'detail': _("Your forum options have been changed.") }) else: return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)
def request_data_download(self, request, pk=None): get_int_or_404(pk) allow_self_only(request.user, pk, _("You can't request data downloads for other users.")) if not settings.MISAGO_ENABLE_DOWNLOAD_OWN_DATA: raise PermissionDenied(_("You can't download your data.")) if user_has_data_download_request(request.user): raise PermissionDenied( _("You can't have more than one data download request at single time.")) request_user_data_download(request.user) return Response({'detail': 'ok'})
def get_votes(self, request, thread_pk, pk): poll_pk = get_int_or_404(pk) try: thread = self.get_thread(request, thread_pk) if thread.poll.pk != poll_pk: raise Http404() except Poll.DoesNotExist: raise Http404() allow_see_poll_votes(request.user, thread.poll) choices = [] voters = {} for choice in thread.poll.choices: choice['voters'] = [] voters[choice['hash']] = choice['voters'] choices.append(choice) queryset = thread.poll.pollvote_set.values( 'voter_id', 'voter_name', 'voter_slug', 'voted_on', 'choice_hash') for voter in queryset.order_by('voter_name').iterator(): voters[voter['choice_hash']].append(PollVoteSerializer(voter).data) return Response(choices)
def search(request, search_provider=None): allowed_providers = searchproviders.get_allowed_providers(request) if not request.user.acl_cache['can_search'] or not allowed_providers: raise PermissionDenied(_("You don't have permission to search site.")) search_query = get_search_query(request) response = [] for provider in allowed_providers: provider_data = { 'id': provider.url, 'name': six.text_type(provider.name), 'icon': provider.icon, 'url': reverse('misago:search', kwargs={'search_provider': provider.url}), 'api': reverse('misago:api:search', kwargs={'search_provider': provider.url}), 'results': None, 'time': None, } if not search_provider or search_provider == provider.url: start_time = time() if search_provider == provider.url: page = get_int_or_404(request.query_params.get('page', 1)) else: page = 1 provider_data['results'] = provider.search(search_query, page) provider_data['time'] = float('%.2f' % (time() - start_time)) response.append(provider_data) return Response(response)
def search(request, search_provider=None): allowed_providers = searchproviders.get_allowed_providers(request) if not request.user.acl['can_search'] or not allowed_providers: raise PermissionDenied(_("You don't have permission to search site.")) search_query = get_search_query(request) response = [] for provider in allowed_providers: provider_data = { 'id': provider.url, 'name': six.text_type(provider.name), 'url': reverse('misago:search', kwargs={'search_provider': provider.url}), 'api': reverse('misago:api:search', kwargs={'search_provider': provider.url}), 'results': None, 'time': None, } if not search_provider or search_provider == provider.url: start_time = time() if search_provider == provider.url: page = get_int_or_404(request.query_params.get('page', 1)) else: page = 1 provider_data['results'] = provider.search(search_query, page) provider_data['time'] = float('%.2f' % (time() - start_time)) response.append(provider_data) return Response(response)
def get_thread(self, request, pk, read_aware=True, subscription_aware=True, select_for_update=False): return self.thread(request, get_int_or_404(pk), None, read_aware, subscription_aware, select_for_update)
def test_invalid_inputs(self): """get_int_or_404 raises Http404 for invalid values""" INVALID_VALUES = ( None, '', 'bob', '1bob', 'b0b', 'bob123', '12.321', '.4', '5.', ) for value in INVALID_VALUES: with self.assertRaises(Http404): get_int_or_404(value)
def get_thread(self, request, pk, path_aware=False, read_aware=False, subscription_aware=False): return self.thread( request, get_int_or_404(pk), path_aware=path_aware, read_aware=read_aware, subscription_aware=subscription_aware, )
def patch_top_category(request, thread, value): category_pk = get_int_or_404(value) root_category = get_object_or_404( Category.objects.all_categories(include_root=True), pk=category_pk) categories = list(Category.objects.all_categories().filter( id__in=request.user.acl['visible_categories'])) add_categories_to_threads(root_category, categories, [thread]) return {'top_category': CategorySerializer(thread.top_category).data}
def get_thread(self, request, pk, read_aware=True, subscription_aware=True, select_for_update=False): return self.thread( request, get_int_or_404(pk), None, read_aware, subscription_aware, select_for_update )
def posts(self, request, pk=None): profile = self.get_user(pk) page = get_int_or_404(request.query_params.get('page', 0)) if page == 1: page = 0 # api allows explicit first page feed = UserPosts(request, profile, page) return Response(feed.get_frontend_context())
def posts(self, request, pk=None): profile = self.get_user(request, pk) page = get_int_or_404(request.query_params.get('page', 0)) if page == 1: page = 0 # api allows explicit first page feed = UserPosts(request, profile, page) return Response(feed.get_frontend_context())
def test_valid_inputs(self): """get_int_or_404 returns int for valid values""" VALID_VALUES = ( ('0', 0), ('123', 123), ('000123', 123), ('1', 1), ) for value, result in VALID_VALUES: self.assertEqual(get_int_or_404(value), result)
def __call__(self, request, **kwargs): page = get_int_or_404(request.query_params.get('page', 0)) if page == 1: page = 0 # api allows explicit first page list_type = request.query_params.get('list', 'all') category = self.get_category(request, pk=request.query_params.get('category')) threads = self.get_threads(request, category, list_type, page) return Response(self.get_response_json(request, category, threads)['THREADS'])
def get(self, request, list_type=None, **kwargs): page = get_int_or_404(request.GET.get('page', 0)) category = self.get_category(request, **kwargs) threads = self.get_threads(request, category, list_type, page) frontend_context = self.get_frontend_context(request, category, threads) request.frontend_context.update(frontend_context) template_context = self.get_template_context(request, category, threads) return render(request, self.template_name, template_context)
def post_editor(self, request, thread_pk, pk): thread = self.thread(request, get_int_or_404(thread_pk)) post = self.post(request, thread, get_int_or_404(pk)).model allow_edit_post(request.user, post) return Response({ 'id': post.pk, 'api': post.get_api_url(), 'post': post.original, 'can_protect': bool(thread.category.acl['can_protect_posts']), 'is_protected': post.is_protected, 'poster': post.poster_name })
def follows(self, request, pk=None): profile = self.get_user(request, pk) page = get_int_or_404(request.query_params.get('page', 0)) if page == 1: page = 0 # api allows explicit first page search = request.query_params.get('search') users = Follows(request, profile, page, search) return Response(users.get_frontend_context())
def reply_editor(self, request, thread_pk): thread = self.thread(request, get_int_or_404(thread_pk)) allow_reply_thread(request.user, thread.model) if 'reply' in request.query_params: reply_to = self.post(request, thread, get_int_or_404( request.query_params['reply'])).model if reply_to.is_event: raise PermissionDenied(_("You can't reply to events.")) if reply_to.is_hidden and not reply_to.acl['can_see_hidden']: raise PermissionDenied(_("You can't reply to hidden posts.")) return Response({ 'id': reply_to.pk, 'post': reply_to.original, 'poster': reply_to.poster_name }) else: return Response({})
def list(self, request, thread_pk): page = get_int_or_404(request.query_params.get('page', 0)) if page == 1: page = 0 # api allows explicit first page thread = self.get_thread(request, thread_pk) posts = self.get_posts(request, thread, page) data = thread.get_frontend_context() data['post_set'] = posts.get_frontend_context() return Response(data)
def get_thread(self, user, thread_id): thread = get_object_or_404(Thread.objects.select_related('category'), id=get_int_or_404(thread_id), category__tree_id=self.TREE_ID, ) add_acl(user, thread.category) add_acl(user, thread) self.validate_thread_visible(user, thread) return thread
def patch_top_category(request, thread, value): category_pk = get_int_or_404(value) root_category = get_object_or_404( Category.objects.all_categories(include_root=True), pk=category_pk ) categories = list(Category.objects.all_categories().filter( id__in=request.user.acl['visible_categories'] )) add_categories_to_items(root_category, categories, [thread]) return {'top_category': CategorySerializer(thread.top_category).data}
def generic(request): page = get_int_or_404(request.GET.get('page', 0)) if page == 1: page = 0 # api allows explicit first page allow_name_search = True queryset = UserModel.objects if not request.user.is_staff: queryset = queryset.filter(is_active=True) if request.query_params.get('followers'): user_pk = get_int_or_404(request.query_params.get('followers')) queryset = get_object_or_404(queryset, pk=user_pk).followed_by elif request.query_params.get('follows'): user_pk = get_int_or_404(request.query_params.get('follows')) queryset = get_object_or_404(queryset, pk=user_pk).follows elif request.query_params.get('rank'): rank_pk = get_int_or_404(request.query_params.get('rank')) rank = get_object_or_404(Rank.objects, pk=rank_pk, is_tab=True) queryset = queryset.filter(rank=rank) allow_name_search = False else: raise Http404() # don't use this api for searches if request.query_params.get('name'): name_starts_with = request.query_params.get('name').strip().lower() if name_starts_with and allow_name_search: queryset = queryset.filter(slug__startswith=name_starts_with) else: raise Http404() queryset = queryset.select_related('rank', 'ban_cache', 'online_tracker').order_by('slug') list_page = paginate(queryset, page, settings.MISAGO_USERS_PER_PAGE, 4) make_users_status_aware(request.user, list_page.object_list) return paginated_response(list_page, serializer=UserSerializer)
def read_threads(user, pk): user.lock() category_id = get_int_or_404(pk) threads_tree_id = trees_map.get_tree_id_for_root(THREADS_ROOT_NAME) category = get_object_or_404(Category, id=category_id, tree_id=threads_tree_id) if category.level: allow_see_category(user, category) allow_browse_category(user, category) read_category(user, category)
def get_poll(self, thread, pk): try: poll_id = get_int_or_404(pk) if thread.poll.pk != poll_id: raise Http404() poll = Poll.objects.select_for_update().get(pk=thread.poll.pk) poll.thread = thread poll.category = thread.category return poll except Poll.DoesNotExist: raise Http404()
def read(self, request): if request.query_params.get('category'): category_id = get_int_or_404(request.query_params.get('category')) category = get_object_or_404(Category.objects, id=category_id, tree_id=self.TREE_ID, ) allow_see_category(request.user, category) allow_browse_category(request.user, category) else: category = Category.objects.root_category() read_category(request.user, category) return Response({'detail': 'ok'})
def get_category(self, request): if request.query_params.get('category'): category_id = get_int_or_404(request.query_params['category']) category = get_object_or_404( Category.objects.select_related('parent'), tree_id=CATEGORIES_TREE_ID, id=category_id, ) allow_see_category(request.user, category) allow_browse_category(request.user, category) return category else: return Category.objects.root_category()
def reply_editor(self, request, thread_pk): thread = self.get_thread( request, get_int_or_404(thread_pk), read_aware=False, subscription_aware=False ) allow_reply_thread(request.user, thread.model) if 'reply' in request.query_params: reply_to = self.get_post(request, thread, get_int_or_404(request.query_params['reply'])).model if reply_to.is_event: raise PermissionDenied(_("You can't reply to events.")) if reply_to.is_hidden and not reply_to.acl['can_see_hidden']: raise PermissionDenied(_("You can't reply to hidden posts.")) return Response({ 'id': reply_to.pk, 'post': reply_to.original, 'poster': reply_to.poster_name }) else: return Response({})
def list(self, request): page = get_int_or_404(request.query_params.get('page', 0)) if page == 1: page = 0 # api allows explicit first page queryset = self.get_queryset() list_page = paginate(queryset, page, 12, 4) data = pagination_dict(list_page) data.update({ 'results': UsernameChangeSerializer(list_page.object_list, many=True).data, }) return Response(data)
def read_threads(user, pk): user.lock() category_id = get_int_or_404(pk) threads_tree_id = trees_map.get_tree_id_for_root(THREADS_ROOT_NAME) category = get_object_or_404(Category, id=category_id, tree_id=threads_tree_id, ) if category.level: allow_see_category(user, category) allow_browse_category(user, category) read_category(user, category)
def get_queryset(self): queryset = UsernameChange.objects if self.request.query_params.get('user'): user_pk = get_int_or_404(self.request.query_params.get('user')) queryset = get_object_or_404(UserModel.objects, pk=user_pk).namechanges if self.request.query_params.get('search'): search_phrase = self.request.query_params.get('search').strip() if search_phrase: queryset = queryset.filter( Q(changed_by_username__istartswith=search_phrase) | Q( new_username__istartswith=search_phrase ) | Q(old_username__istartswith=search_phrase) ) return queryset.select_related('user', 'changed_by').order_by('-id')
def get_queryset(self): queryset = UsernameChange.objects if self.request.query_params.get('user'): user_pk = get_int_or_404(self.request.query_params.get('user')) queryset = get_object_or_404(UserModel.objects, pk=user_pk).namechanges if self.request.query_params.get('search'): search_phrase = self.request.query_params.get('search').strip() if search_phrase: queryset = queryset.filter( Q(changed_by_username__istartswith=search_phrase) | Q(new_username__istartswith=search_phrase) | Q(old_username__istartswith=search_phrase)) return queryset.select_related('user', 'changed_by').order_by('-id')
def read(self, request): if request.query_params.get('category'): threads_tree_id = trees_map.get_tree_id_for_root(THREADS_ROOT_NAME) category_id = get_int_or_404(request.query_params.get('category')) category = get_object_or_404(Category, id=category_id, tree_id=threads_tree_id, ) allow_see_category(request.user, category) allow_browse_category(request.user, category) else: category = Category.objects.root_category() read_category(request.user, category) return Response({'detail': 'ok'})
def read(self, request, pk): request.user.lock() category_id = get_int_or_404(pk) threads_tree_id = trees_map.get_tree_id_for_root(THREADS_ROOT_NAME) category = get_object_or_404(Category, id=category_id, tree_id=threads_tree_id, ) if category.level: allow_see_category(request.user, category) allow_browse_category(request.user, category) read_category(request.user, category) return Response({'detail': 'ok'})
def patch_move(request, thread, value): if thread.acl.get('can_move'): category_pk = get_int_or_404(value) new_category = get_object_or_404( Category.objects.all_categories().select_related('parent'), pk=category_pk ) add_acl(request.user, new_category) allow_see_category(request.user, new_category) allow_browse_category(request.user, new_category) moderation.move_thread(request.user, thread, new_category) return {'category': CategorySerializer(new_category).data} else: raise PermissionDenied( _("You don't have permission to move this thread."))
def get_category(self, request, categories): if request.query_params.get('category'): category_id = get_int_or_404(request.query_params['category']) for category in categories: if category.pk == category_id: if category.level: break else: raise Http404() # disallow root category access else: raise Http404() allow_see_category(request.user, category) allow_browse_category(request.user, category) return category else: return categories[0]
def patch_move(request, thread, value): allow_move_thread(request.user, thread) category_pk = get_int_or_404(value) new_category = get_object_or_404( Category.objects.all_categories().select_related('parent'), pk=category_pk ) add_acl(request.user, new_category) allow_see_category(request.user, new_category) allow_browse_category(request.user, new_category) allow_start_thread(request.user, new_category) if new_category == thread.category: raise PermissionDenied(_("You can't move thread to the category it's already in.")) moderation.move_thread(request, thread, new_category) return {'category': CategorySerializer(new_category).data}