[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