使用数据库检查 Yesod 中的管理员权限

Check for admin permissions in Yesod using database

我正在尝试以类似于 these Yesod book examples 的方式实现 isAdmin 函数。问题是我想将我的 'admin' 电子邮件保留在数据库中,但是当我进行数据库查询时,isAdmin 失去了它的纯度,所以我必须 return Handler-something IO Bool而不仅仅是 Bool。现在,这会废弃 hamlet 中允许这样做的非常好的语法糖:

$if isAdmin
    <p ...

有没有办法在我调用数据库的情况下仍然有一个纯 isAdmin 函数(我严重怀疑......顺便说一下,我不想传递任何参数到 isAdmin)?或者也许我仍然可以将 $if 语法与不纯函数一起使用?

P.S.: 目前,我在 handler 模块中使用 hack:

isadmin <- isAdmin

所以,我可以在那个handler对应的hamlet中写:

$if isadmin

但不通用,我更喜欢第一种方法

N.B.: 我其实不认识Yesod;此答案基于一般 Haskell 实践。

Is there a way to still have a pure isAdmin function even if I make a call to the database (I seriously doubt that

确实不可能。对外部数据库的访问必须以某种方式存在于 IO 中;没有办法解决它。

Currently, I am using a hack in the handler module:

isadmin <- isAdmin

So, I can write in the hamlet corresponding to that handler:

$if isadmin

那不是黑客;它是使用单子计算结果的标准方法之一。事实上,在您链接到的 Yesod 书页中,就在您提到的 isAdmin 示例之前,有一个片段运行数据库查询并以与 $if 非常相似的方式使用结果你现在在做什么:

getBlogR :: Handler Html
getBlogR = do
    -- etc.
    entries <- runDB $ selectList [] [Desc EntryPosted]
    -- etc.
$if null entries
    -- etc.

P.S.:

N.B.: I don't want to pass any parameters to isAdmin

我想知道你为什么不想这样做。也许是因为您只需要检查单个特定用户是否是管理员。在这种情况下,您应该考虑将您的计算重命名为 isCurrentUserAdmin(或任何在您的用例中有意义的名称)。看到像 isAdmin 这样的名字会引出一个问题“ 是管理员?”,因此具有该名称的东西不接受任何参数是相当令人惊讶的。