[Python-modules-commits] [django-impersonate] 01/03: import django-impersonate_1.1~a0~hg20161126.orig.tar.gz
Scott Kitterman
kitterman at moszumanska.debian.org
Sun Nov 27 00:48:20 UTC 2016
This is an automated email from the git hooks/post-receive script.
kitterman pushed a commit to branch master
in repository django-impersonate.
commit 86b64f45bdbb45b5f0d138c7381ffb9f8d73e9e7
Author: Scott Kitterman <scott at kitterman.com>
Date: Sat Nov 26 19:23:33 2016 -0500
import django-impersonate_1.1~a0~hg20161126.orig.tar.gz
---
BSD-LICENSE | 32 +
CHANGELOG | 82 +++
PKG-INFO | 383 +++++++++++
README.rst | 362 ++++++++++
impersonate/__init__.py | 25 +
impersonate/admin.py | 131 ++++
impersonate/apps.py | 9 +
impersonate/decorators.py | 37 ++
impersonate/helpers.py | 184 ++++++
impersonate/middleware.py | 31 +
impersonate/migrations/0001_initial.py | 26 +
impersonate/migrations/__init__.py | 0
impersonate/models.py | 53 ++
impersonate/signals.py | 109 +++
impersonate/templates/impersonate/list_users.html | 24 +
.../templates/impersonate/search_users.html | 31 +
impersonate/tests.py | 733 +++++++++++++++++++++
impersonate/urls.py | 22 +
impersonate/views.py | 149 +++++
setup.py | 54 ++
20 files changed, 2477 insertions(+)
diff --git a/BSD-LICENSE b/BSD-LICENSE
new file mode 100644
index 0000000..cf18d1f
--- /dev/null
+++ b/BSD-LICENSE
@@ -0,0 +1,32 @@
+Copyright (c) 2009, Peter Sanchez <petersanchez at gmail.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the
+following conditions are met:
+
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+ * 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.
+
+ * Neither the name of Peter Sanchez 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 AND CONTRIBUTORS
+"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
+HOLDER OR CONTRIBUTORS 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.
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..c9d56ce
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,82 @@
+Changes
+-------
+
+1.1 (Dev)
+
+- TODO Issue #19
+- Django 1.10 compatibility (get rid of deprecation warnings). (Issue #36)
+- Use USERNAME_FIELD for sorting in admin to avoid custom User model issues. (Issue #37)
+- Added test coverage and refactoring for admin filters.
+- Updated data sent to signal_end signal to be uniform with signal_begin and documentation. (Issue #34)
+- Updated middleware documentation. (Issue #33)
+
+1.0.1 (2016-04-10)
+- Fix migration issues with custom User models. (Issue #31, Pull Request #26)
+
+1.0 (2016-02-14)
+
+- Update to use User PK instead of ID. (Pull Request #20)
+- Use proper URL tag for user search, listing templates. (Pull Requests #21, #22)
+- Add Impersonation Log support. (Issue #7, Issue #28, Pull Request #23)
+- Add support for Django 1.9 (Pull Request #24)
+- Adding unicode_literals for Py3 compatibility. (Issue #29)
+
+0.9.2 (2015-08-24)
+
+- Add http refer specific setting because it broke prevoius usage. (Issue #24, Refs Issue #17)
+
+0.9.1 (2015-04-16)
+
+- Fix unicode issue with redirect variables. (Issue #21)
+- Add redirect to previous impersonation screen. (Issue #17, Pull Request #17)
+- Django 1.8 compatibility. (Pull Request #19)
+
+0.9.0 (2014-09-30)
+
+- Split search query into terms. (Pull Request #15)
+- Edge case bug addressing different versions of Django in different environments. (Issue #15)
+- Moved LOGIN_URL to function to avoid circular import issues. (Pull Request #14)
+- Customize search fields and query type. (Issue #14, Pull Request #13)
+- Django 1.7 compat changes. (Refs Pull Request #16)
+
+0.8.1 (2013-11-09)
+
+- Store user ID for Django 1.6 serialization support. (Issue #12, Pull Request #11)
+- Updated Authors & Changelog
+- Updated tox config to include Django 1.6 environments
+
+0.8.0 (2013-08-24)
+
+- Added "impersonator" to request object. (Issue #5)
+- Ditched custom import method for django importlib. (Issue #6)
+- Updated Authors & Changelog
+- Added session_begin and session_end signals. (Issue #8, Pull Request #7)
+
+0.7.0 (2013-03-28)
+
+- Added Python 3.3 support.
+
+0.6.0 (2013-03-21)
+
+- Added Django 1.5 support
+- Added full test coverage support (Issue #1)
+
+0.5.3 (2012-06-20)
+
+- Fixed Issue impersonating with a staff user (Issue #4)
+
+0.5.2 (2012-03-20)
+
+- Minor updates. Authors and changelog file
+
+0.5.1 (2012-03-04):
+
+- Fixed Django 1.1 compatibility problem (Issue #2)
+- Fixed missing templates directory (Issue #3)
+- Updated AUTHORS file
+
+PREVIOUS VERSIONS:
+
+I've been a bad boy and haven't been keeping a changelog.
+I'll keep this updated moving forward. If you're really
+interested, read the commit history ;)
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..71803fb
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,383 @@
+Metadata-Version: 1.1
+Name: django-impersonate
+Version: 1.1a0
+Summary: Django app to allow superusers to impersonate other users.
+Home-page: http://bitbucket.org/petersanchez/django-impersonate/
+Author: Peter Sanchez
+Author-email: petersanchez at gmail.com
+License: BSD License
+Description: .. |nlshield| image:: https://img.shields.io/badge/100%-Netlandish-blue.svg?style=square-flat
+ :target: http://www.netlandish.com
+
+ ==============================
+ django-impersonate |nlshield|
+ ==============================
+ :Info: Simple application to allow superusers to "impersonate" other non-superuser accounts.
+ :Version: 1.1
+ :Author: Peter Sanchez (http://www.petersanchez.com)
+
+ Dependencies
+ ============
+
+ * It was written for Python 2.7+ and Django 1.8+
+ * Python 3.3+ is supported but Python 3.4+ is required for Django 1.9+
+ * It depends on your project using the django.contrib.session framework.
+
+ **NOTE:**
+
+ * **Version 1.0 adds new functionality by default.** Please see the IMPERSONATE_DISABLE_LOGGING setting section.
+ * If you need to use this with Django older than 1.8, please use version django-impersonate == 1.0.1
+ * If you need to use this with Django older than 1.7, please use version django-impersonate == 0.9.2
+ * **Version 0.9.2 partially reverts work completed in version 0.9.1.** This is because work done to address a request in `Issue #17 <https://bitbucket.org/petersanchez/django-impersonate/issues/17/remember-where-to-return-to-after>`_ broke default behavior for all previous versions. `Issue #24 <https://bitbucket.org/petersanchez/django-impersonate/issues/24/impersonate_redirect_url-no-longer-works>`_ was opened and the fix was released in 0.9.2 to address it. Please see the new I [...]
+ * If you need to use this with Django older than 1.4, please use version django-impersonate == 0.5.3
+
+
+ Installation
+ ============
+
+ PIP::
+
+ pip install django-impersonate
+
+ Basic Manual Install::
+
+ $ python setup.py build
+ $ sudo python setup.py install
+
+ Alternative Install (Manually):
+
+ Place impersonate directory in your Python path. Either in your Python installs site-packages directory or set your $PYTHONPATH environment variable to include a directory where the impersonate directory lives.
+
+
+ Use
+ ===
+
+ #. Add 'impersonate' to your INSTALLED_APPS
+
+ #. Add 'impersonate.middleware.ImpersonateMiddleware' to your MIDDLEWARE_CLASSES
+
+ #. Add 'impersonate.urls' somewhere in your url structure. Example::
+
+ urlpatterns = patterns('',
+ url(r'^admin/', include(admin.site.urls)),
+ url(r'^impersonate/', include('impersonate.urls')),
+ ... (all your other urls here) ...
+ )
+
+ **Note:** The ImpersonationMiddleware class should be placed AFTER the `django.contrib.auth` middleware classes
+
+ Functionality
+ =============
+
+ **You can now impersonate another user by hitting the following path:**
+
+ /impersonate/<user-id>/
+
+ Replace <user-id> with the user id of the user you want to impersonate.
+
+ While in impersonation "mode" the request.user object will have an
+ "is_impersonate" attribute set to True. So if you wanted to check in your
+ templates or view, you just do something like...
+
+ {% if user.is_impersonate %} .... {% endif %}
+
+ The original user is available as "request.impersonator".
+
+ {{ request.user }} ({{ request.impersonator }})
+
+ You can reference this URL with reverse() or the {% url %} template tag
+ as 'impersonate-start'
+
+
+ **To remove the impersonation, hit the following path:**
+
+ /impersonate/stop/
+
+ You can reference this URL with reverse() or the {% url %} template tag
+ as 'impersonate-stop'. When you call this URL, you will be redirected to
+ the page that you used to start impersonating a user (eg, some search results
+ or the user list.)
+
+
+ **To list all users you can go to:**
+
+ /impersonate/list/
+
+ This will render the template 'impersonate/list_users.html' and will pass
+ the following in the context:
+
+ * users - queryset of all users
+ * paginator - Django Paginator instance
+ * page - Current page of objects (from Paginator)
+ * page_number - Current page number, defaults to 1
+
+ You can reference this URL with reverse() or the {% url %} template tag
+ as 'impersonate-list'
+
+
+ **To search all users you can go to:**
+
+ /impersonate/search/
+
+ This will render the template 'impersonate/search_users.html' and will pass
+ the following in the context:
+
+ * users - queryset of all users
+ * paginator - Django Paginator instance
+ * page - Current page of objects (from Paginator)
+ * page_number - Current page number, defaults to 1
+ * query - The search query that was entered
+
+ The view will expect a GET request and look for the 'q' variable being passed.
+ If present, it will search the user entries with the value of 'q'. The default
+ fields searched are:
+
+ User.username, User.first_name, User.last_name, User.email
+
+ You can reference this URL with reverse() or the {% url %} template tag
+ as 'impersonate-search'
+
+
+ **To allow some users to impersonate other users**
+
+ You can optionally allow only some non-superuser and non-staff users to impersonate by adding a **IMPERSONATE_CUSTOM_ALLOW** setting. Create a function that takes a request object, and based on your rules, returns True if the user is allowed to impersonate or not.
+
+ **To limit what users a user can impersonate**
+
+ By, optionally, setting the **IMPERSONATE_CUSTOM_USER_QUERYSET** you can control what users can be impersonated. It takes a request object of the user, and returns a QuerySet of users. This is used when searching for users to impersonate, when listing what users to impersonate, and when trying to start impersonation.
+
+ **Signals**
+
+ If you wish to hook into the impersonation session (for instance, in order to
+ audit access), there are two signals that are fired by django-impersonate, at
+ the beginning and end of a session:
+
+ * session_begin - sent when calling the `impersonate` view
+ * session_end - sent when calling the `stop_impersonate` view
+
+ Both of these signals send the same arguments:
+
+ * sender - this is a Django signal requirement, and is always set to None
+ * impersonator - a reference to the User object of the person doing the impersonation
+ * impersonating - a reference to the User object of the person being impersonated
+ * request - the Django HttpRequest object from which the impersonation was invoked
+
+ The request object is included as it contains pertinent information that you may wish
+ to audit - such as client IP address, user-agent string, etc.
+
+ For an example of how to hook up the signals, see the relevant test - `test_successful_impersonation_signals`.
+
+ NB The session_end signal will only be fired if the impersonator explicitly ends
+ the session.
+
+ Settings
+ ========
+
+ The following settings are available for django-impersonate:
+
+
+ IMPERSONATE_REDIRECT_URL
+
+ This is the URL you want to be redirected to _after_ you have chosen to
+ impersonate another user. If this is not present it will check for
+ the LOGIN_REDIRECT_URL setting and fall back to '/' if neither is
+ present. Value should be a string containing the redirect path.
+
+
+ IMPERSONATE_USE_HTTP_REFERER
+
+ If this is set to True, then the app will attempt to be redirect you to
+ the URL you were at when the impersonation began once you have _stopped_
+ the impersonation. For example, if you were at the url '/foo/bar/' when
+ you began impersonating a user, once you end the impersonation, you will
+ be redirected back to '/foo/bar/' instead of the value in
+ IMPERSONATE_REDIRECT_URL.
+
+ Value should be a boolean (True/False), defaults to False
+
+
+ IMPERSONATE_PAGINATE_COUNT
+
+ This is the number of users to paginate by when using the list or
+ search views. This defaults to 20. Value should be an integer.
+
+
+ IMPERSONATE_REQUIRE_SUPERUSER
+
+ If this is set to True, then only users who have 'is_superuser' set
+ to True will be allowed to impersonate other users. Default is False.
+ If False, then any 'is_staff' user will be able to impersonate other
+ users.
+
+ **Note:** Regardless of this setting, a 'is_staff' user will **not** be
+ allowed to impersonate a 'is_superuser' user.
+
+ Value should be a boolean (True/False)
+
+ If the IMPERSONATE_CUSTOM_ALLOW is set, then that custom function is used, and
+ this setting is ignored.
+
+
+ IMPERSONATE_ALLOW_SUPERUSER
+
+ By default, superusers cannot be impersonated; this setting allows for that.
+
+ **Note:** Even when this is true, only superusers can impersonate other superusers,
+ regardless of the value of IMPERSONATE_REQUIRE_SUPERUSER.
+
+ Value should be a boolean (True/False), and the default is False.
+
+
+ IMPERSONATE_URI_EXCLUSIONS
+
+ Set to a list/tuple of url patterns that, if matched, user
+ impersonation is not completed. It defaults to:
+
+ (r'^admin/',)
+
+ If you do not want to use even the default exclusions then set
+ the setting to an emply list/tuple.
+
+
+ IMPERSONATE_CUSTOM_USER_QUERYSET
+
+ A string that represents a function (e.g. 'module.submodule.mod.function_name')
+ that allows more fine grained control over what users a user can impersonate.
+ It takes one argument, the request object, and should return a QuerySet. Only
+ the users in this queryset can be impersonated.
+
+ This function will not be called when the request has an unauthorised users,
+ and will only be called when the user is allowed to impersonate (cf.
+ IMPERSONATE_REQUIRE_SUPERUSER and IMPERSONATE_CUSTOM_ALLOW )
+
+ Regardless of what this function returns, a user cannot impersonate a
+ superuser, even if there are superusers in the returned QuerySet.
+
+ It is optional, and if it is not present, the user can impersonate any user
+ (i.e. the default is User.objects.all())
+
+
+ IMPERSONATE_CUSTOM_ALLOW
+
+ A string that represents a function (e.g. 'module.submodule.mod.function_name')
+ that allows more fine grained control over who can use the impersonation. It
+ takes one argument, the request object, and should return True to allow
+ impesonation. Regardless of this setting, the user must be logged in to
+ impersonate. If this setting is used, IMPERSONATE_REQUIRE_SUPERUSER is ignored.
+
+ It is optional, and if it is not present, the previous rules about superuser
+ and IMPERSONATE_REQUIRE_SUPERUSER apply.
+
+
+ IMPERSONATE_REDIRECT_FIELD_NAME
+
+ A string that represents the name of a request (GET) parameter which contains
+ the URL to redirect to after impersonating a user. This can be used to redirect
+ to a custom page after impersonating a user. Example:
+
+ # in settings.py
+ IMPERSONATE_REDIRECT_FIELD_NAME = 'next'
+
+ # in your view
+ <a href="{% url 'impersonate-list' %}?next=/some/url/">switch user</a>
+
+ To return always to the current page after impersonating a user, use request.path:
+
+ <a href="{% url 'impersonate-list' %}?next={{request.path}}">switch user</a>
+
+
+ IMPERSONATE_SEARCH_FIELDS
+
+ Array of user model fields used for building searching query. Default value is
+ [User.USERNAME_FIELD, 'first_name', 'last_name', 'email']. If the User model doesn't have
+ the USERNAME_FIELD attribute, it falls back to 'username' (< Django 1.5).
+
+
+ IMPERSONATE_LOOKUP_TYPE
+
+ A string that represents SQL lookup type for searching users by query on
+ fields above. It is 'icontains' by default.
+
+ IMPERSONATE_DISABLE_LOGGING
+
+ A bool that can be used to disable the logging of impersonation sessions. By
+ default each impersonation ``session_begin`` signal will create a new
+ ``ImpersonationLog`` object, which is closed out (duration calculated) at
+ the corresponding ``session_end`` signal.
+
+ It is optional, and defaults to False (i.e. logging is enabled).
+
+ IMPERSONATE_MAX_FILTER_SIZE
+
+ The max number of items acceptable in the admin list filters. If the number of
+ items exceeds this, then the filter is removed (just shows all). This is used
+ by the "Filter by impersonator" filter.
+
+ It is optional, and defaults to 100.
+
+ Testing
+ =======
+
+ You need factory_boy installed for tests to run. To install, use:
+
+ $ pip install factory_boy
+
+ **Note:** This currently not required for Python 3.3+. For more info on factory_boy, see: https://github.com/dnerdy/factory_boy
+
+ From the repo checkout, ensure you have Django in your PYTHONPATH and run:
+
+ $ python runtests.py
+
+ To get test coverage, use::
+
+ $ coverate run --branch runtests.py
+ $ coverage html <- Pretty HTML files for you
+ $ coverage report -m <- Ascii report
+
+ If you're bored and want to test all the supported environments, you'll need tox.::
+
+ $ pip install tox
+ $ tox
+
+ And you should see::
+
+ py3.5-django1.10: commands succeeded
+ py3.5-django1.9: commands succeeded
+ py3.5-django1.8: commands succeeded
+ py3.4-django1.10: commands succeeded
+ py3.4-django1.9: commands succeeded
+ py3.4-django1.8: commands succeeded
+ py3.3-django1.8: commands succeeded
+ py2.7-django1.10: commands succeeded
+ py2.7-django1.9: commands succeeded
+ py2.7-django1.8: commands succeeded
+ congratulations :)
+
+ Copyright & Warranty
+ ====================
+ All documentation, libraries, and sample code are
+ Copyright 2011 Peter Sanchez <petersanchez at gmail.com>. The library and
+ sample code are made available to you under the terms of the BSD license
+ which is contained in the included file, BSD-LICENSE.
+
+
+ ==================
+ Commercial Support
+ ==================
+
+ This software, and lots of other software like it, has been built in support of many of
+ Netlandish's own projects, and the projects of our clients. We would love to help you
+ on your next project so get in touch by dropping us a note at hello at netlandish.com.
+
+Platform: any
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Environment :: Web Environment
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..57bb651
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,362 @@
+.. |nlshield| image:: https://img.shields.io/badge/100%-Netlandish-blue.svg?style=square-flat
+ :target: http://www.netlandish.com
+
+==============================
+django-impersonate |nlshield|
+==============================
+:Info: Simple application to allow superusers to "impersonate" other non-superuser accounts.
+:Version: 1.1
+:Author: Peter Sanchez (http://www.petersanchez.com)
+
+Dependencies
+============
+
+* It was written for Python 2.7+ and Django 1.8+
+* Python 3.3+ is supported but Python 3.4+ is required for Django 1.9+
+* It depends on your project using the django.contrib.session framework.
+
+**NOTE:**
+
+* **Version 1.0 adds new functionality by default.** Please see the IMPERSONATE_DISABLE_LOGGING setting section.
+* If you need to use this with Django older than 1.8, please use version django-impersonate == 1.0.1
+* If you need to use this with Django older than 1.7, please use version django-impersonate == 0.9.2
+* **Version 0.9.2 partially reverts work completed in version 0.9.1.** This is because work done to address a request in `Issue #17 <https://bitbucket.org/petersanchez/django-impersonate/issues/17/remember-where-to-return-to-after>`_ broke default behavior for all previous versions. `Issue #24 <https://bitbucket.org/petersanchez/django-impersonate/issues/24/impersonate_redirect_url-no-longer-works>`_ was opened and the fix was released in 0.9.2 to address it. Please see the new IMPERSONA [...]
+* If you need to use this with Django older than 1.4, please use version django-impersonate == 0.5.3
+
+
+Installation
+============
+
+PIP::
+
+ pip install django-impersonate
+
+Basic Manual Install::
+
+ $ python setup.py build
+ $ sudo python setup.py install
+
+Alternative Install (Manually):
+
+Place impersonate directory in your Python path. Either in your Python installs site-packages directory or set your $PYTHONPATH environment variable to include a directory where the impersonate directory lives.
+
+
+Use
+===
+
+#. Add 'impersonate' to your INSTALLED_APPS
+
+#. Add 'impersonate.middleware.ImpersonateMiddleware' to your MIDDLEWARE_CLASSES
+
+#. Add 'impersonate.urls' somewhere in your url structure. Example::
+
+ urlpatterns = patterns('',
+ url(r'^admin/', include(admin.site.urls)),
+ url(r'^impersonate/', include('impersonate.urls')),
+ ... (all your other urls here) ...
+ )
+
+**Note:** The ImpersonationMiddleware class should be placed AFTER the `django.contrib.auth` middleware classes
+
+Functionality
+=============
+
+**You can now impersonate another user by hitting the following path:**
+
+ /impersonate/<user-id>/
+
+Replace <user-id> with the user id of the user you want to impersonate.
+
+While in impersonation "mode" the request.user object will have an
+"is_impersonate" attribute set to True. So if you wanted to check in your
+templates or view, you just do something like...
+
+ {% if user.is_impersonate %} .... {% endif %}
+
+The original user is available as "request.impersonator".
+
+ {{ request.user }} ({{ request.impersonator }})
+
+You can reference this URL with reverse() or the {% url %} template tag
+as 'impersonate-start'
+
+
+**To remove the impersonation, hit the following path:**
+
+ /impersonate/stop/
+
+You can reference this URL with reverse() or the {% url %} template tag
+as 'impersonate-stop'. When you call this URL, you will be redirected to
+the page that you used to start impersonating a user (eg, some search results
+or the user list.)
+
+
+**To list all users you can go to:**
+
+ /impersonate/list/
+
+This will render the template 'impersonate/list_users.html' and will pass
+the following in the context:
+
+* users - queryset of all users
+* paginator - Django Paginator instance
+* page - Current page of objects (from Paginator)
+* page_number - Current page number, defaults to 1
+
+You can reference this URL with reverse() or the {% url %} template tag
+as 'impersonate-list'
+
+
+**To search all users you can go to:**
+
+ /impersonate/search/
+
+This will render the template 'impersonate/search_users.html' and will pass
+the following in the context:
+
+* users - queryset of all users
+* paginator - Django Paginator instance
+* page - Current page of objects (from Paginator)
+* page_number - Current page number, defaults to 1
+* query - The search query that was entered
+
+The view will expect a GET request and look for the 'q' variable being passed.
+If present, it will search the user entries with the value of 'q'. The default
+fields searched are:
+
+User.username, User.first_name, User.last_name, User.email
+
+You can reference this URL with reverse() or the {% url %} template tag
+as 'impersonate-search'
+
+
+**To allow some users to impersonate other users**
+
+You can optionally allow only some non-superuser and non-staff users to impersonate by adding a **IMPERSONATE_CUSTOM_ALLOW** setting. Create a function that takes a request object, and based on your rules, returns True if the user is allowed to impersonate or not.
+
+**To limit what users a user can impersonate**
+
+By, optionally, setting the **IMPERSONATE_CUSTOM_USER_QUERYSET** you can control what users can be impersonated. It takes a request object of the user, and returns a QuerySet of users. This is used when searching for users to impersonate, when listing what users to impersonate, and when trying to start impersonation.
+
+**Signals**
+
+If you wish to hook into the impersonation session (for instance, in order to
+audit access), there are two signals that are fired by django-impersonate, at
+the beginning and end of a session:
+
+* session_begin - sent when calling the `impersonate` view
+* session_end - sent when calling the `stop_impersonate` view
+
+Both of these signals send the same arguments:
+
+* sender - this is a Django signal requirement, and is always set to None
+* impersonator - a reference to the User object of the person doing the impersonation
+* impersonating - a reference to the User object of the person being impersonated
+* request - the Django HttpRequest object from which the impersonation was invoked
+
+The request object is included as it contains pertinent information that you may wish
+to audit - such as client IP address, user-agent string, etc.
+
+For an example of how to hook up the signals, see the relevant test - `test_successful_impersonation_signals`.
+
+NB The session_end signal will only be fired if the impersonator explicitly ends
+the session.
+
+Settings
+========
+
+The following settings are available for django-impersonate:
+
+
+ IMPERSONATE_REDIRECT_URL
+
+This is the URL you want to be redirected to _after_ you have chosen to
+impersonate another user. If this is not present it will check for
+the LOGIN_REDIRECT_URL setting and fall back to '/' if neither is
+present. Value should be a string containing the redirect path.
+
+
+ IMPERSONATE_USE_HTTP_REFERER
+
+If this is set to True, then the app will attempt to be redirect you to
+the URL you were at when the impersonation began once you have _stopped_
+the impersonation. For example, if you were at the url '/foo/bar/' when
+you began impersonating a user, once you end the impersonation, you will
+be redirected back to '/foo/bar/' instead of the value in
+IMPERSONATE_REDIRECT_URL.
+
+Value should be a boolean (True/False), defaults to False
+
+
+ IMPERSONATE_PAGINATE_COUNT
+
+This is the number of users to paginate by when using the list or
+search views. This defaults to 20. Value should be an integer.
+
+
+ IMPERSONATE_REQUIRE_SUPERUSER
+
+If this is set to True, then only users who have 'is_superuser' set
+to True will be allowed to impersonate other users. Default is False.
+If False, then any 'is_staff' user will be able to impersonate other
+users.
+
+**Note:** Regardless of this setting, a 'is_staff' user will **not** be
+allowed to impersonate a 'is_superuser' user.
+
+Value should be a boolean (True/False)
+
+If the IMPERSONATE_CUSTOM_ALLOW is set, then that custom function is used, and
+this setting is ignored.
+
+
+ IMPERSONATE_ALLOW_SUPERUSER
+
+By default, superusers cannot be impersonated; this setting allows for that.
+
+**Note:** Even when this is true, only superusers can impersonate other superusers,
+regardless of the value of IMPERSONATE_REQUIRE_SUPERUSER.
+
+Value should be a boolean (True/False), and the default is False.
+
+
+ IMPERSONATE_URI_EXCLUSIONS
+
+Set to a list/tuple of url patterns that, if matched, user
+impersonation is not completed. It defaults to:
+
+(r'^admin/',)
+
+If you do not want to use even the default exclusions then set
+the setting to an emply list/tuple.
+
+
+ IMPERSONATE_CUSTOM_USER_QUERYSET
+
+A string that represents a function (e.g. 'module.submodule.mod.function_name')
+that allows more fine grained control over what users a user can impersonate.
+It takes one argument, the request object, and should return a QuerySet. Only
+the users in this queryset can be impersonated.
+
+This function will not be called when the request has an unauthorised users,
+and will only be called when the user is allowed to impersonate (cf.
+IMPERSONATE_REQUIRE_SUPERUSER and IMPERSONATE_CUSTOM_ALLOW )
+
+Regardless of what this function returns, a user cannot impersonate a
+superuser, even if there are superusers in the returned QuerySet.
+
+It is optional, and if it is not present, the user can impersonate any user
+(i.e. the default is User.objects.all())
+
+
+ IMPERSONATE_CUSTOM_ALLOW
+
+A string that represents a function (e.g. 'module.submodule.mod.function_name')
+that allows more fine grained control over who can use the impersonation. It
+takes one argument, the request object, and should return True to allow
+impesonation. Regardless of this setting, the user must be logged in to
+impersonate. If this setting is used, IMPERSONATE_REQUIRE_SUPERUSER is ignored.
+
+It is optional, and if it is not present, the previous rules about superuser
+and IMPERSONATE_REQUIRE_SUPERUSER apply.
+
+
+ IMPERSONATE_REDIRECT_FIELD_NAME
+
+A string that represents the name of a request (GET) parameter which contains
+the URL to redirect to after impersonating a user. This can be used to redirect
+to a custom page after impersonating a user. Example:
+
+ # in settings.py
+ IMPERSONATE_REDIRECT_FIELD_NAME = 'next'
+
+ # in your view
+ <a href="{% url 'impersonate-list' %}?next=/some/url/">switch user</a>
+
+To return always to the current page after impersonating a user, use request.path:
+
+ <a href="{% url 'impersonate-list' %}?next={{request.path}}">switch user</a>
+
+
+ IMPERSONATE_SEARCH_FIELDS
+
+Array of user model fields used for building searching query. Default value is
+[User.USERNAME_FIELD, 'first_name', 'last_name', 'email']. If the User model doesn't have
+the USERNAME_FIELD attribute, it falls back to 'username' (< Django 1.5).
+
+
+ IMPERSONATE_LOOKUP_TYPE
+
+A string that represents SQL lookup type for searching users by query on
+fields above. It is 'icontains' by default.
+
+ IMPERSONATE_DISABLE_LOGGING
+
+A bool that can be used to disable the logging of impersonation sessions. By
+default each impersonation ``session_begin`` signal will create a new
+``ImpersonationLog`` object, which is closed out (duration calculated) at
+the corresponding ``session_end`` signal.
+
+It is optional, and defaults to False (i.e. logging is enabled).
+
+ IMPERSONATE_MAX_FILTER_SIZE
+
+The max number of items acceptable in the admin list filters. If the number of
+items exceeds this, then the filter is removed (just shows all). This is used
+by the "Filter by impersonator" filter.
+
+It is optional, and defaults to 100.
+
+Testing
+=======
+
+You need factory_boy installed for tests to run. To install, use:
+
+ $ pip install factory_boy
+
+**Note:** This currently not required for Python 3.3+. For more info on factory_boy, see: https://github.com/dnerdy/factory_boy
+
+From the repo checkout, ensure you have Django in your PYTHONPATH and run:
+
+ $ python runtests.py
+
+To get test coverage, use::
+
+ $ coverate run --branch runtests.py
+ $ coverage html <- Pretty HTML files for you
+ $ coverage report -m <- Ascii report
+
+If you're bored and want to test all the supported environments, you'll need tox.::
+
+ $ pip install tox
+ $ tox
+
+And you should see::
+
+ py3.5-django1.10: commands succeeded
+ py3.5-django1.9: commands succeeded
+ py3.5-django1.8: commands succeeded
+ py3.4-django1.10: commands succeeded
+ py3.4-django1.9: commands succeeded
+ py3.4-django1.8: commands succeeded
+ py3.3-django1.8: commands succeeded
+ py2.7-django1.10: commands succeeded
+ py2.7-django1.9: commands succeeded
+ py2.7-django1.8: commands succeeded
+ congratulations :)
+
+Copyright & Warranty
+====================
+All documentation, libraries, and sample code are
+Copyright 2011 Peter Sanchez <petersanchez at gmail.com>. The library and
+sample code are made available to you under the terms of the BSD license
+which is contained in the included file, BSD-LICENSE.
+
+
+==================
+Commercial Support
+==================
+
+This software, and lots of other software like it, has been built in support of many of
+Netlandish's own projects, and the projects of our clients. We would love to help you
+on your next project so get in touch by dropping us a note at hello at netlandish.com.
diff --git a/impersonate/__init__.py b/impersonate/__init__.py
new file mode 100644
index 0000000..37f11b4
--- /dev/null
+++ b/impersonate/__init__.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+VERSION = (1, 1, 0, 'alpha', 0)
+
+
+# taken from django-registration
+
+def get_version():
+ "Returns a PEP 386-compliant version number from VERSION."
+ assert len(VERSION) == 5
+ assert VERSION[3] in ('alpha', 'beta', 'rc', 'final')
+
+ # Now build the two parts of the version number:
+ # main = X.Y[.Z]
+ # sub = .devN - for pre-alpha releases
+ # | {a|b|c}N - for alpha, beta and rc releases
+
+ parts = 2 if VERSION[2] == 0 else 3
+ main = '.'.join(str(x) for x in VERSION[:parts])
+
+ sub = ''
+ if VERSION[3] != 'final':
+ mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'}
+ sub = mapping[VERSION[3]] + str(VERSION[4])
+
+ return str(main + sub)
diff --git a/impersonate/admin.py b/impersonate/admin.py
new file mode 100644
index 0000000..9c66154
--- /dev/null
+++ b/impersonate/admin.py
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+import logging
+from django.conf import settings
+from django.contrib import admin
+
+from .helpers import User
+from .models import ImpersonationLog
+
+logger = logging.getLogger(__name__)
+
+
+def friendly_name(user):
+ '''Return proper name if exists, else username.'''
+ name = None
+ if hasattr(user, 'get_full_name'):
+ name = user.get_full_name()
+ return name or user.username
+
+
+class SessionStateFilter(admin.SimpleListFilter):
+ ''' Custom admin filter based on the session state.
+
+ Provides two filter values - 'complete' and 'incomplete'.
+ A session that has no session_ended_at timestamp is
+ considered incomplete. This field is set from the
+ session_end signal receiver.
+ '''
+ title = 'session state'
+ parameter_name = 'session'
+
+ def lookups(self, request, model_admin):
+ return (
+ ('incomplete', 'Incomplete'),
+ ('complete', 'Complete'),
+ )
+
+ def queryset(self, request, queryset):
+ if self.value() == 'incomplete':
+ return queryset.filter(session_ended_at__isnull=True)
+ if self.value() == 'complete':
+ return queryset.filter(session_ended_at__isnull=False)
+ else:
+ return queryset
+
+
+class ImpersonatorFilter(admin.SimpleListFilter):
+ ''' Custom admin filter based on the impersonator.
+
+ Provides a set of users who have impersonated at some point.
+ It is assumed that this is a small list of users - a subset
+ of staff and superusers. There is no corresponding filter
+ for users who have been impersonated, as this could be a
... 1622 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/django-impersonate.git
More information about the Python-modules-commits
mailing list