Obelisk OAuth router type mismatch

78 Views Asked by At

I am using Obelisk OAuth to handle multiple OAuth options (Facebook, Google, & Apple, though only FB is shown below).

I have getOAuthDetails which gets the correct details for each provider.

I use it in backend (at the bottom), but it gives me this error:

backend/src/Backend.hs:144:47-54: error:
    • Couldn't match expected type ‘OAuthProvider’
                  with actual type ‘OAuth a1’
    • In the first argument of ‘getOAuthDetails’, namely ‘provider’
      In the expression: getOAuthDetails provider code
      In a pattern binding: (t, reqUrl) = getOAuthDetails provider code
    • Relevant bindings include
        oauthRoute :: a1 (bound at backend/src/Backend.hs:140:41)
        provider :: OAuth a1 (bound at backend/src/Backend.hs:140:29)
    |
144 |             let (t, reqUrl) = getOAuthDetails provider code
    |                                               ^^^^^^^^

This error is confusing to me because I am explicitly feeding in OAuthProvider as provider in that function. Why would it then say actual type ‘OAuth a1’?

data OAuthProvider =  OAuthProvider_Facebook
                  |   OAuthProvider_Google
                  |   OAuthProvider_Apple

getOAuthDetails :: OAuthProvider -> T.Text -> (TokenRequest BackendRoute, String) -- NB. this last T.Text is a reqUrl
getOAuthDetails OAuthProvider_Facebook code = (fbTokenReq code, (T.unpack fbReqUrl))
getOAuthDetails OAuthProvider_Google code = (googTokenReq code, (T.unpack googReqUrl))
getOAuthDetails OAuthProvider_Apple code = (applTokenReq code, (T.unpack applReqUrl))

fbTokenReq :: T.Text -> TokenRequest BackendRoute
fbTokenReq code = TokenRequest 
              { _tokenRequest_grant = TokenGrant_AuthorizationCode $ T.encodeUtf8 code
              , _tokenRequest_clientId = "fake-client-id" -- Get this from the OAuth authorization server
              , _tokenRequest_clientSecret = "fake-client-secret" -- Get this from the OAuth authorization server
              , _tokenRequest_redirectUri = BackendRoute_OAuth
              }

fbReqUrl :: T.Text
fbReqUrl = "https://graph.facebook.com/oauth/access_token" 

...

-- provider2Auth :: OAuthProvider -> OAuth RedirectUriParams
-- provider2Auth 

backend :: OAuthProvider -> Backend BackendRoute FrontendRoute
backend provider = Backend
  { _backend_run = \serve -> do
    cfg <- getConfigs
    let route = T.strip $ T.decodeUtf8 $ cfg ! "common/route"
    tlsMgr <- Https.newTlsManager
    serve $ \case
      BackendRoute_Missing :/ () -> error "404"
      BackendRoute_OAuth :/ provider :/ oauthRoute -> case oauthRoute of
        OAuth_RedirectUri :/ redirectParams -> case redirectParams of
          Nothing -> liftIO $ error "Expected to receive the authorization code here"
          Just (RedirectUriParams code _mstate) -> do
            let (t, reqUrl) = getOAuthDetails provider code
            rsp <- liftIO $ flip Http.httpLbs tlsMgr =<< getOauthToken reqUrl route checkedEncoder t
            -- ^ this response should include the access token and probably a refresh token
            liftIO $ print rsp
  , _backend_routeEncoder = fullRouteEncoder
  }

EDIT:

ob run displayed this:

backend/src/Backend.hs:140:9-43: error:
    • Could not deduce: a1 ~ R OAuth
      from the context: a ~ Data.Dependent.Sum.DSum OAuth Identity
        bound by a pattern with constructor:
                   BackendRoute_OAuth :: BackendRoute (R OAuth),
                 in a case alternative
        at backend/src/Backend.hs:139:7-24
      ‘a1’ is a rigid type variable bound by
        a pattern with pattern synonym:
          :/ :: forall (f :: * -> *). () => forall a. f a -> a -> R f,
        in a case alternative
        at backend/src/Backend.hs:139:7-36
    • In the pattern: OAuth_RedirectUri :/ redirectParams
      In a case alternative:
          OAuth_RedirectUri :/ redirectParams
            -> case redirectParams of
                 Nothing
                   -> liftIO $ error "Expected to receive the authorization code here"
                 Just (RedirectUriParams code _mstate)
                   -> do let ...
                         ....
      In the expression:
        case oauthRoute of {
          OAuth_RedirectUri :/ redirectParams
            -> case redirectParams of
                 Nothing
                   -> liftIO $ error "Expected to receive the authorization code here"
                 Just (RedirectUriParams code _mstate) -> do ... }
    • Relevant bindings include
        oauthRoute :: a1 (bound at backend/src/Backend.hs:139:41)
        provider :: OAuth a1 (bound at backend/src/Backend.hs:139:29)
    |
140 |         OAuth_RedirectUri :/ redirectParams -> case redirectParams of
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend/src/Backend.hs:143:47-54: error:
    • Couldn't match expected type ‘OAuthProvider’
                  with actual type ‘OAuth a1’
    • In the first argument of ‘getOAuthDetails’, namely ‘provider’
      In the expression: getOAuthDetails provider code
      In a pattern binding: (t, reqUrl) = getOAuthDetails provider code
    • Relevant bindings include
        oauthRoute :: a1 (bound at backend/src/Backend.hs:139:41)
        provider :: OAuth a1 (bound at backend/src/Backend.hs:139:29)
    |
143 |             let (t, reqUrl) = getOAuthDetails provider code
    |                                               ^^^^^^^^

Thanks to Srid, I saw that I had two providers. I modified my backend to:

backend :: OAuthProvider -> Backend BackendRoute FrontendRoute
backend provider = Backend
  { _backend_run = \serve -> do
    cfg <- getConfigs
    let route = T.strip $ T.decodeUtf8 $ cfg ! "common/route"
    tlsMgr <- Https.newTlsManager
    serve $ \case
      BackendRoute_Missing :/ () -> error "404"
      BackendRoute_OAuth :/ oauthRoute -> case oauthRoute of
        OAuth_RedirectUri :/ redirectParams -> case redirectParams of
          Nothing -> liftIO $ error "Expected to receive the authorization code here"
          Just (RedirectUriParams code _mstate) -> do
            let (t, reqUrl) = getOAuthDetails provider code
            rsp <- liftIO $ flip Http.httpLbs tlsMgr =<< getOauthToken reqUrl route checkedEncoder t
            -- ^ this response should include the access token and probably a refresh token
            liftIO $ print rsp
  , _backend_routeEncoder = fullRouteEncoder
  }

And now I get:

Running test...
<interactive>:623:116-130: error:
    • Couldn't match expected type ‘Backend
                                      backendRoute0 FrontendRoute’
                  with actual type ‘OAuthProvider
                                    -> Backend BackendRoute FrontendRoute’
    • Probable cause: ‘backend’ is applied to too few arguments
      In the third argument of ‘Obelisk.Run.run’, namely ‘backend’
      In the expression:
        Obelisk.Run.run
          55245
          (Obelisk.Run.runServeAsset
             "/Users/levelchart/Documents/git/app-obelisk/static")
          backend
          Frontend.frontend
      In an equation for ‘it’:
          it
            = Obelisk.Run.run
                55245
                (Obelisk.Run.runServeAsset
                   "/Users/levelchart/Documents/git/app-obelisk/static")
                backend
                Frontend.frontend


0

There are 0 best solutions below