From 61f36aff56055aeeeab45b6727d0f19fcddc8196 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Fri, 22 Jan 2016 11:13:11 -0800 Subject: [PATCH 1/8] code deduplication --- sec/com/googleapis/www.hoon | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/sec/com/googleapis/www.hoon b/sec/com/googleapis/www.hoon index 205157acf..bad3718c2 100644 --- a/sec/com/googleapis/www.hoon +++ b/sec/com/googleapis/www.hoon @@ -77,15 +77,15 @@ ++ res |= a=httr ^- [sec-move _+>] ?: need-refresh - ?. ?=(2 (div p.a 100)) :: bad response - ~& bad-httr/p.a - [[%redo ~] +>.$] + ?: (bad-response p.a) [[%redo ~] +>.$] :: handle 4xx? ~| %refreshed-token - [[%redo ~] (new-token (grab a parse-toke))] + [[%redo ~] (new-token a)] [[%give a] +>.$] :: +++ bad-response |=(a=@u ?:(=(2 (div a 100)) | ~&(bad-httr/a &))) ++ new-token - |= [typ=term ber=@t tim=@u] + |= a=httr ^+ +> + =+ `[typ=term ber=@t tim=@u]`(grab a parse-toke) ?> ?=(%bearer typ) +>.$(ber ber, ded (add now (mul ~s1 tim))) :: @@ -103,10 +103,7 @@ :: ++ bak |= a=httr ^- [sec-move _+>] - ?. ?=(2 (div p.a 100)) :: bad response - ~& bad-httr/p.a - [[%redo ~] +>.$] - :- [%redo ~] + ?: (bad-response p.a) [[%redo ~] +>.$] :: handle 4xx? =. ref (grab a (ot 'refresh_token'^so ~):jo) - (new-token (grab a parse-toke)) + [[%redo ~] (new-token a)] -- From 1b0cced83c010a8f26892c03286c475a82a79f62 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Fri, 22 Jan 2016 12:45:38 -0800 Subject: [PATCH 2/8] per-user auth v1 --- arvo/eyre.hoon | 46 ++++++++++++++++++++++--------------- arvo/gall.hoon | 16 ++++++++----- arvo/zuse.hoon | 6 ++--- sec/com/googleapis/www.hoon | 3 +-- 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/arvo/eyre.hoon b/arvo/eyre.hoon index 0a852c085..f5106c4fe 100644 --- a/arvo/eyre.hoon +++ b/arvo/eyre.hoon @@ -56,8 +56,8 @@ [%ay p=span:ship q=span:,@uvH ~] :: remote duct [%ha p=path:beak] :: GET request [%he p=whir] :: HEAD request - [%hi p=mark ~] :: outbound HTTP - [%se p=whir-se q=(list ,@t)] :: outbound to domain + [%hi p=span:(unit span) q=mark ~] :: outbound HTTP + [%se p=whir-se q=[span (list ,@t)]] :: outbound to domain [%si ~] :: response done [%of p=ixor q=$|(~ whir-of)] :: associated view [%ow p=ixor ~] :: dying view @@ -89,7 +89,7 @@ wup=(map hole cyst) :: secure sessions sop=(map hole ,[ship ?]) :: foreign sess names wix=(map ixor stem) :: open views - sec=(map (list ,@t) driv) :: security drivers + sec=(map ,[span (list ,@t)] driv) :: security drivers == :: :: ++ driv %+ pair (unit vase) :: driver state @@ -129,7 +129,7 @@ ++ perk :: parsed request $% [%auth p=perk-auth] [%away ~] - [%oath p=(list ,@t)] + [%oath p=span q=(list ,@t)] [%bugs p=?(%as %to) ~] [%beam p=beam] [%deps p=?(%put %delt) q=@uvH] @@ -634,7 +634,8 @@ :: kes (~(del by kes) hen) :: == :: ~& eyre-them/(earn p.u.p.kyz) - (back hi//[p.kyz] %hiss q.kyz) + =+ usr=?~(p.kyz '~' (scot %ta u.p.kyz)) + (back hi//[usr]/[q.kyz] %hiss r.kyz) :: %they :: inbound response =+ kas=(need (~(get by q.ask) p.kyz)) @@ -724,7 +725,7 @@ %thou ?+ -.tee !! %ay (ames-gram (slav %p p.tee) got/~ (slav %uv q.tee) |2.sih) - %hi (cast-thou p.tee httr/!>(p.sih)) + %hi (cast-thou q.tee httr/!>(p.sih)) %se (get-thou:(dom-vi q.tee) p.tee p.sih) == :: @@ -780,10 +781,14 @@ (give-sigh q.sih) :: XX crash? =* cay p.q.sih ?> ?=(%hiss p.cay) + ?: =('~' p.tee) + (eyre-them tee q.cay) + =+ usr=(slav %ta p.tee) =+ ((hard ,[pul=purl ^]) q.q.cay) ?. ?=(%& -.r.p.pul) - (eyre-them hi//[p.tee] q.cay) - (get-req:(dom-vi p.r.p.pul) p.tee q.cay) + ~& [%auth-lost usr p.r.p.pul] + (eyre-them tee q.cay) + (get-req:(dom-vi usr p.r.p.pul) q.tee q.cay) :: :: [%hi ^] :: ?: ?=(%| -.q.sih) @@ -854,8 +859,8 @@ :: ++ ire-ix |=(ire=ixor ~(. ix ire (~(got by wix) ire))) ++ dom-vi - |= dom=path ^+ vi - ~(. vi dom (fall (~(get by sec) dom) *driv)) + |= [usr=span dom=path] ^+ vi :: XX default to initialized user? + ~(. vi [usr dom] (fall (~(get by sec) usr dom) *driv)) :: ++ ses-authed |= ses=hole @@ -1105,9 +1110,9 @@ %ac ?~ but ~|(no-host/`path`/~/[pef] !!) =+ `dom=host`~|(bad-host/i.but (rash i.but thos:urlp)) - ?> ?=([%auth ~] t.but) ?: ?=(%| -.dom) ~|(auth-ip/dom !!) - [%oath p.dom] + =+ usr=~|(bad-user/t.but (raid t.but %ta ~)) + [%oath usr p.dom] :: %at [%auth %at pok(q but)] %am ?~(but !! [%auth %xen i.but pok(q t.but)]) @@ -1231,9 +1236,9 @@ ((teba new-mess.vew) p.hem r.hem q.hem %json !>(`json`s.hem)) :: %oath - ?. (~(has by sec) p.hem) - ~|(no-driver/p.hem !!) - [%| %.(quy (teba get-quay:(dom-vi p.hem)))] + ?. (~(has by sec) [p q]:hem) + ~|(no-driver/[p q]:hem !!) + [%| %.(quy (teba get-quay:(dom-vi [p q]:hem)))] :: %poll ?: ?=([~ %js] p.pok) :: XX treat non-json cases? @@ -1602,13 +1607,16 @@ ++ print-subs |=([a=dock b=path] "{}/{(trip q.a)}{(spud b)}") -- ++ vi :: auth engine - |_ [dom=path cor=(unit vase) req=(qeu ,[p=duct q=mark r=vase:hiss])] + |_ $: [usr=span dom=path] + cor=(unit vase) + req=(qeu ,[p=duct q=mark r=vase:hiss]) + == ++ self . ++ abet +>(sec (~(put by sec) +<)) ++ dead-hiss |=(a=tang (give-sigh:abet %| a)) ++ dead-this |=(a=tang (fail:abet 500 0v0 a)) - ++ pass-note |=([a=whir-se b=note] (pass-note:abet se/[a dom] b)) - ++ eyre-them |=([a=whir-se b=vase] (eyre-them:abet se/[a dom] b)) + ++ pass-note |=([a=whir-se b=note] (pass-note:abet se/[a usr dom] b)) + ++ eyre-them |=([a=whir-se b=vase] (eyre-them:abet se/[a usr dom] b)) :: XX block reqs until correct core checked in? ++ warn |=(a=tang ((slog (flop a)) abet)) ++ pump @@ -1626,7 +1634,7 @@ =. +12.q.u.cor =+ ato=(sky %cx (tope root-beak [%atom (flop %_(dom . sec/dom))])) =+ key=?~(ato '' ;;(@t u.ato)) :: XX jael - `(bale)`[[our now (shas %bale eny) root-beak] dom ~ key] + `(bale)`[[our now (shas %bale eny) root-beak] [usr dom] key] =+ call/[ride/[cnzy/arm `core/u.cor] `sam] (pass-note arm (ford-req root-beak -)) :: diff --git a/arvo/gall.hoon b/arvo/gall.hoon index 2a725868c..79d2a6b74 100644 --- a/arvo/gall.hoon +++ b/arvo/gall.hoon @@ -22,7 +22,7 @@ ++ cote :: ++ap note $% [%meta p=@tas q=vase] :: [%send p=ship q=cush] :: - [%hiss p=mark q=cage] + [%hiss p=(unit span) q=mark r=cage] :: == :: ++ cove (pair bone (mold cote cuft)) :: internal move ++ move ,[p=duct q=(mold note-arvo gift-arvo)] :: typed move @@ -612,7 +612,7 @@ %pass :+ %pass `path`[%use dap p.q.cov] ?- -.q.q.cov - %hiss `note-arvo`[%e %hiss p.q.q.cov q.q.q.cov] + %hiss `note-arvo`[%e %hiss +.q.q.cov] %send `note-arvo`[%g %deal [our p.q.q.cov] q.q.q.cov] %meta `note-arvo`[`@tas`p.q.q.cov %meta `vase`q.q.q.cov] == @@ -806,11 +806,15 @@ ++ ap-move-hiss :: pass %hiss |= [sto=bone vax=vase] ^- [(each cove tang) _+>] - ?. &(?=([p=* q=@ q=^] q.vax) ((sane %tas) q.q.vax)) - :_(+>.$ [%| (ap-suck "hiss: bad hiss ask.[%hiss wire mark cage]")]) - =^ gaw vel (~(slot wa vel) 7 vax) + ?. &(?=([p=* q=* r=@ s=^] q.vax) ((sane %tas) r.q.vax)) + =+ args="[%hiss wire (unit span) mark cage]" + :_(+>.$ [%| (ap-suck "hiss: bad hiss ask.{args}")]) + =^ gaw vel (~(slot wa vel) 15 vax) ?. &(?=([p=@ q=^] q.gaw) ((sane %tas) p.q.gaw)) :_(+>.$ [%| (ap-suck "hiss: malformed cage")]) + =+ usr=((soft (unit span)) p.q.vax) + ?. &(?=(^ usr) ?~(u.usr & ((sane %ta) u.u.usr))) + :_(+>.$ [%| (ap-suck "hiss: malformed (unit span)")]) =+ pux=((soft path) p.q.vax) ?. &(?=(^ pux) (levy u.pux (sane %ta))) :_(+>.$ [%| (ap-suck "hiss: malformed path")]) @@ -818,7 +822,7 @@ :_ +>.$ :^ %& sto %pass :- [(scot %p q.q.pry) %cay u.pux] - [%hiss q.q.vax [p.q.gaw paw]] + [%hiss u.usr q.q.vax [p.q.gaw paw]] :: ++ ap-move-mess :: extract path, target |= vax=vase diff --git a/arvo/zuse.hoon b/arvo/zuse.hoon index 5e379fa13..327f7e9b7 100644 --- a/arvo/zuse.hoon +++ b/arvo/zuse.hoon @@ -1820,8 +1820,8 @@ ++ bale :: driver state |* a=_,* :: %jael keys type $: [our=ship now=@da eny=@uvI byk=beak] :: base info - dom=(list ,@t) :: intercepted domain - [usr=?(~ span) key=a] :: req user, secrets + [usr=?(~ span) dom=(list ,@t)] :: req user, domain + key=a :: secrets from %jael == :: ++ sec-move :: driver effect $% [%send p=hiss] :: http out @@ -2488,7 +2488,7 @@ ++ kiss-eyre :: in request ->$ $% [%born ~] :: new unix process [%crud p=@tas q=(list tank)] :: XX rethink - [%hiss p=mark q=cage] :: outbound user req + [%hiss p=(unit span) q=mark r=cage] :: outbound user req [%init p=@p] :: report install [%them p=(unit hiss)] :: outbound request [%they p=@ud q=httr] :: inbound response diff --git a/sec/com/googleapis/www.hoon b/sec/com/googleapis/www.hoon index bad3718c2..b1ef2decf 100644 --- a/sec/com/googleapis/www.hoon +++ b/sec/com/googleapis/www.hoon @@ -39,7 +39,7 @@ :: redirect-uri/redirect-uri == -++ redirect-uri 'http://localhost:8443/~/ac/www.googleapis.com/auth' +++ redirect-uri 'http://localhost:8443/~/ac/www.googleapis.com/~.' ++ user-state ,[ber=@t ref=@t ded=@da] -- :: @@ -67,7 +67,6 @@ :~ client-id/client-id client-secret/client-secret redirect-uri/redirect-uri - == ++ in |= a=quay ^- sec-move From 87541b4039fe2eab4bf88321cb0e7ec3d2d119b5 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Fri, 22 Jan 2016 16:38:37 -0800 Subject: [PATCH 3/8] fix local github redirect --- sec/com/github/api.hoon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sec/com/github/api.hoon b/sec/com/github/api.hoon index 9680f8877..63128333b 100644 --- a/sec/com/github/api.hoon +++ b/sec/com/github/api.hoon @@ -1,4 +1,4 @@ |_ [bal=(bale ,@t) ~] -++ out |=(a=hiss [%send %_(a p.p [| `6.000 `/localhost], q.q (~(add ja q.q.a) %authorization auth))]) +++ out |=(a=hiss [%send %_(a q.q (~(add ja q.q.a) %authorization auth))]) ++ auth (cat 3 'Basic ' key.bal) -- From 4a31ec56d0e818e28cb55bf7b76aeba149d5ed66 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Fri, 22 Jan 2016 16:39:49 -0800 Subject: [PATCH 4/8] per-user auth v2: ac/.../_state looks for state in quay --- ape/dojo.hoon | 4 ++-- ape/gh.hoon | 4 ++-- arvo/eyre.hoon | 10 ++++++++-- arvo/gall.hoon | 6 ++++-- arvo/zuse.hoon | 2 +- sec/com/facebook/graph.hoon | 5 +++-- sec/com/googleapis/www.hoon | 10 ++++++---- 7 files changed, 26 insertions(+), 15 deletions(-) diff --git a/ape/dojo.hoon b/ape/dojo.hoon index c2a9bedce..0820875e3 100644 --- a/ape/dojo.hoon +++ b/ape/dojo.hoon @@ -86,7 +86,7 @@ ++ card :: general card $% [%diff %sole-effect sole-effect] :: [%send wire [ship term] clap] :: - [%hiss wire mark [%hiss hiss]] :: + [%hiss wire [~ ~] %httr [%hiss hiss]] :: [%exec wire @p (unit ,[beak silk])] :: [%deal wire sock term club] :: [%info wire @p toro] :: @@ -267,7 +267,7 @@ |= [way=wire req=hiss] ^+ +>+> ?> ?=(~ pux) - (he-card(poy `+>+<(pux `way)) %hiss way %httr %hiss req) + (he-card(poy `+>+<(pux `way)) %hiss way `~ %httr %hiss req) :: ++ dy-stop :: stop work ^+ +> diff --git a/ape/gh.hoon b/ape/gh.hoon index adc3c6e08..909020a55 100644 --- a/ape/gh.hoon +++ b/ape/gh.hoon @@ -7,7 +7,7 @@ ++ card $% [%diff sub-result] [%them wire (unit hiss)] - [%hiss wire %httr [%hiss hiss]] + [%hiss wire [~ ~] %httr [%hiss hiss]] == -- |_ [hid=bowl cnt=@ hook=(unit ,@t)] @@ -73,7 +73,7 @@ =+ wir=[%x (scot %ud cnt) pax] =+ [aut hiz]=~(scry gh i.pax t.pax) ?. aut [ost.hid %them wir ~ hiz] - [ost.hid %hiss wir %httr [%hiss hiz]] + [ost.hid %hiss wir `~ %httr [%hiss hiz]] :: ++ sigh-httr-x thou-x ++ thou-x diff --git a/arvo/eyre.hoon b/arvo/eyre.hoon index f5106c4fe..ac9106e06 100644 --- a/arvo/eyre.hoon +++ b/arvo/eyre.hoon @@ -1111,8 +1111,14 @@ ?~ but ~|(no-host/`path`/~/[pef] !!) =+ `dom=host`~|(bad-host/i.but (rash i.but thos:urlp)) ?: ?=(%| -.dom) ~|(auth-ip/dom !!) - =+ usr=~|(bad-user/t.but (raid t.but %ta ~)) - [%oath usr p.dom] + =- [%oath - p.dom] + ~| bad-user/`path`t.but + ?> ?=([@ ~] t.but) + =+ in-quy=(rush i.t.but ;~(pfix cab fque:urlp)) + ?~ in-quy + (slav %ta i.t.but) + =+ src=~|(no/u.in-quy (~(got by (mo quy)) u.in-quy)) + p:(need (puck src)) :: allow state=usr_other-data :: %at [%auth %at pok(q but)] %am ?~(but !! [%auth %xen i.but pok(q t.but)]) diff --git a/arvo/gall.hoon b/arvo/gall.hoon index 79d2a6b74..40a5d74b0 100644 --- a/arvo/gall.hoon +++ b/arvo/gall.hoon @@ -812,7 +812,7 @@ =^ gaw vel (~(slot wa vel) 15 vax) ?. &(?=([p=@ q=^] q.gaw) ((sane %tas) p.q.gaw)) :_(+>.$ [%| (ap-suck "hiss: malformed cage")]) - =+ usr=((soft (unit span)) p.q.vax) + =+ usr=((soft (unit span)) q.q.vax) ?. &(?=(^ usr) ?~(u.usr & ((sane %ta) u.u.usr))) :_(+>.$ [%| (ap-suck "hiss: malformed (unit span)")]) =+ pux=((soft path) p.q.vax) @@ -822,7 +822,9 @@ :_ +>.$ :^ %& sto %pass :- [(scot %p q.q.pry) %cay u.pux] - [%hiss u.usr q.q.vax [p.q.gaw paw]] + ~! *cote + =- ~! - `cote`- + [%hiss u.usr r.q.vax [p.q.gaw paw]] :: ++ ap-move-mess :: extract path, target |= vax=vase diff --git a/arvo/zuse.hoon b/arvo/zuse.hoon index 327f7e9b7..71fb3c31f 100644 --- a/arvo/zuse.hoon +++ b/arvo/zuse.hoon @@ -1820,7 +1820,7 @@ ++ bale :: driver state |* a=_,* :: %jael keys type $: [our=ship now=@da eny=@uvI byk=beak] :: base info - [usr=?(~ span) dom=(list ,@t)] :: req user, domain + [usr=span dom=(list ,@t)] :: req user, domain key=a :: secrets from %jael == :: ++ sec-move :: driver effect diff --git a/sec/com/facebook/graph.hoon b/sec/com/facebook/graph.hoon index 1045b4476..f95c92d10 100644 --- a/sec/com/facebook/graph.hoon +++ b/sec/com/facebook/graph.hoon @@ -20,12 +20,13 @@ ++ decode-key :: XX from bale w/ typed %jael ((hard ,[client-id=@t client-secret=@t ~]) (lore key)) :: -++ redirect-uri 'http://localhost:8443/~/ac/graph.facebook.com/auth' +++ redirect-uri 'http://localhost:8443/~/ac/graph.facebook.com/_state' ++ aut =+ key=decode-key :: XX ^- quay %- fass - :~ client-id/client-id.key + :~ state/(pack usr /'') + client-id/client-id.key redirect-uri/redirect-uri scope/'user_about_me user_posts' == diff --git a/sec/com/googleapis/www.hoon b/sec/com/googleapis/www.hoon index b1ef2decf..63d29b8a9 100644 --- a/sec/com/googleapis/www.hoon +++ b/sec/com/googleapis/www.hoon @@ -28,18 +28,20 @@ ++ toke-url (endpoint /oauth2/v4/token) ++ dbg-post `purl`[[| `6.000 `/localhost] `/testing /] ++ auth-url - |= [cid=@t sop=(list cord)] ^- purl + |= [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]))) :: - redirect-uri/redirect-uri == -++ redirect-uri 'http://localhost:8443/~/ac/www.googleapis.com/~.' +++ redirect-uri 'http://localhost:8443/~/ac/www.googleapis.com/_state' ++ user-state ,[ber=@t ref=@t ded=@da] -- :: @@ -53,7 +55,7 @@ ++ need-refresh (lth ded (add now ~m1)) ++ out |= a=hiss ^- sec-move - ?~ ber [%show (auth-url client-id 'userinfo.email' 'plus.me' ~)] + ?~ ber [%show (auth-url usr client-id 'userinfo.email' 'plus.me' ~)] ?: need-refresh [%send toke-url (toke-req refresh-token/ref grant-type/'refresh_token' ~)] [%send %_(a q.q (~(add ja q.q.a) %authorization (cat 3 'Bearer ' ber)))] From dcb4f98ddfea4b2f1c057563cc451bf36fe8495d Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Fri, 22 Jan 2016 19:06:46 -0800 Subject: [PATCH 5/8] move fb oauth code to lib/oauth --- lib/oauth2.hoon | 134 ++++++++++++++++++++++++++++++++++++ sec/com/facebook/graph.hoon | 80 +++------------------ 2 files changed, 144 insertions(+), 70 deletions(-) create mode 100644 lib/oauth2.hoon diff --git a/lib/oauth2.hoon b/lib/oauth2.hoon new file mode 100644 index 000000000..ac460d5ac --- /dev/null +++ b/lib/oauth2.hoon @@ -0,0 +1,134 @@ +|% +++ 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) +:: +++ join + |= [a=cord b=(list cord)] + ?~ b '' + (rap 3 |-([i.b ?~(t.b ~ ['.' $(b t.b)])])) +:: +++ bad-response |=(a=@u ?:(=(2 (div a 100)) | ~&(bad-httr/a &))) +++ grab-json + |* [a=httr b=fist:jo] + ~| bad-json/r.a + (need (;~(biff poja b) q:(need r.a))) +-- +:: +:::: + :: +|% +++ token ?(~ @t) +++ keys cord:,[cid=@t cis=@t] +++ decode-keys :: XX from bale w/ typed %jael + |=(key=keys ((hard ,[cid=@t cis=@t ~]) (lore key))) +-- +:: +:::: + :: +|= [dialog=[p=host q=path r=quay] code-exchange=path] +|_ [(bale keys) scope=(list cord)] +++ client-id cid:(decode-keys key) +++ 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) +++ auth-url + ^- purl + :+ [& ~ p.dialog] [~ q.dialog] + %- fass + %+ welp r.dialog + :~ state/(pack usr /'') + client-id/client-id + redirect-uri/redirect-uri + scope/(join ' ' scope) + == +:: +++ redirect-uri + %- crip %- earn + [urb-hart `/~/ac/(join '.' (flop dom))/'_state' ~] +:: +++ refresh-expiring + |= [[expires=@da refresh=token] otherwise=$+(hiss sec-move)] + |= a=hiss + ?~ refresh (otherwise a) + ?: (lth expires (add now ~m1)) + (otherwise a) + [%send toke-url (toke-req 'refresh_token' refresh-token/refresh ~)] +:: +++ out-filtered + |= [tok=token aut=$+(hiss hiss)] + |= a=hiss ^- sec-move + ?~(tok [%show auth-url] [%send (aut a)]) +:: +++ out-quay + |= [nam=span tok=token] + %+ out-filtered tok + |=(a=hiss %_(a r.p :_(r.p.a nam^`@t`tok))) +:: +++ out-math + |= ber=token + =+ hed=authorization/(cat 3 'Bearer ' `@t`ber) + %+ out-filtered ber + |=(a=hiss %_(a q.q (~(add ja q.q.a) hed))) +:: +++ toke-req + |= [grant-type=cord 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 + grant-type/grant-type + == +:: +++ in-code + |= a=quay ^- sec-move + =+ code=~|(%no-code (~(got by (mo a)) %code)) + [%send toke-url (toke-req 'authorization_code' code/code ~)] +:: +++ token-type 'token_type'^(cu cass sa):jo +++ expires-in 'expires_in'^ni:jo +++ access-token 'access_token'^so:jo +++ refresh-token 'refresh_token'^so:jo +++ bak-parse-access + |* [done=* parse=(pole ,[span fist]:jo)] + |= handle=$+([token _(need *(ot:jo parse))] _done) + |= a=httr ^- [sec-move _done] + :- [%redo ~] + ?: (bad-response p.a) done :: handle 4xx? + (handle (grab-json a (ot:jo access-token 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))) +:: +-- diff --git a/sec/com/facebook/graph.hoon b/sec/com/facebook/graph.hoon index f95c92d10..0b1be1bea 100644 --- a/sec/com/facebook/graph.hoon +++ b/sec/com/facebook/graph.hoon @@ -1,77 +1,17 @@ -|% -++ 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 :: :::: :: -|_ [(bale ,@t) access-token=@t] -++ decode-key :: XX from bale w/ typed %jael - ((hard ,[client-id=@t client-secret=@t ~]) (lore key)) -:: -++ redirect-uri 'http://localhost:8443/~/ac/graph.facebook.com/_state' -++ aut - =+ key=decode-key :: XX - ^- quay - %- fass - :~ state/(pack usr /'') - client-id/client-id.key - redirect-uri/redirect-uri - scope/'user_about_me user_posts' - == -:: -++ out - |= a=hiss ^- sec-move - ?~ access-token - [%show [& ~ `/com/facebook/www] `/dialog/oauth aut] - [%send %_(a r.p :_(r.p.a 'access_token'^access-token))] -:: -:: -++ graph [& ~ `/com/facebook/graph] -++ in - =+ key=decode-key :: XX - |= a=quay ^- sec-move - =+ cod=~|(%no-code (~(got by (mo a)) %code)) - =- [%send [graph `/'v2.3'/oauth/'access_token' -] %get ~ ~] - %- fass - :~ code/cod - client-id/client-id.key - client-secret/client-secret.key - redirect-uri/redirect-uri - grant-type/'authorization_code' - == -:: -:: -++ parse-bak - |= [@u a=@t] - %. a - ;~ biff - poja - => jo %- ot :~ - 'access_token'^so - 'expires_in'^ni - == - == -:: +=+ [`/com/facebook/www /dialog/oauth response-type/%code ~] +=+ aut=(oauth2 - /'v2.3'/oauth/'access_token') +|_ [bal=(bale keys.aut) access-token=token.aut] +++ auth ~(. aut bal /'user_about_me'/'user_posts') +++ out (out-quay:auth 'access_token'^access-token) +++ in in-code:auth ++ bak - |= res=httr ^- [sec-move _+>] - =+ ~| bad-json/r.res - ^- [access-token=@t expires-in=@u] - (need (parse-bak (need r.res))) - ~& res - =+ token-expires=`@da`(add now (mul ~s1 expires-in)) + %- (bak-parse-access:auth . expires-in.aut ~) + |= [access-token=token.aut expires-in=@u] + =+ token-expires=`@da`(add now.bal (mul ~s1 expires-in)) ~& authenticated-until/token-expires :: XX handle timeout - :- [%redo ~] +>.$(access-token access-token) -- From 1d697a25d9fdb9071abd0dac6e8a3191eaf7ea3a Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Fri, 22 Jan 2016 19:07:42 -0800 Subject: [PATCH 6/8] added slack driver --- sec/com/slack.hoon | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 sec/com/slack.hoon diff --git a/sec/com/slack.hoon b/sec/com/slack.hoon new file mode 100644 index 000000000..5f00e1b27 --- /dev/null +++ b/sec/com/slack.hoon @@ -0,0 +1,70 @@ +|% +++ 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) +-- +:: +:::: + :: +|_ [(bale ,@t) token=@t] +++ decode-key :: XX from bale w/ typed %jael + ((hard ,[client-id=@t client-secret=@t ~]) (lore key)) +:: +++ redirect-uri (cat 3 'http://localhost:8443/~/ac/slack.com/' (scot %ta usr)) +++ aut + =+ key=decode-key :: XX + ^- quay + %- fass + :~ client-id/client-id.key + redirect-uri/redirect-uri + scope/'client admin' + == +:: +++ out + |= a=hiss ^- sec-move + ?~ token + [%show [& ~ `/com/slack] `/oauth/authorize aut] + [%send %_(a r.p :_(r.p.a 'token'^token))] +:: +:: +++ in + =+ key=decode-key :: XX + |= a=quay ^- sec-move + =+ cod=~|(%no-code (~(got by (mo a)) %code)) + =- [%send [[& ~ `/com/slack] `/api/'oauth.access' -] %get ~ ~] + %- fass + :~ code/cod + client-id/client-id.key + client-secret/client-secret.key + redirect-uri/redirect-uri + == +:: +:: +++ parse-bak + |= [@u a=@t] + %. a + ;~ biff + poja + => jo %- ot :~ + 'access_token'^so + == + == +:: +++ bak + |= res=httr ^- [sec-move _+>] + =+ ~| bad-json/r.res + ^- token=@t + (need (parse-bak (need r.res))) + :- [%redo ~] + +>.$(token token) +-- From 963ad9799b48ad0e8fa2ff7a39ab48fd04a172b7 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Mon, 25 Jan 2016 14:49:38 -0800 Subject: [PATCH 7/8] convert slack to lib/oauth2 --- lib/oauth2.hoon | 14 ++++--- sec/com/facebook/graph.hoon | 2 +- sec/com/slack.hoon | 73 ++++--------------------------------- 3 files changed, 16 insertions(+), 73 deletions(-) diff --git a/lib/oauth2.hoon b/lib/oauth2.hoon index ac460d5ac..2b6350495 100644 --- a/lib/oauth2.hoon +++ b/lib/oauth2.hoon @@ -16,7 +16,7 @@ ++ join |= [a=cord b=(list cord)] ?~ b '' - (rap 3 |-([i.b ?~(t.b ~ ['.' $(b t.b)])])) + (rap 3 |-([i.b ?~(t.b ~ [a $(b t.b)])])) :: ++ bad-response |=(a=@u ?:(=(2 (div a 100)) | ~&(bad-httr/a &))) ++ grab-json @@ -36,7 +36,8 @@ :: :::: :: -|= [dialog=[p=host q=path r=quay] code-exchange=path] +|= [dialog=[p=host q=path r=quay] code-exchange=path] +=+ state-usr=& |_ [(bale keys) scope=(list cord)] ++ client-id cid:(decode-keys key) ++ client-secret cis:(decode-keys key) @@ -49,7 +50,7 @@ :+ [& ~ p.dialog] [~ q.dialog] %- fass %+ welp r.dialog - :~ state/(pack usr /'') + :~ state/?.(state-usr '' (pack usr /'')) client-id/client-id redirect-uri/redirect-uri scope/(join ' ' scope) @@ -57,7 +58,8 @@ :: ++ redirect-uri %- crip %- earn - [urb-hart `/~/ac/(join '.' (flop dom))/'_state' ~] + =+ 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)] @@ -106,8 +108,8 @@ ++ refresh-token 'refresh_token'^so:jo ++ bak-parse-access |* [done=* parse=(pole ,[span fist]:jo)] - |= handle=$+([token _(need *(ot:jo parse))] _done) - |= a=httr ^- [sec-move _done] + |= handle=$+(_?~(parse *token [*token (need *(ot:jo parse))]) _done) + |= a=httr ^- [sec-move _done] :- [%redo ~] ?: (bad-response p.a) done :: handle 4xx? (handle (grab-json a (ot:jo access-token parse))) diff --git a/sec/com/facebook/graph.hoon b/sec/com/facebook/graph.hoon index 0b1be1bea..32b6764fa 100644 --- a/sec/com/facebook/graph.hoon +++ b/sec/com/facebook/graph.hoon @@ -1,4 +1,4 @@ -/+ oauth2 +/+ oauth2 :: :::: :: diff --git a/sec/com/slack.hoon b/sec/com/slack.hoon index 5f00e1b27..e05a8c92f 100644 --- a/sec/com/slack.hoon +++ b/sec/com/slack.hoon @@ -1,70 +1,11 @@ -|% -++ 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 :: :::: :: -|_ [(bale ,@t) token=@t] -++ decode-key :: XX from bale w/ typed %jael - ((hard ,[client-id=@t client-secret=@t ~]) (lore key)) -:: -++ redirect-uri (cat 3 'http://localhost:8443/~/ac/slack.com/' (scot %ta usr)) -++ aut - =+ key=decode-key :: XX - ^- quay - %- fass - :~ client-id/client-id.key - redirect-uri/redirect-uri - scope/'client admin' - == -:: -++ out - |= a=hiss ^- sec-move - ?~ token - [%show [& ~ `/com/slack] `/oauth/authorize aut] - [%send %_(a r.p :_(r.p.a 'token'^token))] -:: -:: -++ in - =+ key=decode-key :: XX - |= a=quay ^- sec-move - =+ cod=~|(%no-code (~(got by (mo a)) %code)) - =- [%send [[& ~ `/com/slack] `/api/'oauth.access' -] %get ~ ~] - %- fass - :~ code/cod - client-id/client-id.key - client-secret/client-secret.key - redirect-uri/redirect-uri - == -:: -:: -++ parse-bak - |= [@u a=@t] - %. a - ;~ biff - poja - => jo %- ot :~ - 'access_token'^so - == - == -:: -++ bak - |= res=httr ^- [sec-move _+>] - =+ ~| bad-json/r.res - ^- token=@t - (need (parse-bak (need r.res))) - :- [%redo ~] - +>.$(token token) +=+ aut=(oauth2 [`/com/slack /oauth/authorize ~] /api/'oauth.access') +|_ [(bale keys:oauth2) tok=token.aut] +++ aut ~(. ^aut(state-usr |) +<- /client/admin) +++ out (out-quay:aut 'token'^tok) +++ in in-code:aut +++ bak ((bak-parse-access:aut . ~) |=(tok=token:aut +>(tok tok))) -- From d8c909f80c20e1fecdd0af4859eaadce049087b9 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Mon, 25 Jan 2016 17:41:01 -0800 Subject: [PATCH 8/8] allow all sec/ interface arms to be stateful or stateless --- arvo/eyre.hoon | 62 +++++++++++++++++++++---------------- sec/com/googleapis/www.hoon | 36 ++++++++++++--------- 2 files changed, 57 insertions(+), 41 deletions(-) diff --git a/arvo/eyre.hoon b/arvo/eyre.hoon index ac9106e06..cf91f7c4f 100644 --- a/arvo/eyre.hoon +++ b/arvo/eyre.hoon @@ -1619,8 +1619,8 @@ == ++ self . ++ abet +>(sec (~(put by sec) +<)) - ++ dead-hiss |=(a=tang (give-sigh:abet %| a)) ++ dead-this |=(a=tang (fail:abet 500 0v0 a)) + ++ dead-hiss |=(a=tang (give-sigh:abet(req ~(nap to req)) %| a)) ++ pass-note |=([a=whir-se b=note] (pass-note:abet se/[a usr dom] b)) ++ eyre-them |=([a=whir-se b=vase] (eyre-them:abet se/[a usr dom] b)) :: XX block reqs until correct core checked in? @@ -1679,13 +1679,35 @@ =. ..vi (cast-thou(hen p.ole) q.ole httr/vax) :: error? pump :: - ++ on-error - |= [err=$+(tang _abet) try=$+(vase _abet)] + ++ on-ford-fail + |= [err=$+(tang _abet) try=$+((each cage tang) _abet)] |= a=(each cage tang) ^+ abet + ?-(-.a %| (err p.a), %& (try a)) + :: + ++ on-error + |= [err=$+(tang _abet) handle-move=_|.(|+(vase:sec-move abet))] + |= a=(each cage tang) ^+ abet + =+ try=(possibly-stateful |=(b=_self (handle-move(+ b)))) :: XX types ?: ?=(%| -.a) (err p.a) =- ?-(-.- %& p.-, %| (err p.-)) (mule |.(~|(driver/dom ~|(bad-res/p.q.p.a (try q.p.a))))) :: + ++ possibly-stateful + |= han=_|+(_self |+(vase:sec-move abet)) :: XX |.(|+(vase:sec-move abet)) + |= res=vase ^+ abet + ?: ?=([@ *] q.res) + =. p.res (~(fuse ut p.res) p:!>(*[@ *])) + ((han self) res) + ?. ?=([[@ *] *] q.res) + ~|(%misshapen-result !!) + =. p.res (~(fuse ut p.res) p:!>(*[[@ *] *])) + =+ [mow=(slot 2 res) roc=(slot 3 res)] + =- ((han self(cor (some roc))) mow):+ :: XX better stateless asserts + ?~ cor ~|(%lost-core !!) + ~| %core-mismatch + ?> (~(nest ut p.u.cor) & p.roc) + ~ + :: ++ allow |= a=(list ,[p=term q=$+(vase _abet)]) |= b=vase @@ -1700,17 +1722,11 @@ $(a t.a) :: ++ res-in - %+ on-error dead-this + %+ on-error dead-this |. (allow send/(do-send %in) ~) :: - ++ do-send - |= wir=whir-se ^- $+(vase _abet) - |= res=vase - (eyre-them wir (slam !>(|=([%send a=hiss] a)) res)) - :: ++ res-res - %+ on-error |=(a=tang (dead-hiss(req ~(nap to req)) a)) - %- stateful |= a=_self => a + %+ on-error dead-hiss |. %- allow :~ give/do-give send/(do-send %out) @@ -1718,33 +1734,26 @@ == :: ++ res-bak - %+ on-error dead-this - %- stateful |= a=_self => a + %+ on-error dead-this |. %- allow :~ give/do-give redo/,_pump(..vi (give-html 200 ~ exit:xml)) == :: - ++ stateful - |= han=$+(_self $+(vase:sec-move _abet)) - |= res=vase ^+ abet - ?~ cor ~|(%lost-core !!) - =^ mow u.cor - ~|(%split [mow=(slot 2 res) cor=(slot 3 res)]) - ((han self(cor cor)) mow) - :: ++ res-out - |= a=(each cage tang) ^+ abet - ?: ?=(%| -.a) - (dead-hiss(req ~(nap to req)) p.a) - %. a - %+ on-error warn + %+ on-ford-fail dead-hiss + %+ on-error warn |. %- allow :~ give/do-give send/(do-send %out) show/do-show == :: + ++ do-send + |= wir=whir-se ^- $+(vase _abet) + |= res=vase + (eyre-them wir (slam !>(|=([%send a=hiss] a)) res)) + :: ++ do-show (discard-with !>(auth-print)) ++ discard-with |= a=vase:gate ^- $+(vase _abet) @@ -1770,6 +1779,7 @@ :^ %mute core/[root-beak (flop %_(dom . sec/dom))] [~[`12] `bale/!>(*(bale ,@))] :: XX specify on type? ?~ cor ~ + ?: (~(has in (sa (sloe p.u.cor))) %wipe) ~ :: XX proper adapt [~[`13] `noun/(slot 13 u.cor)]~ :: ++ get-req |=(a=[mark vase:hiss] pump(req (~(put to req) hen a))) diff --git a/sec/com/googleapis/www.hoon b/sec/com/googleapis/www.hoon index 63d29b8a9..7a8851990 100644 --- a/sec/com/googleapis/www.hoon +++ b/sec/com/googleapis/www.hoon @@ -42,7 +42,7 @@ :: == ++ redirect-uri 'http://localhost:8443/~/ac/www.googleapis.com/_state' -++ user-state ,[ber=@t ref=@t ded=@da] +++ user-state ,[ber=@t ded=@da ref=[token=@t pending=?]] -- :: :::: @@ -54,12 +54,16 @@ :: ++ need-refresh (lth ded (add now ~m1)) ++ out - |= a=hiss ^- sec-move - ?~ ber [%show (auth-url usr client-id 'userinfo.email' 'plus.me' ~)] + |= 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 (toke-req refresh-token/ref grant-type/'refresh_token' ~)] - [%send %_(a q.q (~(add ja q.q.a) %authorization (cat 3 'Bearer ' ber)))] + [& [%send toke-url refresh-req]] + =. q.q.a (~(add ja q.q.a) %authorization (cat 3 'Bearer ' ber)) + [| [%send 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']]) @@ -76,19 +80,19 @@ [%send toke-url (toke-req code/cod grant-type/'authorization_code' ~)] :: ++ res - |= a=httr ^- [sec-move _+>] - ?: need-refresh - ?: (bad-response p.a) [[%redo ~] +>.$] :: handle 4xx? - ~| %refreshed-token - [[%redo ~] (new-token a)] - [[%give a] +>.$] + |= 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))) + +>.$(ber ber, ded (add now (mul ~s1 tim)), pending.ref |) :: ++ grab |* [a=httr b=fist:jo] @@ -104,7 +108,9 @@ :: ++ bak |= a=httr ^- [sec-move _+>] - ?: (bad-response p.a) [[%redo ~] +>.$] :: handle 4xx? - =. ref (grab a (ot 'refresh_token'^so ~):jo) - [[%redo ~] (new-token a)] + :- [%redo ~] + ?: (bad-response p.a) +>.$ :: handle 4xx? + =. token.ref (grab a (ot 'refresh_token'^so ~):jo) + (new-token a) +::++ wipe ~ --