aboutsummaryrefslogtreecommitdiff
path: root/lib/Yesod/Auth/Uffd.hs
blob: 4d5e5af842e03a62c77ab9f7df24a66ee9c9c05c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{-# LANGUAGE RecordWildCards #-}
module Yesod.Auth.Uffd (uffdClient, UffdUser(..)) where

import           Control.Monad.IO.Class    (liftIO)
import           Data.Aeson                ((.=))
import qualified Data.Aeson                as A
import           Data.ByteString           (ByteString)
import qualified Data.ByteString.Char8     as C8
import           Data.ByteString.Lazy      (fromStrict, toStrict)
import qualified Data.Text                 as T
import           Data.Text.Encoding        (decodeUtf8)
import           URI.ByteString            (Absolute, URIRef (..))
import           Yesod.Auth
import           Yesod.Auth.OAuth2.Prelude
import           Yesod.Core                (PathPiece (..))
import           Yesod.Core.Handler        (setSession)

data UffdUser = UffdUser
  { uffdId          :: Int
  , uffdName        :: Text
  , uffdDisplayName :: Text
  , uffdEmail       :: Text
  , uffdGroups      :: [Text]
  } deriving (Show)

instance PathPiece UffdUser where
  fromPathPiece = A.decode . fromStrict . C8.pack . T.unpack
  toPathPiece = decodeUtf8 . toStrict . A.encode

instance FromJSON UffdUser where
  parseJSON = withObject "User" $ \o -> UffdUser
    <$> o .: "id"
    <*> o .: "nickname"
    <*> o .: "name"
    <*> o .: "email"
    <*> o .: "groups"

instance ToJSON UffdUser where
  toJSON UffdUser {..} = A.object
    [ "id" .=  uffdId
    , "nickname" .= uffdName
    , "name" .= uffdDisplayName
    , "email" .= uffdEmail
    , "groups" .= uffdGroups
    ]

pluginName = "uffd"


uffdClient :: YesodAuth m => URIRef Absolute -> Text -> Text -> AuthPlugin m
uffdClient url clientId clientSecret =
  authOAuth2 "uffd" oauth2 $ \manager token -> do
    resp@(user@UffdUser {..}, userResponse) <- authGetProfile
      "uffd"
      manager
      token
      (url { uriPath = "/oauth2/userinfo" })

    pure Creds { credsPlugin = "uffd"
               , credsIdent = T.pack $ show uffdId
               , credsExtra =
                 [ ("json", decodeUtf8 $ toStrict (A.encode user)) ]
                 -- just dump the entire extra thing into the session, so we can reconstruct it later
               }
  where oauth2 = OAuth2
          { oauth2ClientId = clientId
          , oauth2ClientSecret = Just clientSecret
          , oauth2AuthorizeEndpoint =
              url { uriPath = "/oauth2/authorize" }
          , oauth2TokenEndpoint =
              url { uriPath = "/oauth2/token" }
          , oauth2RedirectUri = Nothing
          }