truqu / elm-oauth2

OAuth 2.0 client-side utils in Elm
MIT License
81 stars 29 forks source link

Missing function that converts a token string back to an OAuth.Token #2

Closed takkaria closed 6 years ago

takkaria commented 6 years ago

I'm writing an app that uses elm-oauth to connect to YouTube. I want to persist the token in localStorage so if the user refreshes the page, they don't lose their token. At the moment I can access this token for storage using showToken, but I can't convert a token string back into a token afterwards.

If I wrote a patch for this, would you accept it?

KtorZ commented 6 years ago

Hi, I think there's no need for such patch. The Token is an ADT which exposes all its constructors. Hence, the showToken is simply a tiny sugar helper.

The library doesn't make any assumption about the syntax of the token (since OAuth 2.0 doesn't either). As a matter of fact, getting a Token type from a string is as simple as Bearer mystr (http://package.elm-lang.org/packages/truqu/elm-oauth2/2.0.3/OAuth#Token)

So, you can already convert a token string back into a Token using the Bearer constructor :D

takkaria commented 6 years ago

Hm, OK, thanks for pointing out I can use OAuth.Bearer. But showToken returns the token with "Bearer " prepended. I can remove that in my code but I still think it would be nice to have a utility function to remove it in the library.

takkaria commented 6 years ago

Sorry also if I'm missing something here – I am new to Elm!

KtorZ commented 6 years ago

Hey, no problem! The type Token isn't an opaque type which means that you have access to the underlying structure.

type Token
    = Bearer String

Therefore, should you want to extract the string carried by a Token, you have to pattern match on it, for example:

getBearer : Token -> String
getBearer (Bearer str) =
    str

-- or

getBearer : Token -> String
getBearer token =
    let (Bearer str) = token
    in str

-- or

getBearer : Token -> String
getBearer token =
    case token of
        Bearer str ->
            str

Note that the two first examples work only because there's a single type constructor for the type Token (and since the support for MAC tokens is being dropped / deprecated by OAuth 2.0, it will probably always be one constructor).

Why wrapping it inside a Token type rather than passing along a String ? For type-safety. A token has a different semantic than any String. It makes functions signatures more readable and avoid mixing parameters.

Besides, when you actually write an Algebraic Data Type (a.k.a Union type), you can think of the different cases as "constructors". Therefore,

type Token =
    Bearer String

suggests that there's a function Bearer available with the following signature:

Bearer : String -> Token

From a String, it gives you back a token. In essence, a token is represented simply as a String and can be created from any String using the Bearer constructor.

takkaria commented 6 years ago

Great, thanks for your help, I understand now :)