Skip to content

Conversation

@pbrisbin
Copy link
Member

See #71.

New credsExtra keys:

  • accessToken: so you can make your own follow-up requests
  • userResponseJSON: so you can get more information out of the request
    we already made (you just have to parse it yourself)

Removed keys:

  • access_token: renamed to accessToken
  • avatar_url: can be re-parsed
  • email: requires your own request to /emails
  • login: can be re-parsed from userResponseJSON
  • location: can be re-parsed, was not always present
  • name: can be re-parse, was not not always present
  • public_email: can be re-parsed, was not not always present

I'll start going provider by provider now.

See #71. New `credsExtra` keys: - `accessToken`: so you can make your own follow-up requests - `userResponseJSON`: so you can get more information out of the request we already made (you just have to parse it yourself) Removed keys: - `access_token`: renamed to `accessToken` - `avatar_url`: can be re-parsed - `email`: requires your own request to `/emails` - `login`: can be re-parsed from `userResponseJSON` - `location`: can be re-parsed, was not always present - `name`: can be re-parse, was not not always present - `public_email`: can be re-parsed, was not not always present Also re-orders arguments between default and scoped to allow better partial application -- taking advantage of API breakage already.
New keys: - accessToken - userResponseJSON Removed keys: - battleTag
New keys: - accessToken - userResponseJSON Removed keys: - email - login - avatar_url - access_token - name - location
Removed keys: - charName - charId - tokenType - expires All can be recovered by re-parsing userResponseJSON.
Also removes the ability to parse a custom identifier. See the module documentation for a workaround.
@pbrisbin
Copy link
Member Author

pbrisbin commented Jan 28, 2018

I decided to store the raw response at userResponse (not userResponseJSON), since it doesn't have to be JSON. We're providing our own lookup functions, so getUserResponse will return ByteString and getUserResponseJSON will return it parsed to FromJSON a, and may fail if misused.

Also, I'm starting to see a slightly better Provider type come together:

data Provider = Provider { pName :: ProviderName , pToOAuth2 :: ClientId -> ClientSecret -> OAuth2 , pFetchUserResponse :: Manager -> OAuth2Token -> Either String ByteString , pParseCredsIdent :: ByteString -> Either String Text } something :: YesodAuth m => Provider -> ClientId -> ClientSecret -> AuthPlugin m something Provider{..} clientId clientSecret = authOAuth2 pName (pToOAuth2 clientId clientSecret) $ \manager token -> do -- Assumes we adjust authOAuth2 to use Either, not exceptions userResponse <- pFetchUserResponse manager token userId <- pParseCredsIdent userResponse pure Creds { credsPlugin = pName , credsIdent = userId , credsExtra = setExtra token userResponse }

I think I'll branch from this and try that out, as a replacement for #92

@pbrisbin pbrisbin mentioned this pull request Feb 5, 2018
4 tasks
--
getAccessToken :: Creds m -> AccessToken
getAccessToken = AccessToken
. fromJustNote "yesod-auth-oauth2 bug: credsExtra without accessToken"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bummer that we have to use fromJust here. Is this because Yesod.Auth.Creds doesn't have a type parameter, so we have to use stringly typed data for the "extra" bits? Would it be worth trying to change this in Yesod.Auth?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, this is not necessarily a bug, right? If somebody authenticates with username/password and then calls getAccessToken with those creds, that will compile and crash?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth trying to change this in Yesod.Auth?

I'm not really sure that would work. Even if it were Creds e m, for some extras type e, that e couldn't be plugin-specific because it must be the same across all plugins in use. Maybe I'm missing something clever though.

Also, this is not necessarily a bug, right? If somebody authenticates with username/password and then...

You're absolutely right; great catch. I think I lean towards making this Maybe now. I thought there was strong guarantees a value would be present, but non-oauth2-plugins is way too likely.

@jferris
Copy link
Contributor

jferris commented Feb 7, 2018

Nice to see some cleanup and simplification here.

Even though it's "guaranteed" that values will be present because we set them, nothing stops end-users from using these functions on Creds values created by other plugins! Since that seems common, it would be irresponsible of us to remain so unsafe.
@owickstrom
Copy link

@pbrisbin Great stuff, really looking forward to this change!

login tm = [whamlet|<a href=@{tm $ oauth2Url name}>^{widget}|]

-- | Read from the values set via @'setExtra'@
getAccessToken :: Creds m -> Maybe AccessToken
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be more convenient for users to use Either String for all the get* functions. For example, that would let users combine them monadically without writing their own conversions between Either String and Maybe.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know that I follow your reasoning: I think we can't really predict what Monad the user will want to be in, so I don't know that Either would fit any better at call-sites than Maybe (they'll almost certainly be in Handler 99% of the time)... But I can get behind Either for this because it retains information users could choose to silence when in Maybe (e.g. hush), vs the current way where the user would have to invent information when in Either (e.g. note) -- so 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, on second thought I'm not sure. Having these return Either feels like if Map.lookup returned either: that'd be silly because there's only one way it can fail.

I think I'm going to keep this for now.

@pbrisbin pbrisbin merged commit ef38c5c into master Feb 12, 2018
@pbrisbin pbrisbin deleted the pb/fetch-creds branch February 12, 2018 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants