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. Remove Superuser status first." )) if self.object == self.request.user: raise Problem( _("You can not deactivate yourself. Use another account.")) if not self.object.is_active and state: user_reactivated.send(sender=self.__class__, user=self.object, request=self.request) self.object.is_active = state self.object.save(update_fields=("is_active", )) if hasattr(self.object, "contact"): self.object.contact.is_active = state self.object.contact.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 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 _check_for_login_as_problems(redirect_url, impersonator_user, user): if not redirect_url: raise Problem(_("No shop configured.")) if user == impersonator_user: raise Problem(_("You are already logged in.")) if not getattr(user, "is_active", False): raise Problem(_("This user is not active."))
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. Remove superuser permission first.")) if self.object.user == self.request.user: raise Problem(_("You can not deactivate yourself. Use another account to deactivate the current one.")) 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 get(self, request, *args, **kwargs): product = self.object = self.get_object() if product.mode == ProductMode.VARIATION_CHILD: # redirect to parent url with child pre-selected parent_url = reverse("shuup:product", kwargs=dict( pk=product.variation_parent.pk, slug=product.variation_parent.slug)) return HttpResponseRedirect("{}?variation={}".format( parent_url, product.sku)) 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_stripe_error(charge_data): error_dict = charge_data.get("error") if error_dict: raise Problem("Stripe: %(message)s (%(type)s)" % error_dict) failure_code = charge_data.get("failure_code") failure_message = charge_data.get("failure_message") if failure_code or failure_message: raise Problem( _("Stripe: %(failure_message)s (%(failure_code)s)") % charge_data)
def process_user(self, user): if "shuup.front.apps.auth" not in settings.INSTALLED_APPS: raise Problem(_(u"The `shuup.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 _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 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 ship_products(self, shipment, product_quantities): if self.supplier.stock_managed: # Check stocks for stock managed supplier insufficient_stocks = {} for product, quantity in product_quantities.items(): if quantity > 0: if self.supplier.stock_managed: # Check stocks for stock managed supplier stock_status = self.get_stock_status(product.pk) if stock_status.physical_count < quantity: insufficient_stocks[ product] = stock_status.physical_count 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)}) for product, quantity in product_quantities.items(): if quantity == 0: continue sp = shipment.products.create(product=product, quantity=quantity) sp.cache_values() sp.save() shipment.cache_values() shipment.save()
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 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(_("You can't cancel orders that are paid, shipped, or already canceled.")) order.change_status(next_status=new_status, user=request.user) message = _("Order status changed: from `{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 get_payment_process_response(self, service, order, urls): """ Get payment process response for given order. :type service: shuup.core.models.PaymentMethod :type order: shuup.core.models.Order :type urls: PaymentUrls :rtype: django.http.HttpResponse|None """ cielo_transaction = CieloTransaction.objects.filter( pk=order.payment_data.get(CIELO_TRANSACTION_ID_KEY)).first() cielo_order = CieloOrderTransaction.objects.filter( pk=order.payment_data.get(CIELO_ORDER_TRANSACTION_ID_KEY)).first() if not cielo_order or not cielo_transaction: order.set_canceled() order.add_log_entry(_('No payment identified.'), kind=LogEntryKind.ERROR) raise Problem(_('No payment identified.'), title=_('Order cancelled')) # faz as amarrações cielo_order.order = order cielo_order.save() return HttpResponseRedirect(urls.return_url)
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 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 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() # after we save the new layout configs, make sure to reload the saved data in forms # so the returned get() response contains updated data self.build_form() if request.POST.get("publish") == "1": return self.dispatch_publish() return self.get(request, *args, **kwargs)
def handle_post_delete_file(self, data): file = File.objects.get(pk=data["id"]) try: file.delete() except IntegrityError as ie: raise Problem(str(ie)) return JsonResponse({"success": True, "message": _("File deleted.")})
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": force_text(reason)}) login_url = force_str( reverse("shuup_admin:login") + "?" + error_params) resp = redirect_to_login(next=request.path, login_url=login_url) if is_authenticated(request.user): # 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": escape(reason) }).with_link(url=resp.url, title=_("Log in with different credentials..."))) return resp
def check_and_raise_if_only_one_allowed(setting_name, obj): if ShuupSettings.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 dispatch_command(self, request, command): product = self.object if command == "clear_package": clear_existing_package(product) messages.success(self.request, _("Package cleared.")) else: raise Problem("Error! Unknown command: `%s`." % command) return HttpResponseRedirect(self.get_success_url())
def get(self, request, *args, **kwargs): product = self.object = self.get_object() if product.mode == ProductMode.VARIATION_CHILD: return redirect("shuup: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 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 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(_("This recovery link is invalid.")) return super(ResetPasswordView, self).dispatch(request, *args, **kwargs)
def get(self, request): # noqa (C901) model_name = request.GET.get("model") object_id = request.GET.get("pk", request.GET.get("id")) if not model_name or not object_id: return HttpResponseBadRequest(_("Invalid object.")) url = None try: model = apps.get_model(model_name) except LookupError: return HttpResponseBadRequest(_("Invalid model.")) instance = model.objects.filter(pk=object_id).first() if instance: required_permission = "%s.change_%s" % (instance._meta.app_label, instance._meta.model_name) missing_permissions = get_missing_permissions( request.user, [required_permission]) if missing_permissions: reason = _("You do not have the required permission(s): %s" ) % ", ".join(missing_permissions) raise Problem( _("Can't view this page. %(reason)s") % {"reason": reason}, _("Unauthorized")) # try edit first try: url = get_model_url(instance, kind="edit", user=request.user, shop=get_shop(request), required_permissions=[required_permission]) except NoModelUrl: # try detail try: url = get_model_url( instance, kind="detail", user=request.user, shop=get_shop(request), required_permissions=[required_permission]) except NoModelUrl: pass if url: # forward the mode param if request.GET.get("mode"): url = "{}?mode={}".format(url, request.GET["mode"]) return HttpResponseRedirect(url) raise Http404(_("Object not found"))
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("Error! Unknown command: `%s`." % command) return HttpResponseRedirect(self.get_success_url())
def create_charge(self): resp = self._send_request() charge_data = resp.json() if hasattr(resp, "json") else resp _handle_stripe_error(charge_data) if not charge_data.get("paid"): raise Problem(_("Stripe Charge does not say 'paid'")) return self.order.create_payment(self.order.taxful_total_price, payment_identifier="Stripe-%s" % charge_data["id"], description=_("Stripe Charge"))
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 form_valid(self, form): file = form.cleaned_data["file"] if not file.name.endswith(".zip"): raise Problem(_("Only ZIP files are supported")) # TODO: Maybe verify the file before saving? filename = "shuup-addon-%s-%s" % (uuid.uuid4(), os.path.basename(file.name)) with open(os.path.join(tempfile.gettempdir(), filename), "wb") as outf: shutil.copyfileobj(file, outf) return HttpResponseRedirect( manipulate_query_string( reverse("shuup_admin:addon.upload_confirm"), file=filename))
def create_payment_intent(self): resp = self._send_request() payment_intent_data = resp.json() if hasattr(resp, "json") else resp _handle_stripe_error(payment_intent_data) status = payment_intent_data.get("status", False) if not status or 'status' != 'succeeded': raise Problem(_("Stripe status is not 'succeeded'")) return self.order.create_payment( self.order.taxful_total_price, payment_identifier="Stripe-%s" % payment_intent_data["id"], description=_("Stripe Payment Intent"))