跳转到主要内容

Django应用程序,允许超级用户模拟其他用户。

项目描述

django-impersonate nlshield

简单应用程序,允许超级用户“模拟”其他非超级用户账户。

版本 1.9.4

项目链接: 问题 - 邮件列表 - 贡献

作者: Peter Sanchez (https://petersanchez.com)

Python / Django 支持

  • Python 3.7+ 用于 Django 版本 3.2+

注意: 从版本 1.4 开始,我们仅正式支持由官方项目支持的所有Python和Django版本。因此,如果一个Python或Django版本已过时,我们将不再支持该版本。

依赖关系

  • 依赖于您的项目使用django.contrib.session框架。

注意

  • 版本1.9.3及以下版本容易受到XSS脚本漏洞的攻击,攻击者可以构造恶意URL并执行JS,如果授权用户点击/跟随该URL。请升级到1.9.3或更高版本。

  • 版本1.6已正式移除对旧设置格式的支持。请参阅设置部分了解如何配置设置。

  • 版本1.5现在仅正式支持Django的1.11、2.2和3.0

  • 版本1.4现在正式支持Python 3.6+和Django 1.11+

  • 版本1.3增加了设置格式更改。请参阅“设置”部分以获取详细信息。

  • 版本1.0默认添加了新功能。请参阅DISABLE_LOGGING设置选项。

  • 如果您需要与1.8版本以下的Django一起使用,请使用版本django-impersonate == 1.0.1。

  • 如果您需要与1.7版本以下的Django一起使用,请使用版本django-impersonate == 0.9.2。

  • 版本0.9.2部分撤销了0.9.1版本中完成的工作。这是因为在处理问题#17时所做的更改破坏了所有先前版本的默认行为。问题#24已打开,并在0.9.2中发布了修复程序。请参阅新的USE_HTTP_REFERER设置选项。

  • 如果您需要与1.4版本以下的Django一起使用,请使用版本django-impersonate == 0.5.3。

安装

PIP

pip install django-impersonate

基本手动安装

$ python setup.py build
$ sudo python setup.py install

替代安装(手动)

将impersonate目录放在您的Python路径中。可以在您的Python安装的site-packages目录中,或者设置您的$PYTHONPATH环境变量以包括impersonate目录所在的目录。

使用

  1. impersonate添加到您的INSTALLED_APPS

  2. impersonate.middleware.ImpersonateMiddleware添加到您的MIDDLEWARE设置中。

  3. 在您的URL结构中添加impersonate.urls。例如

    urlpatterns = patterns('',
        url(r'^admin/', include(admin.site.urls)),
        url(r'^impersonate/', include('impersonate.urls')),
        ... (all your other urls here) ...
    )

注意:应该将ImpersonationMiddleware类放置在django.contrib.auth.*中间件类之后。

功能

您现在可以通过以下路径来冒充另一个用户

/impersonate/<user-id>/

将<user-id>替换为您想要冒充的用户ID。

在“冒充”模式下,request.user对象将有一个is_impersonate属性设置为True,以及impersonator(以及也request.impersonator)设置为原始用户。因此,如果您想在模板或视图中进行检查,您只需做如下操作...

{% if user.is_impersonate %} .... {% endif %}

原始用户可用作user.impersonatorrequest.impersonator

{{ request.user }} ({{ request.impersonator }})

真实用户可用作request.real_user - 这与调用getattr(request, 'impersonator', request.user)等效。

assert request.real_user == getattr(request, 'impersonator', request.user)

您可以使用reverse或模板标签{% url %}通过impersonate-start引用此URL,并期望用户ID作为参数。示例

reverse('impersonate-start', args=[user.id])
reverse('impersonate-start', uid=user.id)

要取消冒充,请访问以下路径

/impersonate/stop/

您可以使用reverse或模板标签{% url %}通过impersonate-stop引用此URL。当您调用此URL时,您将被重定向到您开始冒充用户时使用的页面(例如,一些搜索结果或用户列表)。

要列出所有用户,您可以访问

/impersonate/list/

这将渲染模板impersonate/list_users.html,并将以下内容传递到上下文中

  • users - 所有用户的查询集

  • paginator - Django Paginator实例

  • page - 对象的当前页(来自Paginator)

  • page_number - 当前页码,默认为1

您可以使用reverse或模板标签{% url %}通过impersonate-list引用此URL。

要搜索所有用户,您可以访问

/impersonate/search/

这将渲染模板“impersonate/search_users.html”,并将以下内容传递到上下文中

  • users - 所有用户的查询集

  • paginator - Django Paginator实例

  • page - 对象的当前页(来自Paginator)

  • page_number - 当前页码,默认为1

  • 查询 - 输入的搜索查询

视图将期望一个GET请求,并寻找传递的q变量。如果存在,它将使用q的值搜索用户条目。默认搜索的字段是

User.usernameUser.first_nameUser.last_nameUser.email

您可以使用reverse{% url %}模板标签以impersonate-search的形式引用此URL。

允许某些用户假冒其他用户

您可以选择通过添加CUSTOM_ALLOW设置选项来仅允许某些非超级用户和非工作人员用户假冒。创建一个函数,该函数接收请求对象,并根据您的规则,如果用户被允许假冒则返回True

限制用户可以假冒的用户

通过可选地设置CUSTOM_USER_QUERYSET选项,您可以控制哪些用户可以被假冒。它接收一个用户请求对象,并返回用户查询集。这在搜索要假冒的用户、列出要假冒的用户和尝试开始假冒时使用。

信号

如果您想挂钩到假冒会话(例如,为了审计访问),django-impersonate会在会话的开始和结束时触发两个信号

  • session_begin - 在调用impersonate视图时发送

  • session_end - 在调用stop_impersonate视图时发送

这两个信号都发送相同的参数

  • sender - 这是Django信号的要求,始终设置为None

  • impersonator - 假冒者的User对象引用

  • impersonating - 被假冒者的User对象引用

  • request - 从中调用假冒的Django HttpRequest对象

请求对象被包含在内,因为它包含您可能希望审计的相关信息,例如客户端IP地址、用户代理字符串等。

有关如何连接信号的示例,请参阅相关的测试 - test_successful_impersonation_signals

session_end信号仅在假冒者明确结束会话时才会触发。

设置

以下设置可供django-impersonate使用。所有设置都应作为字典变量设置在名为IMPERSONATE的属性中。

例如

IMPERSONATE = {
    'REDIRECT_URL': '/some-path/',
    'PAGINATE_COUNT': 10,
}

以下是可用的选项...

REDIRECT_URL

这是您选择假冒其他用户后想要重定向到的URL。如果不存在,它将检查LOGIN_REDIRECT_URL设置,如果两者都不存在,则回退到‘/’。值应是一个包含重定向路径的字符串。

READ_ONLY

一个布尔值,如果设置为True,则任何不是GETHEADOPTIONS的请求将导致“Bad Request”响应(状态码405)。如果您想限制假冒用户为只读假冒会话,请使用此选项。

值应是一个布尔值,默认为False

如果设置了 CUSTOM_READ_ONLY,则使用该自定义函数,并忽略此设置。

CUSTOM_READ_ONLY

表示函数的字符串(例如 module.submodule.mod.function_name),允许更精细地控制哪些用户具有只读访问权限。它接受一个参数,即请求对象,并且应该返回 True 来仅允许 GETHEADOPTIONS 请求。

这是可选的,如果不存在,则应用 READ_ONLY 设置值。

USE_HTTP_REFERER

如果设置为 True,则在停止模拟后,应用将尝试将您重定向到模拟开始时的 URL。例如,如果您在开始模拟用户时位于 URL ‘/foo/bar/’,则在结束模拟后,您将被重定向回 ‘/foo/bar/’,而不是 REDIRECT_URL 中的值。

值应是一个布尔值,默认为False

PAGINATE_COUNT

这是在使用列表或搜索视图时按页分组的用户数量。默认值为 20。值应该是整数。

REQUIRE_SUPERUSER

如果设置为 True,则只有将 is_superuser 设置为 True 的用户才能模拟其他用户。默认值为 False。如果 False,则任何 is_staff 用户都可以模拟其他用户。

注意:无论此设置如何,is_staff 用户将不允许模拟 is_superuser 用户。

值应该是布尔值

如果设置了 CUSTOM_ALLOW,则使用该自定义函数,并忽略此设置。

ALLOW_SUPERUSER

默认情况下,超级用户不能被模拟;此设置允许这样做。

注意:即使此设置为 true,也仅超级用户可以模拟其他超级用户,无论 REQUIRE_SUPERUSER 的值如何。

值应该是布尔值,默认值为 False

URI_EXCLUSIONS

设置为列表/元组,其中包含 URL 模式,如果匹配,则不完成用户模拟。默认为

(r'^admin/',)

如果您甚至不想使用默认排除项,请将该设置设置为空列表/元组。

CUSTOM_USER_QUERYSET

表示函数的字符串(例如 module.submodule.mod.function_name),允许更精细地控制哪些用户可以被用户模拟。它接受一个参数,即请求对象,并应返回一个 QuerySet。只有此 QuerySet 中的用户可以被模拟。

当请求具有未经授权的用户时,将不会调用此函数,并且仅在用户被允许模拟时(与 REQUIRE_SUPERUSERCUSTOM_ALLOW 相比)才会调用。

无论此函数返回什么,用户都不能模拟超级用户,即使返回的 QuerySet 中有超级用户。

这是可选的,如果不存在,则用户可以模拟任何用户(即默认为 User.objects.all())。

CUSTOM_ALLOW

表示函数的字符串(例如 module.submodule.mod.function_name),允许更精细地控制谁可以使用模拟。它接受一个参数,即请求对象,并应返回 True 以允许模拟。无论此设置如何,用户必须登录才能模拟。如果使用此设置,则忽略 REQUIRE_SUPERUSER

这是可选的,如果不存在,则应用有关超级用户和 REQUIRE_SUPERUSER 的先前规则。

REDIRECT_FIELD_NAME

表示请求(GET)参数名称的字符串,该参数包含在模拟用户后要重定向到的 URL。这可以用于在模拟用户后重定向到自定义页面。例如

# in settings.py
IMPERSONATE = {'REDIRECT_FIELD_NAME': 'next'}

# in your template
<a href="{% url 'impersonate-list' %}?next=/some/url/">switch user</a>

在模拟用户后始终返回当前页面,请使用request.path。

`<a href="{% url 'impersonate-list' %}?next={{request.path}}">switch user</a>`

每个用例都不同,因此显然将下一个值设置为您的用例所需的任何值。

SEARCH_FIELDS

用于构建搜索查询的用户模型字段数组。默认值是[User.USERNAME_FIELDfirst_namelast_nameemail]。如果User模型没有USERNAME_FIELD属性,则回退到‘username’(< Django 1.5)。

LOOKUP_TYPE

表示通过在上述字段上查询来搜索用户的SQL查找类型的字符串。默认为icontains

DISABLE_LOGGING

一个布尔值,可以用来禁用模拟会话的日志记录。默认情况下,每个模拟session_begin信号都会创建一个新的ImpersonationLog对象,该对象在相应的session_end信号中关闭(计算持续时间)。

它是可选的,默认为False(即启用日志记录)。

MAX_FILTER_SIZE

在管理列表过滤器中可接受的最大项目数。如果项目数量超过此数,则过滤器列表的大小为设置值的大小。这用于“按模拟者筛选”过滤器。

它是可选的,默认为100。

ADMIN_DELETE_PERMISSION

一个布尔值,用于启用/禁用在Django管理中删除模拟日志。

默认为False

ADMIN_ADD_PERMISSION

一个布尔值,用于启用/禁用在Django管理中添加模拟日志的能力。

默认为False

ADMIN_READ_ONLY

一个布尔值,用于启用/禁用在Django管理中模拟日志的“只读”模式。通常您想保留此启用状态,否则管理员用户可以在Django管理区域中更改日志。

默认为True

MAX_DURATION

指定模拟会话允许的最大持续时间的数字(以秒为单位)。

默认为None

管理

从版本1.3开始,django-impersonate现在包括一个助手管理混合,位于impersonate.admin.UserAdminImpersonateMixin,可以将其包含在您的User模型ModelAdmin中。这提供了从您的用户模型Django管理列表视图直接模拟用户的能力。使用它非常简单,但是如果您使用的是默认的django.contrib.auth.models.User模型,您需要在注册自己的ModelAdmin之前注销旧的管理员。

UserAdminImpersonateMixin有一个名为open_new_window的属性,默认为False。如果将其设置为True,则在直接在管理中点击模拟链接时将打开新窗口以启动新的模拟会话。

以下是一个示例

# 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

admin.site.unregister(User)
admin.site.register(User, NewUserAdmin)

测试

从仓库检出,确保您在PYTHONPATH中安装了Django,然后运行

$ python runtests.py

要获取测试覆盖率,请使用

$ coverage run --branch runtests.py
$ coverage html  <- Pretty HTML files for you
$ coverage report -m  <- Ascii report

如果您无聊并想测试所有支持的环境,您将需要tox。

$ pip install tox
$ tox

您应该看到

py37-django2.2: commands succeeded
py37-django3.2: commands succeeded
py38-django2.2: commands succeeded
py38-django3.2: commands succeeded
py39-django2.2: commands succeeded
py39-django3.2: commands succeeded
py38-django4.0: commands succeeded
py39-django4.0: commands succeeded
py310-django3.2: commands succeeded
py310-django4.0: commands succeeded
congratulations :)

贡献

我们接受通过hg email提交的补丁,这是Mercurial中包含的patchbomb扩展。

您提交补丁的邮件列表是~petersanchez/public-inbox@lists.code.netlandish.com。您也可以在此处查看存档

https://lists.code.netlandish.com/~petersanchez/public-inbox

要快速设置克隆的django-impersonate以提交到邮件列表,请编辑您的.hg/hgrc文件并添加以下内容

[email]
to = ~petersanchez/public-inbox@lists.code.netlandish.com

[patchbomb]
flagtemplate = {separate(' ', 'django-impersonate', flags)}

[diff]
git = 1

我们在此处提供了更多关于此主题的信息

商业支持

本软件及其类似软件已支持Netlandish的许多自身项目和客户项目。我们很乐意帮助您在下一个项目上,请通过发送邮件到 hello@netlandish.com 与我们联系。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源代码发行版

django_impersonate-1.9.4.tar.gz (26.7 kB 查看哈希值)

上传时间 源代码

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面