-rw-r--r-- | include/Makefile.am | 3 | ||||
-rw-r--r-- | include/opkele/oauth/consumer.h | 19 | ||||
-rw-r--r-- | lib/oauth-consumer.cc | 46 | ||||
-rw-r--r-- | test/Makefile.am | 5 | ||||
-rw-r--r-- | test/test-oauth-consumer.cc | 22 |
5 files changed, 68 insertions, 27 deletions
diff --git a/include/Makefile.am b/include/Makefile.am index b41e6cc..2ae510d 100644 --- a/include/Makefile.am +++ b/include/Makefile.am | |||
@@ -18,17 +18,18 @@ nobase_include_HEADERS = \ | |||
18 | opkele/tr1-mem.h \ | 18 | opkele/tr1-mem.h \ |
19 | opkele/basic_rp.h opkele/prequeue_rp.h \ | 19 | opkele/basic_rp.h opkele/prequeue_rp.h \ |
20 | opkele/iterator.h \ | 20 | opkele/iterator.h \ |
21 | opkele/basic_op.h opkele/verify_op.h \ | 21 | opkele/basic_op.h opkele/verify_op.h \ |
22 | opkele/util.h \ | 22 | opkele/util.h \ |
23 | opkele/oauth.h opkele/oauth/consumer.h \ | 23 | opkele/oauth.h opkele/oauth/consumer.h \ |
24 | opkele/curl.h \ | ||
24 | ${NODIST_HEADERS_} | 25 | ${NODIST_HEADERS_} |
25 | 26 | ||
26 | noinst_HEADERS = \ | 27 | noinst_HEADERS = \ |
27 | opkele/data.h \ | 28 | opkele/data.h \ |
28 | opkele/curl.h opkele/expat.h opkele/tidy.h \ | 29 | opkele/expat.h opkele/tidy.h \ |
29 | opkele/util-internal.h \ | 30 | opkele/util-internal.h \ |
30 | opkele/debug.h \ | 31 | opkele/debug.h \ |
31 | opkele/discovery.h | 32 | opkele/discovery.h |
32 | 33 | ||
33 | dist-hook: | 34 | dist-hook: |
34 | rm -f $(addprefix ${distdir}/,${NODIST_HEADERS_}) | 35 | rm -f $(addprefix ${distdir}/,${NODIST_HEADERS_}) |
diff --git a/include/opkele/oauth/consumer.h b/include/opkele/oauth/consumer.h index 1e2784c..eb4f753 100644 --- a/include/opkele/oauth/consumer.h +++ b/include/opkele/oauth/consumer.h | |||
@@ -1,27 +1,30 @@ | |||
1 | #ifndef __OPKELE_OAUTH_CONSUMER_H | 1 | #ifndef __OPKELE_OAUTH_CONSUMER_H |
2 | #define __OPKELE_OAUTH_CONSUMER_H | 2 | #define __OPKELE_OAUTH_CONSUMER_H |
3 | 3 | ||
4 | #include <string> | 4 | #include <string> |
5 | #include <opkele/types.h> | 5 | #include <opkele/types.h> |
6 | #include <opkele/oauth.h> | 6 | #include <opkele/oauth.h> |
7 | #include <opkele/curl.h> | ||
7 | 8 | ||
8 | namespace opkele { | 9 | namespace opkele { |
9 | namespace oauth { | 10 | namespace oauth { |
10 | using std::string; | 11 | using std::string; |
11 | 12 | ||
12 | enum oauth_method_t { | 13 | enum oauth_method_t { |
13 | oauth_auth_header, oauth_post_body, oauth_url_query | 14 | oauth_auth_header, oauth_post_body, oauth_url_query, |
15 | oauth_method_default = oauth_auth_header | ||
14 | }; | 16 | }; |
15 | 17 | ||
16 | struct service_endpoint_t { | 18 | struct service_endpoint_t { |
17 | string url; | 19 | string url; |
18 | string signature_method; | 20 | string signature_method; |
19 | oauth_method_t oauth_method; | 21 | oauth_method_t oauth_method; |
20 | 22 | ||
21 | service_endpoint_t(const string& u,const string& sm,oauth_method_t om) | 23 | service_endpoint_t() : oauth_method(oauth_method_default) { } |
24 | service_endpoint_t(const string& u,const string& sm,oauth_method_t om=oauth_method_default) | ||
22 | : url(u), signature_method(sm), oauth_method(om) { } | 25 | : url(u), signature_method(sm), oauth_method(om) { } |
23 | }; | 26 | }; |
24 | 27 | ||
25 | class basic_provider_endpoints { | 28 | class basic_provider_endpoints { |
26 | public: | 29 | public: |
27 | 30 | ||
@@ -38,14 +41,18 @@ namespace opkele { | |||
38 | struct http_request_t { | 41 | struct http_request_t { |
39 | string authorize_header; | 42 | string authorize_header; |
40 | string method; | 43 | string method; |
41 | string url; | 44 | string url; |
42 | string body; | 45 | string body; |
43 | 46 | ||
47 | util::curl_slist_t _curl_headers_list; | ||
48 | |||
44 | http_request_t(const string& m,const string& u) | 49 | http_request_t(const string& m,const string& u) |
45 | : method(m), url(u) { } | 50 | : method(m), url(u) { } |
51 | |||
52 | void setup_curl(CURL *curl); | ||
46 | }; | 53 | }; |
47 | 54 | ||
48 | class basic_consumer { | 55 | class basic_consumer { |
49 | public: | 56 | public: |
50 | token_t consumer_token; | 57 | token_t consumer_token; |
51 | 58 | ||
@@ -57,22 +64,26 @@ namespace opkele { | |||
57 | virtual const string allocate_nonce(time_t ts) = 0; | 64 | virtual const string allocate_nonce(time_t ts) = 0; |
58 | 65 | ||
59 | token_t get_request_token(); | 66 | token_t get_request_token(); |
60 | const string get_authorize_url(const token_t& rt,const string& callback=""); | 67 | const string get_authorize_url(const token_t& rt,const string& callback=""); |
61 | token_t get_access_token(const token_t& rt); | 68 | token_t get_access_token(const token_t& rt); |
62 | 69 | ||
63 | void prepare_request( | 70 | http_request_t& prepare_request( |
64 | http_request_t& req, | 71 | http_request_t& req, |
65 | const basic_fields& qf,const basic_fields& pf, | 72 | const basic_fields& qf,const basic_fields& pf, |
66 | oauth_method_t om,const string& sm, | 73 | oauth_method_t om,const string& sm, |
67 | const token_t *t=0,const string& realm=""); | 74 | const token_t *t=0,const string& realm=""); |
68 | void prepare_request( | 75 | http_request_t& prepare_request( |
69 | http_request_t& req, | 76 | http_request_t& req, |
70 | const basic_fields& qf,const basic_fields& pf, | 77 | const basic_fields& qf,const basic_fields& pf, |
71 | const service_endpoint_t& sep, | 78 | const service_endpoint_t& sep, |
72 | const token_t *t=0,const string& realm=""); | 79 | const token_t *t=0,const string& realm=""); |
80 | http_request_t& prepare_request( | ||
81 | http_request_t& req, | ||
82 | const basic_fields& qf,const basic_fields& pf, | ||
83 | const token_t *t=0,const string& realm=""); | ||
73 | 84 | ||
74 | const string signature( | 85 | const string signature( |
75 | const string& method, | 86 | const string& method, |
76 | const string& url, | 87 | const string& url, |
77 | const basic_fields& fields, | 88 | const basic_fields& fields, |
78 | const token_t* rt=0); | 89 | const token_t* rt=0); |
diff --git a/lib/oauth-consumer.cc b/lib/oauth-consumer.cc index d717ed3..bb4e89b 100644 --- a/lib/oauth-consumer.cc +++ b/lib/oauth-consumer.cc | |||
@@ -153,13 +153,13 @@ namespace opkele { | |||
153 | rv.secret = util::url_decode(part.substr(eq+1)); | 153 | rv.secret = util::url_decode(part.substr(eq+1)); |
154 | } | 154 | } |
155 | } | 155 | } |
156 | return rv; | 156 | return rv; |
157 | } | 157 | } |
158 | 158 | ||
159 | void basic_consumer::prepare_request( | 159 | http_request_t& basic_consumer::prepare_request( |
160 | http_request_t& req, | 160 | http_request_t& req, |
161 | const basic_fields& qf,const basic_fields& pf, | 161 | const basic_fields& qf,const basic_fields& pf, |
162 | oauth_method_t om,const string& sm, | 162 | oauth_method_t om,const string& sm, |
163 | const token_t *t,const string& realm) { | 163 | const token_t *t,const string& realm) { |
164 | fields_t op; | 164 | fields_t op; |
165 | op.set_field("oauth_consumer_key",consumer_token.key); | 165 | op.set_field("oauth_consumer_key",consumer_token.key); |
@@ -206,25 +206,65 @@ namespace opkele { | |||
206 | qf.append_to(q); op.append_to(q); | 206 | qf.append_to(q); op.append_to(q); |
207 | req.url = q.append_query(req.url); | 207 | req.url = q.append_query(req.url); |
208 | req.body = pf.query_string(); | 208 | req.body = pf.query_string(); |
209 | }else | 209 | }else |
210 | throw opkele::exception(OPKELE_CP_ /* TODO: specialize */ | 210 | throw opkele::exception(OPKELE_CP_ /* TODO: specialize */ |
211 | "Unknown oauth method"); | 211 | "Unknown oauth method"); |
212 | return req; | ||
212 | } | 213 | } |
213 | 214 | ||
214 | void basic_consumer::prepare_request( | 215 | http_request_t& basic_consumer::prepare_request( |
215 | http_request_t& req, | 216 | http_request_t& req, |
216 | const basic_fields& qf,const basic_fields& pf, | 217 | const basic_fields& qf,const basic_fields& pf, |
217 | const service_endpoint_t& sep, | 218 | const service_endpoint_t& sep, |
218 | const token_t *t,const string& realm) { | 219 | const token_t *t,const string& realm) { |
219 | prepare_request( | 220 | return prepare_request( |
220 | req, qf, pf, | 221 | req, qf, pf, |
221 | sep.oauth_method,sep.signature_method, | 222 | sep.oauth_method,sep.signature_method, |
222 | t,realm); | 223 | t,realm); |
223 | } | 224 | } |
224 | 225 | ||
226 | http_request_t& basic_consumer::prepare_request( | ||
227 | http_request_t& req, | ||
228 | const basic_fields& qf,const basic_fields& pf, | ||
229 | const token_t *t,const string& realm) { | ||
230 | service_endpoint_t sep; | ||
231 | return prepare_request( | ||
232 | req, qf, pf, | ||
233 | get_endpoints().get_url_endpoint(sep,req.url), | ||
234 | t, realm ); | ||
235 | } | ||
236 | |||
237 | void http_request_t::setup_curl(CURL *curl) { | ||
238 | CURLcode r; | ||
239 | r = curl_easy_setopt(curl,CURLOPT_URL,url.c_str()); | ||
240 | if(r) | ||
241 | throw exception_curl(OPKELE_CP_ "failed to set curly urlie",r); | ||
242 | if(method=="POST") { | ||
243 | (r = curl_easy_setopt(curl,CURLOPT_POST,1)) | ||
244 | || (r = curl_easy_setopt(curl,CURLOPT_POSTFIELDS,body.c_str())) | ||
245 | || (r = curl_easy_setopt(curl,CURLOPT_POSTFIELDSIZE,body.size())); | ||
246 | }else if(method=="GET") { | ||
247 | r = curl_easy_setopt(curl,CURLOPT_HTTPGET,1); | ||
248 | }else if(method=="HEAD") { | ||
249 | r = curl_easy_setopt(curl,CURLOPT_NOBODY,1); | ||
250 | }else /* TODO: specialize exception */ | ||
251 | throw exception(OPKELE_CP_ "don't know how to handle http method"); | ||
252 | if(r) | ||
253 | throw exception_curl(OPKELE_CP_ "failed to set curly options",r); | ||
254 | if(!authorize_header.empty()) { | ||
255 | r = curl_easy_setopt(curl,CURLOPT_HTTPHEADER,(curl_slist*)( | ||
256 | _curl_headers_list = curl_slist_append( | ||
257 | 0,string("Authorization: "+authorize_header).c_str() | ||
258 | ) | ||
259 | ) ); | ||
260 | if(r) | ||
261 | throw exception_curl(OPKELE_CP_ "failed to setup curlie header"); | ||
262 | } | ||
263 | } | ||
264 | |||
225 | 265 | ||
226 | const basic_provider_endpoints& simple_consumer::get_endpoints() const { | 266 | const basic_provider_endpoints& simple_consumer::get_endpoints() const { |
227 | return peps; } | 267 | return peps; } |
228 | 268 | ||
229 | const string simple_consumer::allocate_nonce(time_t ts) { | 269 | const string simple_consumer::allocate_nonce(time_t ts) { |
230 | # ifndef HAVE_LIBUUID | 270 | # ifndef HAVE_LIBUUID |
diff --git a/test/Makefile.am b/test/Makefile.am index f0c0ea8..7cfe3a4 100644 --- a/test/Makefile.am +++ b/test/Makefile.am | |||
@@ -1,7 +1,8 @@ | |||
1 | noinst_PROGRAMS = test idiscover RP.cgi OP.cgi test-oauth-consumer | 1 | noinst_PROGRAMS = test idiscover test-oauth-consumer \ |
2 | ${_dependent_programs_} | ||
2 | 3 | ||
3 | AM_CPPFLAGS=${CPPFLAGS_DEBUG} | 4 | AM_CPPFLAGS=${CPPFLAGS_DEBUG} |
4 | DEFAULT_INCLUDES = -I${top_builddir} | 5 | DEFAULT_INCLUDES = -I${top_builddir} |
5 | INCLUDES = -I${top_srcdir}/test/ -I${top_builddir}/include/ -I${top_srcdir}/include/ ${KONFORKA_CFLAGS} ${LIBCURL_CPPFLAGS} | 6 | INCLUDES = -I${top_srcdir}/test/ -I${top_builddir}/include/ -I${top_srcdir}/include/ ${KONFORKA_CFLAGS} ${LIBCURL_CPPFLAGS} |
6 | 7 | ||
7 | test_SOURCES = test.cc | 8 | test_SOURCES = test.cc |
@@ -18,12 +19,14 @@ test_oauth_consumer_SOURCES = test-oauth-consumer.cc | |||
18 | test_oauth_consumer_LDADD = ${top_builddir}/lib/libopkele.la | 19 | test_oauth_consumer_LDADD = ${top_builddir}/lib/libopkele.la |
19 | 20 | ||
20 | if HAVE_SQLITE3 | 21 | if HAVE_SQLITE3 |
21 | if HAVE_UUID | 22 | if HAVE_UUID |
22 | if HAVE_KINGATE | 23 | if HAVE_KINGATE |
23 | 24 | ||
25 | _dependent_programs_ = RP.cgi OP.cgi | ||
26 | |||
24 | RP_cgi_SOURCES = RP.cc | 27 | RP_cgi_SOURCES = RP.cc |
25 | nodist_RP_cgi_SOURCES = RP-db.cc | 28 | nodist_RP_cgi_SOURCES = RP-db.cc |
26 | RP_cgi_LDADD = ${top_builddir}/lib/libopkele.la \ | 29 | RP_cgi_LDADD = ${top_builddir}/lib/libopkele.la \ |
27 | ${SQLITE3_LIBS} ${KINGATE_LIBS} | 30 | ${SQLITE3_LIBS} ${KINGATE_LIBS} |
28 | RP_cgi_CFLAGS = ${SQLITE3_CFLAGS} ${KINGATE_CFLAGS} | 31 | RP_cgi_CFLAGS = ${SQLITE3_CFLAGS} ${KINGATE_CFLAGS} |
29 | 32 | ||
diff --git a/test/test-oauth-consumer.cc b/test/test-oauth-consumer.cc index 3b3ca70..b3ddef5 100644 --- a/test/test-oauth-consumer.cc +++ b/test/test-oauth-consumer.cc | |||
@@ -35,34 +35,20 @@ int main(int,char**) { | |||
35 | 35 | ||
36 | opkele::fields_t test; | 36 | opkele::fields_t test; |
37 | test.set_field("foo","bar"); | 37 | test.set_field("foo","bar"); |
38 | opkele::util::curl_pick_t curl = opkele::util::curl_t::easy_init(); | 38 | opkele::util::curl_pick_t curl = opkele::util::curl_t::easy_init(); |
39 | opkele::oauth::http_request_t hr("POST", | 39 | opkele::oauth::http_request_t hr("POST", |
40 | "http://term.ie/oauth/example/echo_api.php"); | 40 | "http://term.ie/oauth/example/echo_api.php"); |
41 | sc.prepare_request(hr, | 41 | CURLcode r = curl.misc_sets(); |
42 | opkele::fields_t(),test, | 42 | r || (r=curl.set_write()); |
43 | opkele::oauth::oauth_auth_header,"HMAC-SHA1", | ||
44 | &at,"realm"); | ||
45 | DOUT_("url: " << hr.url << endl | ||
46 | << "body: " << hr.body << endl | ||
47 | << "header: " << hr.authorize_header); | ||
48 | opkele::util::curl_slist_t rh; | ||
49 | rh.append("Authorization: "+hr.authorize_header); | ||
50 | CURLcode r; | ||
51 | (r=curl.misc_sets()) | ||
52 | || (r=curl.set_write()) | ||
53 | || (r=curl.easy_setopt(CURLOPT_HTTPHEADER,rh) ) | ||
54 | || (r=curl.easy_setopt(CURLOPT_URL,hr.url.c_str())) | ||
55 | || (r=curl.easy_setopt(CURLOPT_POST,1)) | ||
56 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,hr.body.c_str())) | ||
57 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,hr.body.size())); | ||
58 | if(r) | 43 | if(r) |
59 | throw opkele::exception_curl(OPKELE_CP_ "failed to set curly options",r); | 44 | throw opkele::exception_curl(OPKELE_CP_ "failed to set curly options",r); |
45 | sc.prepare_request(hr,opkele::fields_t(),test,&at).setup_curl(curl); | ||
60 | if( (r=curl.easy_perform()) ) | 46 | if( (r=curl.easy_perform()) ) |
61 | throw opkele::exception_curl(OPKELE_CP_ "failed to perform curly request",r); | 47 | throw opkele::exception_curl(OPKELE_CP_ "failed to perform curly request",r); |
62 | DOUT_("Response: " << endl << curl.response); | 48 | cout << "Response: " << curl.response << endl; |
63 | 49 | ||
64 | #ifdef OPKELE_HAVE_KONFORKA | 50 | #ifdef OPKELE_HAVE_KONFORKA |
65 | }catch(konforka::exception& e) { | 51 | }catch(konforka::exception& e) { |
66 | cerr | 52 | cerr |
67 | << "oops, caught " << opkele::util::abi_demangle(typeid(e).name()) << endl | 53 | << "oops, caught " << opkele::util::abi_demangle(typeid(e).name()) << endl |
68 | << " what: " << e.what() << endl | 54 | << " what: " << e.what() << endl |