auth2.hs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. {-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell #-}
  2. {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  3. import Yesod
  4. import Yesod.Mail
  5. import Yesod.Helpers.Auth2
  6. import Yesod.Helpers.Auth2.OpenId
  7. import Yesod.Helpers.Auth2.Rpxnow
  8. import Yesod.Helpers.Auth2.Facebook
  9. import Yesod.Helpers.Auth2.Email
  10. import Control.Monad (join)
  11. import Database.Persist.Sqlite
  12. import Safe (readMay)
  13. mkPersist [$persist|
  14. Email
  15. email String Eq
  16. status Bool update
  17. verkey String null update
  18. password String null update
  19. UniqueEmail email
  20. |]
  21. data A2 = A2 { connPool :: ConnectionPool }
  22. mkYesod "A2" [$parseRoutes|
  23. /auth AuthR Auth getAuth
  24. |]
  25. instance Yesod A2 where approot _ = "http://localhost:3000"
  26. instance YesodAuth A2 where
  27. type AuthId A2 = String
  28. loginDest _ = AuthR CheckR
  29. logoutDest _ = AuthR CheckR
  30. getAuthId = return . Just . credsIdent
  31. showAuthId = const id
  32. readAuthId = const Just
  33. authPlugins =
  34. [ authDummy
  35. , authOpenId
  36. , authRpxnow "yesod-test" "c8043882f14387d7ad8dfc99a1a8dab2e028f690"
  37. , authFacebook
  38. "d790dfc0203e31c0209ed32f90782c31"
  39. "a7685e10c8977f5435e599aaf1d232eb"
  40. []
  41. , authEmail
  42. ]
  43. main :: IO ()
  44. main = withConnectionPool $ \p -> do
  45. flip runConnectionPool p $ runMigration $ migrate (undefined :: Email)
  46. basicHandler 3000 $ A2 p
  47. instance YesodAuthEmail A2 where
  48. type AuthEmailId A2 = EmailId
  49. showAuthEmailId _ = show
  50. readAuthEmailId _ = readMay
  51. addUnverified email verkey = runDB $ insert $ Email email False (Just verkey) Nothing
  52. sendVerifyEmail email verkey verurl = do
  53. render <- getUrlRenderParams
  54. tm <- getRouteToMaster
  55. let lbs = renderHamlet render [$hamlet|
  56. %p
  57. %a!href=$verurl$ Verify your email address.
  58. |]
  59. liftIO $ renderSendMail Mail
  60. { mailHeaders =
  61. [ ("To", email)
  62. , ("From", "reply@orangeroster.com")
  63. , ("Subject", "OrangeRoster: Verify your email address")
  64. ]
  65. , mailPlain = verurl
  66. , mailParts =
  67. [ Part
  68. { partType = "text/html; charset=utf-8"
  69. , partEncoding = None
  70. , partDisposition = Inline
  71. , partContent = lbs
  72. }
  73. ]
  74. }
  75. getVerifyKey emailid = runDB $ do
  76. x <- get $ fromIntegral emailid
  77. return $ maybe Nothing emailVerkey x
  78. setVerifyKey emailid verkey = runDB $
  79. update (fromIntegral emailid) [EmailVerkey $ Just verkey]
  80. verifyAccount emailid' = runDB $ do
  81. let emailid = fromIntegral emailid'
  82. x <- get emailid
  83. uid <-
  84. case x of
  85. Nothing -> return Nothing
  86. Just email -> do
  87. update emailid [EmailStatus True]
  88. return $ Just $ emailEmail email
  89. return uid
  90. getPassword email = runDB $ do
  91. x <- getBy $ UniqueEmail email
  92. return $ x >>= emailPassword . snd
  93. setPassword email password = runDB $
  94. updateWhere [EmailEmailEq email] [EmailPassword $ Just password]
  95. getEmailCreds email = runDB $ do
  96. x <- getBy $ UniqueEmail email
  97. case x of
  98. Nothing -> return Nothing
  99. Just (eid, e) ->
  100. return $ Just EmailCreds
  101. { emailCredsId = fromIntegral eid
  102. , emailCredsAuthId = Just $ emailEmail e
  103. , emailCredsStatus = emailStatus e
  104. , emailCredsVerkey = emailVerkey e
  105. }
  106. getEmail emailid = runDB $ do
  107. x <- get $ fromIntegral emailid
  108. return $ fmap emailEmail x
  109. instance YesodPersist A2 where
  110. type YesodDB A2 = SqlPersist
  111. runDB db = fmap connPool getYesod >>= runConnectionPool db
  112. withConnectionPool :: MonadCatchIO m => (ConnectionPool -> m a) -> m a
  113. withConnectionPool = withSqlitePool "auth2.db3" 10
  114. runConnectionPool :: MonadCatchIO m => SqlPersist m a -> ConnectionPool -> m a
  115. runConnectionPool = runSqlPool