def partial_update(self, request, *args, **kwargs): user = request.user requested_query = int(kwargs["pk"]) if user.is_authenticated: if user == ProductQuery.objects.get(id=requested_query).user: return super().partial_update(request, *args, **kwargs) elif user.role == "support" or user.role == "admin": return super().partial_update(request, *args, **kwargs) else: raise exceptions.PermissionDenied() else: raise exceptions.PermissionDenied()
def edit_comment(request): if request.user.is_anonymous(): raise exceptions.PermissionDenied( _('Sorry, anonymous users cannot edit comments')) if askbot_settings.READ_ONLY_MODE_ENABLED: raise exceptions.PermissionDenied(askbot_settings.READ_ONLY_MESSAGE) form = forms.EditCommentForm(request.POST) if form.is_valid() == False: raise exceptions.PermissionDenied('This content is forbidden') comment_post = models.Post.objects.get(post_type='comment', id=form.cleaned_data['comment_id']) revision = request.user.edit_comment( comment_post=comment_post, body_text=form.cleaned_data['comment'], suppress_email=form.cleaned_data['suppress_email'], ip_addr=request.META.get('REMOTE_ADDR'), ) is_deletable = template_filters.can_delete_comment(comment_post.author, comment_post) is_editable = template_filters.can_edit_comment(comment_post.author, comment_post) tz = ' ' + template_filters.TIMEZONE_STR tz = template_filters.TIMEZONE_STR timestamp = str(comment_post.added_at.replace(microsecond=0)) + tz #need this because the post.text is due to the latest approved #revision, but we may need the suggested revision comment_post.text = revision.text comment_post.html = comment_post.parse_post_text()['html'] return { 'id': comment_post.id, 'object_id': comment_post.parent.id, 'comment_added_at': timestamp, 'html': comment_post.html, 'user_display_name': escape(comment_post.author.username), 'user_url': comment_post.author.get_profile_url(), 'user_id': comment_post.author.id, 'is_deletable': is_deletable, 'is_editable': is_editable, 'score': comment_post.points, #to support unchanged js 'points': comment_post.points, 'voted': comment_post.is_upvoted_by(request.user), }
def update_comment(cls, comment, data, preview, view): super(CommentAPI, cls).update_comment(comment, data, preview, view) new_role = data['role_id'] if comment.role_id != new_role: if new_role not in view.write_roles(): raise exceptions.PermissionDenied() update_role_comments_count(new_role, 1) update_role_comments_count(comment.role_id, -1) comment.role_id = new_role editor_role = data['edit_role_id'] if editor_role not in view.write_roles(): raise exceptions.PermissionDenied() comment.edit_role_id = editor_role
def process_vote(user = None, vote_direction = None, post = None): """function (non-view) that actually processes user votes - i.e. up- or down- votes in the future this needs to be converted into a real view function for that url and javascript will need to be adjusted also in the future make keys in response data be more meaningful right now they are kind of cryptic - "status", "count" """ if user.is_anonymous(): raise exceptions.PermissionDenied(_( 'Sorry, anonymous users cannot vote' )) user.assert_can_vote_for_post(post = post, direction = vote_direction) vote = user.get_old_vote_for_post(post) response_data = {} if vote != None: user.assert_can_revoke_old_vote(vote) score_delta = vote.cancel() response_data['count'] = post.score + score_delta response_data['status'] = 1 #this means "cancel" else: #this is a new vote votes_left = user.get_unused_votes_today() if votes_left <= 0: raise exceptions.PermissionDenied( _('Sorry you ran out of votes for today') ) votes_left -= 1 if votes_left <= \ askbot_settings.VOTES_LEFT_WARNING_THRESHOLD: msg = _('You have %(votes_left)s votes left for today') \ % {'votes_left': votes_left } response_data['message'] = msg if vote_direction == 'up': vote = user.upvote(post = post) else: vote = user.downvote(post = post) response_data['count'] = post.score response_data['status'] = 0 #this means "not cancel", normal operation response_data['success'] = 1 return response_data
def upload(request): #ajax upload file to a question or answer """view that handles file upload via Ajax """ # check upload permission result = '' error = '' new_file_name = '' try: #may raise exceptions.PermissionDenied result, error, file_url, orig_file_name = None, '', None, None if request.user.is_anonymous(): msg = _('Sorry, anonymous users cannot upload files') raise exceptions.PermissionDenied(msg) request.user.assert_can_upload_file() #todo: build proper form validation file_name_prefix = request.POST.get('file_name_prefix', '') if file_name_prefix not in ('', 'group_logo_'): raise exceptions.PermissionDenied( 'invalid upload file name prefix') #todo: check file type uploaded_file = request.FILES['file-upload'] #take first file orig_file_name = uploaded_file.name #todo: extension checking should be replaced with mimetype checking #and this must be part of the form validation file_extension = os.path.splitext(orig_file_name)[1].lower() if False: if not file_extension in settings.ASKBOT_ALLOWED_UPLOAD_FILE_TYPES: file_types = "', '".join( settings.ASKBOT_ALLOWED_UPLOAD_FILE_TYPES) msg = _("allowed file types are '%(file_types)s'") % \ {'file_types': file_types} raise exceptions.PermissionDenied(msg) # generate new file name and storage object file_storage, new_file_name, file_url = store_file( uploaded_file, file_name_prefix) # check file size # byte size = file_storage.size(new_file_name) if size > settings.ASKBOT_MAX_UPLOAD_FILE_SIZE: file_storage.delete(new_file_name) msg = _("maximum upload file size is %(file_size)sK") % \ {'file_size': settings.ASKBOT_MAX_UPLOAD_FILE_SIZE} raise exceptions.PermissionDenied(msg) except exceptions.PermissionDenied, e: error = unicode(e)
def create(self, request, *args, **kwargs): user = request.user if user.is_authenticated: sent_by = request.POST.get('sent_by', None) try: sent_by = int(sent_by) except: pass if sent_by == user.id: return super().create(request, *args, **kwargs) else: raise exceptions.PermissionDenied() else: raise exceptions.PermissionDenied()
def upload(request):#ajax upload file to a question or answer """view that handles file upload via Ajax """ # check upload permission result = '' error = '' new_file_name = '' try: #may raise exceptions.PermissionDenied if request.user.is_anonymous(): msg = _('Sorry, anonymous users cannot upload files') raise exceptions.PermissionDenied(msg) request.user.assert_can_upload_file() # check file type f = request.FILES['file-upload'] file_extension = os.path.splitext(f.name)[1].lower() if not file_extension in settings.ASKBOT_ALLOWED_UPLOAD_FILE_TYPES: file_types = "', '".join(settings.ASKBOT_ALLOWED_UPLOAD_FILE_TYPES) msg = _("allowed file types are '%(file_types)s'") % \ {'file_types': file_types} raise exceptions.PermissionDenied(msg) # generate new file name new_file_name = str( time.time() ).replace( '.', str(random.randint(0,100000)) ) + file_extension file_storage = FileSystemStorage( location = settings.ASKBOT_FILE_UPLOAD_DIR, base_url = reverse('uploaded_file', kwargs = {'path':''}), ) # use default storage to store file file_storage.save(new_file_name, f) # check file size # byte size = file_storage.size(new_file_name) if size > settings.ASKBOT_MAX_UPLOAD_FILE_SIZE: file_storage.delete(new_file_name) msg = _("maximum upload file size is %(file_size)sK") % \ {'file_size': settings.ASKBOT_MAX_UPLOAD_FILE_SIZE} raise exceptions.PermissionDenied(msg) except exceptions.PermissionDenied, e: error = unicode(e)
def update(self, request, *args, **kwargs): user = request.user requested_product = int(kwargs["pk"]) if user.is_authenticated: if ( Seller.objects.get(user_id=user) == Product.objects.get(id=requested_product).seller ): return super().update(request, *args, **kwargs) elif user.role == "support" or user.role == "admin": return super().update(request, *args, **kwargs) else: raise exceptions.PermissionDenied() else: raise exceptions.PermissionDenied()
def partial_update(self, request, *args, **kwargs): user = request.user requested_rating = int(kwargs["pk"]) if user.is_authenticated and user.role == "customer": if ( Customer.objects.get(user_id=user) == Rating.objects.get(id=requested_rating).user ): return super().partial_update(request, *args, **kwargs) elif user.role == "support" or user.role == "admin": return super().partial_update(request, *args, **kwargs) else: raise exceptions.PermissionDenied() else: raise exceptions.PermissionDenied()
def get_context_data(self, **kwargs): """ Returns the context data dictionary for the template (overriden). For this view it is necessary to change dinamically the base template that this template extends since it is different depending on whether the user is a regular or a staff one. :param kwargs: Additional parameters """ context = super(UserProfileView, self).get_context_data(**kwargs) # noinspection PyUnresolvedReferences if self.request.user.is_authenticated(): # noinspection PyUnresolvedReferences context['username'] = self.request.user.username # noinspection PyUnresolvedReferences if self.request.user.is_staff: context['base_template'] = 'staff/staff_home.html' else: context['base_template'] = 'users/users_home.html' else: raise exceptions.PermissionDenied(_("User is not authenticated.")) return context
def validate_state_change(self, old_state, new_state): user = self.context['request'].user if old_state == new_state: return valid_changes = { Classification.DRAFT: {Classification.SENT_FOR_REVIEW}, Classification.SENT_FOR_REVIEW: {Classification.WAITING_FOR_APPROVAL, Classification.DRAFT}, Classification.WAITING_FOR_APPROVAL: {Classification.APPROVED, Classification.DRAFT}, Classification.APPROVED: {Classification.DRAFT}, } if new_state not in valid_changes[old_state]: raise exceptions.ValidationError( {'state': [_('Invalid state change.')]}) state_change_required_permissions = { Classification.SENT_FOR_REVIEW: Classification.CAN_EDIT, Classification.WAITING_FOR_APPROVAL: Classification.CAN_REVIEW, Classification.APPROVED: Classification.CAN_APPROVE, } relevant_state = new_state if new_state != Classification.DRAFT else old_state required_permission = state_change_required_permissions[relevant_state] if not user.has_perm(required_permission): raise exceptions.PermissionDenied( _('No permission for the state change.'))
def join_or_leave_group(request): """called when user wants to join/leave ask to join/cancel join request, depending on the groups acceptance level for the given user returns resulting "membership_level" """ if request.user.is_anonymous(): raise exceptions.PermissionDenied() Group = models.Group Membership = models.GroupMembership group_id = IntegerField().clean(request.POST['group_id']) group = Group.objects.get(id=group_id) membership = request.user.get_group_membership(group) if membership is None: membership = request.user.join_group(group) new_level = membership.get_level_display() else: request.user.leave_group(group) new_level = Membership.get_level_value_display(Membership.NONE) return {'membership_level': new_level}
def retag_question(request, id): """retag question view """ question = get_object_or_404(models.Post, id=id) try: request.user.assert_can_retag_question(question) if request.method == 'POST': form = forms.RetagQuestionForm(question, request.POST) if form.is_valid(): if form.has_changed(): if akismet_check_spam(form.cleaned_data['tags'], request): raise exceptions.PermissionDenied(_( 'Spam was detected on your post, sorry ' 'for if this is a mistake' )) request.user.retag_question(question=question, tags=form.cleaned_data['tags']) if request.is_ajax(): response_data = { 'success': True, 'new_tags': question.thread.tagnames } if request.user.message_set.count() > 0: #todo: here we will possibly junk messages message = request.user.get_and_delete_messages()[-1] response_data['message'] = message data = simplejson.dumps(response_data) return HttpResponse(data, content_type="application/json") else: return HttpResponseRedirect(question.get_absolute_url()) elif request.is_ajax(): response_data = { 'message': format_errors(form.errors['tags']), 'success': False } data = simplejson.dumps(response_data) return HttpResponse(data, content_type="application/json") else: form = forms.RetagQuestionForm(question) data = { 'active_tab': 'questions', 'question': question, 'form' : form, } return render(request, 'question_retag.html', data) except exceptions.PermissionDenied as e: if request.is_ajax(): response_data = { 'message': unicode(e), 'success': False } data = simplejson.dumps(response_data) return HttpResponse(data, content_type="application/json") else: request.user.message_set.create(message = unicode(e)) return HttpResponseRedirect(question.get_absolute_url())
def update_thread(self, data): super(BaseThreadAPI, self).update_thread(data) self.obj.role_id = self.process_role(self.obj.role_id, data) editor_role = data['edit_role_id'] if editor_role not in self.write_roles(): raise exceptions.PermissionDenied() self.obj.edit_role_id = editor_role
def add_tag_category(request): """adds a category at the tip of a given path expects the following keys in the ``request.POST`` * path - array starting with zero giving path to the category page where to add the category * new_category_name - string that must satisfy the same requiremets as a tag return json with the category tree data TODO: switch to json stored in the live settings now we have indented input """ if request.user.is_anonymous() or \ not request.user.is_administrator_or_moderator(): raise exceptions.PermissionDenied() post_data = json.loads(request.raw_post_data) category_name = forms.clean_tag(post_data['new_category_name']) path = post_data['path'] tree = category_tree.get_data() if not category_tree.path_is_valid(tree, path): raise ValueError('category insertion path is invalid') new_path = category_tree.add_category(tree, category_name, path) category_tree.save_data(tree) return {'tree_data': tree, 'new_path': new_path}
def get_queryset(self): order_by = self.request.POST.get('order_by', []) filters = self.request.POST.get('filters', {}) if self.request.user.is_superuser or 'administartors' in self.request.user.groups: pass elif 'partners' in self.request.user.groups: filters.update({ 'client_profile__partner_contr__user_id__exact': self.request.user.id }) elif 'credit_org' in self.request.user.groups: filters.update({ 'proposal__credit_contr__user_id__exact': self.request.user.id }) else: raise exceptions.PermissionDenied() if filters: queryset = self.queryset.filter(**filters) else: queryset = self.queryset if order_by: queryset = queryset.order_by(*order_by) return queryset
def perform_create(self, serializer): # добавлять могут только суперпользователи или партнеры if self.request.user.is_superuser or 'administartors' in self.request.user.groups or 'partners' in self.request.user.groups: super(OrderViewSet, self).perform_create(serializer) self.queryset[0].refresh_from_db() else: raise exceptions.PermissionDenied()
def post_comments( request): #non-view generic ajax handler to load comments to an object # only support get post comments by ajax now user = request.user if request.is_ajax(): post_type = request.REQUEST['post_type'] id = request.REQUEST['post_id'] if post_type == 'question': post_model = models.Question elif post_type == 'answer': post_model = models.Answer else: raise Http404 obj = get_object_or_404(post_model, id=id) if request.method == "GET": response = __generate_comments_json(obj, user) elif request.method == "POST": try: if user.is_anonymous(): msg = _('Sorry, you appear to be logged out and ' 'cannot post comments. Please ' '<a href="%(sign_in_url)s">sign in</a>.') % \ {'sign_in_url': reverse('user_signin')} raise exceptions.PermissionDenied(msg) user.post_comment(parent_post=obj, body_text=request.POST.get('comment')) response = __generate_comments_json(obj, user) except exceptions.PermissionDenied, e: response = HttpResponseForbidden(unicode(e), mimetype="application/json") return response
def delete(self, request, **kwargs): self.get_parent_thread(for_update=True, **kwargs) if not self.obj.edit_right(self.user): raise exceptions.PermissionDenied() mutations.ThreadDeleteMutation(self.obj, self.user, request.GET['comment']).apply() return {'result': True}
def edit_comment(request): if request.user.is_anonymous(): raise exceptions.PermissionDenied( _('Sorry, anonymous users cannot edit comments')) comment_id = int(request.POST['comment_id']) comment_post = models.Post.objects.get(post_type='comment', id=comment_id) request.user.edit_comment(comment_post=comment_post, body_text=request.POST['comment']) is_deletable = template_filters.can_delete_comment(comment_post.author, comment_post) is_editable = template_filters.can_edit_comment(comment_post.author, comment_post) tz = ' ' + template_filters.TIMEZONE_STR return { 'id': comment_post.id, 'object_id': comment_post.parent.id, 'comment_added_at': str(comment_post.added_at.replace(microsecond=0)) + tz, 'html': comment_post.html, 'user_display_name': comment_post.author.username, 'user_url': comment_post.author.get_profile_url(), 'user_id': comment_post.author.id, 'is_deletable': is_deletable, 'is_editable': is_editable, 'score': comment_post.score, 'voted': comment_post.is_upvoted_by(request.user), }
def put(self, request, **kwargs): data = json.loads(request.body) data['title'] = html_converter.html_to_bb(data['title']) data['body'] = html_converter.html_to_bb(data['body']) preview = data.pop('preview', False) transaction.set_autocommit(False) self.get_parent_thread(for_update=not preview, **kwargs) if not self.obj.write_right(self.user): raise exceptions.PermissionDenied() self.obj = self.create_thread(data) signals.before_create.send(self.thread_model, instance=self.obj, data=data, view=self, preview=preview) if not preview: self.obj.save() signals.after_create.send(self.thread_model, instance=self.obj, data=data, preview=preview, view=self) transaction.commit() # TODO notify clients response = self.obj_to_json() signals.to_json.send(self.thread_model, instance=self.obj, response=response, view=self) return response
def create_account(self): if not get_user(self.request).is_superuser: if settings.DEBUG or ("hydroshare.org" in self.request.META.get( 'HTTP_REFERER', '')): # fixme insecure vs spoofed header active = False else: raise exceptions.PermissionDenied( "user must be superuser to create an account") else: active = True params = utils.create_form(CreateOrListAccounts.CreateAccountForm, self.request) if params.is_valid(): r = params.cleaned_data ret = hydroshare.create_account(email=r['email'], username=r['username'], first_name=r['first_name'], last_name=r['last_name'], superuser=r['superuser'], password=r['password'], groups=r['groups'], active=active) return HttpResponse(ret, content_type='text/plain')
def changeform_view(self, request, object_id=None, form_url='', extra_context=None): """Custom changeform_view() that delegates to one of FORM_VIEWS.""" if not self.get_form_view_defs(): raise exceptions.PermissionDenied() # check if redirect action redirect_to = request.GET.get(self._ACTION_REDIRECT_NAME) if redirect_to: return HttpResponseRedirect(redirect_to) # check if edit is cancelled action = request.POST.get('_cancel') if action: return self._get_cancel_url(request, object_id) # reset self._reset_all_fields() # remember our old methods to restore them and call inhertited old_bases = self.__class__.__bases__ try: return super(BaseCustomModelAdmin, self).changeform_view(request, object_id, form_url, extra_context) finally: self.__class__.__bases__ = old_bases
def put(self, _, **kwargs): if not self.user.is_superuser: raise exceptions.PermissionDenied() self.get_parent_thread(for_update=True, deleted=True, **kwargs) self.restore_mutation(self.obj).apply() self.fix_mutation(self.obj).apply() return self.obj_to_json()
def post_comments( request): #generic ajax handler to load comments to an object # only support get post comments by ajax now post_type = request.REQUEST.get('post_type', '') if not request.is_ajax() or post_type not in ('question', 'answer'): raise Http404 # TODO: Shouldn't be 404! More like 400, 403 or sth more specific user = request.user id = request.REQUEST['post_id'] obj = get_object_or_404(models.Post, id=id) if request.method == "GET": response = __generate_comments_json(obj, user) elif request.method == "POST": try: if user.is_anonymous(): msg = _('Sorry, you appear to be logged out and ' 'cannot post comments. Please ' '<a href="%(sign_in_url)s">sign in</a>.') % \ {'sign_in_url': url_utils.get_login_url()} raise exceptions.PermissionDenied(msg) user.post_comment(parent_post=obj, body_text=request.POST.get('comment')) response = __generate_comments_json(obj, user) except exceptions.PermissionDenied, e: response = HttpResponseForbidden(unicode(e), mimetype="application/json")
def update(self, instance, validated_data): user = self.context['request'].user if not user.has_perm(Classification.CAN_EDIT): raise exceptions.PermissionDenied(_('No permission to update.')) if self.partial: allowed_fields = {'state', 'valid_from', 'valid_to'} data = { field: validated_data[field] for field in allowed_fields if field in validated_data } if not data: return instance data['modified_by'] = user # Update only state, valid_from and valid_to fields # and do an actual update instead of a new version return super().update(instance, data) if instance.state in (Classification.SENT_FOR_REVIEW, Classification.WAITING_FOR_APPROVAL): raise exceptions.ValidationError( _('Cannot edit while in state "sent_for_review" or "waiting_for_approval"' )) return self._create_new_version(validated_data)
def wrapper(request, *args, **kwargs): if request.method != 'POST': raise django_exceptions.PermissionDenied( 'request method %s is not supported for this function' % \ request.method ) return view_func(request, *args, **kwargs)
def perform_update(self, serializer): # редактировать могут только суперпользователи if self.request.user.is_superuser or 'administartors' in self.request.user.groups: super(ProfileViewSet, self).perform_update(serializer) self.queryset.get(id=self.request.POST.get('id')).refresh_from_db() else: raise exceptions.PermissionDenied()
def edit_comment(request): if request.user.is_authenticated(): comment_id = int(request.POST['comment_id']) comment = models.Comment.objects.get(id=comment_id) request.user.edit_comment(comment=comment, body_text=request.POST['comment']) is_deletable = template_filters.can_delete_comment( comment.user, comment) is_editable = template_filters.can_edit_comment(comment.user, comment) return { 'id': comment.id, 'object_id': comment.content_object.id, 'comment_age': diff_date(comment.added_at), 'html': comment.html, 'user_display_name': comment.user.username, 'user_url': comment.user.get_profile_url(), 'user_id': comment.user.id, 'is_deletable': is_deletable, 'is_editable': is_editable, } else: raise exceptions.PermissionDenied( _('Sorry, anonymous users cannot edit comments'))
def perform_destroy(self, instance): # удалять могут только суперпользователи if self.request.user.is_superuser or 'administartors' in self.request.user.groups: super(ProfileViewSet, self).perform_destroy(instance) self.queryset.get(id=self.request.POST.get('id')).refresh_from_db() else: raise exceptions.PermissionDenied()