社交网站授权

Dav*_*542 11 python django authorization social-networking

我需要完成与权限相关的以下内容:

我有3个用户:

- User A
- User B
- User C
Run Code Online (Sandbox Code Playgroud)

每个用户都有以下文档和相关的访问设置:

- 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
Run Code Online (Sandbox Code Playgroud)

User A具有User B作为接触,但并不的接触User C(User B并且User C是接触).

因此,User 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)
Run Code Online (Sandbox Code Playgroud)

有人可以解释如何处理这些特权.如果你能把我链接到任何可以帮助我开始运作的文档或文章.谢谢.

Fel*_*eFG 7

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

但是,可重用的应用程序可以大大简化此任务.看看django-guardian其他在对象(或行)级别上工作的.

  • "每个类"我指的是django的admin和auth机制的默认方法.如果您有一个名为"文档"的模型并转到您网站的管理页面,您应该能够编辑用户并分配"yourapp |文档|可以添加文档"(以及"可以更改"和"可以删除" ").但是,这适用于所有Document实例.另一方面,通过"每个对象"(或"每行"),您应该能够为每个单独的文档(A1,A2等)指定权限(例如更改,删除或您可能创建的其他权限). (2认同)

Gar*_*het 5

一般的答案是找到文档所有者和给定联系人之间的距离.在计算机科学术语中,这是一个有向图.

http://techportal.inviqa.com/2009/09/07/graphs-in-the-database-sql-meets-social-networks/上有一篇很好的文章,其中包含一些涵盖此主题的SQL查询.这里是如何概念化问题,而不是试图总结整篇文章:

  • 从一张白纸开始.
  • 在页面的某个位置为每个人绘制一个点(在本例中为用户A,B和C).在CS术语中,这是一个"节点".
  • 从用户绘制箭头到他们所有的联系人.在CS术语中,这是"有向边缘"或"弧形".
    • 这在问题中并不明确,但看起来用户C必须是用户B的联系人,或者是用户A的其他联系人的另一个联系人(因为用户A可以读取C2和C4).
    • 因此,在这种情况下,您将从用户A - >用户B和用户B - >用户C绘制.

另外,如果作为"联系人"是相互的,则可以绘制线段(或双向箭头)而不是箭头.在CS术语中,这将是"无向"与"有向"图形.Facebook关系是一种无关的关系; 如果有人是我的朋友,那么我也是他们的朋友.相比之下,如果有人在我的Outlook通讯录中,我不一定是他们的.所以这是一种有针对性的关系.

随着更多用户被添加到绘图中,您会注意到用户的联系人距离一步之遥,并且他们的联系人联系人距离两步之遥.但是你只能沿着箭头的方向行进.

因此,联系人的问题是,"如何查找图表距离为1的所有节点?" 接触联系人的问题是,"我如何找到图形距离为2的所有节点?".虽然"两个或更少"可能更合适,因为您希望直接联系人可以访问所有"联系人联系人"内容.

对于一般情况,本文中描述的一些SQL查询可能提供一些见解.但是根据您的具体需要,我会考虑使用一些连接.

让我们考虑一个Users表,主键id和其他字段,以及一个HasContact只有两列的表:userIdcontactId.我们假设用户A的id为1,用户B为2,用户C为3. HasContact有行(1,2)和(2,3)来表示上述关系.

一组非常简单的SQL连接可以生成所有朋友或所有朋友朋友的列表.

以下查询将返回用户联系人的所有ID:

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
Run Code Online (Sandbox Code Playgroud)

如果您知道用户ID,则授权查询可能非常简单:

SELECT count(*)
  FROM Relationships "rel"
  WHERE rel.userid = $document_owner_user_id
    AND rel.contactid = $id_of_current_user
Run Code Online (Sandbox Code Playgroud)

如果查询返回0,那么我们知道当前用户不是文档所有者的联系人之一.

我们可以更新第二个查询以指示用户是否是联系人:

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
Run Code Online (Sandbox Code Playgroud)

这应该返回非零,只要在Relationships表中有条目,($document_owner_user_id, X)并且(X, $id_of_current_user)两者都存在.否则,它将返回零.

我知道这是一个长期而且有点间接的答案,所以如果您有任何问题请发表评论.