@@ 1,10 1,10 @@
django-impersonate |nlshield|
-----------------------------
-Simple application to allow superusers to "impersonate" other
+Simple application to allow superusers to “impersonate” other
non-superuser accounts.
-**Version:** 1.6
+**Version:** 1.7.1
**Project Links:**
`Issues <https://todo.code.netlandish.com/~petersanchez/django-impersonate>`__
@@ 35,7 35,7 @@ Dependencies
- **Version 1.6** has officially removed support for the old settings
format. Please see the `settings <#settings>`__ section for how
settings should be configured.
-- **Version 1.5 is now only officially supporting Django's 1.11, 2.2,
+- **Version 1.5 is now only officially supporting Django’s 1.11, 2.2,
and 3.0**
- **Version 1.4 is now officially supporting Python 3.6+ and Django
1.11+**
@@ 64,14 64,14 @@ PIP:
::
- pip install django-impersonate
+ pip install django-impersonate
Basic Manual Install:
::
- $ python setup.py build
- $ sudo python setup.py install
+ $ python setup.py build
+ $ sudo python setup.py install
Alternative Install (Manually):
@@ 82,18 82,18 @@ variable to include a directory where th
Use
===
-1. Add ``impersonate`` to your INSTALLED\_APPS
+1. Add ``impersonate`` to your INSTALLED_APPS
2. Add ``impersonate.middleware.ImpersonateMiddleware`` to your
``MIDDLEWARE`` setting.
3. 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) ...
- )
+ 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
@@ 105,30 105,30 @@ Functionality
::
- /impersonate/<user-id>/
+ /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
+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...:
+in your templates or view, you just do something like…:
::
- {% if user.is_impersonate %} .... {% endif %}
+ {% if user.is_impersonate %} .... {% endif %}
The original user is available as ``request.impersonator``:
::
- {{ request.user }} ({{ request.impersonator }})
+ {{ request.user }} ({{ request.impersonator }})
The real user is available as ``request.real_user`` - this is equivalent
to calling ``getattr(request, 'impersonator', request.user)``:
::
- assert request.real_user == getattr(request, 'impersonator', request.user)
+ assert request.real_user == getattr(request, 'impersonator', request.user)
You can reference this URL with ``reverse`` or the ``{% url %}``
template tag as ``impersonate-start`` and expects the argument of the
@@ 136,14 136,14 @@ user ID. Example:
::
- reverse('impersonate-start', args=[user.id])
- reverse('impersonate-start', uid=user.id)
+ reverse('impersonate-start', args=[user.id])
+ reverse('impersonate-start', uid=user.id)
**To remove the impersonation, hit the following path:**
::
- /impersonate/stop/
+ /impersonate/stop/
You can reference this URL with ``reverse`` or the ``{% url %}``
template tag as ``impersonate-stop``. When you call this URL, you will
@@ 154,7 154,7 @@ be redirected to the page that you used
::
- /impersonate/list/
+ /impersonate/list/
This will render the template ``impersonate/list_users.html`` and will
pass the following in the context:
@@ 171,9 171,9 @@ template tag as ``impersonate-list``.
::
- /impersonate/search/
+ /impersonate/search/
-This will render the template 'impersonate/search\_users.html' and will
+This will render the template ‘impersonate/search_users.html’ and will
pass the following in the context:
- ``users`` - queryset of all users
@@ 249,28 249,28 @@ For example:
::
- IMPERSONATE = {
- 'REDIRECT_URL': '/some-path/',
- 'PAGINATE_COUNT': 10,
- }
+ IMPERSONATE = {
+ 'REDIRECT_URL': '/some-path/',
+ 'PAGINATE_COUNT': 10,
+ }
-Here are the options available...
+Here are the options available…
::
- REDIRECT_URL
+ 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.
+LOGIN_REDIRECT_URL setting and fall back to ‘/’ if neither is present.
Value should be a string containing the redirect path.
::
- READ_ONLY
+ READ_ONLY
A boolean that if set to ``True`` any requests that are not either
-``GET`` or ``HEAD`` will result in a "Bad Request" response (status code
+``GET`` or ``HEAD`` will result in a “Bad Request” response (status code
405). Use this if you want to limit your impersonating users to read
only impersonation sessions.
@@ 278,27 278,27 @@ Value should be a boolean, defaults to `
::
- USE_HTTP_REFERER
+ 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
+‘/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 ``REDIRECT_URL``.
Value should be a boolean, defaults to ``False``
::
- PAGINATE_COUNT
+ 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.
::
- REQUIRE_SUPERUSER
+ 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
@@ 315,33 315,33 @@ this setting is ignored.
::
- ALLOW_SUPERUSER
+ 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 REQUIRE\_SUPERUSER.
+superusers, regardless of the value of REQUIRE_SUPERUSER.
Value should be a boolean and the default is ``False``.
::
- URI_EXCLUSIONS
+ URI_EXCLUSIONS
Set to a list/tuple of url patterns that, if matched, user impersonation
is not completed. It defaults to:
::
- (r'^admin/',)
+ (r'^admin/',)
If you do not want to use even the default exclusions then set the
setting to an empty list/tuple.
::
- CUSTOM_USER_QUERYSET
+ CUSTOM_USER_QUERYSET
A string that represents a function (e.g.
``module.submodule.mod.function_name``) that allows more fine grained
@@ 351,17 351,17 @@ 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. ``REQUIRE_SUPERUSER`` and ``CUSTOM_ALLOW``).
+(cf. ``REQUIRE_SUPERUSER`` and ``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()``).
+user (i.e. the default is ``User.objects.all()``).
::
- CUSTOM_ALLOW
+ CUSTOM_ALLOW
A string that represents a function (e.g.
``module.submodule.mod.function_name``) that allows more fine grained
@@ 375,7 375,7 @@ superuser and ``REQUIRE_SUPERUSER`` appl
::
- REDIRECT_FIELD_NAME
+ 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
@@ 383,62 383,62 @@ used to redirect to a custom page after
::
- # in settings.py
- IMPERSONATE = {'REDIRECT_FIELD_NAME': 'next'}
+ # in settings.py
+ IMPERSONATE = {'REDIRECT_FIELD_NAME': 'next'}
- # in your template
- <a href="{% url 'impersonate-list' %}?next=/some/url/">switch user</a>
+ # in your template
+ <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>`
+ `<a href="{% url 'impersonate-list' %}?next={{request.path}}">switch user</a>`
Each use case is different so obviously set the next value to whatever
your case requires.
::
- SEARCH_FIELDS
+ 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).
+``email``]. If the User model doesn’t have the ``USERNAME_FIELD``
+attribute, it falls back to ‘username’ (< Django 1.5).
::
- LOOKUP_TYPE
+ LOOKUP_TYPE
A string that represents SQL lookup type for searching users by query on
fields above. It is ``icontains`` by default.
::
- DISABLE_LOGGING
+ DISABLE_LOGGING
A boolean 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).
+It is optional, and defaults to False (i.e. logging is enabled).
::
- MAX_FILTER_SIZE
+ MAX_FILTER_SIZE
The max number of items acceptable in the admin list filters. If the
number of items exceeds this, then the filter list is the size of the
-settings value. This is used by the "Filter by impersonator" filter.
+settings value. This is used by the “Filter by impersonator” filter.
It is optional, and defaults to 100.
::
- ADMIN_DELETE_PERMISSION
+ ADMIN_DELETE_PERMISSION
A boolean to enable/disable deletion of impersonation logs in the Django
admin.
@@ 447,7 447,7 @@ Default is ``False``
::
- ADMIN_ADD_PERMISSION
+ ADMIN_ADD_PERMISSION
A boolean to enable/disable ability to add impersonation logs in the
Django admin.
@@ 456,9 456,9 @@ Default is ``False``
::
- ADMIN_READ_ONLY
+ ADMIN_READ_ONLY
-A boolean to enable/disable "read only" mode of impersonation logs in
+A boolean to enable/disable “read only” mode of impersonation logs in
the Django admin. Generally you want to leave this enabled otherwise
admin users can alter logs within the Django admin area.
@@ 466,21 466,21 @@ Default is ``True``
::
- MAX_DURATION
+ MAX_DURATION
A number specifying the maximum allowed duration of impersonation
sessions in **seconds**.
-Default is `None`
+Default is ``None``
Admin
=====
As of version 1.3 django-impersonate now includes a helper admin mixin,
located at ``impersonate.admin.UserAdminImpersonateMixin``, to include
-in your User model's ModelAdmin. This provides a direct link to
-impersonate users from your user model's Django admin list view. Using
-it is very simple, however if you're using the default
+in your User model’s ModelAdmin. This provides a direct link to
+impersonate users from your user model’s Django admin list view. Using
+it is very simple, however if you’re using the default
``django.contrib.auth.models.User`` model you will need to unregister
the old ModelAdmin before registering your own.
@@ 489,23 489,23 @@ The ``UserAdminImpersonateMixin`` has a
True a new window will be opened to start the new impersonation session
when clicking the impersonate link directly in the admin.
-Here's an example:
+Here’s an example:
::
- # yourapp/admin.py
- from django.contrib import admin
- from django.contrib.auth.models import User
- from django.contrib.auth.admin import UserAdmin
- from impersonate.admin import UserAdminImpersonateMixin
+ # yourapp/admin.py
+ from django.contrib import admin
+ from django.contrib.auth.models import User
+ from django.contrib.auth.admin import UserAdmin
+ from impersonate.admin import UserAdminImpersonateMixin
- class NewUserAdmin(UserAdminImpersonateMixin, UserAdmin):
- open_new_window = True
- pass
+ class NewUserAdmin(UserAdminImpersonateMixin, UserAdmin):
+ open_new_window = True
+ pass
- admin.site.unregister(User)
- admin.site.register(User, NewUserAdmin)
+ admin.site.unregister(User)
+ admin.site.register(User, NewUserAdmin)
Testing
=======
@@ 515,38 515,38 @@ and run:
::
- $ python runtests.py
+ $ python runtests.py
To get test coverage, use:
::
- $ coverage run --branch runtests.py
- $ coverage html <- Pretty HTML files for you
- $ coverage report -m <- Ascii report
+ $ coverage 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
+If you’re bored and want to test all the supported environments, you’ll
need tox.:
::
- $ pip install tox
- $ tox
+ $ pip install tox
+ $ tox
And you should see:
::
- py36-django2.2: commands succeeded
- py36-django3.0: commands succeeded
- py36-django3.1: commands succeeded
- py37-django2.2: commands succeeded
- py37-django3.0: commands succeeded
- py37-django3.1: commands succeeded
- py38-django2.2: commands succeeded
- py38-django3.0: commands succeeded
- py38-django3.1: commands succeeded
- congratulations :)
+ py36-django2.2: commands succeeded
+ py36-django3.0: commands succeeded
+ py36-django3.1: commands succeeded
+ py37-django2.2: commands succeeded
+ py37-django3.0: commands succeeded
+ py37-django3.1: commands succeeded
+ py38-django2.2: commands succeeded
+ py38-django3.0: commands succeeded
+ py38-django3.1: commands succeeded
+ congratulations :)
Contributing
============
@@ 554,10 554,6 @@ Contributing
We accept patches submitted via ``hg email`` which is the ``patchbomb``
extension included with Mercurial.
-Please see our `contributing
-document <https://man.code.netlandish.com/contributing.md>`__ for more
-information.
-
The mailing list where you submit your patches is
``~petersanchez/public-inbox@lists.code.netlandish.com``. You can also
view the archives on the web here:
@@ 569,14 565,14 @@ mailing list just edit your ``.hg/hgrc``
::
- [email]
- to = ~petersanchez/public-inbox@lists.code.netlandish.com
+ [email]
+ to = ~petersanchez/public-inbox@lists.code.netlandish.com
- [patchbomb]
- flagtemplate = "django-impersonate"
+ [patchbomb]
+ flagtemplate = "django-impersonate"
- [diff]
- git = 1
+ [diff]
+ git = 1
We have more information on the topic here:
@@ 598,7 594,7 @@ 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
+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@netlandish.com.