-------------------------------------------------------------------------------- -- | -- Module : Network.OpenID.Easy -- Copyright : (c) James Halliday, 2009 -- License : BSD3 -- -- Maintainer : James Halliday -- Stability : -- Portability : -- module Network.OpenID.Easy ( Config(..), Session(..), auth, verify, config, readSession ) where import Network.OpenID import Network.Socket (withSocketsDo) -- | Provides configuration settings for verify and auth. For now, this is just -- the errors which may be thrown by either. data Config = Config { verifyError :: String -> IO (), normalizeError :: IO Session, discoverError, associateError :: String -> IO Session } -- | Provide default configuration with error handlers that just fail with a -- useful message when errors happen. This behavior is what most people would -- probably end up writing themselves anyways. config :: Config config = Config { normalizeError = fail "Unable to normalize identifier", discoverError = fail . ("Discovery Error: " ++), associateError = fail . ("Associate Error: " ++), verifyError = fail . ("Verify Error: " ++) } -- | Wrap up all the data necessary to do a verify into one place, plus some -- extra useful stuff. data Session = Session { -- | the authentication uri to send the client off to sAuthURI :: String, -- | the OpenID provider as a string sProvider :: String, -- | the normalized OpenID identity as a string sIdentity :: String, -- | the uri the client will come back to after authenticating sReturnTo :: String, -- | the association map manager thing used internally sAssocMap :: AssociationMap } deriving (Read,Show) readSession :: String -> Session readSession = read -- | Given a configuration, identity, and return uri, -- contact the remote provider to create a Session object encapsulating the -- useful bits of data to pass along to verify and also to pick out the -- normalized identity from. auth :: Config -> String -> String -> IO Session auth config ident returnTo = withSocketsDo $ do -- this bit is heavily based on the old examples/test.hs case normalizeIdentifier (Identifier ident) of Nothing -> normalizeError config Just normalizedIdent -> do let resolve = makeRequest True rpi <- discover resolve normalizedIdent case rpi of Left err -> discoverError config $ show err Right (provider,identifier) -> do -- either an error or an association manager eam <- associate emptyAssociationMap True resolve provider case eam of Left err -> associateError config $ show err Right am -> return $ Session { sAuthURI = show $ authenticationURI am Setup provider identifier returnTo Nothing, sProvider = show $ providerURI provider, sIdentity = getIdentifier identifier, sReturnTo = returnTo, sAssocMap = am } -- use this to resolve stuff in auth and verify resolver :: Resolver IO resolver = makeRequest True -- | Given a configuration, a Session generated by auth, and the uri that the -- client came back on from the provider, make sure the client properly -- authenticated by running verifyError on failure to verify the credentials. verify :: Config -> Session -> String -> IO () verify config session uri = do let params = parseParams uri verified <- verifyAuthentication (sAssocMap session) params (sReturnTo session) resolver case verified of Left err -> verifyError config $ show err Right _ -> return ()