1 ! Copyright (C) 2016 Björn Lindqvist.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs calendar combinators http.client io
4 json.reader kernel make math.order sequences unicode urls
8 : console-prompt ( query -- str/f )
9 write flush readln [ blank? ] trim [ f ] when-empty ;
11 : post-json-request ( params token-uri -- assoc )
12 <post-request> dup header>> "application/json" "Accept" rot set-at
13 http-request nip json> ;
15 TUPLE: tokens access refresh expiry ;
17 : assoc>expiry ( json -- expiry )
18 "expires_in" of [ seconds now time+ ] [ f ] if* ;
20 : assoc>tokens ( json -- tokens )
22 [ "refresh_token" of ]
23 [ assoc>expiry ] tri tokens boa ;
25 : access-expired? ( tokens -- ? )
26 expiry>> [ now before? ] [ f ] if* ;
28 : update-tokens ( tokens1 tokens2 -- tokens1 )
29 2dup expiry>> >>expiry drop access>> >>access ;
40 : tokens-params ( oauth2 code -- params )
44 [ client-id>> "client_id" ,, ]
45 [ client-secret>> "client_secret" ,, ]
46 [ redirect-uri>> "redirect_uri" ,, ]
49 "authorization_code" "grant_type" ,,
52 : refresh-params ( oauth2 refresh -- params )
55 [ client-id>> "client_id" ,, ]
56 [ client-secret>> "client_secret" ,, ]
57 [ extra-params>> %% ] tri
58 "refresh_token" "grant_type" ,,
61 : auth-params ( oauth2 -- params )
64 [ client-id>> "client_id" ,, ]
65 [ scope>> "scope" ,, ]
66 [ redirect-uri>> "redirect_uri" ,, ]
69 "code" "response_type" ,,
70 "offline" "access_type" ,,
73 : oauth2>auth-uri ( oauth2 -- uri )
74 [ auth-uri>> >url ] [ auth-params ] bi set-query-params ;
76 ! Other flows can be useful to support too.
77 : console-flow ( oauth2 -- tokens/f )
78 dup oauth2>auth-uri open-url
79 "Enter verification code: " console-prompt
81 dupd tokens-params swap token-uri>> post-json-request
85 : refresh-flow ( oauth2 tokens -- tokens' )
86 dupd refresh>> refresh-params swap token-uri>> post-json-request
89 ! Using the token to access secured resources.
90 : add-token ( request url -- )
91 "Bearer " prepend "Authorization" rot header>> set-at ;
93 : oauth-http-get ( url access-token -- response data )
94 [ <get-request> dup ] dip add-token http-request ;