如何建立(GitHub)权限关系?

时间:2017-02-16 20:18:47

标签: database database-design web-applications relational-database data-modeling

tl; dr:我如何实现权限模型,例如github&#39>

已更新以尝试解决@ philipxy的一些评论:

我计划实现类似于github的权限模型:

  1. 用户
  2. 用户可以分组
  3. 用户可以在组织中
  4. 群组可以在组织中
  5. 允许用户对资产,组或组织中的任何C,R,U和D操作
    1. 允许那些(C,R,U,D)操作的个人用户
    2. 已获得这些权限的群组成员
    3. 已被授予这些权限的组织的成员
      1. 或作为该组属于具有权限的组织的组的成员
  6. 授予用户读取权限,因为资产/组/组织对匿名用户是可见的(可读的)(" public")
  7. 用户还应该拥有一组权限来说明他们是否可以对权限执行任何C,R,U或D(用户可以为其他用户创建权限[C,R,U,D] ,团体或组织)
    1. 用户可以为他们创建的任何资产,组或组织设置权限,也可以为他们设置权限的任何资产,组或组织设置权限。
  8. 这些权限将控制谁可以对站点中的资产,组和组织执行创建,读取,更新和删除(CRUD)操作。

    大致如何对此进行建模?

    显然我有这些模特:

    1. 资产
    2. 用户
    3. 组织
    4. 下一步是什么?

      1. 许可?
      2. PermissionType(捕获C / R / U / D)?
      3. 我正在使用节点中的mysql(通过sequelize),但是我可以自己弄清楚具体的语法,我还没有想出如何在概念上做到这一点。

        更多@ philipxy的观点:

        你提议我做的更多的事情确实是我认为我在寻求帮助的事情。也就是说,那些信息设计方法(NIAM,FCO-IM,ORM2,IDEF1X)是我正在寻找的。我对关系数据库实现(学习规范化和普通表单以及诸如此类的东西的日子)知之甚少,但实际上指定业务需求并将其转换为可操作规范的过程是一项挑战。

          由于与nodejs模块的名称冲突,很难找到
        • ORM2 :我已经下载了从NIAM wikipedia page
        • 链接的图书
        • 现在使用NIAM似乎不太常见?
        • FCO-IM:我已经从他们的网站下载了这本书
        • IDEF1X:看起来也很有趣

        我想我会去拿一本数据库教科书。

        更多关于谓词的工作:

        1. U标识User
        2. A标识Asset
        3. G标识Group
        4. User U可以是0或更多Groups G
        5. O标识Organization
        6. User U可以是0或更多Organizations O
        7. Group G可以是0或更多Organizations O
        8. 资产A可以由User U
        9. 创建
        10. Assets上的CRUD:
          1. 允许Entity E(通过Permission P?)在Ac上执行Assets
          2. 那些Actions是:
            1. Create
            2. Read
            3. Update
            4. Delete
          3. Entity可能是以下类型:
            1. User
            2. Group
            3. Organization
            4. Anonymous User /"公众"
          4. 详细信息(仅针对Read显示,但也与CreateUpdateDelete相关:
            1. User U0可以允许其他User U1 Read Asset A
            2. User U0可以Users U Group G成员Read Asset A }} User
            3. U0 Users可以U Organization O Read成员Asset A Users }} U
            4. {li} Group G1位于G1 Group,其中OrganizationO Read Asset因此允许A Read Asset被允许{} {}} A Permission
        11. 引用P Asset的{​​{1}} A只能由特定用户创建:
          1. 默认情况下,作为User的创建者的U Entity可以为Permissions创建Entity
          2. 但他们可能只引用Assets Permission {在基本情况下:那些AssetsU创建
          3. User Grant(?)权限Entity的用户还可以在E
          4. 中引用Permission Gr
          5. Grant标识Grant
            1. Entity授予Permissions创建,阅读,更新或删除Entity引用其他Permissions
            2. 的权限
            3. Grants类似,Organization具有传递性:
              1. 如果O GrantedPermissions特权(例如)修改Entity E的{​​{1}},那么
              2. Users成员O不仅可以Permissions修改E引用Users
                1. Group成员G G O Permissions E的成员{{1}}有权{{1}} {{1}} {{1}} {{1}} {1}}

3 个答案:

答案 0 :(得分:6)

谓词和表格

命题是对业务情况的真或假的陈述。 谓词是一个列参数化语句,给定一个行给出一个命题。表(基础或查询结果)保存从其谓词中生成真命题的行。

user (with id) U has name N
R is a grantor (may grant permissions)

user U has permission to update asset A
grantor R gave permission to grantor E to use an operator of type 'CRUD'
grantor E is of type 'user' AND grantor E has permission to update assets

业务规则

业务规则是一个永远真实的语句,用于定义术语或描述策略或过程。

A user is uniquely identified by an id assigned when their cheque clears.  
A crudable is an asset, group or organization.  
A grantor is a user, group, organization.
"Grantee" refers to a grantor receiving or holding a permission.    
Users can be in organizations.  

您可以创建无参数谓词的真实语句。这些可以使用由FOR ALL&绑定的参数名称。 FOR SOMETHERE EXISTS)。根据这些命题谓词和/或表名称表达的业务规则是数据库约束。鉴于User(U,N)& Grantor(R)作为上述前两个谓词的缩写,作为表User&的谓词Grantor,以下几行都说同样的事情:

A user is a grantor.
FOR ALL U, if U is a user then U is a grantor.

FOR ALL U, (FOR SOME N, User(U, N)) IMPLIES Grantor(U).
(SELECT U FROM User) ⊆ (SELECT R AS U FROM Grantor).

FOR ALL U & N, User(U, N) IMPLIES Grantor(U).
FOR ALL U & N, (U, N) IN User IMPLIES (U) IN Grantor.

FOREIGN KEY User (U) REFERENCES Grantor (R);说明上面做了什么(注意它与中间两个的相似性)加上在Grantor中R是UNIQUE NOT NULL。

不要将规则与谓词混淆。它们有不同的用途和用途。通常不同的形式。 (无参数句子模板可以用作其中之一。)规则是一个真实的陈述;谓词是参数化语句。看看我的答案是如何区分它们的。基表和查询结果表具有谓词。但是规则可能会建议您需要基本谓词/表来记录某些内容。当我们从规则中看到我们必须记录关于当前情况的一些陈述时,我们有基本谓词/表。请注意,一些规则不会激发基本谓词。

您可能希望 reify 类型和权限。

A user is a grantor of type 'user'.
Permission named 'C' is permission for a grantee to create a crudable.

Grantor E is of type 'user'.
Permission P is of type 'CRUD'.
Grantor R gave permission P of type 'CRUD' on crudable C to grantee E.

设计找到必要的&足够的规则和基本谓词

以下是记录您的说明所出现的情况的相关谓词。

  
      
  1. 用户
  2.   
U identifies a user
  
      
  1. 用户可以分组
  2.   
G identifies a group
user U is in group G
  
      
  1. 用户可以在组织中
  2.   
O identifies an organization
user U is in organization O
  
      
  1. 群组可以在组织中
  2.   
group G is in organization O
  
      
  1. 允许用户对资产,组或组织进行CRUD操作
  2.   
A identifies a crudable of type 'asset'
user U is permitted CRUD operations on crudable C
  

5.1作为单个用户,或作为组的成员,或作为组织的成员(或作为该组属于具有权限的组织的组的成员),

P identifies a permission
organization O is permitted CRUD operations on crudable C
  

或者因为资产/组/组织对匿名用户是可见的(可读的)(" public")

crudable C is public
  
      
  1. 用户还应具有一组权限,以表明他们是否可以设置上述权限
  2.   
grantor R has permission to set CRUD permission for users on crudable C --?  

什么是"以上权限"?也许你的意思是用户CRUD权限和组织CRUD权限?也许你的意思是有创建,阅读等操作的个人权限?你需要更清楚。

"一组权限"中的权限是什么?通过"许可"在这里,你真的意味着特定受让人的特别许可"?你需要更清楚。

更明确的方法是给出规则和规则。谓词尽可能简单,但也不是那么简单,以至于他们没有提到相关的实体/价值观。您可能之后想要概括多个规则和谓词为单一的。例如,不是与用户,团体,组织和资产打交道,而是拥有设施和夸大其词:Grantors may grant permissions.& grantor R gives permission P to grantee E。如果某些此类权限也与特定受助者相关联,则可能还需要grantor R gives permission P to grantee E re permission Q and grantee F等谓词。

  

6.1。用户可以为他们创建的任何资产,组或组织设置权限,

user U created crudable C
  

或已获得设置权限的任何资产,组或组织。

user U has permission to set permission P for crudable C --?  

您需要记录user U has name N and ...之类的内容。

了解数据库设计

搜索重新数据库/ SQL子类型/继承/多态性习语。例如,用户,组织和组织是许可拥有者和类型的许可者。持有人;我把它们作为一种类型的设保人的子类型。也许你想要某种许可目标类型,这是一种可以和谐的联盟。押。也许你想要各种类型的权限。也许某些权限权限与关联的受赠者有关。也许' C',' R',' U' &安培; ' d'是权限,&#CR;' CRUD'是一种权限。您可能想要记录授予者给予受让人什么许可的权利。

稍后我们可以通过连接替换表,如果连接在共享PK / UNIQUE上,并且两者中具有相同的值集。当我们加入PK / UNIQUE& FK我们可以用一个像它们的连接替换表,但是用FK可以为空。还有一些时候我们可以毫无问题地替换多个表。但首先确定基本谓词。

了解关系数据库设计。遵循一些信息设计方法。 Best是NIAM / FCO-IM / ORM2系列的成员。窥视IDEF1X。不要依赖产品。

了解约束。他们从谓词和业务规则中跟随。它们是关于谓词的可能业务情况的真相。同样,它们是关于表格中可能的数据库状态的真相。还要了解SQL中的约束,包括声明式(PK,UNIQUE,FK)和触发。

答案 1 :(得分:0)

在我看来,您需要创建一个可以在存储库或组织上接收权限的实体的概念。

在此模型中,问题变得相对简单,因为权限将围绕表单的RepositoryPermissions表:

(EntityId, RepositoryId, canCreate, canRead, canUpdate, canDelete)

和表格的OrganizationPermissions表:

(EntityId, OrganizationId, canCreate, canRead, canUpdate, canDelete)

有两种类型的实体GroupsUsers,并且需要以四种方式检查任何用户的权限:

  • 存储库级别的用户权限
  • 具有存储库级别权限的 用户 成员资格
  • 组织级别的用户权限
  • 具有组织级别权限的 用户成员资格。

以下查询应检索与存储库someUserId上的用户someRepoId相关的所有权限条目

    SELECT
      rp.canCreate,
      rp.canRead,
      rp.canWrite,
      rp.canDelete
    FROM RepositoryPermissions AS rp

    Left JOIN Users      AS u  ON u.EntityId = rp.EntityId
    Left JOIN Groups     AS g  ON g.EntityId = rp.EntityId
    Left JOIN GroupUsers AS gu ON gu.GroupId = g.GroupId

    WHERE rp.repositoryId IS "someRepoId" AND (
      u.UserId IS "someUserId" OR
      gu.UserId IS "someUserId"
    )
UNION
    SELECT 
      op.canCreate,
      op.canRead,
      op.canWrite,
      op.canDelete
    FROM Repositories AS r
    JOIN OrganizationPermissions AS op ON r.repositoryId = op.repositoryId

    Left JOIN Users      AS u  ON u.EntityId = op.EntityId
    Left JOIN Groups     AS g  ON g.EntityId = op.EntityId
    Left JOIN GroupUsers AS gu ON gu.GroupId = g.GroupId

    WHERE r.repositoryId IS "someRepoId" AND (
      u.UserId IS "someUserId" OR
      gu.UserID IS "someUserID"
    )

答案 2 :(得分:-2)

当您尝试使数据库的行为与Github相同时,这是有问题的。数据库具有完全不同的范例。这就是为什么根据C#的工作方式设计数据库同样糟糕的原因。不一样的功能或规则。然而,这是一个有趣的问题,因为很少有人关注权限模型作为数据库设计的一部分,只是给予每个人一切权利,因为它更容易。

首先,用户不应该向其他人授予权限,只有管理员才能这样做。如果您有良好的数据库设计,用户不应该创建对象。数据库设计没有业余爱好者处理的业务。

用户可以是个人,也可以使用来自特定应用程序的所有数据库请求具有相同权限的应用程序用户。应用程序甚至可以拥有多个通用用户,例如XYZAdmin,XYZUser,XYZReadonly(通常用于需要能够查看数据但不会对其进行调整的高级经理)。根据我的经验,通用用户面临的最大问题是难以审核谁更改了数据库中的内容(在受监管的环境中非常重要),而某些用户可能拥有的权限超出了他们真正需要的数量。

在数据库中,您有几种基本类型的权限。您具有扩展到整个数据库和对象级别权限的权限。您还具有一些特定的服务器权限,例如使用批量插入或执行作业的权限。还应为组提供关于他们可以在服务器上看到哪些数据库的权限,因为大多数数据库服务器都有多个数据库因此,您可以授予用户写入任何表的权限,或者授予他们对表的权限,但不授予对特定存储过程或视图的权限。通常,管理人员获得对所有内容的总体权限(或服务器级别权限,例如批量插入权限)。这包括拥有完整权限的DBA和其他专家,如数据分析师/高级开发人员/构建团队成员,他们可能只拥有与作业和数据输入相关的权限,或者创建新对象,但无权执行设置权限等任务。应锁定所有其他用户的对象级权限。

现在不应该给予任何人作为个人的权限(或者至少它应该是罕见的)。每个人都应该有权利的各种群体。可以在与您正在使用的特定数据库产品相关联的文档中解释个人可以在多个组中以及这些组之间的权利交互方式(是的,这是按产品特定的,没有一种尺寸适合所有数据库权限模型。)这样做的好处是,当某人不再是用户时,您只需将其从组中删除,权限就会消失,而不是搜索大量的个人权限。

现在,当您按组处理权限时,您需要定义组。如果希望组仅对记录或列的子集而不是整个表具有权限,则可能还需要定义一些其他视图或存储过程。如果一个数据库中有多个客户端并且需要确保权限仅针对一个特定客户端,则需要使用存储过程/视图并仅在存储过程/视图级别而不是在表级别授予权限。使用权限视图可能会变得棘手,因为每个数据库产品都有关于使视图可更新的具体规则。您需要深入了解这一点,以确定如何管理权限。

创建的所有数据库对象都需要为被授予该对象权限的特定组编写脚本,作为创建脚本的一部分。 (您永远不会通过任何类型的GUI创建数据库对象,始终通过源代码控制中保留的脚本。)

您还可以通过设置一些数据库表来执行一些客户端的权限工作,这些数据库表包含有关用户可以访问的特定页面或允许他访问的特定客户端的元数据。然后,当加载应用程序时,将加载来自这些表的用户数据,并且应用程序将决定他或她可以做什么。坦率地说这很容易,但风险很大。

这意味着用户必须具有表级权限,用户实际上不应该拥有这些权限。由于数据库级别权限更广泛,因此恶意用户更容易在应用程序外部登录并执行他或她应该无法执行的操作。如果您的内部用户可以通过SSMS for SQL Server之外的其他应用程序轻松登录,则需要特别小心。

如果您的数据库应用程序处于受法律监管的领域(例如财务或医疗保健),您需要对权限非常严格,并且禁止使用ORM而不是存储过程,因为您在任何时候都不应该在表级别设置权限