Yesod 硬编码身份验证取决于 AppSettings

Yesod Hardcoded authentication depending on AppSettings

我正在尝试设置硬编码身份验证,以依赖于 Yesod 脚手架中 config/settings.yml 中指定的登录信息。我写了下面的代码:

instance YesodAuthHardcoded App where
    validatePassword u = do
        app <- getYesod
        let user = appUser $ appSettings app
        return . validPassword user u . fromString . unpack
    doesUserNameExist = do
        app <- getYesod
        return . isJust . lookupUser app

并且我收到以下 validatePassord 的错误消息和 doesUserNameExist 的等效消息:

• Couldn't match type ‘HandlerSite ((->) Text)’ with ‘App’
  Expected type: Text -> App
    Actual type: Text -> HandlerSite ((->) Text)
• In a stmt of a 'do' block: app <- getYesod
  In the expression:
    do { app <- getYesod;
         let user = appUser $ appSettings app;
         return . validPassword user u . fromString . unpack }
  In an equation for ‘validatePassword’:
      validatePassword u
        = do { app <- getYesod;
               let user = ...;
               return . validPassword user u . fromString . unpack }

validatePasswordis defined in Yesod.Auth.Hardcoded的原型:

validatePassword :: Text -> Text -> AuthHandler site Bool

AuthHandler is defined in Yesod.Auth:

type MonadAuthHandler master m = (MonadHandler m, YesodAuth master, master ~ HandlerSite m, Auth ~ SubHandlerSite m, MonadUnliftIO m)

type AuthHandler master a = forall m. MonadAuthHandler master m => m a 

终于getYesod is defined as follow in Yesod.Core.Handler:

getYesod :: MonadHandler m => m (HandlerSite m)

从这些定义看来,我应该有一种方法可以从 AuthHandler monad 调用 getYesod,但我不知道如何调用。


编辑: 我已将 yesod 及其脚手架更新为最新版本。我还修改了 validatePassword 如下:

validatePassword u = do
    app <- liftHandler . getYesod
    let user = appUser $ appSettings app
    return . validPassword user u . fromString . unpack

我收到以下错误消息:

    • Couldn't match type ‘m1 a1’ with ‘App’
      Expected type: HandlerFor (HandlerSite m1) a1 -> App
        Actual type: HandlerFor (HandlerSite m1) a1 -> m1 a1
    • In the first argument of ‘(.)’, namely ‘liftHandler’
      In a stmt of a 'do' block: app <- liftHandler . getYesod
      In the expression:
        do app <- liftHandler . getYesod
           let user = appUser $ appSettings app
           return . validPassword user u . fromString . unpack
    |
259 |         app <- liftHandler . getYesod
    |

错误来自于我试图修改 Yesod.Auth.Hardcoded 模块给出的代码片段。我引入了一个 do 符号,它与省略的参数相冲突。指定参数解决问题,代码变为:

instance YesodAuthHardcoded App where
    validatePassword u p = do
        app <- getYesod
        let user = appUser $ appSettings app
        return . validPassword user u . fromString $ unpack p
    doesUserNameExist u = do
        app <- getYesod
        return . isJust $ lookupUser app u