mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	billing: Show the billing page only to admins and billing users.
This commit is contained in:
		@@ -12,23 +12,27 @@
 | 
			
		||||
 | 
			
		||||
    <div class="page-content">
 | 
			
		||||
        <h1>{{ _("Billing") }}</h1>
 | 
			
		||||
        Plan<br/>
 | 
			
		||||
        {{ plan_name }}<br/>
 | 
			
		||||
        <br/>
 | 
			
		||||
        You are paying for {{ seat_count }} users.<br/>
 | 
			
		||||
        Your plan will renew on {{ renewal_date }} for ${{ renewal_amount }}.<br/>
 | 
			
		||||
        {% if prorated_charges %}
 | 
			
		||||
        You have ${{ prorated_charges }} in prorated charges that will be
 | 
			
		||||
        added to your next bill.
 | 
			
		||||
        {% elif prorated_credits %}
 | 
			
		||||
        You have ${{ prorated_credits }} in prorated credits that will be
 | 
			
		||||
        automatically applied to your next bill.
 | 
			
		||||
        {% if admin_access %}
 | 
			
		||||
            Plan<br/>
 | 
			
		||||
            {{ plan_name }}<br/>
 | 
			
		||||
            <br/>
 | 
			
		||||
            You are paying for {{ seat_count }} users.<br/>
 | 
			
		||||
            Your plan will renew on {{ renewal_date }} for ${{ renewal_amount }}.<br/>
 | 
			
		||||
            {% if prorated_charges %}
 | 
			
		||||
            You have ${{ prorated_charges }} in prorated charges that will be
 | 
			
		||||
            added to your next bill.
 | 
			
		||||
            {% elif prorated_credits %}
 | 
			
		||||
            You have ${{ prorated_credits }} in prorated credits that will be
 | 
			
		||||
            automatically applied to your next bill.
 | 
			
		||||
            {% endif %}
 | 
			
		||||
            <br/>
 | 
			
		||||
            <br/>
 | 
			
		||||
            Payment method: {{ payment_method }}.<br/>
 | 
			
		||||
            <br/>
 | 
			
		||||
            Contact support@zulipchat.com for billing history or to make changes to your subscription.
 | 
			
		||||
        {% else %}
 | 
			
		||||
            You must be an organization administrator or a billing administrator to view this page.
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        <br/>
 | 
			
		||||
        <br/>
 | 
			
		||||
        Payment method: {{ payment_method }}.<br/>
 | 
			
		||||
        <br/>
 | 
			
		||||
        Contact support@zulipchat.com for billing history or to make changes to your subscription.
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -129,6 +129,37 @@ class StripeTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(response.status_code, 302)
 | 
			
		||||
        self.assertEqual('/billing/', response.url)
 | 
			
		||||
 | 
			
		||||
    @mock.patch("zilencer.lib.stripe.STRIPE_PUBLISHABLE_KEY", "stripe_publishable_key")
 | 
			
		||||
    @mock.patch("zilencer.views.STRIPE_PUBLISHABLE_KEY", "stripe_publishable_key")
 | 
			
		||||
    @mock.patch("stripe.Invoice.upcoming", side_effect=mock_upcoming_invoice)
 | 
			
		||||
    @mock.patch("stripe.Customer.retrieve", side_effect=mock_retrieve_customer)
 | 
			
		||||
    @mock.patch("stripe.Customer.create", side_effect=mock_create_customer)
 | 
			
		||||
    @mock.patch("stripe.Subscription.create", side_effect=mock_create_subscription)
 | 
			
		||||
    def test_billing_page_permissions(self, mock_create_subscription: mock.Mock,
 | 
			
		||||
                                      mock_create_customer: mock.Mock,
 | 
			
		||||
                                      mock_retrieve_customer: mock.Mock,
 | 
			
		||||
                                      mock_upcoming_invoice: mock.Mock) -> None:
 | 
			
		||||
        # Check that non-admins can access /upgrade via /billing, when there is no Customer object
 | 
			
		||||
        self.login(self.example_email('hamlet'))
 | 
			
		||||
        response = self.client_get("/billing/")
 | 
			
		||||
        self.assertEqual(response.status_code, 302)
 | 
			
		||||
        self.assertEqual('/upgrade/', response.url)
 | 
			
		||||
        # Check that non-admins can sign up and pay
 | 
			
		||||
        self.client_post("/upgrade/", {'stripeToken': self.token,
 | 
			
		||||
                                       'seat_count': self.quantity,
 | 
			
		||||
                                       'plan': Plan.CLOUD_ANNUAL})
 | 
			
		||||
        # Check that the non-admin hamlet can still access /billing
 | 
			
		||||
        response = self.client_get("/billing/")
 | 
			
		||||
        self.assert_in_success_response(["Contact support@zulipchat.com for billing"], response)
 | 
			
		||||
        # Check admins can access billing, even though they are not the billing_user
 | 
			
		||||
        self.login(self.example_email('iago'))
 | 
			
		||||
        response = self.client_get("/billing/")
 | 
			
		||||
        self.assert_in_success_response(["Contact support@zulipchat.com for billing"], response)
 | 
			
		||||
        # Check that non-admin, non-billing_user does not have access
 | 
			
		||||
        self.login(self.example_email("cordelia"))
 | 
			
		||||
        response = self.client_get("/billing/")
 | 
			
		||||
        self.assert_in_success_response(["You must be an organization administrator"], response)
 | 
			
		||||
 | 
			
		||||
    @mock.patch("zilencer.lib.stripe.STRIPE_PUBLISHABLE_KEY", "stripe_publishable_key")
 | 
			
		||||
    @mock.patch("zilencer.views.STRIPE_PUBLISHABLE_KEY", "stripe_publishable_key")
 | 
			
		||||
    @mock.patch("stripe.Customer.create", side_effect=mock_create_customer)
 | 
			
		||||
 
 | 
			
		||||
@@ -199,10 +199,10 @@ def billing_home(request: HttpRequest) -> HttpResponse:
 | 
			
		||||
    if customer is None:
 | 
			
		||||
        return HttpResponseRedirect(reverse('zilencer.views.initial_upgrade'))
 | 
			
		||||
 | 
			
		||||
    # TODO
 | 
			
		||||
    # if not user.is_realm_admin and not user == customer.billing_user:
 | 
			
		||||
        # context['error_message'] = _("You must be an administrator to view this page.")
 | 
			
		||||
        # return render(request, 'zilencer/billing.html', context=context)
 | 
			
		||||
    if not user.is_realm_admin and not user == customer.billing_user:
 | 
			
		||||
        context = {'admin_access': False}  # type: Dict[str, Any]
 | 
			
		||||
        return render(request, 'zilencer/billing.html', context=context)
 | 
			
		||||
    context = {'admin_access': True}
 | 
			
		||||
 | 
			
		||||
    stripe_customer = get_stripe_customer(customer.stripe_customer_id)
 | 
			
		||||
 | 
			
		||||
@@ -230,7 +230,7 @@ def billing_home(request: HttpRequest) -> HttpResponse:
 | 
			
		||||
    if source is not None:
 | 
			
		||||
        payment_method = "Card ending in %(last4)s" % {'last4': source.last4}
 | 
			
		||||
 | 
			
		||||
    context = {
 | 
			
		||||
    context.update({
 | 
			
		||||
        'plan_name': plan_name,
 | 
			
		||||
        'seat_count': seat_count,
 | 
			
		||||
        'renewal_date': renewal_date,
 | 
			
		||||
@@ -238,6 +238,6 @@ def billing_home(request: HttpRequest) -> HttpResponse:
 | 
			
		||||
        'payment_method': payment_method,
 | 
			
		||||
        'prorated_charges': '{:,.2f}'.format(prorated_charges),
 | 
			
		||||
        'prorated_credits': '{:,.2f}'.format(prorated_credits),
 | 
			
		||||
    }  # type: Dict[str, Any]
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    return render(request, 'zilencer/billing.html', context=context)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user