pax_global_header 0000666 0000000 0000000 00000000064 14546353137 0014525 g ustar 00root root 0000000 0000000 52 comment=2d75dc38e402630a40fe279d7c629c6096e2b695
python-django-crum-0.7.9/ 0000775 0000000 0000000 00000000000 14546353137 0015267 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/.coveragerc 0000664 0000000 0000000 00000001047 14546353137 0017412 0 ustar 00root root 0000000 0000000 [run]
branch = True
omit =
parallel = True
data_file = .coverage${TOX_ENV_NAME}
[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover
# Don't complain about missing debug-only code:
def __repr__
if self\.debug
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
# Don't complain if non-runnable code isn't run:
if 0:
if __name__ == .__main__.:
ignore_errors = True
python-django-crum-0.7.9/.github/ 0000775 0000000 0000000 00000000000 14546353137 0016627 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/.github/workflows/ 0000775 0000000 0000000 00000000000 14546353137 0020664 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/.github/workflows/test.yml 0000664 0000000 0000000 00000001246 14546353137 0022371 0 ustar 00root root 0000000 0000000 ---
name: test
on:
push:
pull_request:
schedule:
- cron: '0 9 9 * *'
defaults:
run:
shell: bash
jobs:
test-tox:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install requirements
run: |
python -m pip install -U pip
python -m pip install -U setuptools
make requirements
- name: Test with Tox
run: tox
python-django-crum-0.7.9/.gitignore 0000664 0000000 0000000 00000000131 14546353137 0017252 0 ustar 00root root 0000000 0000000 _build
build
dist
reports
*.egg-info
*.pyc
*.pyo
.coverage*
.pytest_cache
.tox
*.sqlite3
python-django-crum-0.7.9/LICENSE 0000664 0000000 0000000 00000002747 14546353137 0016306 0 ustar 00root root 0000000 0000000 Copyright (c) 2020 Nine More Minutes, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of Nine More Minutes, Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
python-django-crum-0.7.9/MANIFEST.in 0000664 0000000 0000000 00000000140 14546353137 0017020 0 ustar 00root root 0000000 0000000 recursive-include crum *.py
include LICENSE
include README.rst
recursive-exclude test_project *
python-django-crum-0.7.9/Makefile 0000664 0000000 0000000 00000003503 14546353137 0016730 0 ustar 00root root 0000000 0000000 PYTHON_MAJOR_MINOR := $(shell python -c "import sys; print('{0}{1}'.format(*sys.version_info))")
REQUIREMENTS_TXT = requirements/dev$(PYTHON_MAJOR_MINOR).txt
.PHONY: core-requirements
core-requirements:
pip install pip setuptools pip-tools
.PHONY: update-requirements
update-requirements: core-requirements
pip install -U pip setuptools pip-tools
pip-compile -U requirements/dev.in -o $(REQUIREMENTS_TXT)
.PHONY: requirements
requirements: core-requirements
pip-sync $(REQUIREMENTS_TXT)
.PHONY: clean-pyc
clean-pyc: requirements
find . -iname "*.pyc" -delete
find . -iname __pycache__ | xargs rm -rf
.PHONY: tox-update-requirements
tox-update-requirements: clean-pyc
tox -c requirements/tox.ini
.PHONY: develop
develop: clean-pyc
python setup.py develop
.PHONY: check
check: develop
python manage.py check
.PHONY: migrate
migrate: check
python manage.py migrate --noinput
.PHONY: runserver
runserver: migrate
python manage.py runserver
reports:
mkdir -p $@
.PHONY: pycodestyle
pycodestyle: reports requirements
set -o pipefail && $@ | tee reports/$@.report
.PHONY: flake8
flake8: reports requirements
set -o pipefail && $@ | tee reports/$@.report
.PHONY: check8
check8: pycodestyle flake8
.PHONY: test
test: clean-pyc
python setup.py test
.PHONY: clean-tox
clean-tox:
rm -rf .tox
rm -rf .coveragepy*
.PHONY: tox
tox: clean-pyc
tox
.PHONY: tox-parallel
tox-parallel: clean-pyc
tox -p auto
.PHONY: clean-all
clean-all: clean-pyc clean-tox
rm -rf *.egg-info .eggs .cache .coverage build reports
.PHONY: bump-major
bump-major: requirements
bumpversion major
.PHONY: bump-minor
bump-minor: requirements
bumpversion minor
.PHONY: bump-patch
bump-patch: requirements
bumpversion patch
.PHONY: docs
docs: requirements
python setup.py build_sphinx
.PHONY: ship-it
ship-it: requirements clean-pyc
python setup.py ship_it
python-django-crum-0.7.9/README.rst 0000664 0000000 0000000 00000003557 14546353137 0016770 0 ustar 00root root 0000000 0000000 |Build Status| |PyPI Version| |PyPI License| |Python Versions| |Django Versions| |Read the Docs|
Django-CRUM
===========
Django-CRUM (Current Request User Middleware) captures the current request and
user in thread local storage.
It enables apps to check permissions, capture audit trails or otherwise access
the current request and user without requiring the request object to be passed
directly. It also offers a context manager to allow for temporarily
impersonating another user.
It provides a signal to extend the built-in function for getting the current
user, which could be helpful when using custom authentication methods or user
models.
Documentation can be found at `RTFD `_.
It is tested against:
* Django 1.11 (Python 3.5 and 3.6)
* Django 2.0 (Python 3.5, 3.6 and 3.7)
* Django 2.1 (Python 3.5, 3.6 and 3.7)
* Django 2.2 (Python 3.5, 3.6, 3.7, 3.8 and 3.9)
* Django 3.0 (Python 3.6, 3.7, 3.8 and 3.9)
* Django 3.1 (Python 3.6, 3.7, 3.8 and 3.9)
* Django master/3.2 (Python 3.6, 3.7, 3.8 and 3.9)
.. |Build Status| image:: https://img.shields.io/github/workflow/status/ninemoreminutes/django-crum/test
:target: https://github.com/ninemoreminutes/django-crum/actions?query=workflow%3Atest
.. |PyPI Version| image:: https://img.shields.io/pypi/v/django-crum.svg
:target: https://pypi.python.org/pypi/django-crum/
.. |PyPI License| image:: https://img.shields.io/pypi/l/django-crum.svg
:target: https://pypi.python.org/pypi/django-crum/
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/django-crum.svg
:target: https://pypi.python.org/pypi/django-crum/
.. |Django Versions| image:: https://img.shields.io/pypi/djversions/django-crum.svg
:target: https://pypi.org/project/django-crum/
.. |Read the Docs| image:: https://img.shields.io/readthedocs/django-crum.svg
:target: http://django-crum.readthedocs.io/
python-django-crum-0.7.9/crum/ 0000775 0000000 0000000 00000000000 14546353137 0016235 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/crum/__init__.py 0000664 0000000 0000000 00000006233 14546353137 0020352 0 ustar 00root root 0000000 0000000 # Python
import contextlib
import logging
import threading
_thread_locals = threading.local()
_logger = logging.getLogger('crum')
__version__ = '0.7.9'
__all__ = ['get_current_request', 'get_current_user', 'impersonate']
@contextlib.contextmanager
def impersonate(user=None):
"""
Temporarily impersonate the given user for audit trails.
"""
try:
current_user = get_current_user(_return_false=True)
set_current_user(user)
yield user
finally:
set_current_user(current_user)
def get_current_request():
"""
Return the request associated with the current thread.
"""
return getattr(_thread_locals, 'request', None)
def set_current_request(request=None):
"""
Update the request associated with the current thread.
"""
_thread_locals.request = request
# Clear the current user if also clearing the request.
if not request:
set_current_user(False)
def get_current_user(_return_false=False):
"""
Return the user associated with the current request thread.
"""
from crum.signals import current_user_getter
top_priority = -9999
top_user = False if _return_false else None
results = current_user_getter.send_robust(get_current_user)
for receiver, response in results:
priority = 0
if isinstance(response, Exception):
_logger.exception('%r raised exception: %s', receiver, response)
continue
elif isinstance(response, (tuple, list)) and response:
user = response[0]
if len(response) > 1:
priority = response[1]
elif response or response in (None, False):
user = response
else:
_logger.error('%r returned invalid response: %r', receiver,
response)
continue
if user is not False:
if priority > top_priority:
top_priority = priority
top_user = user
return top_user
def set_current_user(user=None):
"""
Update the user associated with the current request thread.
"""
from crum.signals import current_user_setter
results = current_user_setter.send_robust(set_current_user, user=user)
for receiver, response in results:
if isinstance(response, Exception):
_logger.exception('%r raised exception: %s', receiver, response)
class CurrentRequestUserMiddleware(object):
"""
Middleware to capture the request and user from the current thread.
"""
def __init__(self, get_response=None):
self.get_response = get_response
def __call__(self, request): # pragma: no cover
response = self.process_request(request)
try:
response = self.get_response(request)
except Exception as e:
self.process_exception(request, e)
raise
return self.process_response(request, response)
def process_request(self, request):
set_current_request(request)
def process_response(self, request, response):
set_current_request(None)
return response
def process_exception(self, request, exception):
set_current_request(None)
python-django-crum-0.7.9/crum/signals.py 0000664 0000000 0000000 00000002673 14546353137 0020257 0 ustar 00root root 0000000 0000000 # Django
from django.dispatch import Signal, receiver
__all__ = ['current_user_getter']
# Signal used when getting current user. Receivers should return a tuple of
# (user, priority).
current_user_getter = Signal()
# Signal used when setting current user. Takes one keyword argument: 'user'.
# Receivers should store the current user as needed. Return values are ignored.
current_user_setter = Signal()
@receiver(current_user_getter)
def _get_current_user_from_request(sender, **kwargs):
"""
Signal handler to retrieve current user from request.
"""
from crum import get_current_request
return (getattr(get_current_request(), 'user', False), -10)
@receiver(current_user_getter)
def _get_current_user_from_thread_locals(sender, **kwargs):
"""
Signal handler to retrieve current user from thread locals.
"""
from crum import _thread_locals
return (getattr(_thread_locals, 'user', False), 10)
@receiver(current_user_setter)
def _set_current_user_on_request(sender, **kwargs):
"""
Signal handler to store current user to request.
"""
from crum import get_current_request
request = get_current_request()
if request:
request.user = kwargs['user']
@receiver(current_user_setter)
def _set_current_user_on_thread_locals(sender, **kwargs):
"""
Signal handler to store current user on thread locals.
"""
from crum import _thread_locals
_thread_locals.user = kwargs['user']
python-django-crum-0.7.9/docs/ 0000775 0000000 0000000 00000000000 14546353137 0016217 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/docs/Makefile 0000664 0000000 0000000 00000015176 14546353137 0017671 0 ustar 00root root 0000000 0000000 # Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make ' where is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Django-CRUM.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Django-CRUM.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/Django-CRUM"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Django-CRUM"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
python-django-crum-0.7.9/docs/conf.py 0000664 0000000 0000000 00000017517 14546353137 0017531 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# Django-CRUM documentation build configuration file, created by
# sphinx-quickstart on Sat Jul 6 00:44:15 2013.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Django-CRUM'
copyright = u'2018, Nine More Minutes, Inc.'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.7.9'
# The full version, including alpha/beta/rc tags.
release = '0.7.9'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'Django-CRUMdoc'
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'Django-CRUM.tex', u'Django-CRUM Documentation',
u'Nine More Minutes, Inc.', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'django-crum', u'Django-CRUM Documentation',
[u'Nine More Minutes, Inc.'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'Django-CRUM', u'Django-CRUM Documentation',
u'Nine More Minutes, Inc.', 'Django-CRUM', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
python-django-crum-0.7.9/docs/index.rst 0000664 0000000 0000000 00000014406 14546353137 0020065 0 ustar 00root root 0000000 0000000 .. Django-CRUM documentation master file, created by
sphinx-quickstart on Sat Jul 6 00:44:15 2013.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Django-CRUM
===========
**Django-CRUM (Current Request User Middleware)** captures the current request
and user in thread local storage.
It enables apps to check permissions, capture audit trails or otherwise access
the current request and user without requiring the request object to be passed
directly. It also offers a context manager to allow for temporarily
impersonating another user.
It provides a signal to extend the built-in function for getting the current
user, which could be helpful when using custom authentication methods or user
models.
It is tested against:
* Django 1.11 (Python 3.5 and 3.6)
* Django 2.0 (Python 3.5, 3.6 and 3.7)
* Django 2.1 (Python 3.5, 3.6 and 3.7)
* Django 2.2 (Python 3.5, 3.6, 3.7, 3.8 and 3.9)
* Django 3.0 (Python 3.6, 3.7, 3.8 and 3.9)
* Django 3.1 (Python 3.6, 3.7, 3.8 and 3.9)
* Django master/3.2 (Python 3.6, 3.7, 3.8 and 3.9)
Installation
------------
Install the application from PYPI::
pip install django-crum
Add ``CurrentRequestUserMiddleware`` to your
``MIDDLEWARE`` setting::
MIDDLEWARE += ('crum.CurrentRequestUserMiddleware',)
*That's it!*
Usage
-----
The `crum` package exports three functions as its public API.
get_current_request()
~~~~~~~~~~~~~~~~~~~~~
``get_current_request`` returns the current request instance, or ``None`` if
called outside the scope of a request.
For example, the ``Comment`` model below overrides its ``save`` method to track
the IP address of each commenter::
from django.db import models
from crum import get_current_request
class Comment(models.Model):
created = models.DateTimeField(auto_now_add=True)
comment = models.TextField()
remote_addr = models.CharField(blank=True, default='')
def save(self, *args, **kwargs):
request = get_current_request()
if request and not self.remote_addr:
self.remote_addr = request.META['REMOTE_ADDR']
super(Comment, self).save(*args, **kwargs)
get_current_user()
~~~~~~~~~~~~~~~~~~
``get_current_user`` returns the user associated with the current request, or
``None`` if no user is available.
If using the built-in ``User`` model from ``django.contrib.auth``, the returned
value may be the special ``AnonymousUser``, which won't have a primary key.
For example, the ``Thing`` model below records the user who created it as well
as the last user who modified it::
from django.db import models
from crum import get_current_user
class Thing(models.Model):
created = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey('auth.User', blank=True, null=True,
default=None)
modified = models.DateTimeField(auto_now=True)
modified_by = models.ForeignKey('auth.User', blank=True, null=True,
default=None)
def save(self, *args, **kwargs):
user = get_current_user()
if user and not user.pk:
user = None
if not self.pk:
self.created_by = user
self.modified_by = user
super(Thing, self).save(*args, **kwargs)
impersonate(user=None)
~~~~~~~~~~~~~~~~~~~~~~
``impersonate`` is a context manager used to temporarily change the current
user as returned by ``get_current_user``. It is typically used to perform an
action on behalf of a user or disable the default behavior of
``get_current_user``.
For example, a background task may need to create or update ``Thing`` objects
when there is no active request or user (such as from a management command)::
from crum import impersonate
def create_thing_for_user(user):
with impersonate(user):
# This Thing will indicated it was created by the given user.
user_thing = Thing.objects.create()
# But this Thing won't have a created_by user.
other_thing = Thing.objects.create()
When running from within a view, ``impersonate`` may be used to prevent certain
actions from being attributed to the requesting user::
from django.template.response import TemplateResponse
from crum import impersonate
def get_my_things(request):
# Whenever this view is accessed, trigger some cleanup of Things.
with impersonate(None):
Thing.objects.cleanup()
my_things = Thing.objects.filter(created_by=request.user)
return TemplateResponse(request, 'my_things.html',
{'things': my_things})
Signals
-------
(New in 0.6.0) The `crum` package provides a signal to extend the capabilities
of the `get_current_user()` function.
current_user_getter
~~~~~~~~~~~~~~~~~~~
The ``current_user_getter`` signal is dispatched for each call to
``get_current_user()``. Receivers for this signal should return a tuple of
``(user, priority)``. Receivers should return ``None`` for the user when there
is no current user set, or ``False`` when they can not determine the current
user.
The priority value which will be used to determine which response contains the
current user. The response with the highest priority will be used as long as
the user returned is not ``False``, otherwise lower-priority responses will
be used in order of next-highest priority. Built-in receivers for this signal
use priorities of -10 (current request) and +10 (thread locals); any custom
receivers should usually use -10 < priority < 10.
The following example demonstrates how a custom receiver could be implemented
to determine the current user from an auth token passed via an HTTP header::
from django.dispatch import receiver
from crum import get_current_request
from crum.signals import current_user_getter
@receiver(current_user_getter)
def (sender, **kwargs):
request = get_current_request()
if request:
token = request.META.get('HTTP_AUTH_TOKEN', None)
try:
auth_token = AuthToken.objects.get(token=token)
return (auth_token.user, 0)
except AuthToken.DoesNotExist:
return (None, 0)
return (False, 0)
python-django-crum-0.7.9/docs/make.bat 0000664 0000000 0000000 00000015067 14546353137 0017635 0 ustar 00root root 0000000 0000000 @ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^` where ^ is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Django-CRUM.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Django-CRUM.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
:end
python-django-crum-0.7.9/manage.py 0000775 0000000 0000000 00000002042 14546353137 0017072 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
# Python
import os
import sys
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_project.settings')
import django
django.setup()
# Use the runserver addr/port defined in settings.
from django.conf import settings
default_addr = getattr(settings, 'RUNSERVER_DEFAULT_ADDR', '127.0.0.1')
default_port = getattr(settings, 'RUNSERVER_DEFAULT_PORT', 8000)
from django.core.management.commands import runserver as core_runserver
original_handle = core_runserver.Command.handle
def handle(self, *args, **options):
if not options.get('addrport'):
options['addrport'] = '%s:%d' % (default_addr, int(default_port))
elif options.get('addrport').isdigit():
options['addrport'] = '%s:%d' % (default_addr, int(options['addrport']))
return original_handle(self, *args, **options)
core_runserver.Command.handle = handle
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
python-django-crum-0.7.9/requirements/ 0000775 0000000 0000000 00000000000 14546353137 0020012 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/requirements/dev.in 0000664 0000000 0000000 00000000510 14546353137 0021114 0 ustar 00root root 0000000 0000000 # Development/test environment uses Python 3.5 - 3.8 (separate requirements files generated for each).
bumpversion
django
django-debug-toolbar
django-extensions
djangorestframework
flake8
ipython
pycodestyle
pip-tools
pytest
pytest-cov
pytest-django
pytest-flake8
pytest-runner
setuptools-twine
sphinx
tox
tox-gh-actions
twine
python-django-crum-0.7.9/requirements/dev35.txt 0000664 0000000 0000000 00000010120 14546353137 0021473 0 ustar 00root root 0000000 0000000 #
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file=requirements/dev35.txt requirements/dev.in
#
alabaster==0.7.12 # via sphinx
appdirs==1.4.4 # via virtualenv
appnope==0.1.0 # via ipython
attrs==20.3.0 # via pytest
babel==2.8.0 # via sphinx
backcall==0.2.0 # via ipython
bleach==3.2.1 # via readme-renderer
bump2version==1.0.1 # via bumpversion
bumpversion==0.6.0 # via -r requirements/dev.in
certifi==2020.11.8 # via requests
chardet==3.0.4 # via requests
click==7.1.2 # via pip-tools
coverage==5.3 # via pytest-cov
decorator==4.4.2 # via ipython, traitlets
distlib==0.3.1 # via virtualenv
django-debug-toolbar==3.1.1 # via -r requirements/dev.in
django-extensions==3.0.9 # via -r requirements/dev.in
django==2.2.17 # via -r requirements/dev.in, django-debug-toolbar, djangorestframework
djangorestframework==3.12.2 # via -r requirements/dev.in
docutils==0.16 # via readme-renderer, sphinx
filelock==3.0.12 # via tox, virtualenv
flake8==3.8.4 # via -r requirements/dev.in, pytest-flake8
idna==2.10 # via requests
imagesize==1.2.0 # via sphinx
importlib-metadata==2.0.0 # via flake8, pluggy, pytest, tox, virtualenv
importlib-resources==3.2.1 # via virtualenv
iniconfig==1.1.1 # via pytest
ipython-genutils==0.2.0 # via traitlets
ipython==7.9.0 # via -r requirements/dev.in
jedi==0.17.2 # via ipython
jinja2==2.11.2 # via sphinx
markupsafe==1.1.1 # via jinja2
mccabe==0.6.1 # via flake8
packaging==20.4 # via bleach, pytest, sphinx, tox
parso==0.7.1 # via jedi
pathlib2==2.3.5 # via pytest
pexpect==4.8.0 # via ipython
pickleshare==0.7.5 # via ipython
pip-tools==5.3.1 # via -r requirements/dev.in
pkginfo==1.6.1 # via twine
pluggy==0.13.1 # via pytest, tox
prompt-toolkit==2.0.10 # via ipython
ptyprocess==0.6.0 # via pexpect
py==1.9.0 # via pytest, tox
pycodestyle==2.6.0 # via -r requirements/dev.in, flake8
pyflakes==2.2.0 # via flake8
pygments==2.7.2 # via ipython, readme-renderer, sphinx
pyparsing==2.4.7 # via packaging
pytest-cov==2.10.1 # via -r requirements/dev.in
pytest-django==4.1.0 # via -r requirements/dev.in
pytest-flake8==1.0.6 # via -r requirements/dev.in
pytest-runner==5.2 # via -r requirements/dev.in
pytest==6.1.2 # via -r requirements/dev.in, pytest-cov, pytest-django, pytest-flake8
pytz==2020.4 # via babel, django
readme-renderer==28.0 # via twine
requests-toolbelt==0.9.1 # via twine
requests==2.24.0 # via requests-toolbelt, sphinx, twine
setuptools-twine==0.1.2 # via -r requirements/dev.in
six==1.15.0 # via bleach, packaging, pathlib2, pip-tools, prompt-toolkit, readme-renderer, tox, traitlets, virtualenv
snowballstemmer==2.0.0 # via sphinx
sphinx==3.3.0 # via -r requirements/dev.in
sphinxcontrib-applehelp==1.0.2 # via sphinx
sphinxcontrib-devhelp==1.0.2 # via sphinx
sphinxcontrib-htmlhelp==1.0.3 # via sphinx
sphinxcontrib-jsmath==1.0.1 # via sphinx
sphinxcontrib-qthelp==1.0.3 # via sphinx
sphinxcontrib-serializinghtml==1.1.4 # via sphinx
sqlparse==0.4.1 # via django, django-debug-toolbar
toml==0.10.2 # via pytest, tox
tox-gh-actions==2.1.0 # via -r requirements/dev.in
tox==3.20.1 # via -r requirements/dev.in, tox-gh-actions
tqdm==4.51.0 # via twine
traitlets==4.3.3 # via ipython
twine==1.15.0 # via -r requirements/dev.in, setuptools-twine
urllib3==1.25.11 # via requests
virtualenv==20.1.0 # via tox
wcwidth==0.2.5 # via prompt-toolkit
webencodings==0.5.1 # via bleach
zipp==1.2.0 # via importlib-metadata, importlib-resources
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools
python-django-crum-0.7.9/requirements/dev36.txt 0000664 0000000 0000000 00000010270 14546353137 0021502 0 ustar 00root root 0000000 0000000 #
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file=requirements/dev36.txt requirements/dev.in
#
alabaster==0.7.12 # via sphinx
appdirs==1.4.4 # via virtualenv
appnope==0.1.0 # via ipython
asgiref==3.3.1 # via django
attrs==20.3.0 # via pytest
babel==2.8.0 # via sphinx
backcall==0.2.0 # via ipython
bleach==3.2.1 # via readme-renderer
bump2version==1.0.1 # via bumpversion
bumpversion==0.6.0 # via -r requirements/dev.in
certifi==2020.11.8 # via requests
chardet==3.0.4 # via requests
click==7.1.2 # via pip-tools
colorama==0.4.4 # via twine
coverage==5.3 # via pytest-cov
decorator==4.4.2 # via ipython, traitlets
distlib==0.3.1 # via virtualenv
django-debug-toolbar==3.1.1 # via -r requirements/dev.in
django-extensions==3.0.9 # via -r requirements/dev.in
django==3.1.3 # via -r requirements/dev.in, django-debug-toolbar, djangorestframework
djangorestframework==3.12.2 # via -r requirements/dev.in
docutils==0.16 # via readme-renderer, sphinx
filelock==3.0.12 # via tox, virtualenv
flake8==3.8.4 # via -r requirements/dev.in, pytest-flake8
idna==2.10 # via requests
imagesize==1.2.0 # via sphinx
importlib-metadata==2.0.0 # via flake8, keyring, pluggy, pytest, tox, twine, virtualenv
importlib-resources==3.3.0 # via virtualenv
iniconfig==1.1.1 # via pytest
ipython-genutils==0.2.0 # via traitlets
ipython==7.16.1 # via -r requirements/dev.in
jedi==0.17.2 # via ipython
jinja2==2.11.2 # via sphinx
keyring==21.5.0 # via twine
markupsafe==1.1.1 # via jinja2
mccabe==0.6.1 # via flake8
packaging==20.4 # via bleach, pytest, sphinx, tox
parso==0.7.1 # via jedi
pexpect==4.8.0 # via ipython
pickleshare==0.7.5 # via ipython
pip-tools==5.3.1 # via -r requirements/dev.in
pkginfo==1.6.1 # via twine
pluggy==0.13.1 # via pytest, tox
prompt-toolkit==3.0.8 # via ipython
ptyprocess==0.6.0 # via pexpect
py==1.9.0 # via pytest, tox
pycodestyle==2.6.0 # via -r requirements/dev.in, flake8
pyflakes==2.2.0 # via flake8
pygments==2.7.2 # via ipython, readme-renderer, sphinx
pyparsing==2.4.7 # via packaging
pytest-cov==2.10.1 # via -r requirements/dev.in
pytest-django==4.1.0 # via -r requirements/dev.in
pytest-flake8==1.0.6 # via -r requirements/dev.in
pytest-runner==5.2 # via -r requirements/dev.in
pytest==6.1.2 # via -r requirements/dev.in, pytest-cov, pytest-django, pytest-flake8
pytz==2020.4 # via babel, django
readme-renderer==28.0 # via twine
requests-toolbelt==0.9.1 # via twine
requests==2.24.0 # via requests-toolbelt, sphinx, twine
rfc3986==1.4.0 # via twine
setuptools-twine==0.1.2 # via -r requirements/dev.in
six==1.15.0 # via bleach, packaging, pip-tools, readme-renderer, tox, traitlets, virtualenv
snowballstemmer==2.0.0 # via sphinx
sphinx==3.3.0 # via -r requirements/dev.in
sphinxcontrib-applehelp==1.0.2 # via sphinx
sphinxcontrib-devhelp==1.0.2 # via sphinx
sphinxcontrib-htmlhelp==1.0.3 # via sphinx
sphinxcontrib-jsmath==1.0.1 # via sphinx
sphinxcontrib-qthelp==1.0.3 # via sphinx
sphinxcontrib-serializinghtml==1.1.4 # via sphinx
sqlparse==0.4.1 # via django, django-debug-toolbar
toml==0.10.2 # via pytest, tox
tox-gh-actions==2.1.0 # via -r requirements/dev.in
tox==3.20.1 # via -r requirements/dev.in, tox-gh-actions
tqdm==4.51.0 # via twine
traitlets==4.3.3 # via ipython
twine==3.2.0 # via -r requirements/dev.in, setuptools-twine
urllib3==1.25.11 # via requests
virtualenv==20.1.0 # via tox
wcwidth==0.2.5 # via prompt-toolkit
webencodings==0.5.1 # via bleach
zipp==3.4.0 # via importlib-metadata, importlib-resources
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools
python-django-crum-0.7.9/requirements/dev37.txt 0000664 0000000 0000000 00000010140 14546353137 0021477 0 ustar 00root root 0000000 0000000 #
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file=requirements/dev37.txt requirements/dev.in
#
alabaster==0.7.12 # via sphinx
appdirs==1.4.4 # via virtualenv
appnope==0.1.0 # via ipython
asgiref==3.3.1 # via django
attrs==20.3.0 # via pytest
babel==2.8.0 # via sphinx
backcall==0.2.0 # via ipython
bleach==3.2.1 # via readme-renderer
bump2version==1.0.1 # via bumpversion
bumpversion==0.6.0 # via -r requirements/dev.in
certifi==2020.11.8 # via requests
chardet==3.0.4 # via requests
click==7.1.2 # via pip-tools
colorama==0.4.4 # via twine
coverage==5.3 # via pytest-cov
decorator==4.4.2 # via ipython
distlib==0.3.1 # via virtualenv
django-debug-toolbar==3.1.1 # via -r requirements/dev.in
django-extensions==3.0.9 # via -r requirements/dev.in
django==3.1.3 # via -r requirements/dev.in, django-debug-toolbar, djangorestframework
djangorestframework==3.12.2 # via -r requirements/dev.in
docutils==0.16 # via readme-renderer, sphinx
filelock==3.0.12 # via tox, virtualenv
flake8==3.8.4 # via -r requirements/dev.in, pytest-flake8
idna==2.10 # via requests
imagesize==1.2.0 # via sphinx
importlib-metadata==2.0.0 # via flake8, keyring, pluggy, pytest, tox, twine, virtualenv
iniconfig==1.1.1 # via pytest
ipython-genutils==0.2.0 # via traitlets
ipython==7.19.0 # via -r requirements/dev.in
jedi==0.17.2 # via ipython
jinja2==2.11.2 # via sphinx
keyring==21.5.0 # via twine
markupsafe==1.1.1 # via jinja2
mccabe==0.6.1 # via flake8
packaging==20.4 # via bleach, pytest, sphinx, tox
parso==0.7.1 # via jedi
pexpect==4.8.0 # via ipython
pickleshare==0.7.5 # via ipython
pip-tools==5.3.1 # via -r requirements/dev.in
pkginfo==1.6.1 # via twine
pluggy==0.13.1 # via pytest, tox
prompt-toolkit==3.0.8 # via ipython
ptyprocess==0.6.0 # via pexpect
py==1.9.0 # via pytest, tox
pycodestyle==2.6.0 # via -r requirements/dev.in, flake8
pyflakes==2.2.0 # via flake8
pygments==2.7.2 # via ipython, readme-renderer, sphinx
pyparsing==2.4.7 # via packaging
pytest-cov==2.10.1 # via -r requirements/dev.in
pytest-django==4.1.0 # via -r requirements/dev.in
pytest-flake8==1.0.6 # via -r requirements/dev.in
pytest-runner==5.2 # via -r requirements/dev.in
pytest==6.1.2 # via -r requirements/dev.in, pytest-cov, pytest-django, pytest-flake8
pytz==2020.4 # via babel, django
readme-renderer==28.0 # via twine
requests-toolbelt==0.9.1 # via twine
requests==2.24.0 # via requests-toolbelt, sphinx, twine
rfc3986==1.4.0 # via twine
setuptools-twine==0.1.2 # via -r requirements/dev.in
six==1.15.0 # via bleach, packaging, pip-tools, readme-renderer, tox, virtualenv
snowballstemmer==2.0.0 # via sphinx
sphinx==3.3.0 # via -r requirements/dev.in
sphinxcontrib-applehelp==1.0.2 # via sphinx
sphinxcontrib-devhelp==1.0.2 # via sphinx
sphinxcontrib-htmlhelp==1.0.3 # via sphinx
sphinxcontrib-jsmath==1.0.1 # via sphinx
sphinxcontrib-qthelp==1.0.3 # via sphinx
sphinxcontrib-serializinghtml==1.1.4 # via sphinx
sqlparse==0.4.1 # via django, django-debug-toolbar
toml==0.10.2 # via pytest, tox
tox-gh-actions==2.1.0 # via -r requirements/dev.in
tox==3.20.1 # via -r requirements/dev.in, tox-gh-actions
tqdm==4.51.0 # via twine
traitlets==5.0.5 # via ipython
twine==3.2.0 # via -r requirements/dev.in, setuptools-twine
urllib3==1.25.11 # via requests
virtualenv==20.1.0 # via tox
wcwidth==0.2.5 # via prompt-toolkit
webencodings==0.5.1 # via bleach
zipp==3.4.0 # via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools
python-django-crum-0.7.9/requirements/dev38.txt 0000664 0000000 0000000 00000007724 14546353137 0021516 0 ustar 00root root 0000000 0000000 #
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file=requirements/dev38.txt requirements/dev.in
#
alabaster==0.7.12 # via sphinx
appdirs==1.4.4 # via virtualenv
appnope==0.1.0 # via ipython
asgiref==3.3.1 # via django
attrs==20.3.0 # via pytest
babel==2.8.0 # via sphinx
backcall==0.2.0 # via ipython
bleach==3.2.1 # via readme-renderer
bump2version==1.0.1 # via bumpversion
bumpversion==0.6.0 # via -r requirements/dev.in
certifi==2020.11.8 # via requests
chardet==3.0.4 # via requests
click==7.1.2 # via pip-tools
colorama==0.4.4 # via twine
coverage==5.3 # via pytest-cov
decorator==4.4.2 # via ipython
distlib==0.3.1 # via virtualenv
django-debug-toolbar==3.1.1 # via -r requirements/dev.in
django-extensions==3.0.9 # via -r requirements/dev.in
django==3.1.3 # via -r requirements/dev.in, django-debug-toolbar, djangorestframework
djangorestframework==3.12.2 # via -r requirements/dev.in
docutils==0.16 # via readme-renderer, sphinx
filelock==3.0.12 # via tox, virtualenv
flake8==3.8.4 # via -r requirements/dev.in, pytest-flake8
idna==2.10 # via requests
imagesize==1.2.0 # via sphinx
iniconfig==1.1.1 # via pytest
ipython-genutils==0.2.0 # via traitlets
ipython==7.19.0 # via -r requirements/dev.in
jedi==0.17.2 # via ipython
jinja2==2.11.2 # via sphinx
keyring==21.5.0 # via twine
markupsafe==1.1.1 # via jinja2
mccabe==0.6.1 # via flake8
packaging==20.4 # via bleach, pytest, sphinx, tox
parso==0.7.1 # via jedi
pexpect==4.8.0 # via ipython
pickleshare==0.7.5 # via ipython
pip-tools==5.3.1 # via -r requirements/dev.in
pkginfo==1.6.1 # via twine
pluggy==0.13.1 # via pytest, tox
prompt-toolkit==3.0.8 # via ipython
ptyprocess==0.6.0 # via pexpect
py==1.9.0 # via pytest, tox
pycodestyle==2.6.0 # via -r requirements/dev.in, flake8
pyflakes==2.2.0 # via flake8
pygments==2.7.2 # via ipython, readme-renderer, sphinx
pyparsing==2.4.7 # via packaging
pytest-cov==2.10.1 # via -r requirements/dev.in
pytest-django==4.1.0 # via -r requirements/dev.in
pytest-flake8==1.0.6 # via -r requirements/dev.in
pytest-runner==5.2 # via -r requirements/dev.in
pytest==6.1.2 # via -r requirements/dev.in, pytest-cov, pytest-django, pytest-flake8
pytz==2020.4 # via babel, django
readme-renderer==28.0 # via twine
requests-toolbelt==0.9.1 # via twine
requests==2.24.0 # via requests-toolbelt, sphinx, twine
rfc3986==1.4.0 # via twine
setuptools-twine==0.1.2 # via -r requirements/dev.in
six==1.15.0 # via bleach, packaging, pip-tools, readme-renderer, tox, virtualenv
snowballstemmer==2.0.0 # via sphinx
sphinx==3.3.0 # via -r requirements/dev.in
sphinxcontrib-applehelp==1.0.2 # via sphinx
sphinxcontrib-devhelp==1.0.2 # via sphinx
sphinxcontrib-htmlhelp==1.0.3 # via sphinx
sphinxcontrib-jsmath==1.0.1 # via sphinx
sphinxcontrib-qthelp==1.0.3 # via sphinx
sphinxcontrib-serializinghtml==1.1.4 # via sphinx
sqlparse==0.4.1 # via django, django-debug-toolbar
toml==0.10.2 # via pytest, tox
tox-gh-actions==2.1.0 # via -r requirements/dev.in
tox==3.20.1 # via -r requirements/dev.in, tox-gh-actions
tqdm==4.51.0 # via twine
traitlets==5.0.5 # via ipython
twine==3.2.0 # via -r requirements/dev.in, setuptools-twine
urllib3==1.25.11 # via requests
virtualenv==20.1.0 # via tox
wcwidth==0.2.5 # via prompt-toolkit
webencodings==0.5.1 # via bleach
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools
python-django-crum-0.7.9/requirements/dev39.txt 0000664 0000000 0000000 00000007724 14546353137 0021517 0 ustar 00root root 0000000 0000000 #
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file=requirements/dev39.txt requirements/dev.in
#
alabaster==0.7.12 # via sphinx
appdirs==1.4.4 # via virtualenv
appnope==0.1.0 # via ipython
asgiref==3.3.1 # via django
attrs==20.3.0 # via pytest
babel==2.8.0 # via sphinx
backcall==0.2.0 # via ipython
bleach==3.2.1 # via readme-renderer
bump2version==1.0.1 # via bumpversion
bumpversion==0.6.0 # via -r requirements/dev.in
certifi==2020.11.8 # via requests
chardet==3.0.4 # via requests
click==7.1.2 # via pip-tools
colorama==0.4.4 # via twine
coverage==5.3 # via pytest-cov
decorator==4.4.2 # via ipython
distlib==0.3.1 # via virtualenv
django-debug-toolbar==3.1.1 # via -r requirements/dev.in
django-extensions==3.0.9 # via -r requirements/dev.in
django==3.1.3 # via -r requirements/dev.in, django-debug-toolbar, djangorestframework
djangorestframework==3.12.2 # via -r requirements/dev.in
docutils==0.16 # via readme-renderer, sphinx
filelock==3.0.12 # via tox, virtualenv
flake8==3.8.4 # via -r requirements/dev.in, pytest-flake8
idna==2.10 # via requests
imagesize==1.2.0 # via sphinx
iniconfig==1.1.1 # via pytest
ipython-genutils==0.2.0 # via traitlets
ipython==7.19.0 # via -r requirements/dev.in
jedi==0.17.2 # via ipython
jinja2==2.11.2 # via sphinx
keyring==21.5.0 # via twine
markupsafe==1.1.1 # via jinja2
mccabe==0.6.1 # via flake8
packaging==20.4 # via bleach, pytest, sphinx, tox
parso==0.7.1 # via jedi
pexpect==4.8.0 # via ipython
pickleshare==0.7.5 # via ipython
pip-tools==5.3.1 # via -r requirements/dev.in
pkginfo==1.6.1 # via twine
pluggy==0.13.1 # via pytest, tox
prompt-toolkit==3.0.8 # via ipython
ptyprocess==0.6.0 # via pexpect
py==1.9.0 # via pytest, tox
pycodestyle==2.6.0 # via -r requirements/dev.in, flake8
pyflakes==2.2.0 # via flake8
pygments==2.7.2 # via ipython, readme-renderer, sphinx
pyparsing==2.4.7 # via packaging
pytest-cov==2.10.1 # via -r requirements/dev.in
pytest-django==4.1.0 # via -r requirements/dev.in
pytest-flake8==1.0.6 # via -r requirements/dev.in
pytest-runner==5.2 # via -r requirements/dev.in
pytest==6.1.2 # via -r requirements/dev.in, pytest-cov, pytest-django, pytest-flake8
pytz==2020.4 # via babel, django
readme-renderer==28.0 # via twine
requests-toolbelt==0.9.1 # via twine
requests==2.24.0 # via requests-toolbelt, sphinx, twine
rfc3986==1.4.0 # via twine
setuptools-twine==0.1.2 # via -r requirements/dev.in
six==1.15.0 # via bleach, packaging, pip-tools, readme-renderer, tox, virtualenv
snowballstemmer==2.0.0 # via sphinx
sphinx==3.3.0 # via -r requirements/dev.in
sphinxcontrib-applehelp==1.0.2 # via sphinx
sphinxcontrib-devhelp==1.0.2 # via sphinx
sphinxcontrib-htmlhelp==1.0.3 # via sphinx
sphinxcontrib-jsmath==1.0.1 # via sphinx
sphinxcontrib-qthelp==1.0.3 # via sphinx
sphinxcontrib-serializinghtml==1.1.4 # via sphinx
sqlparse==0.4.1 # via django, django-debug-toolbar
toml==0.10.2 # via pytest, tox
tox-gh-actions==2.1.0 # via -r requirements/dev.in
tox==3.20.1 # via -r requirements/dev.in, tox-gh-actions
tqdm==4.51.0 # via twine
traitlets==5.0.5 # via ipython
twine==3.2.0 # via -r requirements/dev.in, setuptools-twine
urllib3==1.25.11 # via requests
virtualenv==20.1.0 # via tox
wcwidth==0.2.5 # via prompt-toolkit
webencodings==0.5.1 # via bleach
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools
python-django-crum-0.7.9/requirements/tox.ini 0000664 0000000 0000000 00000000402 14546353137 0021321 0 ustar 00root root 0000000 0000000 [tox]
envlist = py3{5,6,7,8,9}
skipsdist = true
[testenv]
commands =
make -C .. update-requirements requirements
whitelist_externals = make
basepython =
py35: python3.5
py36: python3.6
py37: python3.7
py38: python3.8
py39: python3.9
python-django-crum-0.7.9/setup.cfg 0000664 0000000 0000000 00000005434 14546353137 0017116 0 ustar 00root root 0000000 0000000 [bumpversion]
commit = True
current_version = 0.7.9
tag = True
tag_name = {new_version}
[metadata]
name = django-crum
version = attr: crum.__version__
author = Nine More Minutes, Inc.
author_email = support@ninemoreminutes.com
description = Django middleware to capture current request and user.
long_description = file: README.rst
long_description_content_type = text/x-rst
keywords = django, request, user, middleware, thread, local
license = BSD
url = https://github.com/ninemoreminutes/django-crum/
project_urls =
Documentation = https://django-crum.rtfd.org/
Source = https://github.com/ninemoreminutes/django-crum/
Tracker = https://github.com/ninemoreminutes/django-crum/issues
classifiers =
Development Status :: 4 - Beta
Environment :: Web Environment
Framework :: Django
Framework :: Django :: 1.11
Framework :: Django :: 2.0
Framework :: Django :: 2.1
Framework :: Django :: 2.2
Framework :: Django :: 3.0
Framework :: Django :: 3.1
Intended Audience :: Developers
License :: OSI Approved :: BSD License
Operating System :: OS Independent
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.4
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Topic :: Internet :: WWW/HTTP
Topic :: Software Development :: Libraries
Topic :: Software Development :: Libraries :: Python Modules
[options]
zip_safe = False
packages = crum
include_package_data = True
setup_requires =
pytest-runner
setuptools-twine
tests_require =
django>=1.8
djangorestframework
pytest
pytest-cov
pytest-django
pytest-flake8
install_requires =
django>=1.8
[check]
metadata = True
restructuredtext = True
strict = True
[clean]
all = True
[egg_info]
tag_build = .dev
[build_sphinx]
source_dir = docs
build_dir = docs/_build
all_files = True
version = attr: crum.__version__
release = attr: crum.__version__
[upload_sphinx]
upload_dir = docs/_build/html
[upload_docs]
upload_dir = docs/_build/html
[bdist_wheel]
universal = 1
[aliases]
dev_build = clean test egg_info sdist bdist_wheel twine_check build_sphinx
release_build = clean test egg_info -b "" sdist bdist_wheel twine_check build_sphinx
test = pytest
ship_it = release_build twine_upload
[bumpversion:file:crum/__init__.py]
[bumpversion:file:docs/conf.py]
[pycodestyle]
ignore = E501
exclude = .git,.tox,build,dist,docs
[flake8]
ignore = E501
exclude = .git,.tox,build,dist,docs
[tool:pytest]
DJANGO_SETTINGS_MODULE = test_project.settings
python_files = test*.py
testpaths = crum test_project
norecursedirs = .git .tox build dist docs
flake8-ignore = E501
addopts = --reuse-db --nomigrations --cache-clear --flake8 --cov crum --cov-append --cov-report term-missing
python-django-crum-0.7.9/setup.py 0000775 0000000 0000000 00000000113 14546353137 0016777 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
# Setuptools
from setuptools import setup
setup()
python-django-crum-0.7.9/test_project/ 0000775 0000000 0000000 00000000000 14546353137 0017774 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/test_project/__init__.py 0000664 0000000 0000000 00000000000 14546353137 0022073 0 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/test_project/settings.py 0000664 0000000 0000000 00000006507 14546353137 0022216 0 ustar 00root root 0000000 0000000 # Python
import os
# Absolute path to the directory containing this Django project.
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
DEBUG = True
TEMPLATE_DEBUG = DEBUG
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'test_project.sqlite3'),
}
}
TIME_ZONE = 'America/New_York'
USE_TZ = True
SITE_ID = 1
SECRET_KEY = '347e28aa55547c3195e028fdead3448817e74fe2'
STATICFILES_DIRS = ()
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'public', 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'public', 'media')
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'crum.CurrentRequestUserMiddleware',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
'APP_DIRS': True,
'OPTIONS': {},
},
]
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),
)
ROOT_URLCONF = 'test_project.urls'
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'rest_framework',
'test_project.test_app',
)
try:
import django_extensions # noqa
INSTALLED_APPS += ('django_extensions',)
except ImportError:
pass
try:
import debug_toolbar # noqa
INSTALLED_APPS += ('debug_toolbar',)
MIDDLEWARE += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
DEBUG_TOOLBAR_CONFIG = {
'INTERCEPT_REDIRECTS': False,
}
except ImportError:
pass
RUNSERVER_DEFAULT_ADDR = '127.0.0.1'
RUNSERVER_DEFAULT_PORT = '8034'
INTERNAL_IPS = ('127.0.0.1',)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'null': {
'class': 'logging.NullHandler',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django': {
'handlers': ['console'],
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'django.security': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'py.warnings': {
'handlers': ['console'],
},
'crum': {
'handlers': ['null'],
},
},
}
python-django-crum-0.7.9/test_project/templates/ 0000775 0000000 0000000 00000000000 14546353137 0021772 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/test_project/templates/admin/ 0000775 0000000 0000000 00000000000 14546353137 0023062 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/test_project/templates/admin/base_site.html 0000664 0000000 0000000 00000001307 14546353137 0025707 0 ustar 00root root 0000000 0000000 {# Admin site customizations. #}
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}{{ title }} | {% trans 'Django CRUM Admin' %}{% endblock %}
{% block extrastyle %}
{{ block.super }}
{% endblock %}
{% block extrahead %}
{{ block.super }}
{% endblock %}
{% block blockbots %}
{{ block.super }}
{% endblock %}
{% block branding %}
{% trans 'Django CRUM Admin' %}
{% endblock %}
{% block userlinks %}
{{ block.super }}
{% endblock %}
{% block nav-global %}
{% if user.is_active and user.is_staff and not is_popup %}
{# Placeholder for version/hostname info. #}
{% endif %}
{{ block.super }}
{% endblock %}
{% block content_title %}
{{ block.super }}
{% endblock %}
python-django-crum-0.7.9/test_project/test_app/ 0000775 0000000 0000000 00000000000 14546353137 0021613 5 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/test_project/test_app/__init__.py 0000664 0000000 0000000 00000000000 14546353137 0023712 0 ustar 00root root 0000000 0000000 python-django-crum-0.7.9/test_project/test_app/models.py 0000664 0000000 0000000 00000000036 14546353137 0023447 0 ustar 00root root 0000000 0000000 from . import signals # noqa
python-django-crum-0.7.9/test_project/test_app/signals.py 0000664 0000000 0000000 00000002064 14546353137 0023627 0 ustar 00root root 0000000 0000000 # Django
from django.dispatch import receiver
# Django-CRUM
from crum import get_current_request
from crum.signals import current_user_getter, current_user_setter
@receiver(current_user_getter)
def _get_current_user_always_raises_exception(sender, **kwargs):
raise RuntimeError('this receiver always raises an exception')
@receiver(current_user_getter)
def _get_current_user_always_returns_invalid(sender, **kwargs):
return []
@receiver(current_user_getter)
def _get_current_user_always_returns_false(sender, **kwargs):
return False
@receiver(current_user_getter)
def _get_current_user_always_returns_list_with_false(sender, **kwargs):
return [False]
@receiver(current_user_setter)
def _set_current_user_always_raises_exception(sender, **kwargs):
raise RuntimeError('this receiver always raises an exception')
@receiver(current_user_getter)
def _get_current_user_from_drf_request(sender, **kwargs):
request = get_current_request()
drf_request = getattr(request, 'drf_request', None)
return (getattr(drf_request, 'user', False), 0)
python-django-crum-0.7.9/test_project/test_app/tests.py 0000664 0000000 0000000 00000011736 14546353137 0023337 0 ustar 00root root 0000000 0000000 # Python
from __future__ import with_statement
from __future__ import unicode_literals
import base64
try:
from importlib import reload as reload_module
except ImportError:
from imp import reload as reload_module
import json
# Django
from django.test import TestCase
from django.test.client import Client
try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
try:
from django.utils.six import binary_type, text_type
except ImportError:
binary_type, text_type = bytes, str
# Django-CRUM
from crum import get_current_user, impersonate
class TestCRUM(TestCase):
"""Test cases for the CRUM app."""
def setUp(self):
super(TestCRUM, self).setUp()
self.user_password = User.objects.make_random_password()
self.user = User.objects.create_user('user', 'user@example.com',
self.user_password)
def test_middleware(self):
# For test coverage.
import crum
reload_module(crum)
# Test anonymous user.
self.assertEqual(get_current_user(), None)
url = reverse('test_app:index')
response = self.client.get(url)
response_content = response.content.decode('utf-8')
self.assertEqual(response.status_code, 200)
self.assertEqual(response_content, 'AnonymousUser')
self.assertEqual(get_current_user(), None)
# Test logged in user.
self.client.login(username=self.user.username,
password=self.user_password)
response = self.client.get(url)
response_content = response.content.decode('utf-8')
self.assertEqual(response.status_code, 200)
self.assertEqual(response_content, text_type(self.user))
self.assertEqual(get_current_user(), None)
# Test impersonate context manager.
with impersonate(self.user):
self.assertEqual(get_current_user(), self.user)
self.assertEqual(get_current_user(), None)
# Test impersonate(None) within view requested by logged in user.
self.client.login(username=self.user.username,
password=self.user_password)
response = self.client.get(url + '?impersonate=1')
response_content = response.content.decode('utf-8')
self.assertEqual(response.status_code, 200)
self.assertEqual(response_content, text_type(None))
self.assertEqual(get_current_user(), None)
# Test when request raises exception.
try:
response = self.client.get(url + '?raise=1')
except RuntimeError:
response = None
self.assertEqual(response, None)
self.assertEqual(get_current_user(), None)
def test_middleware_with_rest_framework(self):
# Test anonymous user.
self.assertEqual(get_current_user(), None)
url = reverse('test_app:api_index')
response = self.client.get(url)
response_content = json.loads(response.content.decode('utf-8'))
self.assertEqual(response.status_code, 200)
self.assertEqual(response_content, text_type('AnonymousUser'))
self.assertEqual(get_current_user(), None)
# Test logged in user (session auth).
self.client.login(username=self.user.username,
password=self.user_password)
response = self.client.get(url)
response_content = json.loads(response.content.decode('utf-8'))
self.assertEqual(response.status_code, 200)
self.assertEqual(response_content, text_type(self.user))
self.assertEqual(get_current_user(), None)
# Test logged in user (basic auth).
basic_auth = '{0}:{1}'.format(self.user.username, self.user_password)
basic_auth = binary_type(basic_auth.encode('utf-8'))
basic_auth = base64.b64encode(basic_auth).decode('ascii')
client_kwargs = {'HTTP_AUTHORIZATION': 'Basic %s' % basic_auth}
client = Client(**client_kwargs)
response = client.get(url)
response_content = json.loads(response.content.decode('utf-8'))
self.assertEqual(response.status_code, 200)
self.assertEqual(response_content, text_type(self.user))
self.assertEqual(get_current_user(), None)
# Test impersonate(None) within view requested by logged in user.
self.client.login(username=self.user.username,
password=self.user_password)
response = self.client.get(url + '?impersonate=1')
response_content = json.loads(response.content.decode('utf-8'))
self.assertEqual(response.status_code, 200)
self.assertEqual(response_content, text_type(None))
self.assertEqual(get_current_user(), None)
# Test when request raises exception.
try:
response = self.client.get(url + '?raise=1')
except RuntimeError:
response = None
self.assertEqual(response, None)
self.assertEqual(get_current_user(), None)
python-django-crum-0.7.9/test_project/test_app/urls.py 0000664 0000000 0000000 00000000504 14546353137 0023151 0 ustar 00root root 0000000 0000000 # Django
try:
from django.urls import re_path
except ImportError:
from django.conf.urls import url as re_path
# Test App
from test_project.test_app.views import index, api_index
app_name = 'test_app'
urlpatterns = [
re_path(r'^$', index, name='index'),
re_path(r'^api/$', api_index, name='api_index'),
]
python-django-crum-0.7.9/test_project/test_app/views.py 0000664 0000000 0000000 00000003177 14546353137 0023332 0 ustar 00root root 0000000 0000000 # Python
from __future__ import with_statement
from __future__ import unicode_literals
# Django
from django.http import HttpResponse
from django.views.generic.base import View
try:
from django.utils.six import text_type
except ImportError:
text_type = str
# Django-REST-Framework
from rest_framework.response import Response
from rest_framework.views import APIView
# Django-CRUM
from crum import get_current_user, impersonate
class IndexView(View):
def get(self, request):
if request.GET.get('raise', ''):
raise RuntimeError()
if request.GET.get('impersonate', ''):
with impersonate(None):
current_user = text_type(get_current_user())
else:
current_user = text_type(get_current_user())
return HttpResponse(current_user, content_type='text/plain')
index = IndexView.as_view()
class ApiIndexView(APIView):
def initialize_request(self, request, *args, **kwargs):
"""Store the REST Framework request on the Django request."""
req = super(ApiIndexView, self).initialize_request(request, *args,
**kwargs)
request.drf_request = req
return req
def get(self, request, format=None):
if request.query_params.get('raise', ''):
raise RuntimeError()
if request.query_params.get('impersonate', ''):
with impersonate(None):
current_user = text_type(get_current_user())
else:
current_user = text_type(get_current_user())
return Response(current_user)
api_index = ApiIndexView.as_view()
python-django-crum-0.7.9/test_project/urls.py 0000664 0000000 0000000 00000001272 14546353137 0021335 0 ustar 00root root 0000000 0000000 # Django
from django.conf import settings
try:
from django.urls import include, re_path
except ImportError:
from django.conf.urls import include, url as re_path
include_kwargs = dict(namespace='test_app')
urlpatterns = [
re_path(r'^test_app/', include('test_project.test_app.urls', **include_kwargs)),
]
if 'django.contrib.admin' in settings.INSTALLED_APPS:
from django.contrib import admin
admin.autodiscover()
urlpatterns += [
re_path(r'', admin.site.urls),
]
if 'django.contrib.staticfiles' in settings.INSTALLED_APPS and settings.DEBUG:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
python-django-crum-0.7.9/tox.ini 0000664 0000000 0000000 00000002275 14546353137 0016610 0 ustar 00root root 0000000 0000000 [tox]
envlist =
py35-dj{111,200,210,220},
py36-dj{200,210,220,300,310,master},
py37-dj{200,210,220,300,310,master},
py38-dj{220,300,310,master}
py39-dj{220,300,310,master}
[testenv]
commands =
coverage erase
py.test {posargs}
basepython =
py35: python3.5
py36: python3.6
py37: python3.7
py38: python3.8
py39: python3.9
deps =
dj111: Django~=1.11.0
dj111: djangorestframework~=3.11.0
dj200: Django~=2.0.0
dj200: djangorestframework
dj210: Django~=2.1.0
dj210: djangorestframework
dj220: Django~=2.2.0
dj220: djangorestframework
dj300: Django~=3.0.0
dj300: djangorestframework
dj310: Django~=3.1.0
dj310: djangorestframework
djmaster: https://github.com/django/django/zipball/master#egg=Django
djmaster: https://github.com/encode/django-rest-framework/zipball/master#egg=djangorestframework
pytest
pytest-cov
pytest-django
pytest-flake8
pytest-runner
setenv =
DJANGO_SETTINGS_MODULE = test_project.settings
PYTHONDONTWRITEBYTECODE = 1
install_command = pip install --pre {opts} {packages}
[gh-actions]
python =
3.5: py35
3.6: py36
3.7: py37
3.8: py38
3.9: py39