# Path: boardinghouse/exceptions.py
# class Forbidden(Exception):
#     """
#     An exception that will be raised when an attempt to activate a non-valid
#     schema is made.
#     """
# 
# class TemplateSchemaActivation(Forbidden):
#     """
#     An exception that will be raised when a user attempts to activate
#     the settings.TEMPLATE_SCHEMA schema.
#     """
#     def __init__(self, *args, **kwargs):
#         super(TemplateSchemaActivation, self).__init__(
#             'Activating template schema forbidden.', *args, **kwargs
#         )
# 
# class SchemaNotFound(Exception):
#     """
#     An exception that is raised when an attempt to activate a schema that
#     is not in the database is made.
#     """
# 
# Path: boardinghouse/schema.py
# def activate_schema(schema_name):
#     """
#     Activate the current schema: this will execute, in the database
#     connection, something like:
# 
#     .. code:: sql
# 
#         SET search_path TO "foo",public;
# 
#     It sends signals before and after that the schema will be, and was
#     activated.
# 
#     Must be passed a string: the internal name of the schema to activate.
#     """
#     from .signals import schema_pre_activate, schema_post_activate
# 
#     if schema_name == settings.TEMPLATE_SCHEMA:
#         raise TemplateSchemaActivation()
# 
#     schema_pre_activate.send(sender=None, schema_name=schema_name)
#     _set_search_path(schema_name)
#     found_schema = _get_search_path()
#     if found_schema != schema_name:
#         raise SchemaNotFound('Schema activation failed. Expected "{0}", saw "{1}"'.format(
#             schema_name, found_schema,
#         ))
#     schema_post_activate.send(sender=None, schema_name=schema_name)
#     _thread_locals.schema = schema_name
# 
# def deactivate_schema(schema=None):
#     """
#     Deactivate the provided (or current) schema.
#     """
#     from .signals import schema_pre_activate, schema_post_activate
# 
#     cursor = connection.cursor()
#     schema_pre_activate.send(sender=None, schema_name=None)
#     cursor.execute('SET search_path TO "$user",{0}'.format(settings.PUBLIC_SCHEMA))
#     schema_post_activate.send(sender=None, schema_name=None)
#     _thread_locals.schema = None
#     cursor.close()
# 
# Path: boardinghouse/signals.py



import logging
import re
from django.conf import settings
from django.contrib import messages
from django.db import ProgrammingError
from django.http import (
    HttpResponse, HttpResponseForbidden, HttpResponseRedirect,
)
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
from .exceptions import Forbidden, TemplateSchemaActivation, SchemaNotFound
from .schema import activate_schema, deactivate_schema
from .signals import session_requesting_schema_change, session_schema_changed
    if schema == session.get('schema'):
        return

    # Valid schema providers should listen for this signal, and do one of three
    # things: return an object that has a 'schema' attribute, return None, or
    # raise an exception. Returning an object with an attribute of 'schema' will
    # cause no further handlers to run. Returning None or False will cause the next
    # handler to attempt to find a valid schema, and raising an exception will
    # bubble up the call stack.
    for handler, response in session_requesting_schema_change.send(
        sender=request,
        schema=schema,
        user=user,
        session=session
    ):
        if response:
            if hasattr(response, 'schema'):
                session.update({
                    'schema': response.schema,
                    'schema_name': getattr(response, 'name', None),
                })
            if isinstance(response, dict) and 'schema' in response:
                session.update({
                    'schema': response['schema'],
                    'schema_name': response.get('name'),
                })
            break
    else:
        # If no receivers stepped forwards to say they could handle it, that means
        # this user/session is not permitted to change to that schema.

# Path: boardinghouse/exceptions.py
# class Forbidden(Exception):
#     """
#     An exception that will be raised when an attempt to activate a non-valid
#     schema is made.
#     """
# 
# class TemplateSchemaActivation(Forbidden):
#     """
#     An exception that will be raised when a user attempts to activate
#     the settings.TEMPLATE_SCHEMA schema.
#     """
#     def __init__(self, *args, **kwargs):
#         super(TemplateSchemaActivation, self).__init__(
#             'Activating template schema forbidden.', *args, **kwargs
#         )
# 
# class SchemaNotFound(Exception):
#     """
#     An exception that is raised when an attempt to activate a schema that
#     is not in the database is made.
#     """
# 
# Path: boardinghouse/schema.py
# def activate_schema(schema_name):
#     """
#     Activate the current schema: this will execute, in the database
#     connection, something like:
# 
#     .. code:: sql
# 
#         SET search_path TO "foo",public;
# 
#     It sends signals before and after that the schema will be, and was
#     activated.
# 
#     Must be passed a string: the internal name of the schema to activate.
#     """
#     from .signals import schema_pre_activate, schema_post_activate
# 
#     if schema_name == settings.TEMPLATE_SCHEMA:
#         raise TemplateSchemaActivation()
# 
#     schema_pre_activate.send(sender=None, schema_name=schema_name)
#     _set_search_path(schema_name)
#     found_schema = _get_search_path()
#     if found_schema != schema_name:
#         raise SchemaNotFound('Schema activation failed. Expected "{0}", saw "{1}"'.format(
#             schema_name, found_schema,
#         ))
#     schema_post_activate.send(sender=None, schema_name=schema_name)
#     _thread_locals.schema = schema_name
# 
# def deactivate_schema(schema=None):
#     """
#     Deactivate the provided (or current) schema.
#     """
#     from .signals import schema_pre_activate, schema_post_activate
# 
#     cursor = connection.cursor()
#     schema_pre_activate.send(sender=None, schema_name=None)
#     cursor.execute('SET search_path TO "$user",{0}'.format(settings.PUBLIC_SCHEMA))
#     schema_post_activate.send(sender=None, schema_name=None)
#     _thread_locals.schema = None
#     cursor.close()
# 
# Path: boardinghouse/signals.py



# Path: boardinghouse/middleware.py
import logging
import re
from django.conf import settings
from django.contrib import messages
from django.db import ProgrammingError
from django.http import (
    HttpResponse, HttpResponseForbidden, HttpResponseRedirect,
)
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
from .exceptions import Forbidden, TemplateSchemaActivation, SchemaNotFound
from .schema import activate_schema, deactivate_schema
from .signals import session_requesting_schema_change, session_schema_changed

    if schema == session.get('schema'):
        return

    # Valid schema providers should listen for this signal, and do one of three
    # things: return an object that has a 'schema' attribute, return None, or
    # raise an exception. Returning an object with an attribute of 'schema' will
    # cause no further handlers to run. Returning None or False will cause the next
    # handler to attempt to find a valid schema, and raising an exception will
    # bubble up the call stack.
    for handler, response in session_requesting_schema_change.send(
        sender=request,
        schema=schema,
        user=user,
        session=session
    ):
        if response:
            if hasattr(response, 'schema'):
                session.update({
                    'schema': response.schema,
                    'schema_name': getattr(response, 'name', None),
                })
            if isinstance(response, dict) and 'schema' in response:
                session.update({
                    'schema': response['schema'],
                    'schema_name': response.get('name'),
                })
            break
    else:
        # If no receivers stepped forwards to say they could handle it, that means
        # this user/session is not permitted to change to that schema.

        raise Forbidden()