oauth2callback ::
     ByteString
  -> Database
  -> (Text, OAuth2Client)
  -> BackendConf
  -> W.Application
oauth2callback key db (provider, oa2c) be req resp =
  case param "code" of
    Nothing -> badRequest "missing auth code" req resp
    Just code ->
      case param "state" of
        Nothing -> badRequest "missing auth state" req resp
        Just state ->
          case State.decode key state of
            Left msg -> badRequest ("invalid state: " ++ msg) req resp
            Right url -> do
              au <- oauth2Authenticate oa2c code (redirectURL req provider)
              let email = getEmail au
              Log.info $ "login " ++ show email ++ " by " ++ show provider
              exists <- userExists db email
              if exists
                then authenticate key be au url req resp
                else userNotFound au req resp
  where
    param p = do
      (_, v) <- find ((==) p . fst) $ W.queryString req
      v

-- XXX: RFC6265: the user agent MUST NOT attach more than one Cookie header field
oauth2callback ::
     ByteString
  -> Database
  -> (Text, OAuth2Client)
  -> BackendConf
  -> W.Application
oauth2callback key db (provider, oa2c) be req resp =
  case param "code" of
    Nothing -> badRequest "missing auth code" req resp
    Just code ->
      case param "state" of
        Nothing -> badRequest "missing auth state" req resp
        Just state ->
          case State.decode key state of
            Left msg -> badRequest ("invalid state: " ++ msg) req resp
            Right url -> do
              au <- oauth2Authenticate oa2c code (redirectURL req provider)
              let email = getEmail au
              Log.info $ "login " ++ show email ++ " by " ++ show provider
              exists <- userExists db email
              if exists
                then authenticate key be au url req resp
                else userNotFound au req resp
  where
    param p = do
      (_, v) <- find ((==) p . fst) $ W.queryString req
      v

-- XXX: RFC6265: the user agent MUST NOT attach more than one Cookie header field
oauth2callback key db (provider, oa2c) be req resp =
  case param "code" of
    Nothing -> badRequest "missing auth code" req resp
    Just code ->
      case param "state" of
        Nothing -> badRequest "missing auth state" req resp
        Just state ->
          case State.decode key state of
            Left msg -> badRequest ("invalid state: " ++ msg) req resp
            Right url -> do
              au <- oauth2Authenticate oa2c code (redirectURL req provider)
              let email = getEmail au
              Log.info $ "login " ++ show email ++ " by " ++ show provider
              exists <- userExists db email
              if exists
                then authenticate key be au url req resp
                else userNotFound au req resp
  where
    param p = do
      (_, v) <- find ((==) p . fst) $ W.queryString req
      v

-- XXX: RFC6265: the user agent MUST NOT attach more than one Cookie header field