From 9125a0003e4d3469bb85f4f4f4488e1fa405e735 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Tue, 26 Jan 2016 17:44:14 -0800 Subject: [PATCH] move refresh token logic to lib/oauth2 --- lib/oauth2.hoon | 72 ++++++++++++--------- sec/com/facebook/graph.hoon | 4 +- sec/com/googleapis/www.hoon | 126 +++++++----------------------------- 3 files changed, 63 insertions(+), 139 deletions(-) diff --git a/lib/oauth2.hoon b/lib/oauth2.hoon index 0bdff1eeb..4bbadcc95 100644 --- a/lib/oauth2.hoon +++ b/lib/oauth2.hoon @@ -18,6 +18,8 @@ ?~ b '' (rap 3 |-([i.b ?~(t.b ~ [a $(b t.b)])])) :: +++ dbg-post `purl`[[| `6.000 `/localhost] `/testing /] +++ endpoint |=([dom=(list cord) a=path] [[& ~ `dom] [~ a] ~]) ++ bad-response |=(a=@u ?:(=(2 (div a 100)) | ~&(bad-httr/a &))) ++ grab-json |* [a=httr b=fist:jo] @@ -29,6 +31,7 @@ :: |% ++ token ?(~ @t) +++ refresh ,[tok=token needed=@da pending=_`?`|] ++ keys cord:,[cid=@t cis=@t] ++ core-move |*(a=* $&([sec-move _a] sec-move)) ++ decode-keys :: XX from bale w/ typed %jael @@ -44,8 +47,7 @@ ++ client-secret cis:(decode-keys key) :: ++ urb-hart [| `8.443 `/localhost] :: XX get from eyre -++ endpoint |=(a=path [[& ~ `dom] [~ a] ~]) -++ toke-url (endpoint code-exchange) +++ toke-url (endpoint dom code-exchange) ++ auth-url ^- purl :+ [& ~ p.dialog] [~ q.dialog] @@ -62,14 +64,6 @@ =+ usr-span=?:(state-usr '_state' (scot %ta usr)) [urb-hart `/~/ac/(join '.' (flop dom))/[usr-span] ~] :: -++ refresh-expiring - |= [[expires=@da refresh=token] otherwise=$+(hiss sec-move)] - |= a=hiss - ?~ refresh (otherwise a) - ?: (lth expires (add now ~m1)) - (otherwise a) - (toke-req 'refresh_token' refresh-token/refresh ~) -:: ++ out-filtered |= [tok=token aut=$+(hiss hiss)] |= a=hiss ^- sec-move @@ -111,33 +105,47 @@ ++ bak-save-access |* [done=* handle=$+(cord:token *)] :: $+(token _done) %- (bak-parse done access-token ~) - |=(tok=token [[%redo ~] (handle tok)]) + |=(tok=cord:token [[%redo ~] (handle tok)]) :: ++ bak-parse |* [done=* parse=(pole ,[span fist]:jo)] - =+ fin=$&([sec-move _done] sec-move) - |= handle=$+(_?~(parse ~ (need *(ot:jo parse))) fin) - |= a=httr ^- fin + |= handle=$+(_?~(parse ~ (need *(ot:jo parse))) (core-move done)) + |= a=httr ^- (core-move done) ?: (bad-response p.a) [%redo ~] :: handle 4xx? (handle (grab-json a (ot:jo parse))) :: -:: ++ bak-parse-refresh -:: |= a=httr ^- [sec-move _+>] -:: ?: (bad-response p.a) [[%redo ~] +>.$] :: handle 4xx? -:: =. ref (grab a (ot 'refresh_token'^so ~):jo) -:: [[%redo ~] (new-token a)] -:: ++ res-catch-refresh -:: |= a=httr ^- [sec-move _+>] -:: ?: need-refresh -:: ?: (bad-response p.a) [[%redo ~] +>.$] :: handle 4xx? -:: ~| %refreshed-token -:: [[%redo ~] (new-token a)] -:: [[%give a] +>.$] -:: -:: ++ new-token -:: |= a=httr ^+ +> -:: =+ `[typ=term ber=@t tim=@u]`(grab a parse-toke) -:: ?> ?=(%bearer typ) -:: +>.$(ber ber, ded (add now (mul ~s1 tim))) +++ res-give |=(a=httr [%give a]) :: +++ re + |* cor=* :: XX redundant with *export, but type headaches + |_ [ref=refresh export=$+(refresh _cor)] + ++ out-fix-expired + |= default=$+(hiss sec-move) + ^- $+(hiss (core-move cor)) + ?~ tok.ref default + ?. (lth needed.ref (add now ~m59.s30)) + default + |= a=hiss + :_ (export ref(pending &)) + (toke-req 'refresh_token' refresh-token/tok.ref ~) + :: + ++ res-handle-refreshed + |= [handle-access=_=>(cor |=(@t +>)) default=$+(httr sec-move)] + ^- $+(httr (core-move cor)) + ?. pending.ref default + %- (bak-parse cor expires-in access-token ~) + |= [exp=@u tok=axs=@t] ^- [sec-move _cor] + =. +>.handle-access + (export tok.ref (add now (mul ~s1 exp)) |) + [[%redo ~] (handle-access axs.tok)] + :: + ++ bak-save-tokens + |= handle-access=_=>(cor |=(@t +>)) + %- (bak-parse cor expires-in access-token refresh-token ~) + |= [exp=@u tok=[axs=@t ref=@t]] ^- [sec-move _cor] + =. +>.handle-access + (export ref.tok (add now (mul ~s1 exp)) |) + [[%redo ~] (handle-access axs.tok)] + -- -- + diff --git a/sec/com/facebook/graph.hoon b/sec/com/facebook/graph.hoon index 31ac82edf..bfbd15cf0 100644 --- a/sec/com/facebook/graph.hoon +++ b/sec/com/facebook/graph.hoon @@ -6,9 +6,7 @@ =+ aut=(oauth2 - /'v2.3'/oauth/'access_token') |_ [bal=(bale keys.aut) access-token=token.aut] ++ auth ~(. aut bal /'user_about_me'/'user_posts') -++ out - ~& access-token - (out-quay:auth 'access_token'^access-token) +++ out (out-quay:auth 'access_token'^access-token) ++ in in-code:auth ++ bak %- (bak-parse:auth . access-token.aut expires-in.aut ~) diff --git a/sec/com/googleapis/www.hoon b/sec/com/googleapis/www.hoon index 7a8851990..a9db4e6de 100644 --- a/sec/com/googleapis/www.hoon +++ b/sec/com/googleapis/www.hoon @@ -1,116 +1,34 @@ -|% -++ fass :: rewrite quay - |= a=quay - %+ turn a - |= [p=@t q=@t] ^+ +< - [(gsub '-' '_' p) q] -:: -++ gsub :: replace chars - |= [a=@t b=@t t=@t] - ^- @t - ?~ t t - %+ add (lsh 3 1 $(t (rsh 3 1 t))) - =+ c=(mod t (bex 8)) - ?:(=(a c) b c) --- +/+ oauth2 :: :::: :: |% -:: ++ crypto :: XX in zuse -:: |= [our=@p now=@da] -:: =+ `mac=mace`p:;;(buck .^(a//(crip )/buck/(crip )/(crip ))) -:: ?> ?=([^ ~] mac) :: current, single life -:: (weur q.i.mac) -:: -++ join |=([a=tape b=(list tank)] rose/[a ~ ~]^b) -++ endpoint |=(a=path [[& ~ `/com/googleapis/www] [~ a] ~]) -++ toke-url (endpoint /oauth2/v4/token) -++ dbg-post `purl`[[| `6.000 `/localhost] `/testing /] -++ auth-url - |= [usr=@t cid=@t sop=(list cord)] ^- purl - :+ [& ~ `/com/google/accounts] [~ /o/oauth2/v2/auth] - %- fass :~ - state/(pack usr /'') - login-hint/?~(usr '' (cat 3 usr '@gmail.com')) - client-id/cid - access-type/%offline - response-type/%code - redirect-uri/redirect-uri - =< scope/(crip ~(ram re (join " " (turn sop .)))) - |=(a=cord leaf/(earn (endpoint /auth/[a]))) - :: +++ user-state ,[ber=token ref=refresh]:oauth2 +++ auth-lon + |= lon=span + =< .(state-usr &) + %- oauth2 + =- [[`/com/google/accounts /o/oauth2/v2/auth -] /oauth2/v4/token] + :~ login-hint/?~(lon '' (cat 3 lon '@gmail.com')) + access-type/%offline + response-type/%code == -++ redirect-uri 'http://localhost:8443/~/ac/www.googleapis.com/_state' -++ user-state ,[ber=@t ded=@da ref=[token=@t pending=?]] -- :: :::: :: -|_ [(bale ,@t) user-state] -++ decode-keys ((hard ,[cid=@t cis=@t ~]) (lore key)) :: XX typed %jael -++ client-id cid:decode-keys -++ client-secret cis:decode-keys +|_ [bal=(bale keys:oauth2) user-state] +++ auth-re ~(. (re:auth .) ref |=(a=_ref +>(ref a))) +++ auth ~(. (auth-lon usr.bal) bal (scopes 'userinfo.email' 'plus.me' ~)) +++ scopes + =+ scope=|=(b=@ta (endpoint:oauth2 dom.bal /auth/[b])) + |=(a=(list ,@ta) (turn a |=(b=@ta (crip (earn (scope b)))))) :: -++ need-refresh (lth ded (add now ~m1)) -++ out - |= a=hiss ^- [sec-move _+>] - =- [mov +>.$(pending.ref is-ref)] - ^- [is-ref=? mov=sec-move] - ?~ ber [| [%show (auth-url usr client-id 'userinfo.email' 'plus.me' ~)]] - ?: need-refresh - [& [%send toke-url refresh-req]] - =. q.q.a (~(add ja q.q.a) %authorization (cat 3 'Bearer ' ber)) - [| [%send a]] +++ out (out-fix-expired:auth-re (out-math:auth ber)) +++ res (res-handle-refreshed:auth-re save-access res-give:auth) +++ save-access |=(a=cord:[token:oauth2] +>(ber a)) :: -++ refresh-req (toke-req refresh-token/token.ref grant-type/'refresh_token' ~) -++ toke-req - |= quy=quay ^- moth - :+ %post (mo ~[content-type/~['application/x-www-form-urlencoded']]) - =- `(tact +:(tail:earn -)) - %- fass - %+ welp quy - :~ client-id/client-id - client-secret/client-secret - redirect-uri/redirect-uri - == -++ in - |= a=quay ^- sec-move - =+ cod=~|(%no-code (~(got by (mo a)) %code)) - [%send toke-url (toke-req code/cod grant-type/'authorization_code' ~)] -:: -++ res - |= a=httr ^- $&([sec-move _+>] sec-move) - ?. pending.ref [%give a] - ?: (bad-response p.a) [%redo ~] :: handle 4xx? - ~| %refreshed-token - =. pending.ref | - [[%redo ~] (new-token a)] -:: -++ bad-response |=(a=@u ?:(=(2 (div a 100)) | ~&(bad-httr/a &))) -++ new-token - |= a=httr ^+ +> - =+ `[typ=term ber=@t tim=@u]`(grab a parse-toke) - ?> ?=(%bearer typ) - +>.$(ber ber, ded (add now (mul ~s1 tim)), pending.ref |) -:: -++ grab - |* [a=httr b=fist:jo] - ~| bad-json/r.a - (need (;~(biff poja b) q:(need r.a))) -:: -++ parse-toke - => jo %- ot :~ - 'token_type'^(cu cass sa) - 'access_token'^so - 'expires_in'^ni - == -:: -++ bak - |= a=httr ^- [sec-move _+>] - :- [%redo ~] - ?: (bad-response p.a) +>.$ :: handle 4xx? - =. token.ref (grab a (ot 'refresh_token'^so ~):jo) - (new-token a) -::++ wipe ~ +++ in in-code:auth +++ bak (bak-save-tokens:auth-re save-access) +:: ++ wipe ~ --