diff --git a/app/settings.py b/app/settings.py
index c89b4b4..dda8222 100644
--- a/app/settings.py
+++ b/app/settings.py
@@ -72,6 +72,7 @@ TEMPLATES = [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
+ "core.util.django_settings_export.settings_export",
],
},
},
diff --git a/core/models.py b/core/models.py
index 4fc3bf9..a78614f 100644
--- a/core/models.py
+++ b/core/models.py
@@ -1,6 +1,7 @@
import logging
import stripe
+from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.db import models
@@ -35,25 +36,29 @@ class User(AbstractUser):
"""
Override the save function to create a Stripe customer.
"""
- if not self.stripe_id: # stripe ID not stored
- self.stripe_id = get_or_create(self.email, self.first_name, self.last_name)
-
- to_update = {}
- if self.email != self._original.email:
- to_update["email"] = self.email
- if self.first_name != self._original.first_name:
- to_update["first_name"] = self.first_name
- if self.last_name != self._original.last_name:
- to_update["last_name"] = self.last_name
-
- update_customer_fields(self.stripe_id, **to_update)
+ if settings.STRIPE_ENABLED:
+ if not self.stripe_id: # stripe ID not stored
+ self.stripe_id = get_or_create(
+ self.email, self.first_name, self.last_name
+ )
+
+ to_update = {}
+ if self.email != self._original.email:
+ to_update["email"] = self.email
+ if self.first_name != self._original.first_name:
+ to_update["first_name"] = self.first_name
+ if self.last_name != self._original.last_name:
+ to_update["last_name"] = self.last_name
+
+ update_customer_fields(self.stripe_id, **to_update)
super().save(*args, **kwargs)
def delete(self, *args, **kwargs):
- if self.stripe_id:
- stripe.Customer.delete(self.stripe_id)
- logger.info(f"Deleted Stripe customer {self.stripe_id}")
+ if settings.STRIPE_ENABLED:
+ if self.stripe_id:
+ stripe.Customer.delete(self.stripe_id)
+ logger.info(f"Deleted Stripe customer {self.stripe_id}")
super().delete(*args, **kwargs)
def has_plan(self, plan):
diff --git a/core/templates/base.html b/core/templates/base.html
index ad1acf9..7843324 100644
--- a/core/templates/base.html
+++ b/core/templates/base.html
@@ -201,10 +201,12 @@
Home
- {% if user.is_authenticated %}
-
- Billing
-
+ {% if settings.STRIPE_ENABLED %}
+ {% if user.is_authenticated %}
+
+ Billing
+
+ {% endif %}
{% endif %}
{% if user.is_superuser %}
diff --git a/core/util/django_settings_export.py b/core/util/django_settings_export.py
new file mode 100644
index 0000000..2649e22
--- /dev/null
+++ b/core/util/django_settings_export.py
@@ -0,0 +1,78 @@
+"""
+Export Django settings to templates
+
+https://github.com/jakubroztocil/django-settings-export
+
+"""
+from django.conf import settings as django_settings
+from django.core.exceptions import ImproperlyConfigured
+
+
+__version__ = '1.2.1'
+
+
+VARIABLE_NAME = getattr(django_settings,
+ 'SETTINGS_EXPORT_VARIABLE_NAME',
+ 'settings')
+
+
+class SettingsExportError(ImproperlyConfigured):
+ """Base error indicating misconfiguration."""
+
+
+class UndefinedSettingError(SettingsExportError):
+ """An undefined setting name included in SETTINGS_EXPORT."""
+
+
+class UnexportedSettingError(SettingsExportError):
+ """An unexported setting has been accessed from a template."""
+
+
+def settings_export(request):
+ """
+ The template context processor that adds settings defined in
+ `SETTINGS_EXPORT` to the context. If SETTINGS_EXPORT_VARIABLE_NAME is not
+ set, the context variable will be `settings`.
+
+ """
+ variable_name = getattr(django_settings,
+ 'SETTINGS_EXPORT_VARIABLE_NAME',
+ 'settings')
+ return {
+ variable_name: _get_exported_settings()
+ }
+
+
+class ExportedSettings(dict):
+
+ def __getitem__(self, item):
+ """Fail loudly if accessing a setting that is not exported."""
+ try:
+ return super(ExportedSettings, self).__getitem__(item)
+ except KeyError:
+ if hasattr(self, item):
+ # Let the KeyError propagate so that Django templates
+ # can access the existing attribute (e.g. `items()`).
+ raise
+ raise UnexportedSettingError(
+ 'The `{key}` setting key is not accessible'
+ ' from templates: add "{key}" to'
+ ' `settings.SETTINGS_EXPORT` to change that.'
+ .format(key=item)
+ )
+
+
+def _get_exported_settings():
+ exported_settings = ExportedSettings()
+ for key in getattr(django_settings, 'SETTINGS_EXPORT', []):
+ try:
+ value = getattr(django_settings, key)
+ except AttributeError:
+ raise UndefinedSettingError(
+ '"settings.%s" is included in settings.SETTINGS_EXPORT '
+ 'but it does not exist. '
+ % key
+ )
+ exported_settings[key] = value
+ return exported_settings
+
diff --git a/core/views/base.py b/core/views/base.py
index 250aa48..777ca03 100644
--- a/core/views/base.py
+++ b/core/views/base.py
@@ -30,6 +30,8 @@ class Billing(LoginRequiredMixin, View):
template_name = "billing.html"
async def get(self, request):
+ if not settings.STRIPE_ENABLED:
+ return redirect(reverse("home"))
plans = await sync_to_async(list)(Plan.objects.all())
user_plans = await sync_to_async(list)(request.user.plans.all())
context = {"plans": plans, "user_plans": user_plans}
@@ -38,6 +40,8 @@ class Billing(LoginRequiredMixin, View):
class Order(LoginRequiredMixin, View):
async def get(self, request, plan_name):
+ if not settings.STRIPE_ENABLED:
+ return redirect(reverse("home"))
plan = Plan.objects.get(name=plan_name)
try:
cast = {
@@ -63,6 +67,8 @@ class Order(LoginRequiredMixin, View):
class Cancel(LoginRequiredMixin, View):
async def get(self, request, plan_name):
+ if not settings.STRIPE_ENABLED:
+ return redirect(reverse("home"))
plan = Plan.objects.get(name=plan_name)
try:
subscriptions = stripe.Subscription.list(
@@ -88,6 +94,8 @@ class Signup(CreateView):
class Portal(LoginRequiredMixin, View):
async def get(self, request):
+ if not settings.STRIPE_ENABLED:
+ return redirect(reverse("home"))
session = stripe.billing_portal.Session.create(
customer=request.user.stripe_id,
return_url=request.build_absolute_uri(reverse("billing")),
diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml
index 1540e86..739cae9 100644
--- a/docker/docker-compose.prod.yml
+++ b/docker/docker-compose.prod.yml
@@ -9,8 +9,8 @@ services:
# - ${PORTAINER_GIT_DIR}/docker/prod/uwsgi.ini:/conf/uwsgi.ini
- ${APP_LOCAL_SETTINGS}:/code/app/local_settings.py
- ${APP_DATABASE_FILE}:/code/db.sqlite3
- ports:
- - "8000:8000" # uwsgi socket
+ #ports:
+ # - "8000:8000" # uwsgi socket
env_file:
- ../stack.env
volumes_from: