Scopes can now be passed in, most of the spotify user object is returned in the credentials

This commit is contained in:
Paul Harper 2014-09-21 23:42:13 -07:00
parent 04a5aad6c1
commit 261cbc30aa

View File

@ -9,37 +9,63 @@ import Control.Applicative ((<$>), (<*>))
import Control.Exception.Lifted
import Control.Monad (mzero)
import Data.Aeson
import Data.Text (Text)
import Data.ByteString (ByteString)
import Data.Maybe
import Data.Text (Text)
import Data.Text.Encoding (encodeUtf8)
import Network.HTTP.Conduit(Manager)
import Yesod.Auth
import Yesod.Auth.OAuth2
import qualified Data.ByteString as B
import qualified Data.Text as T
data SpotifyUserImage = SpotifyUserImage
{ spotifyUserImageHeight :: Maybe Int
, spotifyUserImageWidth :: Maybe Int
, spotifyUserImageUrl :: Text
}
instance FromJSON SpotifyUserImage where
parseJSON (Object v) = SpotifyUserImage <$>
v .: "height" <*>
v .: "width" <*>
v .: "url"
parseJSON _ = mzero
data SpotifyUser = SpotifyUser
{ spotifyUserId :: Text
, spotifyUserHref :: Text
, spotifyUserDisplayName :: Text
, spotifyProduct :: Text
, spotifyUserUri :: Text
, spotifyUserDisplayName :: Maybe Text
, spotifyUserProduct :: Maybe Text
, spotifyUserCountry :: Maybe Text
, spotifyUserEmail :: Maybe Text
, spotifyUserImages :: Maybe [SpotifyUserImage]
}
instance FromJSON SpotifyUser where
parseJSON (Object v) = SpotifyUser <$>
v .: "id" <*>
v .: "href" <*>
v .: "display_name" <*>
v .: "product"
v .: "uri" <*>
v .:? "display_name" <*>
v .:? "product" <*>
v .:? "country" <*>
v .:? "email" <*>
v .:? "images"
parseJSON _ = mzero
oauth2Spotify :: YesodAuth m
=> Text -- ^ Client ID
-> Text -- ^ Client Secret
-> [ByteString] -- ^ Scopes
-> AuthPlugin m
oauth2Spotify clientId clientSecret = authOAuth2 "spotify"
oauth2Spotify clientId clientSecret scope = authOAuth2 "spotify"
(OAuth2
{ oauthClientId = encodeUtf8 clientId
, oauthClientSecret = encodeUtf8 clientSecret
, oauthOAuthorizeEndpoint = "https://accounts.spotify.com/authorize"
, oauthOAuthorizeEndpoint = B.append "https://accounts.spotify.com/authorize?scope=" (B.intercalate "%20" scope)
, oauthAccessTokenEndpoint = "https://accounts.spotify.com/api/token"
, oauthCallback = Nothing
})
@ -55,7 +81,28 @@ fetchSpotifyProfile manager token = do
toCreds :: SpotifyUser -> Creds m
toCreds user = Creds "spotify"
(spotifyUserId user)
[ ("href" , spotifyUserHref user)
, ("display_name", spotifyUserDisplayName user)
, ("product" , spotifyProduct user)
]
(mapMaybe getExtra extrasTemplate)
where
userImage :: Maybe SpotifyUserImage
userImage = spotifyUserImages user >>= listToMaybe
userImagePart :: (SpotifyUserImage -> Maybe a) -> Maybe a
userImagePart getter = userImage >>= getter
extrasTemplate = [ ("href" , Just $ spotifyUserHref user)
, ("uri" , Just $ spotifyUserUri user)
, ("display_name", spotifyUserDisplayName user)
, ("product" , spotifyUserProduct user)
, ("country" , spotifyUserCountry user)
, ("email" , spotifyUserEmail user)
, ("image_url" , userImage >>=
return . spotifyUserImageUrl)
, ("image_height", userImagePart spotifyUserImageHeight >>=
return . T.pack . show)
, ("image_width" , userImagePart spotifyUserImageWidth >>=
return . T.pack . show)
]
getExtra :: (Text, Maybe Text) -> Maybe (Text, Text)
getExtra (key, val) = fmap ((,) key) val