summaryrefslogtreecommitdiff
path: root/Biz/Auth.hs
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2021-06-26 07:46:31 -0400
committerBen Sima <ben@bsima.me>2021-11-26 13:47:36 -0500
commit460d25b80051d99ec17128dac4fd9253e99e7515 (patch)
treee286f60c366d77f3c3d5557182e685aff3581cc1 /Biz/Auth.hs
parentb52fd2e354c41ea2949a68d79d590925353779a5 (diff)
Factor OAuth code into Biz.Auth
Diffstat (limited to 'Biz/Auth.hs')
-rw-r--r--Biz/Auth.hs89
1 files changed, 78 insertions, 11 deletions
diff --git a/Biz/Auth.hs b/Biz/Auth.hs
index 3648395..ed904b9 100644
--- a/Biz/Auth.hs
+++ b/Biz/Auth.hs
@@ -1,18 +1,85 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+
+-- | A module for common OAuth flows.
+--
+-- Consider using authenticate-oauth package
module Biz.Auth
- ( Error (..),
- Password,
- Username,
+ ( -- * OAuth
+ OAuthResponse (..),
+ OAuthArgs (..),
+
+ -- * GitHub Authentication
+ githubOauth,
+
+ -- * Servant Helpers
+ SetCookies,
)
where
-import Data.ByteString (ByteString)
-import Data.Text (Text)
-import Miso.String
+import Alpha
+import qualified Data.Aeson as Aeson
+import Network.HTTP.Req ((/:), (=:))
+import qualified Network.HTTP.Req as Req
+import Servant (Header, Headers)
+import qualified Servant.Auth.Server as Auth
+import qualified System.Envy as Envy
+
+-- | Wrapper around 'Auth.SetCookie' that you can put in a servant path
+-- descriptor.
+type SetCookies ret =
+ (Headers '[Header "Set-Cookie" Auth.SetCookie, Header "Set-Cookie" Auth.SetCookie] ret)
+
+-- | These are arguments that a 3rd-party OAuth provider needs in order for us
+-- to authenticate a user.
+data OAuthArgs = OAuthArgs
+ { clientSecret :: Text,
+ clientId :: Text,
+ clientState :: Text
+ }
+ deriving (Generic, Show)
+
+instance Envy.DefConfig OAuthArgs where
+ defConfig =
+ OAuthArgs
+ { clientSecret = mempty,
+ clientId = mempty,
+ clientState = mempty
+ }
-data Error
- = BadUsername
- | BadPassword
+instance Envy.FromEnv OAuthArgs
-type Password = MisoString
+-- | A type for parsing JSON auth responses, used in 'githubOauth' below.
+-- Should be moved to Biz.Auth with others.
+data OAuthResponse = OAuthResponse
+ { access_token :: Text,
+ scope :: Text,
+ token_type :: Text
+ }
+ deriving (Generic, Aeson.FromJSON)
-type Username = MisoString
+-- | POST to GitHub's OAuth service and get the user's oAuth token.
+githubOauth ::
+ OAuthArgs ->
+ -- | This should be GitHub.Token but GitHub.Auth doesn't export Token.
+ Text ->
+ IO OAuthResponse
+githubOauth OAuthArgs {..} code =
+ accessTokenRequest
+ /> Req.responseBody
+ |> Req.runReq Req.defaultHttpConfig
+ where
+ accessTokenRequest :: Req.Req (Req.JsonResponse OAuthResponse)
+ accessTokenRequest =
+ Req.req
+ Req.POST
+ (Req.https "github.com" /: "login" /: "oauth" /: "access_token")
+ Req.NoReqBody
+ Req.jsonResponse
+ <| "client_id" =: clientId
+ <> "client_secret" =: clientSecret
+ <> "code" =: code
+ <> "state" =: clientState