通过数据库触发器邀请用户的授权

时间:2013-10-15 20:01:21

标签: function postgresql stored-procedures authorization

给出以下架构:

Table "public.users"
        Column        |           Type           |                         Modifiers
----------------------+--------------------------+------------------------------------------------------------
 uuid                 | uuid                     | not null default uuid_generate_v4()
 email                | character varying(254)   | not null
 name                 | text                     | not null
 created_at           | timestamp with time zone | not null default now()

Table "public.users_projects"
     Column      |           Type           |                 Modifiers
-----------------+--------------------------+--------------------------------------------
 project_uuid    | uuid                     | not null
 user_uuid       | uuid                     | not null
 invitation_uuid | uuid                     |
 membership_type | membership_type          | not null default 'member'::membership_type
 created_at      | timestamp with time zone | not null default now()

Table "public.projects"
   Column   |           Type           |              Modifiers
------------+--------------------------+-------------------------------------
 uuid       | uuid                     | not null default uuid_generate_v4()
 name       | character varying(100)   | not null
 created_at | timestamp with time zone | not null default now()

Table "public.invitations"
     Column      |           Type           |                 Modifiers
-----------------+--------------------------+--------------------------------------------
 uuid            | uuid                     | not null default uuid_generate_v4()
 email           | character varying(254)   | not null
 target_type     | character varying(50)    | not null
 target_uuid     | uuid                     | not null
 membership_type | membership_type          | not null default 'member'::membership_type
 token           | character varying(32)    | not null default md5((random())::text)
 creator_uuid    | uuid                     | not null

还有一个枚举类型CREATE TYPE membership_type AS ENUM ('guest', 'member', 'manager', 'owner');

我想知道我是否可以使用触发器验证用户是否无法创建对资源的邀请,而且联接表上至少没有manager成员资格类型。

我的主要问题是:

  • 我可以在插入行之前使用触发器CREATE TRIGGER check_authorisation BEFORE INSERT OR UPDATE ON invitations FOR EACH ROW EXECUTE PROCEDURE check_authorisation();
  • 我可以在错误消息中提供多少信息,而不是因为数据库连接中断而导致失败等等。
  • 这是一个理智的方法吗?作为Web应用程序开发人员,我习惯于在应用程序代码中检查它的环境,但我正在研究一个将由两个应用程序共享的数据库(Golang和Ruby)
  • 我可以以某种方式在多态字段(REFERENCEStarget_type)上实现target_uuid吗?

1 个答案:

答案 0 :(得分:0)

  

我可以在插入行之前使用触发器,在插入或更新邀请之前创建TRIGGER check_authorisation对于每个行执行过程check_authorisation();

使其成为(后)约束触发器,并在适当时引发异常。

更一般地说,在触发器传播副作用和约束触发器以验证完整性之后,使用before触发器在需要时修改传入数据。

  

我可以在错误消息中提供多少信息,而不是因为数据库连接中断而导致失败,等等

在提出异常时要尽可能多地发送。

  

这是一种理智的方法吗?作为一名Web应用程序开发人员,我习惯于在应用程序代码中检查它的环境,但我正在研究一个将由两个应用程序共享的数据库(Golang和Ruby)

如果做得对,这可能是理智的,但是对于授权来说,基本上不可能妥善管理所有棘手的情况,因此这种类型的逻辑通常更好地位于数据库之外。

一个很好的例子:当经理的秘书更换(原来的产假是休产假)时会发生什么呢?

  

我能以某种方式在多态字段(target_type,target_uuid)上实现REFERENCES吗?

你可以使用后触发器。但是,根据您正在做的事情,请考虑使用单独的字段,外键和检查约束对其进行规范化,以确保它们是互斥的。管理通常比手动重写外键逻辑更容易/更清晰。