text: """
  dj-stripe middleware
  
  Refer to SubscriptionPaymentMiddleware docstring for more info.
  """
  import fnmatch
  
  from django.conf import settings
  from django.core.exceptions import ImproperlyConfigured
  from django.shortcuts import redirect
  from django.urls import resolve
  from django.utils.deprecation import MiddlewareMixin
  
  from .settings import SUBSCRIPTION_REDIRECT, subscriber_request_callback
  from .utils import subscriber_has_active_subscription
  
  DJSTRIPE_SUBSCRIPTION_REQUIRED_EXCEPTION_URLS = getattr(
  	settings, "DJSTRIPE_SUBSCRIPTION_REQUIRED_EXCEPTION_URLS", ()
  )
  
  
  # So we don't have crazy long lines of code
  EXEMPT = list(DJSTRIPE_SUBSCRIPTION_REQUIRED_EXCEPTION_URLS)
  EXEMPT.append("[djstripe]")
  
  
  class SubscriptionPaymentMiddleware(MiddlewareMixin):
  	"""
  	Used to redirect users from subcription-locked request destinations.
  
  	Rules:
  
  		* "(app_name)" means everything from this app is exempt
  		* "[namespace]" means everything with this name is exempt
  		* "namespace:name" means this namespaced URL is exempt
  		* "name" means this URL is exempt
  		* The entire djstripe namespace is exempt
  		* If settings.DEBUG is True, then django-debug-toolbar is exempt
  		* A 'fn:' prefix means the rest of the URL is fnmatch'd.
  
  	Example::
  
  		DJSTRIPE_SUBSCRIPTION_REQUIRED_EXCEPTION_URLS = (
  			"[blogs]",  # Anything in the blogs namespace
  			"products:detail",  # A ProductDetail view you want shown to non-payers
  			"home",  # Site homepage
  			"fn:/accounts*",  # anything in the accounts/ URL path
  		)
  	"""
  
  	def process_request(self, request):
  		"""Check the subscriber's subscription status.
  
  		Returns early if request does not outlined in this middleware's docstring.
  		"""
  		if self.is_matching_rule(request):
  			return
  
  		return self.check_subscription(request)
  
  	def is_matching_rule(self, request):
  		"""Check according to the rules defined in the class docstring."""
  		# First, if in DEBUG mode and with django-debug-toolbar, we skip
  		#   this entire process.
  		if settings.DEBUG and request.path.startswith("/__debug__"):
  			return True
  
  		# Second we check against matches
  		match = resolve(request.path, getattr(request, "urlconf", settings.ROOT_URLCONF))
  		if "({0})".format(match.app_name) in EXEMPT:
  			return True
  
  		if "[{0}]".format(match.namespace) in EXEMPT:
  			return True
  
  		if "{0}:{1}".format(match.namespace, match.url_name) in EXEMPT:
  			return True
  
  		if match.url_name in EXEMPT:
  			return True
  
  		# Third, we check wildcards:
  		for exempt in [x for x in EXEMPT if x.startswith("fn:")]:
  			exempt = exempt.replace("fn:", "")
  			if fnmatch.fnmatch(request.path, exempt):
  				return True
  
  		return False
  
  	def check_subscription(self, request):
  		"""Redirect to the subscribe page if the user lacks an active subscription."""
  		subscriber = subscriber_request_callback(request)
  
  		if not subscriber_has_active_subscription(subscriber):
  			if not SUBSCRIPTION_REDIRECT:
  				raise ImproperlyConfigured("DJSTRIPE_SUBSCRIPTION_REDIRECT is not set.")
  			return redirect(SUBSCRIPTION_REDIRECT)
  