def _handle_set_is_active(self): old_state = self.object.is_active state = bool(int(self.request.POST["set_is_active"])) if not state and hasattr(self.object, "user"): if (getattr(self.object.user, 'is_superuser', False) and not getattr(self.request.user, 'is_superuser', False)): raise Problem(_("You can not deactivate a superuser.")) if self.object.user == self.request.user: raise Problem(_("You can not deactivate yourself.")) self.object.is_active = state self.object.save(update_fields=("is_active", )) messages.success( self.request, _("%(contact)s is now %(state)s.") % { "contact": self.object, "state": _("active") if state else _("inactive") }) if (self.object.is_active and self.object.is_active != old_state and isinstance(self.object, CompanyContact)): company_contact_activated.send(sender=type(self.object), instance=self.object, request=self.request) return HttpResponseRedirect(self.request.path)
def post(self, request, *args, **kwargs): front_url = get_front_url() user = self.get_object() username_field = self.model.USERNAME_FIELD impersonator_user_id = request.user.pk if not front_url: raise Problem(_("No shop configured.")) if user == request.user: raise Problem(_("You are already logged in.")) if not getattr(request.user, "is_superuser", False): raise PermissionDenied if getattr(user, "is_superuser", False) or getattr(user, "is_staff", False): raise PermissionDenied if not getattr(user, "is_active", False): raise Problem(_("This user is not active.")) if not hasattr(user, 'backend'): for backend in django_settings.AUTHENTICATION_BACKENDS: if user == load_backend(backend).get_user(user.pk): user.backend = backend break login(request, user) request.session["impersonator_user_id"] = impersonator_user_id message = _("You're now logged in as {username}").format(username=user.__dict__[username_field]) messages.success(request, message) return HttpResponseRedirect(front_url)
def _handle_set_is_active(self): state = bool(int(self.request.POST["set_is_active"])) if not state: if (getattr(self.object, 'is_superuser', False) and not getattr(self.request.user, 'is_superuser', False)): raise Problem(_("You can not deactivate a superuser.")) if self.object == self.request.user: raise Problem(_("You can not deactivate yourself.")) self.object.is_active = state self.object.save(update_fields=("is_active",)) messages.success(self.request, _("%(user)s is now %(state)s.") % { "user": self.object, "state": _("active") if state else _("inactive") }) return HttpResponseRedirect(self.request.path)
def process_user(self, user): if "wshop.front.apps.auth" not in settings.INSTALLED_APPS: raise Problem( _(u"The `wshop.front.apps.auth` app needs to be enabled for password reset." )) r = RecoverPasswordForm() r.request = self.request if r.process_user(user): messages.success( self.request, _(u"Password recovery email sent to %(email)s") % {"email": getattr(user, 'email', '')}) else: raise Problem(_(u"Sending the password recovery email failed."))
def _populate_vars(self): theme = get_theme_by_identifier(self.request.GET["theme"], self.request.shop) if not theme: raise Problem(_("Unable to determine current theme.")) view_name = self.request.GET["view"] global_type = self.request.GET.get("global_type", None) self.view_config = ViewConfig( theme=theme, shop=self.request.shop, view_name=view_name, draft=True, global_type=global_type, ) self.placeholder_name = self.request.GET["ph"] self.default_layout = self._get_default_layout() self.layout = self.view_config.get_placeholder_layout( placeholder_name=self.placeholder_name, default_layout=self.default_layout) (x, y) = self.current_cell_coords = ( int(self.request.GET.get("x", -1)), int(self.request.GET.get("y", -1)), ) self.current_cell = self.layout.get_cell(x=x, y=y) self.build_form()
def ship_products(self, shipment, product_quantities): insufficient_stocks = {} for product, quantity in product_quantities.items(): if quantity > 0: stock_status = self.get_stock_status(product.pk) if (product.stock_behavior == StockBehavior.STOCKED) and ( stock_status.physical_count < quantity): insufficient_stocks[product] = stock_status.physical_count sp = shipment.products.create(product=product, quantity=quantity) sp.cache_values() sp.save() if insufficient_stocks: formatted_counts = [ _("%(name)s (physical stock: %(quantity)s)") % { "name": force_text(name), "quantity": force_text(quantity) } for (name, quantity) in insufficient_stocks.items() ] raise Problem( _("Insufficient physical stock count for following products: %(product_counts)s" ) % {"product_counts": ", ".join(formatted_counts)}) shipment.cache_values() shipment.save()
def check_and_raise_if_only_one_allowed(setting_name, obj): if WshopSettings.get_setting(setting_name): return if not obj.pk and obj.__class__.objects.count() >= 1: raise Problem( _("Only one %(model)s permitted.") % {"model": obj._meta.verbose_name})
def _get_unauth_response(self, request, reason): """ Get an error response (or raise a Problem) for a given request and reason message. :type request: Request :param request: HttpRequest :type reason: Reason string :param reason: str """ if request.is_ajax(): return HttpResponseForbidden( json.dumps({"error": force_text(reason)})) error_params = urlencode({"error": reason}) login_url = force_str( reverse("wshop_admin:login") + "?" + error_params) resp = redirect_to_login(next=request.path, login_url=login_url) if request.user.is_authenticated(): # Instead of redirecting to the login page, let the user know what's wrong with # a helpful link. raise (Problem( _("Can't view this page. %(reason)s") % { "reason": reason }).with_link(url=resp.url, title=_("Log in with different credentials..."))) return resp
def html_to_pdf(html, stylesheet_paths=[]): if not weasyprint: raise Problem(_("Could not create PDF since Weasyprint is not available. Please contact support.")) stylesheets = [] for stylesheet_path in stylesheet_paths: stylesheets.append(weasyprint.CSS(string=_fetch_static_resource_str(stylesheet_path))) return weasyprint.HTML( string=html, url_fetcher=_custom_url_fetcher ).write_pdf( stylesheets=stylesheets )
def dispatch(self, request, *args, **kwargs): user = self.get_target_user() token = self.kwargs["token"] valid = (user is not None and self.token_generator.check_token(user, token)) if not valid: raise Problem(_(u"This recovery link is invalid.")) return super(RecoverPasswordConfirmView, self).dispatch(request, *args, **kwargs)
def dispatch_command(self, request, command): product = self.object if command == "unvariate": product.clear_variation() messages.success(self.request, _("Variation cleared.")) elif command == "simplify": product.simplify_variation() messages.success(self.request, _("Variation simplified.")) else: raise Problem("Unknown command: %s" % command) return HttpResponseRedirect(self.get_success_url())
def get_user(self): bind_user_id = self.request.GET.get("user_id") if bind_user_id: bind_user = get_user_model().objects.get(pk=bind_user_id) if PersonContact.objects.filter(user=bind_user).exists(): raise Problem( _("User %(bind_user)s already has a contact", bind_user=bind_user)) else: bind_user = None return bind_user
def get(self, request, *args, **kwargs): product = self.object = self.get_object() if product.mode == ProductMode.VARIATION_CHILD: return redirect("wshop:product", pk=product.variation_parent.pk, slug=product.variation_parent.slug) try: shop_product = self.shop_product = product.get_shop_instance( request.shop, allow_cache=True) except ShopProduct.DoesNotExist: raise Problem(_(u"This product is not available in this shop.")) errors = list( shop_product.get_visibility_errors(customer=request.customer)) if errors: raise Problem("\n".join(extract_messages(errors))) return super(ProductDetailView, self).get(request, *args, **kwargs)
def handle_post_delete_file(self, data): shop = get_shop(self.request) file = _get_file_query(shop).get(pk=data["id"]) if _is_file_shared(file): message = _("Can not delete shared file.") return JsonResponse({"success": False, "message": message}) try: file.delete() except IntegrityError as ie: raise Problem(str(ie)) return JsonResponse({"success": True, "message": _("File deleted.")})
def __init__(self, changing_user, target_user, *args, **kwargs): super(PasswordChangeForm, self).__init__(*args, **kwargs) self.changing_user = changing_user self.target_user = target_user if getattr(self.target_user, 'is_superuser', False) and not getattr( self.changing_user, 'is_superuser', False): raise Problem(_("You can not change the password of a superuser.")) if not (self.changing_user == self.target_user or getattr(self.target_user, 'is_superuser', False)): # Only require old password when changing your own or a superuser's password. self.fields.pop("old_password")
def post(self, request, *args, **kwargs): order = self.object = self.get_object() new_status = OrderStatus.objects.get(pk=int(request.POST["status"])) old_status = order.status if new_status.role == OrderStatusRole.COMPLETE and not order.can_set_complete( ): raise Problem(_("Unable to set order as completed at this point")) if new_status.role == OrderStatusRole.CANCELED and not order.can_set_canceled( ): raise Problem( _("Paid, shipped, or canceled orders cannot be canceled")) order.status = new_status order.save(update_fields=("status", )) message = _( "Order status changed: {old_status} to {new_status}").format( old_status=old_status, new_status=new_status) order.add_log_entry(message, user=request.user, identifier="status_change") messages.success(self.request, message) return HttpResponseRedirect(get_model_url(self.get_object()))
def process_payment_return_request(self, service, order, request): transform = self._get_text_transformer(service) mac = self.compute_pseudo_mac(order) if request.GET.get("mac") != mac: raise Problem(u"Invalid MAC.") if not order.is_paid(): order.create_payment( order.taxful_total_price, payment_identifier="Pseudo-%s" % now().isoformat(), description=transform("Wshop Pseudo Payment Service Payment") ) msg = transform( "Pseudo Payment successfully processed the request.") messages.success(request, msg)
def command_dispatch(request): """ Xtheme command dispatch view. :param request: A request :type request: django.http.HttpRequest :return: A response :rtype: django.http.HttpResponse """ command = request.POST.get("command") if command: response = handle_command(request, command) if response: return response raise Problem("Unknown command: %r" % command)
def dispatch(self, request, *args, **kwargs): # doccov: ignore if not could_edit(request): raise Problem(_("No access to editing")) self._populate_vars() if self.default_layout: self.view_config.save_default_placeholder_layout( self.placeholder_name, self.default_layout) # We saved the default layout, so get rid of the humongous GET arg and try again get_args = dict(self.request.GET.items()) get_args.pop("default_config", None) global_type = get_args.pop("global_type", None) if global_type: get_args["view"] = XTHEME_GLOBAL_VIEW_NAME # We are overriding the view with XTHEME_GLOBAL_VIEW_NAME if this is a global placeholder return HttpResponseRedirect( "%s?%s" % (self.request.path, urlencode(get_args))) return super(EditorView, self).dispatch(request, *args, **kwargs)
def form_valid(self, form): file = form.cleaned_data["file"] if not file.name.lower().endswith(".whl"): raise Problem(_("Only wheel files are supported")) # TODO: Maybe verify the file before saving? tmp_dir = tempfile.mkdtemp(prefix='wshop') tmp_token = os.path.basename(tmp_dir) filename = os.path.basename(file.name) with open(os.path.join(tmp_dir, filename), "wb") as outf: shutil.copyfileobj(file, outf) return HttpResponseRedirect( manipulate_query_string( reverse("wshop_admin:addon.upload_confirm"), file=filename, token=tmp_token ) )
def _transform_request_file(self): try: filename = get_import_file_path(self.request.GET.get("n")) if not os.path.isfile(filename): raise ValueError( _("%s is not a file") % self.request.GET.get("n")) except: raise Problem(_("File missing.")) try: mode = "xls" if filename.endswith("xlsx"): mode = "xlsx" if filename.endswith("csv"): mode = "csv" return transform_file(mode, filename) except (Exception, RuntimeError) as e: messages.error(self.request, e)
def process_data(rows): headers = [] got_data = set() data = [] if not len(data): for y, row in enumerate(rows): if y == 0: headers = [x.lower().strip() for x in row] continue datum = dict(zip(headers, row)) got_data.update(set(h for (h, d) in six.iteritems(datum) if d)) data.append(datum) row_limit = getattr(settings, "IMPORT_MAX_ROWS", 1000) if len(data) > row_limit: raise Problem( _("Cannot import more than %s rows from one file.") % row_limit) return (data, got_data)
def handle(self, command, kwargs=None): """ Dispatch and handle processing of the given command. :param command: Name of command to run :type command: unicode :param kwargs: Arguments to pass to the command handler. If empty, `request.POST` is used. :type kwargs: dict :return: response :rtype: HttpResponse """ kwargs = kwargs or dict(six.iteritems(self.request.POST)) try: handler = self.get_command_handler(command) if not handler or not callable(handler): raise Problem(_(u"Invalid command %s") % command) kwargs.pop( "csrfmiddlewaretoken", None) # The CSRF token should never be passed as a kwarg kwargs.pop("command", None) # Nor the command kwargs.update(request=self.request, basket=self.basket) kwargs = self.preprocess_kwargs(command, kwargs) response = handler(**kwargs) or {} except (Problem, ValidationError) as exc: if not self.ajax: raise msg = exc.message if hasattr(exc, "message") else exc response = { "error": force_text(msg, errors="ignore"), "code": force_text(getattr(exc, "code", None) or "", errors="ignore") } response = self.postprocess_response(command, kwargs, response) if self.ajax: return JsonResponse(response) return_url = (response.get("return") or kwargs.get("return")) if return_url and return_url.startswith("/"): return HttpResponseRedirect(return_url) return redirect("wshop:basket")
def post(self, request, *args, **kwargs): # doccov: ignore command = request.POST.get("command") if command: dispatcher = getattr(self, "dispatch_%s" % command, None) if not callable(dispatcher): raise Problem(_("Unknown command %s") % command) dispatch_kwargs = dict(request.POST.items()) rv = dispatcher(**dispatch_kwargs) if rv: return rv self.request.method = "GET" # At this point, we won't want to cause form validation self.build_form() # and it's not a bad idea to rebuild the form return super(EditorView, self).get(request, *args, **kwargs) if request.POST.get("save") and self.form and self.form.is_valid(): self.form.save() self.save_layout() return super(EditorView, self).get(request, *args, **kwargs)
def get_object(self, queryset=None): contact = self.get_contact() user = getattr(contact, "user", None) if not user: raise Problem(_(u"The contact does not have an associated user.")) return user