def test_contact_redirect(self): request = self.request_factory.get('/contact') request.user = AnonymousUser() service = AppRedirectionService() self.assertEqual('https://welcome.astrobin.com/contact', service.contact_redirect(request))
def test_contact_redirect_with_user(self): request = self.request_factory.get('/contact') request.user = Generators.user() service = AppRedirectionService() url = service.contact_redirect(request) self.assertTrue('username=%s' % urllib.quote(request.user.username) in url) self.assertTrue('email=%s' % urllib.quote(request.user.email) in url)
def test_redirect_from_astrobin(self): request = RequestFactory().get("/") service = AppRedirectionService() request.META['HTTP_HOST'] = 'www.astrobin.com ' self.assertEquals( 'http://app.astrobin.com/foo', service.redirect(request, '/foo'), )
def test_redirect_from_localhost(self): request = RequestFactory().get('/') service = AppRedirectionService() request.META['HTTP_HOST'] = 'localhost:8083' self.assertEquals( 'http://localhost:4400/foo', service.redirect(request, '/foo'), )
def reject(self, request, pk): edit_proposal: EquipmentItemEditProposalMixin = get_object_or_404( self.get_serializer().Meta.model, pk=pk) check_permissions, response = self.check_edit_proposal_permissions( request, edit_proposal) if not check_permissions: return response edit_proposal.edit_proposal_reviewed_by = request.user edit_proposal.edit_proposal_review_ip = request.META.get('REMOTE_ADDR') edit_proposal.edit_proposal_review_timestamp = timezone.now() edit_proposal.edit_proposal_review_comment = request.data.get( 'comment') edit_proposal.edit_proposal_review_status = 'REJECTED' edit_proposal.save() target = edit_proposal.edit_proposal_target push_notification( [ x for x in list( {edit_proposal.edit_proposal_by, target.created_by}) if x != request.user ], request.user, 'equipment-edit-proposal-rejected', { 'user': request.user.userprofile.get_display_name(), 'user_url': build_notification_url( settings.BASE_URL + reverse('user_page', args=(request.user.username, ))), 'item': f'{target.brand.name if target.brand else _("(DIY)")} {target.name}', 'item_url': build_notification_url( AppRedirectionService.redirect( f'/equipment' f'/explorer' f'/{target.item_type}/{target.pk}' f'/{target.slug}')), 'edit_proposal_url': build_notification_url( AppRedirectionService.redirect( f'/equipment' f'/explorer' f'/{target.item_type}/{target.pk}' f'/{target.slug}' f'/edit-proposals' f'/{edit_proposal.pk}/')), 'comment': edit_proposal.edit_proposal_review_comment }) serializer = self.serializer_class(edit_proposal) return Response(serializer.data)
def test_contact_redirect_with_request_data(self): request = self.request_factory.get('/contact') request.user = AnonymousUser() request.GET = {'subject': 'foo', 'message': 'bar'} service = AppRedirectionService() url = service.contact_redirect(request) self.assertTrue('subject=foo' in url) self.assertTrue('message=bar' in url)
def reject(self, request, pk): if not request.user.groups.filter(name='equipment_moderators').exists(): raise PermissionDenied(request.user) strategy: GearMigrationStrategy = self.get_object() if strategy.migration_flag is None: return Response(status=409) if request.user == strategy.migration_flag_moderator: raise PermissionDenied target = strategy.migration_content_object push_notification( [strategy.migration_flag_moderator], request.user, 'equipment-item-migration-rejected', { 'user': request.user.userprofile.get_display_name(), 'user_url': build_notification_url( settings.BASE_URL + reverse('user_page', args=(request.user.username,)) ), 'migration_flag': strategy.migration_flag, 'reason': request.data.get('reason'), 'comment': request.data.get('comment'), 'legacy_item': strategy.gear, 'target_item': f'{target.brand.name if target.brand else _("(DIY)")} {target.name}' if target else None, 'target_url': build_notification_url( AppRedirectionService.redirect( f'/equipment' f'/explorer' f'/{target.item_type}/{target.pk}' f'/{target.slug}' ) ) if target else None, 'migration_tool_url': build_notification_url( AppRedirectionService.redirect( f'/equipment' f'/migration-tool' ) ) if target else None, } ) strategy.gear.migration_flag_moderator_lock = None strategy.gear.migration_flag_moderator_lock_timestamp = None strategy.gear.save() strategy.delete() serializer = self.get_serializer(strategy) return Response(serializer.data)
def test_contact_redirect_with_user_and_request_data(self): request = self.request_factory.get('/contact') request.user = Generators.user() request.GET = {'subject': 'foo', 'message': 'bar'} service = AppRedirectionService() url = service.contact_redirect(request) self.assertTrue('username=%s' % urllib.parse.quote(request.user.username) in url) self.assertTrue('email=%s' % urllib.parse.quote(request.user.email) in url) self.assertTrue('subject=foo' in url) self.assertTrue('message=bar' in url)
def get_absolute_url_base(self, type: str) -> str: target_id: int = self.edit_proposal_target.id slug: str = slugify(f'{self.brand.name} {self.name}') id: int = self.id return AppRedirectionService.redirect( f'/equipment/explorer/{type}/{target_id}/{slug}/edit-proposals/{id}' )
def test_contact_redirect_with_user_with_non_ascii_username(self): request = self.request_factory.get('/contact') user = Generators.user() user.username = '******' user.save() request.user = user service = AppRedirectionService() url = service.contact_redirect(request) self.assertTrue( 'username=%s' % urllib.parse.quote(str(request.user.username).encode('utf-8')) in url) self.assertTrue('email=%s' % urllib.parse.quote(request.user.email) in url)
def process_response(self, request, response): if self._process(request): token, created = Token.objects.get_or_create(user=request.user) response.set_cookie( REST_FRAMEWORK_TOKEN_COOKIE, token, max_age=60 * 60 * 24 * 180, domain=AppRedirectionService.cookie_domain(request)) return response
def post(self, request, *args, **kwargs): cookie_name = "astrobin_use_high_contrast_theme" response = self.render_json_response({"status": "OK"}) if request.COOKIES.get(cookie_name): response.delete_cookie( cookie_name, domain=AppRedirectionService.cookie_domain(request)) else: max_age = 365 * 10 * 24 * 60 * 60 expires = datetime.strftime( datetime.utcnow() + timedelta(seconds=max_age), "%a, %d-%b-%Y %H:%M:%S GMT") response.set_cookie( cookie_name, 1, max_age=max_age, expires=expires, domain=AppRedirectionService.cookie_domain(request)) return response
def approve(self, request, pk): item = get_object_or_404(self.get_serializer().Meta.model.objects, pk=pk) if item.reviewed_by is not None: return Response("This item was already reviewed", HTTP_400_BAD_REQUEST) if item.created_by == request.user: return Response("You cannot review an item that you created", HTTP_400_BAD_REQUEST) item.reviewed_by = request.user item.reviewed_timestamp = timezone.now() item.reviewer_decision = 'APPROVED' item.reviewer_comment = request.data.get('comment') if item.created_by: push_notification( [item.created_by], request.user, 'equipment-item-approved', { 'user': request.user.userprofile.get_display_name(), 'user_url': build_notification_url( settings.BASE_URL + reverse('user_page', args=(request.user.username, ))), 'item': f'{item.brand.name} {item.name}', 'item_url': build_notification_url( AppRedirectionService.redirect( f'/equipment/explorer/{EquipmentItemService(item).get_type()}/{item.pk}' )), 'comment': item.reviewer_comment, }) item.save() serializer = self.serializer_class(item) return Response(serializer.data)
def create_checkout_session(request, user_pk, product, currency): stripe.api_key = settings.STRIPE_SECRET_KEY try: user = User.objects.get(pk=user_pk) except User.DoesNotExist: log.error("create_checkout_session: %d, %s, %s: %s" % (user_pk, product, currency, "Invalid user")) raise Http404 if currency.upper() not in settings.SUPPORTED_CURRENCIES: log.error("create_checkout_session: %d, %s, %s: %s" % (user.pk, product, currency, "Invalid currency")) return HttpResponseBadRequest() if product not in ('lite', 'premium', 'ultimate'): log.error("create_checkout_session: %d, %s, %s: %s" % (user.pk, product, currency, "Invalid product")) return HttpResponseBadRequest() stripe_products = { 'lite': settings.STRIPE_PRODUCT_LITE, 'premium': settings.STRIPE_PRODUCT_PREMIUM, 'ultimate': settings.STRIPE_PRODUCT_ULTIMATE } price = PricingService.get_full_price(product, currency.upper()) log.info("create_checkout_session: %d, %s, %s %.2f" % (user.pk, product, currency, price)) try: customer = PricingService.get_stripe_customer(user) customer_id = None if customer: customer_id = customer['id'] discounts = PricingService.get_stripe_discounts(user) if currency.upper() == 'EUR': payment_method_types = ['card', 'sepa_debit'] elif currency.upper() == 'CNY': payment_method_types = ['card', 'alipay'] else: payment_method_types = ['card'] kwargs = { 'success_url': AppRedirectionService.redirect( '/subscriptions/success?product=' + product + '&session_id={CHECKOUT_SESSION_ID}'), 'cancel_url': AppRedirectionService.redirect('/subscriptions/cancelled/'), 'mode': 'payment', 'payment_method_types': payment_method_types, 'client_reference_id': user.pk, 'customer': customer_id if customer_id else None, 'customer_email': user.email if not customer_id else None, 'submit_type': 'pay', 'line_items': [{ 'quantity': 1, 'price_data': { 'currency': currency.lower(), 'product': stripe_products[product], 'unit_amount_decimal': price * 100, # Stripe uses cents } }], 'metadata': { 'product': product }, } if discounts != []: kwargs['discounts'] = discounts else: kwargs['allow_promotion_codes'] = True checkout_session = stripe.checkout.Session.create(**kwargs) return JsonResponse({'sessionId': checkout_session['id']}) except Exception as e: log.exception("create_checkout_session: %d, %s, %s: %s" % (user.pk, product, currency, str(e))) return JsonResponse({'error': 'Internal error: %s' % str(e)})
def create_checkout_session(request, user_pk, product, currency): stripe.api_key = settings.STRIPE_SECRET_KEY try: user = User.objects.get(pk=user_pk) except User.DoesNotExist: log.error("create_checkout_session: %d, %s, %s: %s" % (user_pk, product, currency, "Invalid user")) raise Http404 if currency.upper() not in settings.SUPPORTED_CURRENCIES: log.error("create_checkout_session: %d, %s, %s: %s" % (user.pk, product, currency, "Invalid currency")) return HttpResponseBadRequest() if product not in ('lite', 'premium', 'ultimate'): log.error("create_checkout_session: %d, %s, %s: %s" % (user.pk, product, currency, "Invalid product")) return HttpResponseBadRequest() stripe_products = { 'lite': settings.STRIPE_PRODUCT_LITE, 'premium': settings.STRIPE_PRODUCT_PREMIUM, 'ultimate': settings.STRIPE_PRODUCT_ULTIMATE } price = PricingService.get_price(product, currency.upper()) log.info("create_checkout_session: %d, %s, %s %.2f" % (user.pk, product, currency, price)) try: customer_result = stripe.Customer.list(email=user.email, limit=1) customer = None if len(customer_result['data']) == 1: customer = customer_result['data'][0]['id'] checkout_session = stripe.checkout.Session.create( success_url=AppRedirectionService.redirect( request, '/subscriptions/success?product=' + product + '&session_id={CHECKOUT_SESSION_ID}'), cancel_url=AppRedirectionService.redirect( request, '/subscriptions/cancelled/'), mode='payment', payment_method_types=['card'], client_reference_id=user.pk, customer=customer if customer else None, customer_email=user.email if not customer else None, allow_promotion_codes=True, submit_type='pay', line_items=[{ 'quantity': 1, 'price_data': { 'currency': currency.lower(), 'product': stripe_products[product], 'unit_amount_decimal': price * 100, # Stripe uses cents } }], metadata={'product': product}) return JsonResponse({'sessionId': checkout_session['id']}) except Exception as e: log.exception("create_checkout_session: %d, %s, %s: %s" % (user.pk, product, currency, str(e))) return JsonResponse({'error': 'Internal error: %s' % str(e)})
def get_redirect_url(self, *args, **kwargs): return AppRedirectionService.redirect(self.request, '/notifications')
def send_notifications(self, force=False): if self.comment.pending_moderation and not force: return instance = self.comment model_class = instance.content_type.model_class() obj = instance.content_type.get_object_for_this_type(id=instance.object_id) object_owner = None notification = None mentions = MentionsService.get_mentions(instance.text) url = None if model_class == Image: object_owner = obj.user notification = 'new_comment' url = settings.BASE_URL + instance.get_absolute_url() elif hasattr(model_class, 'edit_proposal_by'): object_owner = obj.edit_proposal_by notification = 'new_comment_to_edit_proposal' url = instance.get_absolute_url() elif model_class == Iotd: object_owner = obj.judge notification = 'new_comment_to_scheduled_iotd' url = AppRedirectionService.redirect(f'/iotd/judgement-queue#comments-{obj.pk}-{instance.pk}') if UserService(object_owner).shadow_bans(instance.author): log.info("Skipping notification for comment because %d shadow-bans %d" % ( object_owner.pk, instance.author.pk)) return exclude = MentionsService.get_mentioned_users_with_notification_enabled(mentions, 'new_comment_mention') if instance.parent and \ instance.parent.author != instance.author and \ not instance.pending_moderation: recipients = [x for x in [instance.parent.author] if x not in exclude] if recipients: push_notification( recipients, instance.author, 'new_comment_reply', { 'url': build_notification_url(url, instance.author), 'user': instance.author.userprofile.get_display_name(), 'user_url': settings.BASE_URL + reverse( 'user_page', kwargs={'username': instance.author.username} ), } ) if model_class == Image: if (force or not instance.pending_moderation) and not obj.is_wip: add_story(instance.author, verb='VERB_COMMENTED_IMAGE', action_object=instance, target=obj) if object_owner and notification: if instance.author != object_owner and \ (instance.parent is None or instance.parent.author != object_owner) and \ not instance.pending_moderation: recipients = [x for x in [object_owner] if x not in exclude] if recipients: push_notification( recipients, instance.author, notification, { 'url': build_notification_url(url, instance.author), 'user': instance.author.userprofile.get_display_name(), 'user_url': settings.BASE_URL + reverse( 'user_page', kwargs={'username': instance.author.username} ), } )
def send_edit_proposal_created_notification(sender, instance, created, **kwargs): if created and instance.edit_proposal_target.created_by: target = instance.edit_proposal_target owner = instance.edit_proposal_target.created_by user = instance.edit_proposal_by recipients = [] if owner != user: recipients.append(owner) previous_proposals = User.objects.filter( **{ f'astrobin_apps_equipment_{instance.__class__.__name__.lower()}_edit_proposals__' f'edit_proposal_target': target }) previous_proposals_reviewed = User.objects.filter( **{ f'astrobin_apps_equipment_{instance.__class__.__name__.lower()}_edit_proposals_reviewed__' f'edit_proposal_target': target }) commenters = User.objects.filter(pk__in=NestedComment.objects.filter( content_type=ContentType.objects.get_for_model(instance.__class__), object_id__in=instance.__class__.objects.filter( edit_proposal_target=target)).values_list('author', flat=True)) recipients.extend(list(previous_proposals)) recipients.extend(list(previous_proposals_reviewed)) recipients.extend(list(commenters)) recipients = list(set(recipients)) recipients.remove(user) if len(recipients) > 0: push_notification( recipients, user, 'equipment-edit-proposal-created', { 'user': user.userprofile.get_display_name(), 'user_url': build_notification_url( settings.BASE_URL + reverse('user_page', args=(user.username, ))), 'item': f'{target.brand.name if target.brand else _("(DIY)")} {target.name}', 'item_url': build_notification_url( AppRedirectionService.redirect( f'/equipment' f'/explorer' f'/{target.item_type}/{target.pk}' f'/{target.slug}')), 'edit_proposal_url': build_notification_url( AppRedirectionService.redirect( f'/equipment' f'/explorer' f'/{target.item_type}/{target.pk}' f'/{target.slug}' f'/edit-proposals' f'/{instance.pk}/')), })
def app_redirection_service(request, path): return AppRedirectionService.redirect(request, path)
def app_redirection_service(path): return AppRedirectionService.redirect(path)
def get_redirect_url(self, *args, **kwargs): return AppRedirectionService.contact_redirect(self.request)
def dispatch(self, request, *args, **kwargs): return HttpResponsePermanentRedirect( AppRedirectionService.redirect('/iotd/review-queue'))
def test_redirect_from_localhost(self): service = AppRedirectionService() self.assertEqual('http://localhost:4400/foo', service.redirect('/foo'))
def test_redirect_from_astrobin(self): service = AppRedirectionService() self.assertEqual('https://app.astrobin.com/foo', service.redirect('/foo'))
def revision_upload_url(image: Image, request): return AppRedirectionService.redirect('/uploader/revision/%d' % image.pk)
def get_redirect_url(self, *args, **kwargs): return AppRedirectionService.redirect('/notifications/settings')