move refresh token logic to lib/oauth2

This commit is contained in:
Anton Dyudin 2016-01-26 17:44:14 -08:00
parent 88401dacf2
commit 9125a0003e
3 changed files with 63 additions and 139 deletions

View File

@ -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)]
--
--

View File

@ -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 ~)

View File

@ -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 <our>)/buck/(crip <now>)/(crip <our>)))
:: ?> ?=([^ ~] 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 ~
--