Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 社交网站中的授权_Python_Django_Authorization_Social Networking - Fatal编程技术网

Python 社交网站中的授权

Python 社交网站中的授权,python,django,authorization,social-networking,Python,Django,Authorization,Social Networking,我需要完成以下与特权相关的工作: 我有3个用户: - User A - User B - User C 每个用户都有以下具有关联访问设置的文档: - User A - Document A1, only allow contacts to view - Document A2, allow everyone to view - Document A3, allow no one to view except myself - Document A4, allow

我需要完成以下与特权相关的工作:

我有3个用户:

- User A
- User B
- User C
每个用户都有以下具有关联访问设置的文档:

- User A
    - Document A1, only allow contacts to view
    - Document A2, allow everyone to view
    - Document A3, allow no one to view except myself
    - Document A4, allow contacts, and contacts of contacts to view
- User B
    - Documents B1, B2, B3, B4 with similar privileges
- User C
    - Documents C1, C2, C3, C4 with similar privileges
用户A
用户B
作为联系人,但不是
用户C
的联系人(
用户B
用户C
是联系人)

因此,
用户A
将能够查看以下内容:

- Document B1 (contacts can view)
- Document B2 (everyone can view) 
- Document B4 (contacts of contacts)
- Document C2 (everyone can view)
- Document C4 (contacts of contacts)

我有兴趣了解如何处理这些特权。我也在寻找任何有助于我起步的文档或文章。

您基本上需要的是。但是带有“联系人中的联系人”的部分可能会导致非常复杂的sql查询。我建议你重新考虑这个要求。(我有很多我喜欢和信任的好朋友。但是他们有各种各样的奇怪的人作为朋友…

不幸的是,Django的授权系统不允许您为每个对象分配权限,只允许为每个类分配权限。这里我假设您的每个“文档”都是一个模型类的实例

然而,有一些可重用的应用程序大大简化了这项任务。查看或处理对象(或行)级别的内容。

可以包含“朋友的朋友”字段。这将是一个非常大的表(比如,200*200*N=40000*N…如果你对朋友没有限制,并且某人是100万人的朋友,也就是100万人有100万FoF),那么这将比每个视图访问数据库200次更容易。

你需要的是一个根据每个用户网络而变化的表。标准
django.contrib.auth
模块中没有ACL和基于对象的权限。实际上,我已经在Django中实现了一个ACL,但它是基于类而不是基于对象的。在应用程序的上下文中,它的工作原理就像
用户A
可以查看任何人的文档,只要他在某个授权组(比如
管理员
组)中。但是,如果
用户A
用户B
联系人组中,它可以像
用户A
一样工作,可以查看
用户B
的文档

我可以从定制的auth应用程序的模型结构方面解释如何做到这一点。
用户
权限
模型将与标准Django auth应用程序相同(您可以从中复制)。然后,您需要一个模型来表示不同级别的权限(每个人、联系人、联系人、我自己)。这样做很简单,只需向标准django auth groups模型添加另一个字段。此字段将是同一模型的外键,它将表示每个组将从中继承的组。现在模型看起来像这样

class SocialGroup(models.Model):
  name = models.CharField(unique=True, max_length=150)
  parent = models.ForeignKey('self')
现在,您可以添加关系,例如
联系人
group,通过将
每个人
group设置为
联系人
组的父级,可以查看
每个人
组可以查看的所有内容。请注意,与
权限
模型没有外键关系。接下来,我们需要一种方法来指定用户和组之间的关系

class Relationship(models.Model):
  user  = models.ForeignKey(User)
  related_user = models.ForeignKey(User)
  related_by = models.ForeignKey(SocialGroup)
在这个模型中,我们可以说
用户A
(相关用户)通过处于
用户B
s
联系人组中而与
用户B
(用户)相关。然后我们需要一种为每个文档指定权限的方法

class DocumentPermissions(models.Model):
  document = models.ForeignKey(Document)
  group = models.ForeignKey(SocialGroup)
  Permission = models.ForeignKey(Permission)
现在我们可以说
联系人
组拥有
可以查看
文档B1
的权限。请注意,此模型应位于文档模型所在的任何位置,而不是在新的auth应用程序中的auth models.py。就这样,现在我们所要做的就是编写逻辑来查找给定用户对给定文档的权限。因此,当
用户B
试图查看
文档A1
时,我们需要做的是

  • 首先检查文档属于哪个人(
    用户A
  • 然后查找所有者和试图从关系模型(联系人)访问文档的人之间的关系组
  • 然后检查
    DocumentPermissions
    ,查看该组或其继承的任何组是否具有查看文档的权限

此逻辑可以在Django的新身份验证后端(将使用我们的新身份验证模型)中实现,Django可以进入新的身份验证应用程序。您可以在标准中检查
是否具有\u perm
功能。这就是你需要做的。所有的装饰器和其他东西仍然可以工作。

一般的答案是找到文档所有者和给定联系人之间的距离。用计算机科学的术语来说,这是一个问题

上有一篇很好的文章介绍了一些SQL查询,介绍了这个主题。以下是如何将问题概念化,而不是试图总结整篇文章:

  • 从一张空白的纸开始
  • 在页面上为每个人(在本例中为用户a、B和C)的某处画一个点。在CS术语中,这是一个“节点”
  • 从用户到其所有联系人绘制箭头。在CS术语中,这是“定向边”或“弧”。
    • 这在问题中并不明确,但看起来用户C必须是用户B的联系人,或者是用户a的其他联系人中的另一个联系人(因为用户a可以读取C2和C4)
    • 在本例中,您将从用户A->用户B和用户B->用户C中进行绘制
另一方面,如果“接触”是相互的,则可以绘制线段(或双向箭头)而不是箭头。在CS术语中,这将是一个“无向”与“定向”图。Facebook关系是一种无方向的关系;如果有人是我的朋友,那么我也是他们的朋友。相反,如果有人在我的Outlook通讯录中,我不一定在他们的通讯录中。所以这是一种定向关系

随着越来越多的用户添加到图形中,您会注意到用户的联系人距离您只有一步之遥,而他们的联系人距离您只有两步之遥。但你只能沿着箭头的方向行进

所以,联系人的问题是,“我该怎么做
SELECT contact.id
  FROM Users "user"
    LEFT JOIN Relationships "rel"
      ON user.id = rel.userid
    LEFT JOIN Users "contact"
      ON rel.contactId = contact.id
  WHERE user.id = $id_of_current_user
SELECT count(*)
  FROM Relationships "rel"
  WHERE rel.userid = $document_owner_user_id
    AND rel.contactid = $id_of_current_user
SELECT count(*)
  FROM Relationships "rel_1"
    INNER JOIN Relationships "rel_2"
      ON rel_1.contactId = rel_2.userId
  WHERE rel_1.userid = $document_owner_user_id
    AND rel_2.contactid = $id_of_current_user