Пример #1
0
    def render_to_response(self, context):

        # Allow superusers to set ?dwft_bypass_teamwork=1
        # while viewing a transcript.
        flag_is_active(self.request, 'bypass_teamwork')

        return super(TranscriptDetailView, self).render_to_response(context)
Пример #2
0
def payments_confirm(request, addon_id, addon):
    data = {}
    # TODO(solitude): remove all references to AddonPaymentData.
    if waffle.flag_is_active(request, 'solitude-payments'):
        data = client.get_seller_paypal_if_exists(addon) or {}

    adp, created = AddonPaymentData.objects.safer_get_or_create(addon=addon)
    if not data:
        data = model_to_dict(adp)

    form = PaypalPaymentData(request.POST or data)
    if request.method == 'POST' and form.is_valid():
        if waffle.flag_is_active(request, 'solitude-payments'):
            # TODO(solitude): when the migration of data is completed, we
            # will be able to remove this.
            pk = client.create_seller_for_pay(addon)
            client.patch_seller_paypal(pk=pk, data=form.cleaned_data)

        # TODO(solitude): remove this.
        adp.update(**form.cleaned_data)
        AppSubmissionChecklist.objects.get(addon=addon).update(payments=True)
        addon.mark_done()
        return redirect('submit.app.done', addon.app_slug)

    return jingo.render(request, 'submit/payments-confirm.html', {
                        'step': 'payments',
                        'addon': addon,
                        'form': form
                        })
def test(request):
    c = {}

    if waffle.flag_is_active(request, 'feature1'):
        c["feature11"] = "View Feature 1 is live!"
    else:
        c["feature11"] = "View Feature 1 is not available right now"

    # question feature
    users = User.objects.all()

    c['question_array'] = []
    if waffle.flag_is_active(request, 'question'):
        for user in users:
            questions = Question.objects.filter(user=user.id)
            c['question_array'].append("")
            c['question_array'].append(user.username + ":")
            if questions:
                for question in questions:
                    c['question_array'].append(question.text)
            else:
                c['question_array'].append("Hasn't asked any questions... sad.")

    if waffle.flag_is_active(request, 'answer'):
        c["answer_array"] = Answer.objects.all()

    c['cookie_answer'] = request.COOKIES.get('dwf_answer')
    c['cookie_question'] = request.COOKIES.get('dwf_question')
    c['cookie_feature1'] = request.COOKIES.get('dwf_feature1')

    return render_to_response('test.html',c, context_instance = RequestContext(request))
Пример #4
0
    def _check_readonly(request, *args, **kwargs):
        if not flag_is_active(request, 'kumaediting'):
            raise ReadOnlyException("kumaediting")
        elif flag_is_active(request, 'kumabanned'):
            raise ReadOnlyException("kumabanned")

        return view(request, *args, **kwargs)
Пример #5
0
def payment(request, status=None):
    # Note this is not post required, because PayPal does not reply with a
    # POST but a GET, that's a sad face.
    pre, created = PreApprovalUser.objects.safer_get_or_create(user=request.amo_user)

    context = {"preapproval": pre, "currency": CurrencyForm(initial={"currency": pre.currency or "USD"})}

    if status:
        data = request.session.get("setup-preapproval", {})

        context["status"] = status

        if status == "complete":
            # The user has completed the setup at PayPal and bounced back.
            if "setup-preapproval" in request.session:
                if waffle.flag_is_active(request, "solitude-payments"):
                    client.put_preapproval(data={"uuid": request.amo_user}, pk=data["solitude-key"])

                paypal_log.info(u"Preapproval key created: %s" % request.amo_user.pk)
                amo.log(amo.LOG.PREAPPROVAL_ADDED)
                # TODO(solitude): once this is turned off, we will want to
                # keep preapproval table populated with something, perhaps
                # a boolean inplace of pre-approval key.
                pre.update(paypal_key=data.get("key"), paypal_expiry=data.get("expiry"))

                # If there is a target, bounce to it and don't show a message
                # we'll let whatever set this up worry about that.
                if data.get("complete"):
                    return http.HttpResponseRedirect(data["complete"])

                messages.success(request, _("You're all set for instant app purchases with PayPal."))
                del request.session["setup-preapproval"]

        elif status == "cancel":
            # The user has chosen to cancel out of PayPal. Nothing really
            # to do here, PayPal just bounce to the cancel page if defined.
            if data.get("cancel"):
                return http.HttpResponseRedirect(data["cancel"])

            messages.success(request, _("Your payment pre-approval has been cancelled."))

        elif status == "remove":
            # The user has an pre approval key set and chooses to remove it
            if waffle.flag_is_active(request, "solitude-payments"):
                other = client.lookup_buyer_paypal(request.amo_user)
                if other:
                    client.patch_buyer_paypal(pk=other["resource_pk"], data={"key": ""})

            if pre.paypal_key:
                # TODO(solitude): again, we'll want to maintain some local
                # state in zamboni, so this will probably change to a
                # boolean in the future.
                pre.update(paypal_key="")

                amo.log(amo.LOG.PREAPPROVAL_REMOVED)
                messages.success(request, _("Your payment pre-approval has been disabled."))
                paypal_log.info(u"Preapproval key removed for user: %s" % request.amo_user)

    return jingo.render(request, "account/payment.html", context)
Пример #6
0
    def test_flag_all_sites_override(self):
        name = 'sample'
        Flag.objects.create(name=name, everyone=True, site=self.site1)

        self.assertTrue(waffle.flag_is_active(get(), name))

        with self.settings(SITE_ID=2):
            self.assertTrue(waffle.flag_is_active(get(), name))
Пример #7
0
    def test_testing_disabled_flag(self):
        Flag.objects.create(name='foo')
        request = get(dwft_foo='1')
        assert not waffle.flag_is_active(request, 'foo')
        assert not hasattr(request, 'waffle_tests')

        request = get(dwft_foo='0')
        assert not waffle.flag_is_active(request, 'foo')
        assert not hasattr(request, 'waffle_tests')
Пример #8
0
        def _wrapped_view(request, *args, **kwargs):
            if flag_name.startswith('!'):
                active = not flag_is_active(request, flag_name[1:])
            else:
                active = flag_is_active(request, flag_name)

            if not active:
                raise Http404
            return view(request, *args, **kwargs)
Пример #9
0
    def test_testing_disabled_flag(self):
        Flag.objects.create(name="foo")
        request = get(dwft_foo="1")
        assert not waffle.flag_is_active(request, "foo")
        assert not hasattr(request, "waffle_tests")

        request = get(dwft_foo="0")
        assert not waffle.flag_is_active(request, "foo")
        assert not hasattr(request, "waffle_tests")
Пример #10
0
    def dispatch(self, request, *args, **kwargs):
        if self.waffle_flag.startswith('!'):
            active = not flag_is_active(request, self.waffle_flag[1:])
        else:
            active = flag_is_active(request, self.waffle_flag)

        if not active:
            raise Http404
        return super(WaffleFlagMixin, self).dispatch(request, *args, **kwargs)
Пример #11
0
    def test_flag_existed_and_was_active(self):
        Flag.objects.create(name='foo', everyone=True)

        with override_flag('foo', active=True):
            assert waffle.flag_is_active(req(), 'foo')

        with override_flag('foo', active=False):
            assert not waffle.flag_is_active(req(), 'foo')

        assert Flag.objects.get(name='foo').everyone
Пример #12
0
    def test_flag_existed_and_was_null(self):
        Flag.objects.create(name="foo", everyone=None)

        with override_flag("foo", active=True):
            assert waffle.flag_is_active(req(), "foo")

        with override_flag("foo", active=False):
            assert not waffle.flag_is_active(req(), "foo")

        assert Flag.objects.get(name="foo").everyone is None
Пример #13
0
    def test_flag_existed_and_was_null(self):
        waffle.get_waffle_flag_model().objects.create(name='foo', everyone=None)

        with override_flag('foo', active=True):
            assert waffle.flag_is_active(req(), 'foo')

        with override_flag('foo', active=False):
            assert not waffle.flag_is_active(req(), 'foo')

        assert waffle.get_waffle_flag_model().objects.get(name='foo').everyone is None
Пример #14
0
    def test_flag_did_not_exist(self):
        assert not Flag.objects.filter(name='foo').exists()

        with override_flag('foo', active=True):
            assert waffle.flag_is_active(req(), 'foo')

        with override_flag('foo', active=False):
            assert not waffle.flag_is_active(req(), 'foo')

        assert not Flag.objects.filter(name='foo').exists()
Пример #15
0
    def test_cache_is_flushed_by_testutils_even_in_transaction(self):
        waffle.get_waffle_flag_model().objects.create(name='foo', everyone=True)

        with transaction.atomic():
            with override_flag('foo', active=True):
                assert waffle.flag_is_active(req(), 'foo')

            with override_flag('foo', active=False):
                assert not waffle.flag_is_active(req(), 'foo')

        assert waffle.flag_is_active(req(), 'foo')
Пример #16
0
    def test_testing_flag(self):
        Flag.objects.create(name='foo', testing=True)
        request = get(dwft_foo='1')
        assert waffle.flag_is_active(request, 'foo')
        assert 'foo' in request.waffle_tests
        assert request.waffle_tests['foo']

        request = get(dwft_foo='0')
        assert not waffle.flag_is_active(request, 'foo')
        assert 'foo' in request.waffle_tests
        assert not request.waffle_tests['foo']
Пример #17
0
    def test_testing_flag(self):
        Flag.objects.create(name="foo", testing=True)
        request = get(dwft_foo="1")
        assert waffle.flag_is_active(request, "foo")
        assert "foo" in request.waffle_tests
        assert request.waffle_tests["foo"]

        request = get(dwft_foo="0")
        assert not waffle.flag_is_active(request, "foo")
        assert "foo" in request.waffle_tests
        assert not request.waffle_tests["foo"]
Пример #18
0
    def test_custom_segment(self):
        Flag.objects.create(name='flag-1', custom_segment=(
            '{"even_numbers": 1}'
        ))
        Flag.objects.create(name='flag-2', custom_segment=(
            '{"even_numbers": 2}'
        ))

        request = get()
        self.assertFalse(waffle.flag_is_active(request, 'flag-1'))
        self.assertTrue(waffle.flag_is_active(request, 'flag-2'))
Пример #19
0
 def akismet_parameter_overrides(self):
     """
     Get parameter overrides based on user's waffle flags.
     """
     parameters = {}
     if flag_is_active(self.request, constants.SPAM_ADMIN_FLAG):
         parameters['user_role'] = 'administrator'
     if flag_is_active(self.request, constants.SPAM_SPAMMER_FLAG):
         parameters['comment_author'] = 'viagra-test-123'
     if flag_is_active(self.request, constants.SPAM_TESTING_FLAG):
         parameters['is_test'] = True
     return parameters
Пример #20
0
def PAID_PLATFORMS(request=None, is_packaged=False):
    import waffle

    platforms = (("paid-firefoxos", _("Firefox OS")),)

    android_payments_enabled = request and waffle.flag_is_active(request, "android-payments")
    android_packaged_enabled = request and waffle.flag_is_active(request, "android-packaged")

    if android_payments_enabled:
        if not is_packaged or (is_packaged and android_packaged_enabled):
            platforms += (("paid-android-mobile", _("Firefox Mobile")), ("paid-android-tablet", _("Firefox Tablet")))

    return platforms
Пример #21
0
    def test_testing_flag(self):
        Flag.objects.create(name="foo", testing=True)
        request = get(dwft_foo="1")
        assert waffle.flag_is_active(request, "foo")
        assert "foo" in request.waffle_tests
        assert request.waffle_tests["foo"]

        # GET param should override cookie
        request = get(dwft_foo="0")
        request.COOKIES["dwft_foo"] = "True"
        assert not waffle.flag_is_active(request, "foo")
        assert "foo" in request.waffle_tests
        assert not request.waffle_tests["foo"]
Пример #22
0
    def test_testing_flag(self):
        Flag.objects.create(name='foo', testing=True)
        request = get(dwft_foo='1')
        assert waffle.flag_is_active(request, 'foo')
        assert 'foo' in request.waffle_tests
        assert request.waffle_tests['foo']

        # GET param should override cookie
        request = get(dwft_foo='0')
        request.COOKIES['dwft_foo'] = 'True'
        assert not waffle.flag_is_active(request, 'foo')
        assert 'foo' in request.waffle_tests
        assert not request.waffle_tests['foo']
Пример #23
0
 def _set_packaged_errors(self):
     """Add packaged-app submission errors for incompatible platforms."""
     devices = self._get_combined()
     bad_android = (
         not waffle.flag_is_active(self.request, 'android-packaged') and
         ('android-mobile' in devices or 'android-tablet' in devices)
     )
     bad_desktop = (
         not waffle.flag_is_active(self.request, 'desktop-packaged') and
         'desktop' in devices
     )
     if bad_android or bad_desktop:
         self._errors['free_platforms'] = self._errors['paid_platforms'] = (
             self.ERRORS['packaged'])
Пример #24
0
        def _wrapped_view(request, *args, **kwargs):
            if flag_name.startswith('!'):
                active = not flag_is_active(request, flag_name[1:])
            else:
                active = flag_is_active(request, flag_name)

            if not active:
                response_to_redirect_to = get_response_to_redirect(redirect_to)
                if response_to_redirect_to:
                    return response_to_redirect_to
                else:
                    raise Http404

            return view(request, *args, **kwargs)
Пример #25
0
def FREE_PLATFORMS(request=None, is_packaged=False):
    import waffle

    platforms = (("free-firefoxos", _("Firefox OS")),)

    android_packaged_enabled = request and waffle.flag_is_active(request, "android-packaged")
    desktop_packaged_enabled = request and waffle.flag_is_active(request, "desktop-packaged")

    if not is_packaged or (is_packaged and desktop_packaged_enabled):
        platforms += (("free-desktop", _("Firefox for Desktop")),)

    if not is_packaged or (is_packaged and android_packaged_enabled):
        platforms += (("free-android-mobile", _("Firefox Mobile")), ("free-android-tablet", _("Firefox Tablet")))

    return platforms
Пример #26
0
 def test_reroll(self, uniform):
     """Even without a cookie, calling flag_is_active twice should return
     the same value."""
     Flag.objects.create(name="myflag", percent="50.0")
     # Make sure we're not really random.
     request = get()  # Create a clean request.
     assert not hasattr(request, "waffles")
     uniform.return_value = "10"  # < 50. Flag is True.
     assert waffle.flag_is_active(request, "myflag")
     assert hasattr(request, "waffles")  # We should record this flag.
     assert "myflag" in request.waffles
     assert request.waffles["myflag"][0]
     uniform.return_value = "70"  # > 50. Normally, Flag would be False.
     assert waffle.flag_is_active(request, "myflag")
     assert request.waffles["myflag"][0]
Пример #27
0
 def test_reroll(self, uniform):
     """Even without a cookie, calling flag_is_active twice should return
     the same value."""
     Flag.objects.create(name='myflag', percent='50.0')
     # Make sure we're not really random.
     request = get()  # Create a clean request.
     assert not hasattr(request, 'waffles')
     uniform.return_value = '10'  # < 50. Flag is True.
     assert waffle.flag_is_active(request, 'myflag')
     assert hasattr(request, 'waffles')  # We should record this flag.
     assert 'myflag' in request.waffles
     assert request.waffles['myflag'][0]
     uniform.return_value = '70'  # > 50. Normally, Flag would be False.
     assert waffle.flag_is_active(request, 'myflag')
     assert request.waffles['myflag'][0]
Пример #28
0
def root(request, format=None, **kwargs):
    """
    The documentation for the Open Science Framework API can be found at [developer.osf.io](https://developer.osf.io).
    The contents of this endpoint are variable and subject to change without notification.
    """
    if request.user and not request.user.is_anonymous:
        user = request.user
        current_user = UserSerializer(user, context={'request': request}).data
    else:
        current_user = None
    flags = [name for name in Flag.objects.values_list('name', flat=True) if flag_is_active(request, name)]
    kwargs = request.parser_context['kwargs']
    return_val = {
        'meta': {
            'message': 'Welcome to the OSF API.',
            'version': request.version,
            'current_user': current_user,
            'active_flags': flags,
        },
        'links': {
            'nodes': utils.absolute_reverse('nodes:node-list', kwargs=kwargs),
            'users': utils.absolute_reverse('users:user-list', kwargs=kwargs),
            'collections': utils.absolute_reverse('collections:collection-list', kwargs=kwargs),
            'registrations': utils.absolute_reverse('registrations:registration-list', kwargs=kwargs),
            'institutions': utils.absolute_reverse('institutions:institution-list', kwargs=kwargs),
            'licenses': utils.absolute_reverse('licenses:license-list', kwargs=kwargs),
            'schemas': utils.absolute_reverse('schemas:registration-schema-list', kwargs=kwargs),
            'addons': utils.absolute_reverse('addons:addon-list', kwargs=kwargs),
        },
    }

    if utils.has_admin_scope(request):
        return_val['meta']['admin'] = True

    return Response(return_val)
Пример #29
0
    def get_context_data(self, **kwargs):
        context = super(CommitteeListView, self).get_context_data(**kwargs)
        context['tags_cloud'] = Tag.objects.cloud_for_model(CommitteeMeeting)
        if waffle.flag_is_active(self.request, 'show_committee_topics'):
            context = self._add_topics_to_context(context)

        return context
Пример #30
0
 def test_all_flags_matched(self):
     """
     The flag has been found in ALL_FLAGS. Must return True.
     """
     setattr(waffle, 'ALL_FLAGS', ['foo', ])
     request = get()
     assert waffle.flag_is_active(request, 'foo')
Пример #31
0
def overview_series(request, addon, group, start, end, format):
    """Combines downloads_series and updates_series into one payload."""
    date_range = check_series_params_or_404(group, start, end, format)
    start_date, end_date = date_range
    check_stats_permission(request, addon)

    if waffle.flag_is_active(request, 'bigquery-download-stats'):
        downloads = get_download_series(
            addon=addon, start_date=start_date, end_date=end_date
        )
    else:
        downloads = get_series(
            DownloadCount, addon=addon.id, date__range=date_range
        )

    updates = get_updates_series(
        addon=addon, start_date=start_date, end_date=end_date
    )

    series = zip_overview(downloads, updates)

    return render_json(request, addon, series)
Пример #32
0
    def _add_to_context_data(self, context):
        formset = context.get('formset', [])
        lines = context.get('line_list', [])
        site_configuration = self.request.site.siteconfiguration

        context_updates, lines_data = self.process_basket_lines(lines)
        context.update(context_updates)
        context.update(self.process_totals(context))

        context.update({
            'analytics_data':
            prepare_analytics_data(
                self.request.user,
                site_configuration.segment_key,
            ),
            'enable_client_side_checkout':
            False,
            'sdn_check':
            site_configuration.enable_sdn_check
        })

        payment_processors = site_configuration.get_payment_processors()
        if (site_configuration.client_side_payment_processor
                and waffle.flag_is_active(self.request,
                                          CLIENT_SIDE_CHECKOUT_FLAG_NAME)):
            payment_processors_data = self._get_payment_processors_data(
                payment_processors)
            context.update(payment_processors_data)

        context.update({
            'formset_lines_data': list(zip(formset, lines_data)),
            'homepage_url': get_lms_url(''),
            'min_seat_quantity': 1,
            'max_seat_quantity': 100,
            'payment_processors': payment_processors,
            'lms_url_root': site_configuration.lms_url_root,
        })
        return context
Пример #33
0
    def _get_basket(self, basket_id):
        if not basket_id:
            return None

        try:
            basket_id = int(basket_id)
            basket = Basket.objects.get(id=basket_id)
            basket.strategy = strategy.Default()
            # TODO: Remove as a part of REVMI-124 as this is a hacky solution
            # The problem is that orders are being created after payment processing, and the discount is not
            # saved in the database, so it needs to be calculated again in order to save the correct info to the
            # order. REVMI-124 will create the order before payment processing, when we have the discount context.
            if waffle.flag_is_active(
                    self.request,
                    DYNAMIC_DISCOUNT_FLAG) and basket.lines.count() == 1:
                discount_lms_url = get_lms_url('/api/discounts/')
                lms_discount_client = EdxRestApiClient(
                    discount_lms_url,
                    jwt=self.request.site.siteconfiguration.access_token)
                ck = basket.lines.first().product.course_id
                user_id = self.request.user.lms_user_id
                try:
                    response = lms_discount_client.user(user_id).course(
                        ck).get()
                    self.request.POST = self.request.POST.copy()
                    self.request.POST['discount_jwt'] = response.get('jwt')
                except (SlumberHttpBaseException,
                        requests.exceptions.Timeout) as error:
                    logger.warning(
                        'Failed to get discount jwt from LMS. [%s] returned [%s]',
                        discount_lms_url, error.response)
            # End TODO
            Applicator().apply(basket, basket.owner, self.request)
            logger.info('Applicator applied, basket id: [%s]', basket.id)
            return basket
        except (ValueError, ObjectDoesNotExist) as error:
            logger.warning('Could not get basket--error: [%s]', str(error))
            return None
Пример #34
0
    def process_totals(self, context):
        """
        Returns a Dictionary of data related to total price and discounts.
        """
        # Total benefit displayed in price summary.
        # Currently only one voucher per basket is supported.
        try:
            applied_voucher = self.request.basket.vouchers.first()
            total_benefit_object = applied_voucher.best_offer.benefit if applied_voucher else None
        # TODO This ValueError handling no longer seems to be required and could probably be removed
        except ValueError:  # pragma: no cover
            total_benefit_object = None

        num_of_items = self.request.basket.num_items

        discount_jwt = None
        discount_percent = None
        if waffle.flag_is_active(self.request, DYNAMIC_DISCOUNT_FLAG):
            applied_offers = self.request.basket.applied_offers().values()
            if len(applied_offers) == 1 and list(applied_offers)[
                    0].condition.name == 'dynamic_discount_condition':
                discount_jwt = self.request.GET.get('discount_jwt')
                discount_percent = get_percentage_from_request()
        return {
            'total_benefit_object':
            total_benefit_object,
            'total_benefit':
            format_benefit_value(total_benefit_object)
            if total_benefit_object else None,
            'free_basket':
            context['order_total'].incl_tax == 0,
            'line_price': (self.request.basket.total_incl_tax_excl_discounts /
                           num_of_items) if num_of_items > 0 else 0,
            'discount_jwt':
            discount_jwt,
            'discount_percent':
            discount_percent,
        }
    def akismet_error(self, parameters, exception=None):
        """
        Upon errors from the Akismet API records the user, document
        and date of the attempt for further analysis. Then call the
        parent class' error handler.
        """
        try:
            document = self.instance.document
        except ObjectDoesNotExist:
            document = None

        if exception and isinstance(exception, AkismetError):
            # For Akismet errors, save the submission and exception details
            dsa_params = parameters.copy()
            dsa_params['akismet_status_code'] = exception.status_code
            dsa_params['akismet_debug_help'] = exception.debug_help
            dsa_params['akismet_response'] = exception.response.content
            review = DocumentSpamAttempt.AKISMET_ERROR
        else:
            # For detected spam, save the details for review
            dsa_params = parameters
            review = DocumentSpamAttempt.NEEDS_REVIEW

        # Wrapping this in a try/finally to make sure that even if
        # creating a spam attempt object fails we call the parent
        # method that raises a ValidationError
        try:
            DocumentSpamAttempt.objects.create(
                title=self.cleaned_data['title'],
                slug=self.cleaned_data['slug'],
                user=self.request.user,
                document=document,
                data=json.dumps(dsa_params, indent=2, sort_keys=True),
                review=review
            )
        finally:
            if not waffle.flag_is_active(self.request, SPAM_TRAINING_FLAG):
                super(RevisionForm, self).akismet_error(parameters, exception)
Пример #36
0
def create_stripe_subscription(request):
    user = request.user

    if not flag_is_active(request, "subscription"):
        return HttpResponseForbidden("subscription flag not active for this user")

    has_stripe_error = False
    try:
        email = request.POST.get("stripe_email", "")
        stripe_token = request.POST.get("stripe_token", "")
        create_stripe_customer_and_subscription_for_user(user, email, stripe_token)

    except stripe.error.StripeError:
        raven_client.captureException()
        has_stripe_error = True

    return redirect(
        urlparams(
            reverse("users.user_edit", args=[user.username]),
            has_stripe_error=has_stripe_error,
        )
        + "#subscription"
    )
Пример #37
0
 def form_valid(self, form):
     if waffle.flag_is_active(self.request, "create_note"):
         form.instance.created_by = self.request.user
         leadid = self.request.POST.get("create_note_lead")
         urlparameters = self.request.POST.get("urlparameters")
         try:
             lead = Lead.objects.get(pk=leadid)
         except Exception as e:
             print(str(e))
             logger.critical("Note Create error - Lead not found")
             messages.error(self.request, "There is an error on the form.")
             return redirect(
                 reverse("leads:listnote", args=[leadid]) + "?" +
                 urlparameters)
         else:
             form.instance.lead = lead
             return super().form_valid(form)
     else:
         messages.error(
             self.request,
             "Please update your subscription to continue using this feature.",
         )
         return super(NoteCreateView, self).form_valid(form)
Пример #38
0
def subscriptions(request):
    if not request.user.is_authenticated or not flag_is_active(
            request, "subscription"):
        return Response(None, status=status.HTTP_403_FORBIDDEN)

    if request.method == "POST":
        create_stripe_customer_and_subscription_for_user(
            request.user, request.user.email, request.data["stripe_token"])
        return Response(None, status=status.HTTP_201_CREATED)
    elif request.method == "DELETE":
        cancelled = cancel_stripe_customer_subscriptions(request.user)
        if cancelled:
            return Response(None, status=status.HTTP_204_NO_CONTENT)
        else:
            return Response("nothing to cancel", status=status.HTTP_410_GONE)

    all_subscriptions = []
    subscription_info = retrieve_and_synchronize_subscription_info(
        request.user)
    if subscription_info:
        all_subscriptions.append(subscription_info)

    return Response({"subscriptions": all_subscriptions})
Пример #39
0
def wafflejs(request):
    flags = cache.get(FLAGS_ALL_CACHE_KEY)
    if not flags:
        flags = Flag.objects.values_list('name', flat=True)
        cache.add(FLAGS_ALL_CACHE_KEY, flags)
    flag_values = [(f, flag_is_active(request, f)) for f in flags]

    switches = cache.get(SWITCHES_ALL_CACHE_KEY)
    if not switches:
        switches = Switch.objects.values_list('name', 'active')
        cache.add(SWITCHES_ALL_CACHE_KEY, switches)

    samples = cache.get(SAMPLES_ALL_CACHE_KEY)
    if not samples:
        samples = Sample.objects.values_list('name', flat=True)
        cache.add(SAMPLES_ALL_CACHE_KEY, samples)
    sample_values = [(s, sample_is_active(s)) for s in samples]
    return render_to_response('waffle/waffle.js', {
        'flags': flag_values,
        'switches': switches,
        'samples': sample_values
    },
                              mimetype='application/x-javascript')
Пример #40
0
def check_stats_permission(request, addon, beta):
    """
    Check if user is allowed to view stats/beta stats for ``addon``.

    Raises PermissionDenied if user is not allowed.

    Raises Http404 if user cannot access the beta mode (only if enabled).
    """
    user = request.user
    user_cannot_access_beta = not user.is_authenticated or (
        user.is_authenticated
        and not (user.email.endswith('@mozilla.com')
                 or waffle.flag_is_active(request, 'beta-stats')))
    addon_has_no_beta = addon.type not in amo.ADDON_TYPES_WITH_STATS

    if beta and (user_cannot_access_beta or addon_has_no_beta):
        raise http.Http404

    can_view = user.is_authenticated and (
        addon.has_author(user)
        or acl.action_allowed(request, amo.permissions.STATS_VIEW))
    if not can_view:
        raise PermissionDenied
Пример #41
0
def home(request):
    """Home page."""

    if flag_is_active(request, 'redesign'):
        demos = Submission.objects.exclude(
            hidden=True).order_by('-modified').all()[:4]
    else:
        demos = Submission.objects.filter(id=constance.config.DEMOS_DEVDERBY_HOMEPAGE_FEATURED_DEMO)\
                    .exclude(hidden=True)\
                    .order_by('-modified').all()[:1]

    updates = []
    for s in SECTION_USAGE:
        updates += Bundle.objects.recent_entries(s.updates)[:5]

    return render(
        request, 'landing/homepage.html', {
            'demos':
            demos,
            'updates':
            updates,
            'current_challenge_tag_name':
            str(constance.config.DEMOS_DEVDERBY_CURRENT_CHALLENGE_TAG).strip()
        })
Пример #42
0
def get_course_tabs(user, course, active_page, request):
    """
    Return the tabs to show a particular user, as a list of CourseTab items.
    """
    if not hasattr(course, 'tabs') or not course.tabs:
        return get_default_tabs(user, course, active_page, request)

    # TODO (vshnayder): There needs to be a place to call this right after course
    # load, but not from inside xmodule, since that doesn't (and probably
    # shouldn't) know about the details of what tabs are supported, etc.
    validate_tabs(course)

    tabs = []

    if waffle.flag_is_active(request, 'merge_course_tabs'):
        course_tabs = [
            tab for tab in course.tabs if tab['type'] != "course_info"
        ]
    else:
        course_tabs = course.tabs

    for tab in course_tabs:
        # expect handlers to return lists--handles things that are turned off
        # via feature flags, and things like 'textbook' which might generate
        # multiple tabs.
        gen = VALID_TAB_TYPES[tab['type']].generator
        tabs.extend(gen(tab, user, course, active_page, request))

    # Instructor tab is special--automatically added if user is staff for the course
    if has_access(user, course, 'staff'):
        tabs.append(
            CourseTab('Instructor',
                      reverse('instructor_dashboard', args=[course.id]),
                      active_page == 'instructor'))

    return tabs
Пример #43
0
def can_use_enterprise_catalog(enterprise_uuid):
    """
    Function to check if enterprise-catalog endpoints should be hit given an enterprise uuid.

    Checks the USE_ENTERPRISE_CATALOG waffle sample and ensures the passed
    enterprise uuid is not in the ENTERPRISE_CUSTOMERS_EXCLUDED_FROM_CATALOG list.

    Args:
        enterprise_uuid: the unique identifier for an enterprise customer

    Returns:
        boolean: True if sample is active and enterprise is not excluded
                 False if sample not active or enterprise is excluded
    """
    customer_uuid = str(enterprise_uuid)
    is_flag_active = waffle.flag_is_active(crum.get_current_request(),
                                           USE_ENTERPRISE_CATALOG)
    can_use_catalog = customer_uuid not in getattr(
        settings, 'ENTERPRISE_CUSTOMERS_EXCLUDED_FROM_CATALOG', [])
    log.info(
        'ENT-2885: USE_ENTEPRISE_CATALOG flag %s active. Enterprise %s %s use the enterprise-catalog service.',
        'IS' if is_flag_active else 'IS NOT', customer_uuid,
        'CAN' if can_use_catalog else 'CANNOT')
    return is_flag_active and can_use_catalog
Пример #44
0
    def post(self, request):
        form = RunForm(request.POST)
        if form.is_valid():
            parameters = dict()
            for f in ALL_FIELDS:
                parameters[f] = form.cleaned_data[f]

            r = Run(**parameters)
            rr = RunRecord()
            rr.user = request.user
            rr.from_run(r)
            out = r.run()

            ror = RunOutputRecord(run=rr)
            skew_params = dict(mass=0., intake=0., expenditure=0.)

            if waffle.flag_is_active(request, 'demo_mode'):
                skew_params = apply_skews(request, skew_params)
            ror.from_runoutput(out, skew_params)
            return HttpResponseRedirect(rr.get_absolute_url())
        return render(
            request, self.template_name,
            dict(form=form, interventions=Intervention.objects.all(),
                 parameters=Parameter.objects.all()))
Пример #45
0
def profile_view(request, username):
    profile = get_object_or_404(UserProfile, user__username=username)
    user = profile.user

    DEMOS_PAGE_SIZE = getattr(settings, 'DEMOS_PAGE_SIZE', 12)
    sort_order = request.GET.get('sort', 'created')
    try:
        page_number = int(request.GET.get('page', 1))
    except ValueError:
        page_number = 1
    show_hidden = (user == request.user) or user.is_superuser

    demos = Submission.objects.all_sorted(sort_order).filter(
        creator=profile.user)
    if not show_hidden:
        demos = demos.exclude(hidden=True)

    demos_paginator = Paginator(demos, DEMOS_PAGE_SIZE, True)
    demos_page = demos_paginator.page(page_number)

    wiki_activity, docs_feed_items = None, None
    if waffle.flag_is_active(request, 'kumawiki'):
        wiki_activity = profile.wiki_activity()
    else:
        docs_feed_items = UserDocsActivityFeed(user.username).items
        if docs_feed_items is not False:
            docs_feed_items = docs_feed_items[:DOCS_ACTIVITY_MAX_ITEMS]

    return jingo.render(
        request, 'devmo/profile.html',
        dict(profile=profile,
             demos=demos,
             demos_paginator=demos_paginator,
             demos_page=demos_page,
             docs_feed_items=docs_feed_items,
             wiki_activity=wiki_activity))
Пример #46
0
 def test_override(self):
     request = get(foo='1')
     waffle.get_waffle_flag_model().objects.create(
         name='foo')  # Off for everyone.
     assert waffle.flag_is_active(request, 'foo')
Пример #47
0
 def test_undefined_default(self):
     """WAFFLE_FLAG_DEFAULT controls undefined flags."""
     request = get()
     assert waffle.flag_is_active(request, 'foo')
Пример #48
0
 def test_undefined(self):
     """Undefined flags are always false."""
     request = get()
     assert not waffle.flag_is_active(request, 'foo')
Пример #49
0
def payments(request, addon_id, addon, webapp=False):
    premium_form = forms_payments.PremiumForm(request.POST or None,
                                              request=request,
                                              addon=addon,
                                              user=request.user)

    region_form = forms.RegionForm(request.POST or None,
                                   product=addon,
                                   request=request)

    upsell_form = forms_payments.UpsellForm(request.POST or None,
                                            addon=addon,
                                            user=request.user)

    providers = get_providers()

    if 'form-TOTAL_FORMS' in request.POST:
        formset_data = request.POST
    else:
        formset_data = None
    account_list_formset = forms_payments.AccountListFormSet(
        data=formset_data,
        provider_data=[{
            'addon': addon,
            'user': request.user,
            'provider': provider
        } for provider in providers])

    if request.method == 'POST':

        active_forms = [premium_form, region_form, upsell_form]
        if formset_data is not None:
            active_forms.append(account_list_formset)

        success = all(form.is_valid() for form in active_forms)

        if success:
            region_form.save()

            try:
                premium_form.save()
            except client.Error as err:
                success = False
                log.error('Error setting payment information (%s)' % err)
                messages.error(
                    request,
                    _(u'We encountered a problem connecting to the '
                      u'payment server.'))
                raise  # We want to see these exceptions!

            is_free_inapp = addon.premium_type == mkt.ADDON_FREE_INAPP
            is_now_paid = (addon.premium_type in mkt.ADDON_PREMIUMS
                           or is_free_inapp)

            # If we haven't changed to a free app, check the upsell.
            if is_now_paid and success:
                try:
                    if not is_free_inapp:
                        upsell_form.save()
                    if formset_data is not None:
                        account_list_formset.save()
                except client.Error as err:
                    log.error('Error saving payment information (%s)' % err)
                    messages.error(
                        request,
                        _(u'We encountered a problem connecting to '
                          u'the payment server.'))
                    success = False
                    raise  # We want to see all the solitude errors now.

        # If everything happened successfully, give the user a pat on the back.
        if success:
            messages.success(request, _('Changes successfully saved.'))
            return redirect(addon.get_dev_url('payments'))

    # TODO: refactor this (bug 945267)
    android_pay = waffle.flag_is_active(request, 'android-payments')
    desktop_pay = waffle.flag_is_active(request, 'desktop-payments')

    # If android payments is not allowed then firefox os must
    # be 'checked' and android-mobile and android-tablet should not be.
    invalid_paid_platform_state = []

    if not android_pay:
        # When android-payments is off...
        invalid_paid_platform_state += [('android-mobile', True),
                                        ('android-tablet', True),
                                        ('firefoxos', False)]

    if not desktop_pay:
        # When desktop-payments is off...
        invalid_paid_platform_state += [('desktop', True)]

    cannot_be_paid = (addon.premium_type == mkt.ADDON_FREE
                      and any(premium_form.device_data['free-%s' % x] == y
                              for x, y in invalid_paid_platform_state))

    try:
        tier_zero = Price.objects.get(price='0.00', active=True)
        tier_zero_id = tier_zero.pk
    except Price.DoesNotExist:
        tier_zero = None
        tier_zero_id = ''

    # Get the regions based on tier zero. This should be all the
    # regions with payments enabled.
    paid_region_ids_by_name = []
    if tier_zero:
        paid_region_ids_by_name = tier_zero.region_ids_by_name()

    platforms = PAID_PLATFORMS(request)
    paid_platform_names = [unicode(platform[1]) for platform in platforms]

    provider_regions = {}
    if tier_zero:
        provider_regions = tier_zero.provider_regions()

    return render(
        request,
        'developers/payments/premium.html',
        {
            'addon':
            addon,
            'webapp':
            webapp,
            'premium':
            addon.premium,
            'form':
            premium_form,
            'upsell_form':
            upsell_form,
            'tier_zero_id':
            tier_zero_id,
            'region_form':
            region_form,
            'PLATFORMS_NAMES':
            PLATFORMS_NAMES,
            'is_paid': (addon.premium_type in mkt.ADDON_PREMIUMS
                        or addon.premium_type == mkt.ADDON_FREE_INAPP),
            'cannot_be_paid':
            cannot_be_paid,
            'paid_platform_names':
            paid_platform_names,
            'is_packaged':
            addon.is_packaged,
            # Bango values
            'account_list_forms':
            account_list_formset.forms,
            'account_list_formset':
            account_list_formset,
            # Waffles
            'api_pricelist_url':
            reverse('price-list'),
            'payment_methods': {
                PAYMENT_METHOD_ALL: _('All'),
                PAYMENT_METHOD_CARD: _('Credit card'),
                PAYMENT_METHOD_OPERATOR: _('Carrier'),
            },
            'provider_lookup':
            dict(PROVIDER_CHOICES),
            'all_paid_region_ids_by_name':
            paid_region_ids_by_name,
            'providers':
            providers,
            'provider_regions':
            provider_regions,
            'enabled_provider_ids': [
                acct.payment_account.provider
                for acct in addon.all_payment_accounts()
            ]
        })
Пример #50
0
 def toggle_is_active(self, flag):
     return waffle.flag_is_active(get(), flag.name)
Пример #51
0
    def get(self, request):  # pylint: disable=too-many-statements
        """ Calculate basket totals given a list of sku's

        Create a temporary basket add the sku's and apply an optional voucher code.
        Then calculate the total price less discounts. If a voucher code is not
        provided apply a voucher in the Enterprise entitlements available
        to the user.

        Query Params:
            sku (string): A list of sku(s) to calculate
            code (string): Optional voucher code to apply to the basket.
            username (string): Optional username of a user for which to calculate the basket.

        Returns:
            JSON: {
                    'total_incl_tax_excl_discounts': basket.total_incl_tax_excl_discounts,
                    'total_incl_tax': basket.total_incl_tax,
                    'currency': basket.currency
                }
        """
        RequestCache.set(TEMPORARY_BASKET_CACHE_KEY,
                         True)  # TODO: LEARNER 5463

        partner = get_partner_for_site(request)
        skus = request.GET.getlist('sku')
        if not skus:
            return HttpResponseBadRequest(_('No SKUs provided.'))
        skus.sort()

        code = request.GET.get('code', None)
        try:
            voucher = Voucher.objects.get(code=code) if code else None
        except Voucher.DoesNotExist:
            voucher = None

        products = Product.objects.filter(stockrecords__partner=partner,
                                          stockrecords__partner_sku__in=skus)
        if not products:
            return HttpResponseBadRequest(
                _('Products with SKU(s) [{skus}] do not exist.').format(
                    skus=', '.join(skus)))

        # If there is only one product apply an Enterprise entitlement voucher
        if not voucher and len(products) == 1:
            voucher = get_entitlement_voucher(request, products[0])

        basket_owner = request.user

        requested_username = request.GET.get('username', default='')
        is_anonymous = request.GET.get('is_anonymous',
                                       'false').lower() == 'true'

        use_default_basket = is_anonymous

        # validate query parameters
        if requested_username and is_anonymous:
            return HttpResponseBadRequest(
                _('Provide username or is_anonymous query param, but not both')
            )
        elif not requested_username and not is_anonymous:
            logger.warning(
                "Request to Basket Calculate must supply either username or is_anonymous query"
                " param. Requesting user=%s. Future versions of this API will treat this "
                "WARNING as an ERROR and raise an exception.",
                basket_owner.username)
            requested_username = request.user.username

        # If a username is passed in, validate that the user has staff access or is the same user.
        if requested_username:
            if basket_owner.username.lower() == requested_username.lower():
                pass
            elif basket_owner.is_staff:
                try:
                    basket_owner = User.objects.get(
                        username=requested_username)
                except User.DoesNotExist:
                    # This case represents a user who is logged in to marketing, but
                    # doesn't yet have an account in ecommerce. These users have
                    # never purchased before.
                    use_default_basket = True
            else:
                return HttpResponseForbidden('Unauthorized user credentials')

        if basket_owner.username == self.MARKETING_USER and not use_default_basket:
            # For legacy requests that predate is_anonymous parameter, we will calculate
            # an anonymous basket if the calculated user is the marketing user.
            # TODO: LEARNER-5057: Remove this special case for the marketing user
            # once logs show no more requests with no parameters (see above).
            use_default_basket = True

        if use_default_basket:
            basket_owner = None

        cache_key = None
        if use_default_basket:
            # For an anonymous user we can directly get the cached price, because
            # there can't be any enrollments or entitlements.
            cache_key = get_cache_key(site_comain=request.site,
                                      resource_name='calculate',
                                      skus=skus)
            cached_response = TieredCache.get_cached_response(cache_key)
            if cached_response.is_hit:
                return Response(cached_response.value)

        if waffle.flag_is_active(
                request,
                "disable_calculate_temporary_basket_atomic_transaction"):
            response = self._calculate_temporary_basket(
                basket_owner, request, products, voucher, skus, code)
        else:
            response = self._calculate_temporary_basket_atomic(
                basket_owner, request, products, voucher, skus, code)

        if response and use_default_basket:
            TieredCache.set_all_tiers(
                cache_key, response,
                settings.ANONYMOUS_BASKET_CALCULATE_CACHE_TIMEOUT)

        return Response(response)
Пример #52
0
 def test_no_logging_missing_flag_by_default(self, mock_logger):
     request = get()
     waffle.flag_is_active(request, 'foo')
     mock_logger.log.call_count == 0
Пример #53
0
 def test_logging_missing_flag(self, mock_logger):
     request = get()
     waffle.flag_is_active(request, 'foo')
     mock_logger.log.assert_called_with(logging.WARNING,
                                        'Flag %s not found', 'foo')
Пример #54
0
    def get_context_data(self, **kwargs):
        context = super(BasketSummaryView, self).get_context_data(**kwargs)
        formset = context.get('formset', [])
        lines = context.get('line_list', [])
        site_configuration = self.request.site.siteconfiguration

        failed_enterprise_consent_code = self.request.GET.get(
            CONSENT_FAILED_PARAM)
        if failed_enterprise_consent_code:
            messages.error(
                self.request,
                _("Could not apply the code '{code}'; it requires data sharing consent."
                  ).format(code=failed_enterprise_consent_code))

        context_updates, lines_data = self._process_basket_lines(lines)
        context.update(context_updates)

        user = self.request.user
        context.update({
            'analytics_data':
            prepare_analytics_data(
                user,
                site_configuration.segment_key,
            ),
            'enable_client_side_checkout':
            False,
            'sdn_check':
            site_configuration.enable_sdn_check
        })

        payment_processors = site_configuration.get_payment_processors()
        if site_configuration.client_side_payment_processor \
                and waffle.flag_is_active(self.request, CLIENT_SIDE_CHECKOUT_FLAG_NAME):
            payment_processors_data = self._get_payment_processors_data(
                payment_processors)
            context.update(payment_processors_data)

        # Total benefit displayed in price summary.
        # Currently only one voucher per basket is supported.
        try:
            applied_voucher = self.request.basket.vouchers.first()
            total_benefit = (format_benefit_value(
                applied_voucher.best_offer.benefit)
                             if applied_voucher else None)
        except ValueError:
            total_benefit = None
        num_of_items = self.request.basket.num_items
        context.update({
            'formset_lines_data':
            zip(formset, lines_data),
            'free_basket':
            context['order_total'].incl_tax == 0,
            'homepage_url':
            get_lms_url(''),
            'min_seat_quantity':
            1,
            'max_seat_quantity':
            100,
            'payment_processors':
            payment_processors,
            'total_benefit':
            total_benefit,
            'line_price': (self.request.basket.total_incl_tax_excl_discounts /
                           num_of_items) if num_of_items > 0 else 0
        })
        return context
Пример #55
0
def payments(request, addon_id, addon, webapp=False):
    premium_form = forms_payments.PremiumForm(
        request.POST or None, request=request, addon=addon,
        user=request.amo_user)

    region_form = forms.RegionForm(
        request.POST or None, product=addon, request=request)

    upsell_form = forms_payments.UpsellForm(
        request.POST or None, addon=addon, user=request.amo_user)

    account_list_form = forms_payments.AccountListForm(
        request.POST or None, addon=addon, user=request.amo_user)

    if request.method == 'POST':

        success = all(form.is_valid() for form in
                      [premium_form, region_form, upsell_form,
                       account_list_form])

        if success:
            region_form.save()

            try:
                premium_form.save()
            except client.Error as err:
                success = False
                log.error('Error setting payment information (%s)' % err)
                messages.error(
                    request, _(u'We encountered a problem connecting to the '
                               u'payment server.'))
                raise  # We want to see these exceptions!

            is_free_inapp = addon.premium_type == amo.ADDON_FREE_INAPP
            is_now_paid = (addon.premium_type in amo.ADDON_PREMIUMS
                           or is_free_inapp)

            # If we haven't changed to a free app, check the upsell.
            if is_now_paid and success:
                try:
                    if not is_free_inapp:
                        upsell_form.save()
                    account_list_form.save()
                except client.Error as err:
                    log.error('Error saving payment information (%s)' % err)
                    messages.error(
                        request, _(u'We encountered a problem connecting to '
                                   u'the payment server.'))
                    success = False
                    raise  # We want to see all the solitude errors now.

        # If everything happened successfully, give the user a pat on the back.
        if success:
            messages.success(request, _('Changes successfully saved.'))
            return redirect(addon.get_dev_url('payments'))

    # TODO: refactor this (bug 945267)
    is_packaged = addon.is_packaged
    android_payments_enabled = waffle.flag_is_active(request,
                                                     'android-payments')
    android_packaged_enabled = waffle.flag_is_active(request,
                                                     'android-packaged')
    desktop_packaged_enabled = waffle.flag_is_active(request,
                                                     'desktop-packaged')

    # If android payments is not allowed then firefox os must
    # be 'checked' and android-mobile and android-tablet should not be.
    invalid_paid_platform_state = []

    # If isn't packaged or it is packaged and the android-packaged flag is on
    # then we should check that desktop isn't set to True.
    if not is_packaged or (is_packaged and desktop_packaged_enabled):
        invalid_paid_platform_state.append(('desktop', True))

    if not android_payments_enabled:
        # When android-payments is off...
        # If isn't packaged or it is packaged and the android-packaged flag is on
        # then we should check for the state of android-mobile and android-tablet.
        if not is_packaged or (is_packaged and android_packaged_enabled):
            invalid_paid_platform_state += [('android-mobile', True),
                                            ('android-tablet', True)]
        invalid_paid_platform_state.append(('firefoxos', False))

    cannot_be_paid = (
        addon.premium_type == amo.ADDON_FREE and
        any(premium_form.device_data['free-%s' % x] == y
            for x, y in invalid_paid_platform_state))

    try:
        tier_zero = Price.objects.get(price='0.00', active=True)
        tier_zero_id = tier_zero.pk
    except Price.DoesNotExist:
        tier_zero = None
        tier_zero_id = ''

    # Get the regions based on tier zero. This should be all the
    # regions with payments enabled.
    paid_region_ids_by_slug = []
    if tier_zero:
        paid_region_ids_by_slug = tier_zero.region_ids_by_slug()

    provider = get_provider()
    paid_platform_names = [unicode(platform[1])
                           for platform in PAID_PLATFORMS(request, is_packaged)]

    return render(request, 'developers/payments/premium.html',
                  {'addon': addon, 'webapp': webapp, 'premium': addon.premium,
                   'form': premium_form, 'upsell_form': upsell_form,
                   'tier_zero_id': tier_zero_id, 'region_form': region_form,
                   'DEVICE_LOOKUP': DEVICE_LOOKUP,
                   'is_paid': (addon.premium_type in amo.ADDON_PREMIUMS
                               or addon.premium_type == amo.ADDON_FREE_INAPP),
                   'cannot_be_paid': cannot_be_paid,
                   'paid_platform_names': paid_platform_names,
                   'has_incomplete_status': addon.status == amo.STATUS_NULL,
                   'is_packaged': addon.is_packaged,
                   # Bango values
                   'account_form': provider.forms['account'](),
                   'account_list_form': account_list_form,
                   # Waffles
                   'api_pricelist_url': reverse('price-list'),
                   'payment_methods': {
                       PAYMENT_METHOD_ALL: _('All'),
                       PAYMENT_METHOD_CARD: _('Credit card'),
                       PAYMENT_METHOD_OPERATOR: _('Carrier'),
                   },
                   'all_paid_region_ids_by_slug': paid_region_ids_by_slug,
                   'provider': provider})
Пример #56
0
                               uuid=str(uuid_),
                               price_tier=tier,
                               type=amo.CONTRIB_INAPP_PENDING,
                               paykey=paykey,
                               user=request.amo_user)
        log.debug('Storing in-app payment contrib for uuid: %s' % uuid_)

        # If this was a pre-approval, it's completed already, we'll
        # double check this with PayPal, just to be sure nothing went wrong.
        if status == 'COMPLETED':
            paypal.paypal_log_cef(request, product, uuid_, 'Purchase',
                                  'PURCHASE',
                                  'A user purchased using pre-approval')

            log.debug('Status is completed for uuid: %s' % uuid_)
            if waffle.flag_is_active(request, 'solitude-payments'):
                result = client.post_pay_check(data={'pay_key': paykey})
                if result['status'] == 'COMPLETED':
                    log.debug(
                        'Check in-app payment is completed for uuid: %s' %
                        uuid_)
                    contrib.type = amo.CONTRIB_INAPP
                else:
                    # In this case PayPal disagreed, we should not be trusting
                    # what get_paykey said. Which is a worry.
                    log.error('Check in-app payment failed on uuid: %s' %
                              uuid_)
                    status = 'NOT-COMPLETED'
            else:
                # TODO(solitude): remove this when solitude goes live.
                if paypal.check_purchase(paykey) == 'COMPLETED':
Пример #57
0
    def _create_courseware_context(self, request):
        """
        Returns and creates the rendering context for the courseware.
        Also returns the table of contents for the courseware.
        """
        course_url_name = default_course_url_name(request)
        course_url = reverse(course_url_name,
                             kwargs={'course_id': unicode(self.course.id)})
        courseware_context = {
            'csrf':
            csrf(self.request)['csrf_token'],
            'course':
            self.course,
            'course_url':
            course_url,
            'chapter':
            self.chapter,
            'section':
            self.section,
            'init':
            '',
            'fragment':
            Fragment(),
            'staff_access':
            self.is_staff,
            'masquerade':
            self.masquerade,
            'supports_preview_menu':
            True,
            'studio_url':
            get_studio_url(self.course, 'course'),
            'xqa_server':
            settings.FEATURES.get('XQA_SERVER', "http://your_xqa_server.com"),
            'bookmarks_api_url':
            reverse('bookmarks'),
            'language_preference':
            self._get_language_preference(),
            'disable_optimizely':
            not WaffleSwitchNamespace('RET').is_enabled(
                'enable_optimizely_in_courseware'),
            'section_title':
            None,
            'sequence_title':
            None,
            'disable_accordion':
            waffle.flag_is_active(request, UNIFIED_COURSE_VIEW_FLAG),
            # TODO: (Experimental Code). See https://openedx.atlassian.net/wiki/display/RET/2.+In-course+Verification+Prompts
            'upgrade_link':
            check_and_get_upgrade_link(request, self.effective_user,
                                       self.course.id),
            'upgrade_price':
            get_cosmetic_verified_display_price(self.course),
            # ENDTODO
        }
        table_of_contents = toc_for_course(
            self.effective_user,
            self.request,
            self.course,
            self.chapter_url_name,
            self.section_url_name,
            self.field_data_cache,
        )
        courseware_context['accordion'] = render_accordion(
            self.request,
            self.course,
            table_of_contents['chapters'],
        )

        courseware_context['course_sock_fragment'] = CourseSockFragmentView(
        ).render_to_fragment(request, course=self.course)

        # entrance exam data
        self._add_entrance_exam_to_context(courseware_context)

        # staff masquerading data
        if not is_course_open_for_learner(self.effective_user, self.course):
            # Disable student view button if user is staff and
            # course is not yet visible to students.
            courseware_context['disable_student_access'] = True
            courseware_context['supports_preview_menu'] = False

        if self.section:
            # chromeless data
            if self.section.chrome:
                chrome = [
                    s.strip() for s in self.section.chrome.lower().split(",")
                ]
                if 'accordion' not in chrome:
                    courseware_context['disable_accordion'] = True
                if 'tabs' not in chrome:
                    courseware_context['disable_tabs'] = True

            # default tab
            if self.section.default_tab:
                courseware_context['default_tab'] = self.section.default_tab

            # section data
            courseware_context[
                'section_title'] = self.section.display_name_with_default
            section_context = self._create_section_context(
                table_of_contents['previous_of_active_section'],
                table_of_contents['next_of_active_section'],
            )
            courseware_context['fragment'] = self.section.render(
                STUDENT_VIEW, section_context)
            if self.section.position and self.section.has_children:
                display_items = self.section.get_display_items()
                if display_items:
                    try:
                        courseware_context['sequence_title'] = display_items[self.section.position - 1] \
                            .display_name_with_default
                    except IndexError:
                        log.exception(
                            "IndexError loading courseware for user %s, course %s, section %s, position %d. Total items: %d. URL: %s",
                            self.real_user.username,
                            self.course.id,
                            self.section.display_name_with_default,
                            self.section.position,
                            len(display_items),
                            self.url,
                        )
                        raise
        return courseware_context
Пример #58
0
    def get_table_items(self, request):
        items = []

        enrollment_items = {
            'name':
            _('Enrollment'),
            'icon':
            'fa-child',
            'heading':
            _('Who are my learners?'),
            'items': [
                {
                    'title':
                    ugettext_noop('How many learners are in my course?'),
                    'view': 'courses:enrollment:activity',
                    'breadcrumbs': [_('Activity')],
                    'fragment': '',
                    'scope': 'course',
                    'lens': 'enrollment',
                    'report': 'activity',
                    'depth': ''
                },
                {
                    'title': ugettext_noop('How old are my learners?'),
                    'view': 'courses:enrollment:demographics_age',
                    'breadcrumbs': [_('Demographics'),
                                    _('Age')],
                    'fragment': '',
                    'scope': 'course',
                    'lens': 'enrollment',
                    'report': 'demographics',
                    'depth': 'age'
                },
                {
                    'title':
                    ugettext_noop(
                        'What level of education do my learners have?'),
                    'view':
                    'courses:enrollment:demographics_education',
                    'breadcrumbs': [_('Demographics'),
                                    _('Education')],
                    'fragment':
                    '',
                    'scope':
                    'course',
                    'lens':
                    'enrollment',
                    'report':
                    'demographics',
                    'depth':
                    'education'
                },
                {
                    'title':
                    ugettext_noop('What is the learner gender breakdown?'),
                    'view': 'courses:enrollment:demographics_gender',
                    'breadcrumbs': [_('Demographics'),
                                    _('Gender')],
                    'fragment': '',
                    'scope': 'course',
                    'lens': 'enrollment',
                    'report': 'demographics',
                    'depth': 'gender'
                },
                {
                    'title': ugettext_noop('Where are my learners?'),
                    'view': 'courses:enrollment:geography',
                    'breadcrumbs': [_('Geography')],
                    'fragment': '',
                    'scope': 'course',
                    'lens': 'enrollment',
                    'report': 'geography',
                    'depth': ''
                },
            ],
        }
        items.append(enrollment_items)

        engagement_items = {
            'name':
            _('Engagement'),
            'icon':
            'fa-bar-chart',
            'heading':
            _('What are learners doing in my course?'),
            'items': [{
                'title':
                ugettext_noop(
                    'How many learners are interacting with my course?'),
                'view':
                'courses:engagement:content',
                'breadcrumbs': [_('Content')],
                'fragment':
                '',
                'scope':
                'course',
                'lens':
                'engagement',
                'report':
                'content',
                'depth':
                ''
            }]
        }
        if switch_is_active('enable_engagement_videos_pages'):
            engagement_items['items'].append({
                'title':
                ugettext_noop('How did learners interact with course videos?'),
                'view':
                'courses:engagement:videos',
                'breadcrumbs': [_('Videos')],
                'fragment':
                '',
                'scope':
                'course',
                'lens':
                'engagement',
                'report':
                'videos',
                'depth':
                ''
            })

        items.append(engagement_items)

        if self.course_api_enabled:
            subitems = [{
                'title':
                ugettext_noop(
                    'How are learners doing on graded course assignments?'),
                'view':
                'courses:performance:graded_content',
                'breadcrumbs': [_('Graded Content')],
                'fragment':
                '',
                'scope':
                'course',
                'lens':
                'performance',
                'report':
                'graded',
                'depth':
                ''
            }, {
                'title':
                ugettext_noop('How are learners doing on ungraded exercises?'),
                'view':
                'courses:performance:ungraded_content',
                'breadcrumbs': [_('Ungraded Problems')],
                'fragment':
                '',
                'scope':
                'course',
                'lens':
                'performance',
                'report':
                'ungraded',
                'depth':
                ''
            }]

            if switch_is_active('enable_performance_learning_outcome'):
                subitems.append({
                    'title':
                    ugettext_noop(
                        'What is the breakdown for course learning outcomes?'),
                    'view':
                    'courses:performance:learning_outcomes',
                    'breadcrumbs': [_('Learning Outcomes')],
                    'fragment':
                    '',
                    'scope':
                    'course',
                    'lens':
                    'performance',
                    'report':
                    'outcomes',
                    'depth':
                    ''
                })

            if switch_is_active('enable_problem_response_download'):
                try:
                    info = CourseReportDownloadPresenter(
                        self.course_id).get_report_info(
                            report_name=CourseReportDownloadPresenter.
                            PROBLEM_RESPONSES)
                except NotFoundError:
                    info = {}
                if 'download_url' in info:
                    # A problem response report CSV is available:
                    subitems.append({
                        'title':
                        ugettext_noop(
                            'How are learners responding to questions?'),
                        'view':
                        'courses:csv:performance_problem_responses',
                        'breadcrumbs': [_('Problem Response Report')],
                        'format':
                        'csv',
                    })

            items.append({
                'name':
                _('Performance'),
                'icon':
                'fa-check-square-o',
                'heading':
                _('How are learners doing on course assignments?'),
                'items':
                subitems
            })

        if flag_is_active(request, 'display_learner_analytics'):
            items.append({
                'name':
                _('Learners'),
                'icon':
                'fa-users',
                'heading':
                _('What are individual learners doing?'),
                'items': [
                    {
                        'title': ugettext_noop("Who is engaged? Who isn't?"),
                        'view': 'courses:learners:learners',
                        'breadcrumbs': [_('All Learners')],
                        'fragment': '#?ignore_segments=inactive',
                        'scope': 'course',
                        'lens': 'learners',
                        'report': 'roster',
                        'depth': ''
                    },
                    # TODO: this is commented out until we complete the deep linking work, AN-6671
                    # {
                    #     'title': _('Who has been active recently?'),
                    #     'view': 'courses:learners:learners',  # TODO: map this to the actual action in AN-6205
                    #     # TODO: what would the breadcrumbs be?
                    #     'breadcrumbs': [_('Learners')]
                    # },
                    # {
                    #     'title': _('Who is most engaged in the discussions?'),
                    #     'view': 'courses:learners:learners',  # TODO: map this to the actual action in AN-6205
                    #     # TODO: what would the breadcrumbs be?
                    #     'breadcrumbs': [_('Learners')]
                    # },
                    # {
                    #     'title': _("Who hasn't watched videos recently?"),
                    #     'view': 'courses:learners:learners',  # TODO: map this to the actual action in AN-6205
                    #     # TODO: what would the breadcrumbs be?
                    #     'breadcrumbs': [_('Learners')]
                    # }
                ]
            })

        translate_dict_values(items, ('name', ))
        for item in items:
            translate_dict_values(item['items'], ('title', ))

        return items
Пример #59
0
def pay(request, signed_req, pay_req):
    paykey, status = '', ''
    preapproval = None
    if request.amo_user:
        preapproval = request.amo_user.get_preapproval()
    tier, price, currency = _get_price(pay_req, preapproval=preapproval)

    source = request.POST.get('source', '')
    product = pay_req['_config'].addon
    # L10n: {0} is the product name. {1} is the application name.
    contrib_for = (
        _(u'Firefox Marketplace in-app payment for {0} to {1}').format(
            pay_req['request']['name'], product.name))
    # TODO(solitude): solitude lib will create these for us.
    uuid_ = hashlib.md5(str(uuid.uuid4())).hexdigest()

    if waffle.flag_is_active(request, 'solitude-payments'):
        # TODO(solitude): when the migration of data is completed, we
        # will be able to remove this. Seller data is populated in solitude
        # on submission or devhub changes. If those don't occur, you won't be
        # able to sell at all.
        client.create_seller_for_pay(product)

        complete = reverse('inapp_pay.pay_status',
                           args=[pay_req['_config'].pk, 'complete'])
        cancel = reverse('inapp_pay.pay_status',
                         args=[pay_req['_config'].pk, 'cancel'])

        # TODO(bug 748137): remove retry is False.
        try:
            result = client.pay(
                {
                    'amount': price,
                    'currency': currency,
                    'buyer': request.amo_user,
                    'seller': product,
                    'memo': contrib_for,
                    'complete': complete,
                    'cancel': cancel
                },
                retry=False)
        except client.Error as exc:
            paypal.paypal_log_cef(request, product, uuid_,
                                  'in-app PayKey Failure', 'PAYKEYFAIL',
                                  'There was an error getting the paykey')
            log.error(u'Error getting paykey, in-app payment: %s' %
                      pay_req['_config'].pk,
                      exc_info=True)
            InappPayLog.log(request, 'PAY_ERROR', config=pay_req['_config'])
            return render_error(request, exc)

        #TODO(solitude): just use the dictionary when solitude is live.
        paykey = result.get('pay_key', '')
        status = result.get('status', '')
        uuid_ = result.get('uuid', '')

    else:
        try:
            paykey, status = paypal.get_paykey(
                dict(
                    amount=price,
                    chains=settings.PAYPAL_CHAINS,
                    currency=currency,
                    email=product.paypal_id,
                    ip=request.META.get('REMOTE_ADDR'),
                    memo=contrib_for,
                    pattern='inapp_pay.pay_status',
                    preapproval=preapproval,
                    qs={'realurl': request.POST.get('realurl')},
                    slug=pay_req['_config'].pk,  # passed to pay_done()
                    # via reverse()
                    uuid=uuid_))
        except paypal.PaypalError, exc:
            paypal.paypal_log_cef(request, product, uuid_,
                                  'in-app PayKey Failure', 'PAYKEYFAIL',
                                  'There was an error getting the paykey')
            log.error(u'Error getting paykey, in-app payment: %s' %
                      pay_req['_config'].pk,
                      exc_info=True)
            InappPayLog.log(request, 'PAY_ERROR', config=pay_req['_config'])
            return render_error(request, exc)
Пример #60
0
    def get_context_data(self, **kwargs):
        context = super(BasketSummaryView, self).get_context_data(**kwargs)
        formset = context.get('formset', [])
        lines = context.get('line_list', [])
        lines_data = []
        is_verification_required = is_bulk_purchase = False
        switch_link_text = partner_sku = ''
        basket = self.request.basket
        site = self.request.site
        site_configuration = site.siteconfiguration

        for line in lines:
            course_key = CourseKey.from_string(line.product.attr.course_key)
            course_name = None
            image_url = None
            short_description = None
            try:
                course = get_course_info_from_catalog(self.request.site, course_key)
                try:
                    image_url = course['image']['src']
                except (KeyError, TypeError):
                    image_url = ''
                short_description = course.get('short_description', '')
                course_name = course.get('title', '')
            except (ConnectionError, SlumberBaseException, Timeout):
                logger.exception('Failed to retrieve data from Catalog Service for course [%s].', course_key)

            if self.request.site.siteconfiguration.enable_enrollment_codes:
                # Get variables for the switch link that toggles from enrollment codes and seat.
                switch_link_text, partner_sku = get_basket_switch_data(line.product)
                if line.product.get_product_class().name == ENROLLMENT_CODE_PRODUCT_CLASS_NAME:
                    is_bulk_purchase = True
                    # Iterate on message storage so all messages are marked as read.
                    # This will hide the success messages when a user updates the quantity
                    # for an item in the basket.
                    list(messages.get_messages(self.request))

            if line.has_discount:
                benefit = basket.applied_offers().values()[0].benefit
                benefit_value = format_benefit_value(benefit)
            else:
                benefit_value = None

            lines_data.append({
                'seat_type': self._determine_seat_type(line.product),
                'course_name': course_name,
                'course_key': course_key,
                'image_url': image_url,
                'course_short_description': short_description,
                'benefit_value': benefit_value,
                'enrollment_code': line.product.get_product_class().name == ENROLLMENT_CODE_PRODUCT_CLASS_NAME,
                'line': line,
            })

            user = self.request.user
            context.update({
                'analytics_data': prepare_analytics_data(
                    user,
                    self.request.site.siteconfiguration.segment_key,
                    unicode(course_key)
                ),
                'enable_client_side_checkout': False,
            })

            if site_configuration.client_side_payment_processor \
                    and waffle.flag_is_active(self.request, CLIENT_SIDE_CHECKOUT_FLAG_NAME):
                payment_processor_class = site_configuration.get_client_side_payment_processor_class()

                if payment_processor_class:
                    payment_processor = payment_processor_class(site)

                    context.update({
                        'enable_client_side_checkout': True,
                        'payment_form': PaymentForm(user=user, initial={'basket': basket}, label_suffix=''),
                        'payment_url': payment_processor.client_side_payment_url,
                    })
                else:
                    msg = 'Unable to load client-side payment processor [{processor}] for ' \
                          'site configuration [{sc}]'.format(processor=site_configuration.client_side_payment_processor,
                                                             sc=site_configuration.id)
                    raise SiteConfigurationError(msg)

            # Check product attributes to determine if ID verification is required for this basket
            try:
                is_verification_required = line.product.attr.id_verification_required \
                    and line.product.attr.certificate_type != 'credit'
            except AttributeError:
                pass

        context.update({
            'free_basket': context['order_total'].incl_tax == 0,
            'payment_processors': site_configuration.get_payment_processors(),
            'homepage_url': get_lms_url(''),
            'formset_lines_data': zip(formset, lines_data),
            'is_verification_required': is_verification_required,
            'min_seat_quantity': 1,
            'is_bulk_purchase': is_bulk_purchase,
            'switch_link_text': switch_link_text,
            'partner_sku': partner_sku,
        })

        return context