1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of gsignond
6 * Copyright (C) 2012 Intel Corporation.
8 * Contact: Alexander Kanavin <alex.kanavin@gmail.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 #include "gsignond-oauth-plugin.h"
29 #include <gsignond/gsignond-session-data.h>
30 #include <gsignond/gsignond-plugin-interface.h>
31 #include <gsignond/gsignond-error.h>
32 #include <gsignond/gsignond-config.h>
33 #include <gsignond/gsignond-utils.h>
34 #include <libsoup/soup.h>
36 static void response_callback(GSignondPlugin* plugin, GSignondSessionData* result,
39 GSignondSessionData** user_data_p = user_data;
40 *user_data_p = result;
41 gsignond_dictionary_ref(result);
44 static void store_callback(GSignondPlugin* plugin, GSignondSessionData* result,
47 response_callback(plugin, result, user_data);
50 static void user_action_required_callback(GSignondPlugin* plugin,
51 GSignondSignonuiData* ui_request,
54 GSignondSignonuiData** user_data_p = user_data;
55 *user_data_p = ui_request;
56 gsignond_dictionary_ref(ui_request);
59 static void error_callback(GSignondPlugin* plugin, GError* error,
62 GError** user_data_p = user_data;
63 *user_data_p = g_error_copy(error);
66 static GVariant* make_normal_token()
68 GSignondDictionary* token = gsignond_dictionary_new();
69 gsignond_dictionary_set_string(token, "AccessToken", "megaaccesstoken");
70 gsignond_dictionary_set_string(token, "TokenSecret", "megatokensecret");
71 gsignond_dictionary_set_string(token, "Realm", "megarealm");
72 GVariant* token_var = gsignond_dictionary_to_variant(token);
73 gsignond_dictionary_unref(token);
77 static GVariant* make_no_realm_token()
79 GSignondDictionary* token = gsignond_dictionary_new();
80 gsignond_dictionary_set_string(token, "AccessToken", "megaaccesstoken");
81 gsignond_dictionary_set_string(token, "TokenSecret", "megatokensecret");
82 GVariant* token_var = gsignond_dictionary_to_variant(token);
83 gsignond_dictionary_unref(token);
87 static GSignondDictionary* make_tokens(const gchar* client_id, GVariant* token)
89 GSignondDictionary* tokens = gsignond_dictionary_new();
90 gsignond_dictionary_set(tokens, client_id, token);
94 START_TEST (test_oauth1_request)
98 plugin = g_object_new(GSIGNOND_TYPE_OAUTH_PLUGIN, NULL);
99 fail_if(plugin == NULL);
101 GSignondSessionData* result = NULL;
102 GSignondSessionData* store = NULL;
103 GSignondSignonuiData* ui_action = NULL;
104 GError* error = NULL;
106 g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback), &result);
107 g_signal_connect(plugin, "user-action-required",
108 G_CALLBACK(user_action_required_callback), &ui_action);
109 g_signal_connect(plugin, "store", G_CALLBACK(store_callback), &store);
110 g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
112 GSignondSessionData* data = gsignond_dictionary_new();
113 GSignondDictionary* tokens = make_tokens("megaclient", make_normal_token());
116 gsignond_plugin_request_initial(plugin, data, tokens, "unknown-mech");
118 fail_if(result != NULL);
119 fail_if(ui_action != NULL);
120 fail_if(store != NULL);
121 fail_if(error == NULL);
122 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
123 GSIGNOND_ERROR_MECHANISM_NOT_AVAILABLE));
128 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
130 fail_if(result != NULL);
131 fail_if(ui_action != NULL);
132 fail_if(store != NULL);
133 fail_if(error == NULL);
134 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
135 GSIGNOND_ERROR_MISSING_DATA));
139 gsignond_dictionary_set_string(data, "ConsumerKey", "megaclient");
141 // try using normal token without requesting realm
142 gsignond_session_data_set_ui_policy(data, GSIGNOND_UI_POLICY_DEFAULT);
143 gsignond_dictionary_unref(tokens);
144 tokens = make_tokens("megaclient", make_normal_token());
145 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
146 fail_if(result != NULL);
147 fail_if(ui_action != NULL);
148 fail_if(store != NULL);
149 fail_if(error == NULL);
150 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
151 GSIGNOND_ERROR_MISSING_DATA));
155 // try using normal token with realm
156 gsignond_dictionary_set_string(data, "Realm", "megarealm");
157 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
158 fail_if(result == NULL);
159 fail_if(g_strcmp0(gsignond_dictionary_get_string(result, "AccessToken"),
160 "megaaccesstoken") != 0);
161 fail_if(g_strcmp0(gsignond_dictionary_get_string(result, "TokenSecret"),
162 "megatokensecret") != 0);
163 fail_if(g_strcmp0(gsignond_dictionary_get_string(result, "Realm"),
165 gsignond_dictionary_unref(result);
167 fail_if(ui_action != NULL);
168 fail_if(store != NULL);
169 fail_if(error != NULL);
171 //try using no-realm token with realm request
172 gsignond_dictionary_unref(tokens);
173 tokens = make_tokens("megaclient", make_no_realm_token());
174 gsignond_dictionary_set_string(data, "Realm", "megarealm");
175 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
176 fail_if(result != NULL);
177 fail_if(ui_action != NULL);
178 fail_if(store != NULL);
179 fail_if(error == NULL);
180 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
181 GSIGNOND_ERROR_MISSING_DATA));
185 //try using no-realm token with no-realm request
186 gsignond_dictionary_remove(data, "Realm");
187 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
188 fail_if(result == NULL);
189 fail_if(g_strcmp0(gsignond_dictionary_get_string(result, "AccessToken"),
190 "megaaccesstoken") != 0);
191 fail_if(g_strcmp0(gsignond_dictionary_get_string(result, "TokenSecret"),
192 "megatokensecret") != 0);
193 fail_if(gsignond_dictionary_get(result, "Realm") != NULL);
194 gsignond_dictionary_unref(result);
196 fail_if(ui_action != NULL);
197 fail_if(store != NULL);
198 fail_if(error != NULL);
201 gsignond_session_data_set_ui_policy(data, GSIGNOND_UI_POLICY_REQUEST_PASSWORD);
202 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
204 fail_if(result != NULL);
205 fail_if(ui_action != NULL);
206 fail_if(store != NULL);
207 fail_if(error == NULL);
208 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
209 GSIGNOND_ERROR_MISSING_DATA));
213 gsignond_dictionary_unref(data);
214 gsignond_dictionary_unref(tokens);
215 g_object_unref(plugin);
219 START_TEST (test_oauth1_allowed_realms)
223 plugin = g_object_new(GSIGNOND_TYPE_OAUTH_PLUGIN, NULL);
224 fail_if(plugin == NULL);
226 GSignondSessionData* result = NULL;
227 GSignondSessionData* store = NULL;
228 GSignondSignonuiData* ui_action = NULL;
229 GError* error = NULL;
231 g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback), &result);
232 g_signal_connect(plugin, "user-action-required",
233 G_CALLBACK(user_action_required_callback), &ui_action);
234 g_signal_connect(plugin, "store", G_CALLBACK(store_callback), &store);
235 g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
237 GSignondSessionData* data = gsignond_dictionary_new();
238 GSignondDictionary* tokens = make_tokens("someotherclient", make_normal_token());
239 gsignond_dictionary_set_string(data, "ConsumerKey", "megaclient");
240 gsignond_dictionary_set_string(data, "Realm", "megarealm");
241 gsignond_session_data_set_ui_policy(data, GSIGNOND_UI_POLICY_DEFAULT);
242 gsignond_dictionary_set_string(data, "RequestEndpoint", "https://localhost/somepath");
243 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
246 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
247 fail_if(result != NULL);
248 fail_if(ui_action != NULL);
249 fail_if(store != NULL);
250 fail_if(error == NULL);
251 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
252 GSIGNOND_ERROR_MISSING_DATA));
253 fail_unless(g_strcmp0(error->message, "Missing realm list") == 0);
257 //allowed realms is empty
258 const gchar *empty_realm_list[] = { NULL };
259 GSequence *allowed_realms = gsignond_copy_array_to_sequence(empty_realm_list);
260 gsignond_session_data_set_allowed_realms(data, allowed_realms);
261 g_sequence_free(allowed_realms);
263 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
264 fail_if(result != NULL);
265 fail_if(ui_action != NULL);
266 fail_if(store != NULL);
267 fail_if(error == NULL);
268 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
269 GSIGNOND_ERROR_NOT_AUTHORIZED));
270 fail_unless(g_strcmp0(error->message, "Unauthorized host") == 0);
274 //allowed realms does not contain same domain
275 const gchar *non_realm_list[] = { "somedomain1.com", "somedomain2.com", "somedomain3.com", NULL };
276 allowed_realms = gsignond_copy_array_to_sequence(non_realm_list);
277 gsignond_session_data_set_allowed_realms(data, allowed_realms);
278 g_sequence_free(allowed_realms);
279 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
280 fail_if(result != NULL);
281 fail_if(ui_action != NULL);
282 fail_if(store != NULL);
283 fail_if(error == NULL);
284 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
285 GSIGNOND_ERROR_NOT_AUTHORIZED));
286 fail_unless(g_strcmp0(error->message, "Unauthorized host") == 0);
290 //allowed realms contains same domain
291 const gchar *realm_list[] = { "otherhost.somedomain.com", "localhost", "thehost.somedomain.com", NULL };
292 allowed_realms = gsignond_copy_array_to_sequence(realm_list);
293 gsignond_session_data_set_allowed_realms(data, allowed_realms);
294 g_sequence_free(allowed_realms);
295 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
296 fail_if(result != NULL);
297 fail_if(ui_action != NULL);
298 fail_if(store != NULL);
299 fail_if(error == NULL);
300 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
301 GSIGNOND_ERROR_MISSING_DATA));
302 fail_unless(g_strcmp0(error->message, "Unknown oauth1 signature method") == 0);
306 gsignond_dictionary_unref(data);
307 gsignond_dictionary_unref(tokens);
308 g_object_unref(plugin);
312 static void check_nonce(const gchar* nonce)
314 fail_if(nonce == NULL);
315 fail_if(strlen(nonce) < 20);
318 static void check_timestamp(const gchar* timestamp)
320 fail_if(timestamp == NULL);
321 fail_if(strlen(timestamp) < 10);
324 static void check_hmac_sha1_signature(const gchar* signature)
327 guchar* signature_decoded = g_base64_decode_inplace(
328 soup_uri_decode(signature), &sig_len);
330 fail_if(sig_len != 20);
332 g_free(signature_decoded);
335 static void check_rsa_sha1_signature(const gchar* signature)
338 guchar* signature_decoded = g_base64_decode_inplace(
339 soup_uri_decode(signature), &sig_len);
341 fail_if(sig_len != 256);
343 g_free(signature_decoded);
348 temporary_token_server_callback (SoupServer *server,
352 SoupClientContext *client,
355 const gchar* normal_token_response = "oauth_token=hh5s93j4hdidpola&\
356 oauth_token_secret=hdhd0244k9j7ao03&oauth_callback_confirmed=true";
357 const gchar* invalid_body_error = "some invalid body";
359 fail_if(g_str_has_prefix (path, "/temporarytokenpath") == FALSE);
360 fail_if(g_strcmp0(msg->method, "POST") != 0);
361 const char* authorization = soup_message_headers_get_one(msg->request_headers,
363 fail_if(authorization == NULL);
364 //printf("temporary auth header %s\n", authorization);
365 fail_unless(g_str_has_prefix(authorization, "OAuth "));
366 GHashTable* auth_params = soup_header_parse_param_list (authorization+6);
368 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "realm"), "megarealm") != 0);
369 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "oauth_consumer_key"), "megaclient") != 0);
370 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "oauth_version"), "1.0") != 0);
371 gchar* oauth_callback = soup_uri_decode(g_hash_table_lookup(auth_params, "oauth_callback"));
372 fail_if(g_strcmp0(oauth_callback, "http://localhost/somegsignondoauthcallback") != 0);
373 g_free(oauth_callback);
375 const gchar* signature_method = g_hash_table_lookup(auth_params, "oauth_signature_method");
376 if (g_strcmp0(signature_method, "PLAINTEXT") == 0) {
377 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "oauth_signature"), "megasecret%26") != 0);
378 } else if (g_strcmp0(signature_method, "HMAC-SHA1") == 0) {
379 check_nonce(g_hash_table_lookup(auth_params, "oauth_nonce"));
380 check_timestamp(g_hash_table_lookup(auth_params, "oauth_timestamp"));
381 check_hmac_sha1_signature(g_hash_table_lookup(auth_params, "oauth_signature"));
382 } else if (g_strcmp0(signature_method, "RSA-SHA1") == 0) {
383 check_nonce(g_hash_table_lookup(auth_params, "oauth_nonce"));
384 check_timestamp(g_hash_table_lookup(auth_params, "oauth_timestamp"));
385 check_rsa_sha1_signature(g_hash_table_lookup(auth_params, "oauth_signature"));
388 soup_header_free_param_list(auth_params);
390 if (g_strrstr(path, "error/invalid_body") != NULL) {
391 soup_message_set_status(msg, SOUP_STATUS_OK);
392 soup_message_set_response(msg, "application/x-www-form-urlencoded",
394 invalid_body_error, strlen(invalid_body_error));
395 } else if (g_strrstr(path, "error") != NULL) {
396 soup_message_set_status(msg, SOUP_STATUS_BAD_REQUEST);
398 soup_message_set_status (msg, SOUP_STATUS_OK);
399 soup_message_set_response (msg, "application/x-www-form-urlencoded",
401 normal_token_response, strlen(normal_token_response));
406 access_token_server_callback (SoupServer *server,
410 SoupClientContext *client,
413 const gchar* normal_token_response = "oauth_token=j49ddk933skd9dks\
414 &oauth_token_secret=ll399dj47dskfjdk";
415 const gchar* invalid_body_error = "some invalid body";
417 fail_if(g_str_has_prefix (path, "/accesstokenpath") == FALSE);
418 fail_if(g_strcmp0(msg->method, "POST") != 0);
419 const char* authorization = soup_message_headers_get_one(msg->request_headers,
421 fail_if(authorization == NULL);
422 //printf("access auth header %s\n", authorization);
423 fail_unless(g_str_has_prefix(authorization, "OAuth "));
424 GHashTable* auth_params = soup_header_parse_param_list (authorization+6);
426 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "realm"), "megarealm") != 0);
427 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "oauth_consumer_key"), "megaclient") != 0);
428 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "oauth_version"), "1.0") != 0);
429 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "oauth_verifier"), "somerandomverifier") != 0);
430 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "oauth_token"), "hh5s93j4hdidpola") != 0);
432 const gchar* signature_method = g_hash_table_lookup(auth_params, "oauth_signature_method");
433 if (g_strcmp0(signature_method, "PLAINTEXT") == 0) {
434 fail_if(g_strcmp0(g_hash_table_lookup(auth_params, "oauth_signature"), "megasecret%26hdhd0244k9j7ao03") != 0);
435 } else if (g_strcmp0(signature_method, "HMAC-SHA1") == 0) {
436 check_nonce(g_hash_table_lookup(auth_params, "oauth_nonce"));
437 check_timestamp(g_hash_table_lookup(auth_params, "oauth_timestamp"));
438 check_hmac_sha1_signature(g_hash_table_lookup(auth_params, "oauth_signature"));
439 } else if (g_strcmp0(signature_method, "RSA-SHA1") == 0) {
440 check_nonce(g_hash_table_lookup(auth_params, "oauth_nonce"));
441 check_timestamp(g_hash_table_lookup(auth_params, "oauth_timestamp"));
442 check_rsa_sha1_signature(g_hash_table_lookup(auth_params, "oauth_signature"));
445 soup_header_free_param_list(auth_params);
447 if (g_strrstr(path, "error/invalid_body") != NULL) {
448 soup_message_set_status(msg, SOUP_STATUS_OK);
449 soup_message_set_response(msg, "application/x-www-form-urlencoded",
451 invalid_body_error, strlen(invalid_body_error));
452 } else if (g_strrstr(path, "error") != NULL) {
453 soup_message_set_status(msg, SOUP_STATUS_BAD_REQUEST);
455 soup_message_set_status (msg, SOUP_STATUS_OK);
456 soup_message_set_response (msg, "application/x-www-form-urlencoded",
458 normal_token_response, strlen(normal_token_response));
463 START_TEST (test_oauth1_request_temporary_token)
467 plugin = g_object_new(GSIGNOND_TYPE_OAUTH_PLUGIN, NULL);
468 fail_if(plugin == NULL);
470 GSignondSessionData* result = NULL;
471 GSignondSessionData* store = NULL;
472 GSignondSignonuiData* ui_action = NULL;
473 GError* error = NULL;
475 g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback), &result);
476 g_signal_connect(plugin, "user-action-required",
477 G_CALLBACK(user_action_required_callback), &ui_action);
478 g_signal_connect(plugin, "store", G_CALLBACK(store_callback), &store);
479 g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
481 GSignondSessionData* data = gsignond_dictionary_new();
482 GSignondDictionary* tokens = make_tokens("someotherclient", make_normal_token());
483 gsignond_dictionary_set_string(data, "ConsumerKey", "megaclient");
484 gsignond_dictionary_set_string(data, "Realm", "megarealm");
485 gsignond_session_data_set_ui_policy(data, GSIGNOND_UI_POLICY_DEFAULT);
488 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
489 fail_if(result != NULL);
490 fail_if(ui_action != NULL);
491 fail_if(store != NULL);
492 fail_if(error == NULL);
493 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
494 GSIGNOND_ERROR_MISSING_DATA));
498 //RequestEndpoint does not use https
499 gsignond_dictionary_set_string(data, "RequestEndpoint", "http://localhost/somepath");
500 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
501 fail_if(result != NULL);
502 fail_if(ui_action != NULL);
503 fail_if(store != NULL);
504 fail_if(error == NULL);
505 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
506 GSIGNOND_ERROR_MISSING_DATA));
507 fail_unless(g_strcmp0(error->message, "RequestEndpoint must use https") == 0);
511 //no signature method
512 const gchar *realm_list[] = { "otherhost.somedomain.com", "localhost", "thehost.somedomain.com", NULL };
513 GSequence *allowed_realms = gsignond_copy_array_to_sequence(realm_list);
514 gsignond_session_data_set_allowed_realms(data, allowed_realms);
515 g_sequence_free(allowed_realms);
516 gsignond_dictionary_set_string(data, "RequestEndpoint", "https://localhost/somepath");
517 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
518 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
519 fail_if(result != NULL);
520 fail_if(ui_action != NULL);
521 fail_if(store != NULL);
522 fail_if(error == NULL);
523 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
524 GSIGNOND_ERROR_MISSING_DATA));
525 fail_unless(g_strcmp0(error->message, "Unknown oauth1 signature method") == 0);
529 //unknown signature method
530 gsignond_dictionary_set_string(data, "SignatureMethod", "unknownmethod");
531 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
532 fail_if(result != NULL);
533 fail_if(ui_action != NULL);
534 fail_if(store != NULL);
535 fail_if(error == NULL);
536 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
537 GSIGNOND_ERROR_MISSING_DATA));
538 fail_unless(g_strcmp0(error->message, "Unknown oauth1 signature method") == 0);
542 //PLAINTEXT method, but no server
543 gsignond_dictionary_set_string(data, "SignatureMethod", "PLAINTEXT");
544 gsignond_dictionary_set_string(data, "ConsumerSecret", "megasecret");
545 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
546 fail_if(result != NULL);
547 fail_if(ui_action != NULL);
548 fail_if(store != NULL);
549 fail_if(error != NULL);
552 g_main_context_iteration(g_main_context_default(), TRUE);
556 fail_if(result != NULL);
557 fail_if(ui_action != NULL);
558 fail_if(store != NULL);
559 fail_if(error == NULL);
560 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
561 GSIGNOND_ERROR_NOT_AUTHORIZED));
562 fail_if(g_str_has_prefix(error->message,
563 "Temporary token endpoint returned an error") == FALSE);
567 //set up the server and try again
568 // to genenerate cert and key
569 // openssl genrsa -out privkey.pem 2048
570 // openssl req -new -x509 -key privkey.pem -out cacert.pem -days 365000
571 SoupServer* server = soup_server_new(SOUP_SERVER_SSL_CERT_FILE, "cacert.pem",
572 SOUP_SERVER_SSL_KEY_FILE, "privkey.pem",
574 soup_server_add_handler (server, "/temporarytokenpath", temporary_token_server_callback,
576 soup_server_run_async(server);
578 gsignond_dictionary_set_boolean(data, "SslStrict", FALSE);
580 gchar* server_uri = g_strdup_printf("https://localhost:%d/temporarytokenpath", soup_server_get_port(server));
581 gsignond_dictionary_set_string(data, "RequestEndpoint", server_uri);
583 gsignond_dictionary_set_string(data, "AuthorizationEndpoint", "https://localhost/authorization");
585 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
586 fail_if(result != NULL);
587 fail_if(ui_action != NULL);
588 fail_if(store != NULL);
589 fail_if(error != NULL);
592 g_main_context_iteration(g_main_context_default(), TRUE);
593 if(ui_action != NULL)
596 fail_if(result != NULL);
597 fail_if(ui_action == NULL);
599 fail_if(g_strcmp0(gsignond_signonui_data_get_open_url(ui_action),
600 "https://localhost/authorization?oauth_token=hh5s93j4hdidpola") != 0);
601 fail_if(g_strcmp0(gsignond_signonui_data_get_final_url(ui_action),
602 "http://localhost/somegsignondoauthcallback") != 0);
604 gsignond_dictionary_unref(ui_action);
606 fail_if(store != NULL);
607 fail_if(error != NULL);
609 //reject the PLAINTEXT request
610 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
611 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
612 server_uri = g_strdup_printf("https://localhost:%d/temporarytokenpath/error", soup_server_get_port(server));
613 gsignond_dictionary_set_string(data, "RequestEndpoint", server_uri);
615 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
616 fail_if(result != NULL);
617 fail_if(ui_action != NULL);
618 fail_if(store != NULL);
619 fail_if(error != NULL);
622 g_main_context_iteration(g_main_context_default(), TRUE);
626 fail_if(result != NULL);
627 fail_if(ui_action != NULL);
628 fail_if(store != NULL);
629 fail_if(error == NULL);
630 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
631 GSIGNOND_ERROR_NOT_AUTHORIZED));
632 fail_if(g_str_has_prefix(error->message,
633 "Temporary token endpoint returned an error") == FALSE);
637 //provide invalid data for PLAINTEXT request
638 server_uri = g_strdup_printf("https://localhost:%d/temporarytokenpath/error/invalid_body", soup_server_get_port(server));
639 gsignond_dictionary_set_string(data, "RequestEndpoint", server_uri);
641 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
642 fail_if(result != NULL);
643 fail_if(ui_action != NULL);
644 fail_if(store != NULL);
645 fail_if(error != NULL);
648 g_main_context_iteration(g_main_context_default(), TRUE);
652 fail_if(result != NULL);
653 fail_if(ui_action != NULL);
654 fail_if(store != NULL);
655 fail_if(error == NULL);
656 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
657 GSIGNOND_ERROR_NOT_AUTHORIZED));
658 fail_if(g_str_has_prefix(error->message,
659 "Temporary token endpoint returned an invalid response") == FALSE);
664 gsignond_dictionary_set_string(data, "SignatureMethod", "HMAC-SHA1");
665 server_uri = g_strdup_printf("https://localhost:%d/temporarytokenpath", soup_server_get_port(server));
666 gsignond_dictionary_set_string(data, "RequestEndpoint", server_uri);
668 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
669 fail_if(result != NULL);
670 fail_if(ui_action != NULL);
671 fail_if(store != NULL);
672 fail_if(error != NULL);
675 g_main_context_iteration(g_main_context_default(), TRUE);
676 if(ui_action != NULL)
679 fail_if(result != NULL);
680 fail_if(ui_action == NULL);
682 fail_if(g_strcmp0(gsignond_signonui_data_get_open_url(ui_action),
683 "https://localhost/authorization?oauth_token=hh5s93j4hdidpola") != 0);
684 fail_if(g_strcmp0(gsignond_signonui_data_get_final_url(ui_action),
685 "http://localhost/somegsignondoauthcallback") != 0);
687 gsignond_dictionary_unref(ui_action);
689 fail_if(store != NULL);
690 fail_if(error != NULL);
692 //RSA-SHA1 request with no private key
693 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
694 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
695 gsignond_dictionary_set_string(data, "SignatureMethod", "RSA-SHA1");
696 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
697 fail_if(result != NULL);
698 fail_if(ui_action != NULL);
699 fail_if(store != NULL);
700 fail_if(error == NULL);
701 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
702 GSIGNOND_ERROR_MISSING_DATA));
703 fail_if(g_str_has_prefix(error->message,
704 "Client did not supply RSAPrivateKey") == FALSE);
708 //RSA-SHA1 request with invalid private key
709 gsignond_dictionary_set_string(data, "RSAPrivateKey", "some bogus key");
710 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
711 fail_if(result != NULL);
712 fail_if(ui_action != NULL);
713 fail_if(store != NULL);
714 fail_if(error == NULL);
715 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
716 GSIGNOND_ERROR_MISSING_DATA));
717 fail_if(g_str_has_prefix(error->message,
718 "Invalid RSA private key") == FALSE);
722 //RSA-SHA1 request with valid private key
724 fail_unless(g_file_get_contents("privkey.pem", &privkey, NULL, NULL));
725 gsignond_dictionary_set_string(data, "RSAPrivateKey", privkey);
727 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
728 fail_if(result != NULL);
729 fail_if(ui_action != NULL);
730 fail_if(store != NULL);
731 fail_if(error != NULL);
734 g_main_context_iteration(g_main_context_default(), TRUE);
735 if(ui_action != NULL)
738 fail_if(result != NULL);
739 fail_if(ui_action == NULL);
741 fail_if(g_strcmp0(gsignond_signonui_data_get_open_url(ui_action),
742 "https://localhost/authorization?oauth_token=hh5s93j4hdidpola") != 0);
743 fail_if(g_strcmp0(gsignond_signonui_data_get_final_url(ui_action),
744 "http://localhost/somegsignondoauthcallback") != 0);
746 gsignond_dictionary_unref(ui_action);
748 fail_if(store != NULL);
749 fail_if(error != NULL);
751 gsignond_dictionary_unref(data);
752 gsignond_dictionary_unref(tokens);
753 g_object_unref(plugin);
754 g_object_unref(server);
758 START_TEST (test_oauth1_ui_request)
762 SoupServer* server = soup_server_new(SOUP_SERVER_SSL_CERT_FILE, "cacert.pem",
763 SOUP_SERVER_SSL_KEY_FILE, "privkey.pem",
765 soup_server_add_handler (server, "/temporarytokenpath", temporary_token_server_callback,
767 soup_server_run_async(server);
769 plugin = g_object_new(GSIGNOND_TYPE_OAUTH_PLUGIN, NULL);
770 fail_if(plugin == NULL);
772 GSignondSessionData* result = NULL;
773 GSignondSessionData* store = NULL;
774 GSignondSignonuiData* ui_action = NULL;
775 GError* error = NULL;
777 g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback), &result);
778 g_signal_connect(plugin, "user-action-required",
779 G_CALLBACK(user_action_required_callback), &ui_action);
780 g_signal_connect(plugin, "store", G_CALLBACK(store_callback), &store);
781 g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
783 GSignondSessionData* data = gsignond_dictionary_new();
784 GSignondDictionary* tokens = make_tokens("someotherclient", make_normal_token());
785 GSignondSignonuiData* ui_data = gsignond_dictionary_new();
787 gsignond_dictionary_set_string(data, "ConsumerKey", "megaclient");
788 gsignond_dictionary_set_string(data, "Realm", "megarealm");
789 gsignond_session_data_set_ui_policy(data, GSIGNOND_UI_POLICY_DEFAULT);
790 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
791 gsignond_dictionary_set_string(data, "SignatureMethod", "PLAINTEXT");
792 gsignond_dictionary_set_string(data, "ConsumerSecret", "megasecret");
794 gsignond_dictionary_set_boolean(data, "SslStrict", FALSE);
796 gchar* server_uri = g_strdup_printf("https://localhost:%d/temporarytokenpath", soup_server_get_port(server));
797 gsignond_dictionary_set_string(data, "RequestEndpoint", server_uri);
799 gsignond_dictionary_set_string(data, "AuthorizationEndpoint", "https://localhost/authorization");
801 const gchar *realm_list[] = { "otherhost.somedomain.com", "localhost", "thehost.somedomain.com", NULL };
802 GSequence *allowed_realms = gsignond_copy_array_to_sequence(realm_list);
803 gsignond_session_data_set_allowed_realms(data, allowed_realms);
804 g_sequence_free(allowed_realms);
806 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
808 fail_if(result != NULL);
809 fail_if(ui_action != NULL);
810 fail_if(store != NULL);
811 fail_if(error != NULL);
814 g_main_context_iteration(g_main_context_default(), TRUE);
815 if(ui_action != NULL)
818 fail_if(result != NULL);
819 fail_if(ui_action == NULL);
820 gsignond_dictionary_unref(ui_action);
822 fail_if(store != NULL);
823 fail_if(error != NULL);
825 //return an empty response
826 gsignond_plugin_user_action_finished(plugin, ui_data);
827 fail_if(result != NULL);
828 fail_if(ui_action != NULL);
829 fail_if(store != NULL);
830 fail_if(error == NULL);
831 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
832 GSIGNOND_ERROR_USER_INTERACTION));
833 fail_if(g_str_has_prefix(error->message,
834 "userActionFinished did not return an error value") == FALSE);
838 //ui session was cancelled
839 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
840 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
841 gsignond_signonui_data_set_query_error(ui_data, SIGNONUI_ERROR_CANCELED);
843 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
845 fail_if(result != NULL);
846 fail_if(ui_action != NULL);
847 fail_if(store != NULL);
848 fail_if(error != NULL);
851 g_main_context_iteration(g_main_context_default(), TRUE);
852 if(ui_action != NULL)
855 fail_if(result != NULL);
856 fail_if(ui_action == NULL);
857 gsignond_dictionary_unref(ui_action);
859 fail_if(store != NULL);
860 fail_if(error != NULL);
862 gsignond_plugin_user_action_finished(plugin, ui_data);
863 fail_if(result != NULL);
864 fail_if(ui_action != NULL);
865 fail_if(store != NULL);
866 fail_if(error == NULL);
867 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
868 GSIGNOND_ERROR_SESSION_CANCELED));
869 fail_if(g_str_has_prefix(error->message,
870 "Session canceled") == FALSE);
874 //some other ui error
875 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
876 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
877 gsignond_signonui_data_set_query_error(ui_data, SIGNONUI_ERROR_BAD_PARAMETERS);
879 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
881 fail_if(result != NULL);
882 fail_if(ui_action != NULL);
883 fail_if(store != NULL);
884 fail_if(error != NULL);
887 g_main_context_iteration(g_main_context_default(), TRUE);
888 if(ui_action != NULL)
891 fail_if(result != NULL);
892 fail_if(ui_action == NULL);
893 gsignond_dictionary_unref(ui_action);
895 fail_if(store != NULL);
896 fail_if(error != NULL);
898 gsignond_plugin_user_action_finished(plugin, ui_data);
899 fail_if(result != NULL);
900 fail_if(ui_action != NULL);
901 fail_if(store != NULL);
902 fail_if(error == NULL);
903 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
904 GSIGNOND_ERROR_USER_INTERACTION));
905 fail_if(g_str_has_prefix(error->message,
906 "userActionFinished error:") == FALSE);
910 //no error, but no final url
911 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
912 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
913 gsignond_signonui_data_set_query_error(ui_data, SIGNONUI_ERROR_NONE);
915 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
917 fail_if(result != NULL);
918 fail_if(ui_action != NULL);
919 fail_if(store != NULL);
920 fail_if(error != NULL);
923 g_main_context_iteration(g_main_context_default(), TRUE);
924 if(ui_action != NULL)
927 fail_if(result != NULL);
928 fail_if(ui_action == NULL);
929 gsignond_dictionary_unref(ui_action);
931 fail_if(store != NULL);
932 fail_if(error != NULL);
934 gsignond_plugin_user_action_finished(plugin, ui_data);
935 fail_if(result != NULL);
936 fail_if(ui_action != NULL);
937 fail_if(store != NULL);
938 fail_if(error == NULL);
939 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
940 GSIGNOND_ERROR_NOT_AUTHORIZED));
941 fail_if(g_str_has_prefix(error->message,
942 "Callback URI and URI supplied by UI don't match") == FALSE);
946 //final url doesn't match callback url
947 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
948 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
949 gsignond_signonui_data_set_final_url(ui_data, "http://somebogusurl");
951 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
953 fail_if(result != NULL);
954 fail_if(ui_action != NULL);
955 fail_if(store != NULL);
956 fail_if(error != NULL);
959 g_main_context_iteration(g_main_context_default(), TRUE);
960 if(ui_action != NULL)
963 fail_if(result != NULL);
964 fail_if(ui_action == NULL);
965 gsignond_dictionary_unref(ui_action);
967 fail_if(store != NULL);
968 fail_if(error != NULL);
970 gsignond_plugin_user_action_finished(plugin, ui_data);
971 fail_if(result != NULL);
972 fail_if(ui_action != NULL);
973 fail_if(store != NULL);
974 fail_if(error == NULL);
975 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
976 GSIGNOND_ERROR_NOT_AUTHORIZED));
977 fail_if(g_str_has_prefix(error->message,
978 "Callback URI and URI supplied by UI don't match") == FALSE);
982 //correct final url, but no query
983 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
984 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
985 gsignond_signonui_data_set_url_response(ui_data, "http://localhost/somegsignondoauthcallback");
987 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
989 fail_if(result != NULL);
990 fail_if(ui_action != NULL);
991 fail_if(store != NULL);
992 fail_if(error != NULL);
995 g_main_context_iteration(g_main_context_default(), TRUE);
996 if(ui_action != NULL)
999 fail_if(result != NULL);
1000 fail_if(ui_action == NULL);
1001 gsignond_dictionary_unref(ui_action);
1003 fail_if(store != NULL);
1004 fail_if(error != NULL);
1006 gsignond_plugin_user_action_finished(plugin, ui_data);
1007 fail_if(result != NULL);
1008 fail_if(ui_action != NULL);
1009 fail_if(store != NULL);
1010 fail_if(error == NULL);
1011 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
1012 GSIGNOND_ERROR_NOT_AUTHORIZED));
1013 fail_if(g_str_has_prefix(error->message,
1014 "No query in returned redirect URI") == FALSE);
1015 g_error_free(error);
1018 //correct final url, with bogus token
1019 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
1020 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
1021 gsignond_signonui_data_set_url_response(ui_data, "http://localhost/somegsignondoauthcallback?oauth_token=somebogustoken");
1023 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1025 fail_if(result != NULL);
1026 fail_if(ui_action != NULL);
1027 fail_if(store != NULL);
1028 fail_if(error != NULL);
1031 g_main_context_iteration(g_main_context_default(), TRUE);
1032 if(ui_action != NULL)
1035 fail_if(result != NULL);
1036 fail_if(ui_action == NULL);
1037 gsignond_dictionary_unref(ui_action);
1039 fail_if(store != NULL);
1040 fail_if(error != NULL);
1042 gsignond_plugin_user_action_finished(plugin, ui_data);
1043 fail_if(result != NULL);
1044 fail_if(ui_action != NULL);
1045 fail_if(store != NULL);
1046 fail_if(error == NULL);
1047 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
1048 GSIGNOND_ERROR_NOT_AUTHORIZED));
1049 fail_if(g_str_has_prefix(error->message,
1050 "Token returned by callback URI and temporary token don't match") == FALSE);
1051 g_error_free(error);
1054 //correct final url, correct token, absent verifier
1055 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
1056 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
1057 gsignond_signonui_data_set_url_response(ui_data, "http://localhost/somegsignondoauthcallback?oauth_token=hh5s93j4hdidpola");
1059 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1061 fail_if(result != NULL);
1062 fail_if(ui_action != NULL);
1063 fail_if(store != NULL);
1064 fail_if(error != NULL);
1067 g_main_context_iteration(g_main_context_default(), TRUE);
1068 if(ui_action != NULL)
1071 fail_if(result != NULL);
1072 fail_if(ui_action == NULL);
1073 gsignond_dictionary_unref(ui_action);
1075 fail_if(store != NULL);
1076 fail_if(error != NULL);
1078 gsignond_plugin_user_action_finished(plugin, ui_data);
1079 fail_if(result != NULL);
1080 fail_if(ui_action != NULL);
1081 fail_if(store != NULL);
1082 fail_if(error == NULL);
1083 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
1084 GSIGNOND_ERROR_NOT_AUTHORIZED));
1085 fail_if(g_str_has_prefix(error->message,
1086 "No oauth_verifier in callback URI") == FALSE);
1087 g_error_free(error);
1090 //correct final url, correct token, correct verifier
1091 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
1092 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
1093 gsignond_signonui_data_set_url_response(ui_data, "http://localhost/somegsignondoauthcallback?oauth_token=hh5s93j4hdidpola&oauth_verifier=somerandomverifier");
1095 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1097 fail_if(result != NULL);
1098 fail_if(ui_action != NULL);
1099 fail_if(store != NULL);
1100 fail_if(error != NULL);
1103 g_main_context_iteration(g_main_context_default(), TRUE);
1104 if(ui_action != NULL)
1107 fail_if(result != NULL);
1108 fail_if(ui_action == NULL);
1109 gsignond_dictionary_unref(ui_action);
1111 fail_if(store != NULL);
1112 fail_if(error != NULL);
1114 gsignond_plugin_user_action_finished(plugin, ui_data);
1115 fail_if(result != NULL);
1116 fail_if(ui_action != NULL);
1117 fail_if(store != NULL);
1118 fail_if(error == NULL);
1119 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
1120 GSIGNOND_ERROR_MISSING_DATA));
1121 fail_if(g_str_has_prefix(error->message,
1122 "Client did not supply TokenEndpoint") == FALSE);
1123 g_error_free(error);
1126 gsignond_dictionary_unref(data);
1127 gsignond_dictionary_unref(tokens);
1128 gsignond_dictionary_unref(ui_data);
1129 g_object_unref(plugin);
1130 g_object_unref(server);
1134 START_TEST (test_oauth1_request_access_token)
1138 SoupServer* server = soup_server_new(SOUP_SERVER_SSL_CERT_FILE, "cacert.pem",
1139 SOUP_SERVER_SSL_KEY_FILE, "privkey.pem",
1141 soup_server_add_handler (server, "/temporarytokenpath", temporary_token_server_callback,
1143 soup_server_add_handler (server, "/accesstokenpath", access_token_server_callback,
1145 soup_server_run_async(server);
1147 plugin = g_object_new(GSIGNOND_TYPE_OAUTH_PLUGIN, NULL);
1148 fail_if(plugin == NULL);
1150 GSignondSessionData* result = NULL;
1151 GSignondSessionData* store = NULL;
1152 GSignondSignonuiData* ui_action = NULL;
1153 GError* error = NULL;
1155 g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback), &result);
1156 g_signal_connect(plugin, "user-action-required",
1157 G_CALLBACK(user_action_required_callback), &ui_action);
1158 g_signal_connect(plugin, "store", G_CALLBACK(store_callback), &store);
1159 g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
1161 GSignondSessionData* data = gsignond_dictionary_new();
1162 GSignondDictionary* tokens = make_tokens("someotherclient", make_normal_token());
1163 GSignondSignonuiData* ui_data = gsignond_dictionary_new();
1165 gsignond_dictionary_set_string(data, "ConsumerKey", "megaclient");
1166 gsignond_dictionary_set_string(data, "Realm", "megarealm");
1167 gsignond_session_data_set_ui_policy(data, GSIGNOND_UI_POLICY_DEFAULT);
1168 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
1169 gsignond_dictionary_set_string(data, "SignatureMethod", "PLAINTEXT");
1170 gsignond_dictionary_set_string(data, "ConsumerSecret", "megasecret");
1172 gsignond_dictionary_set_boolean(data, "SslStrict", FALSE);
1174 gchar* server_uri = g_strdup_printf("https://localhost:%d/temporarytokenpath", soup_server_get_port(server));
1175 gsignond_dictionary_set_string(data, "RequestEndpoint", server_uri);
1177 gsignond_dictionary_set_string(data, "AuthorizationEndpoint", "https://localhost/authorization");
1178 gsignond_signonui_data_set_url_response(ui_data, "http://localhost/somegsignondoauthcallback?oauth_token=hh5s93j4hdidpola&oauth_verifier=somerandomverifier");
1179 gsignond_signonui_data_set_query_error(ui_data, SIGNONUI_ERROR_NONE);
1181 const gchar *realm_list[] = { "otherhost.somedomain.com", "localhost", "thehost.somedomain.com", NULL };
1182 GSequence *allowed_realms = gsignond_copy_array_to_sequence(realm_list);
1183 gsignond_session_data_set_allowed_realms(data, allowed_realms);
1184 g_sequence_free(allowed_realms);
1186 //bogus token endpoint
1187 gsignond_dictionary_set_string(data, "TokenEndpoint", "some bogus endpoint");
1188 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1190 fail_if(result != NULL);
1191 fail_if(ui_action != NULL);
1192 fail_if(store != NULL);
1193 fail_if(error != NULL);
1196 g_main_context_iteration(g_main_context_default(), TRUE);
1197 if(ui_action != NULL)
1200 fail_if(result != NULL);
1201 fail_if(ui_action == NULL);
1202 gsignond_dictionary_unref(ui_action);
1204 fail_if(store != NULL);
1205 fail_if(error != NULL);
1207 gsignond_plugin_user_action_finished(plugin, ui_data);
1208 fail_if(result != NULL);
1209 fail_if(ui_action != NULL);
1210 fail_if(store != NULL);
1211 fail_if(error == NULL);
1212 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
1213 GSIGNOND_ERROR_MISSING_DATA));
1214 fail_if(g_str_has_prefix(error->message,
1215 "Client did not supply a valid TokenEndpoint") == FALSE);
1216 g_error_free(error);
1219 //token endpoint that doesn't use https
1220 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
1221 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
1222 gsignond_dictionary_remove(data, "_OauthVerifier");
1223 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
1225 gsignond_dictionary_set_string(data, "TokenEndpoint", "http://somehost");
1226 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1228 fail_if(result != NULL);
1229 fail_if(ui_action != NULL);
1230 fail_if(store != NULL);
1231 fail_if(error != NULL);
1233 g_main_context_iteration(g_main_context_default(), TRUE);
1234 if(ui_action != NULL)
1237 fail_if(result != NULL);
1238 fail_if(ui_action == NULL);
1239 gsignond_dictionary_unref(ui_action);
1241 fail_if(store != NULL);
1242 fail_if(error != NULL);
1244 gsignond_plugin_user_action_finished(plugin, ui_data);
1245 fail_if(result != NULL);
1246 fail_if(ui_action != NULL);
1247 fail_if(store != NULL);
1248 fail_if(error == NULL);
1249 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
1250 GSIGNOND_ERROR_MISSING_DATA));
1251 fail_if(g_str_has_prefix(error->message,
1252 "TokenEndpoint must use https") == FALSE);
1253 g_error_free(error);
1256 //token endpoint returned an error
1257 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
1258 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
1259 gsignond_dictionary_remove(data, "_OauthVerifier");
1260 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
1262 server_uri = g_strdup_printf("https://localhost:%d/accesstokenpath/error", soup_server_get_port(server));
1263 gsignond_dictionary_set_string(data, "TokenEndpoint", server_uri);
1266 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1268 fail_if(result != NULL);
1269 fail_if(ui_action != NULL);
1270 fail_if(store != NULL);
1271 fail_if(error != NULL);
1273 g_main_context_iteration(g_main_context_default(), TRUE);
1274 if(ui_action != NULL)
1277 fail_if(result != NULL);
1278 fail_if(ui_action == NULL);
1279 gsignond_dictionary_unref(ui_action);
1281 fail_if(store != NULL);
1282 fail_if(error != NULL);
1284 gsignond_plugin_user_action_finished(plugin, ui_data);
1285 fail_if(result != NULL);
1286 fail_if(ui_action != NULL);
1287 fail_if(store != NULL);
1288 fail_if(error != NULL);
1290 g_main_context_iteration(g_main_context_default(), TRUE);
1294 fail_if(result != NULL);
1295 fail_if(ui_action != NULL);
1296 fail_if(store != NULL);
1297 fail_if(error == NULL);
1298 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
1299 GSIGNOND_ERROR_NOT_AUTHORIZED));
1300 fail_if(g_str_has_prefix(error->message,
1301 "Access token endpoint returned an error") == FALSE);
1302 g_error_free(error);
1305 //token endpoint returned a bogus response
1306 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
1307 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
1308 gsignond_dictionary_remove(data, "_OauthVerifier");
1309 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
1311 server_uri = g_strdup_printf("https://localhost:%d/accesstokenpath/error/invalid_body", soup_server_get_port(server));
1312 gsignond_dictionary_set_string(data, "TokenEndpoint", server_uri);
1315 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1317 fail_if(result != NULL);
1318 fail_if(ui_action != NULL);
1319 fail_if(store != NULL);
1320 fail_if(error != NULL);
1322 g_main_context_iteration(g_main_context_default(), TRUE);
1323 if(ui_action != NULL)
1326 fail_if(result != NULL);
1327 fail_if(ui_action == NULL);
1328 gsignond_dictionary_unref(ui_action);
1330 fail_if(store != NULL);
1331 fail_if(error != NULL);
1333 gsignond_plugin_user_action_finished(plugin, ui_data);
1334 fail_if(result != NULL);
1335 fail_if(ui_action != NULL);
1336 fail_if(store != NULL);
1337 fail_if(error != NULL);
1339 g_main_context_iteration(g_main_context_default(), TRUE);
1343 fail_if(result != NULL);
1344 fail_if(ui_action != NULL);
1345 fail_if(store != NULL);
1346 fail_if(error == NULL);
1347 fail_unless(g_error_matches(error, GSIGNOND_ERROR,
1348 GSIGNOND_ERROR_NOT_AUTHORIZED));
1349 fail_if(g_str_has_prefix(error->message,
1350 "Access token endpoint returned an invalid response") == FALSE);
1351 g_error_free(error);
1354 //token endpoint returned a valid response for PLAINTEXT
1355 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
1356 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
1357 gsignond_dictionary_remove(data, "_OauthVerifier");
1358 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
1360 server_uri = g_strdup_printf("https://localhost:%d/accesstokenpath", soup_server_get_port(server));
1361 gsignond_dictionary_set_string(data, "TokenEndpoint", server_uri);
1364 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1366 fail_if(result != NULL);
1367 fail_if(ui_action != NULL);
1368 fail_if(store != NULL);
1369 fail_if(error != NULL);
1371 g_main_context_iteration(g_main_context_default(), TRUE);
1372 if(ui_action != NULL)
1375 fail_if(result != NULL);
1376 fail_if(ui_action == NULL);
1377 gsignond_dictionary_unref(ui_action);
1379 fail_if(store != NULL);
1380 fail_if(error != NULL);
1382 gsignond_plugin_user_action_finished(plugin, ui_data);
1383 fail_if(result != NULL);
1384 fail_if(ui_action != NULL);
1385 fail_if(store != NULL);
1386 fail_if(error != NULL);
1388 g_main_context_iteration(g_main_context_default(), TRUE);
1392 fail_if(result == NULL);
1393 const gchar* realm = gsignond_dictionary_get_string(result, "Realm");
1394 const gchar* token_s = gsignond_dictionary_get_string(result, "AccessToken");
1395 const gchar* secret = gsignond_dictionary_get_string(result, "TokenSecret");
1396 fail_if(g_strcmp0(realm, "megarealm") != 0);
1397 fail_if(g_strcmp0(token_s, "j49ddk933skd9dks") != 0);
1398 fail_if(g_strcmp0(secret, "ll399dj47dskfjdk") != 0);
1399 gsignond_dictionary_unref(result);
1401 fail_if(ui_action != NULL);
1402 fail_if(store == NULL);
1404 fail_if(g_hash_table_size(store) != 2);
1405 GSignondDictionary* token = gsignond_dictionary_new_from_variant(
1406 gsignond_dictionary_get(store, "megaclient"));
1407 fail_if(token == NULL);
1408 realm = gsignond_dictionary_get_string(token, "Realm");
1409 token_s = gsignond_dictionary_get_string(token, "AccessToken");
1410 secret = gsignond_dictionary_get_string(token, "TokenSecret");
1411 fail_if(g_strcmp0(realm, "megarealm") != 0);
1412 fail_if(g_strcmp0(token_s, "j49ddk933skd9dks") != 0);
1413 fail_if(g_strcmp0(secret, "ll399dj47dskfjdk") != 0);
1414 gsignond_dictionary_unref(token);
1416 gsignond_dictionary_unref(store);
1418 fail_if(error != NULL);
1420 // valid response for HMAC-SHA1
1421 gsignond_dictionary_remove(tokens, "megaclient");
1422 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
1423 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
1424 gsignond_dictionary_remove(data, "_OauthVerifier");
1425 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
1427 gsignond_dictionary_set_string(data, "SignatureMethod", "HMAC-SHA1");
1429 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1431 fail_if(result != NULL);
1432 fail_if(ui_action != NULL);
1433 fail_if(store != NULL);
1434 fail_if(error != NULL);
1436 g_main_context_iteration(g_main_context_default(), TRUE);
1437 if(ui_action != NULL)
1440 fail_if(result != NULL);
1441 fail_if(ui_action == NULL);
1442 gsignond_dictionary_unref(ui_action);
1444 fail_if(store != NULL);
1445 fail_if(error != NULL);
1447 gsignond_plugin_user_action_finished(plugin, ui_data);
1448 fail_if(result != NULL);
1449 fail_if(ui_action != NULL);
1450 fail_if(store != NULL);
1451 fail_if(error != NULL);
1453 g_main_context_iteration(g_main_context_default(), TRUE);
1457 fail_if(result == NULL);
1458 realm = gsignond_dictionary_get_string(result, "Realm");
1459 token_s = gsignond_dictionary_get_string(result, "AccessToken");
1460 secret = gsignond_dictionary_get_string(result, "TokenSecret");
1461 fail_if(g_strcmp0(realm, "megarealm") != 0);
1462 fail_if(g_strcmp0(token_s, "j49ddk933skd9dks") != 0);
1463 fail_if(g_strcmp0(secret, "ll399dj47dskfjdk") != 0);
1464 gsignond_dictionary_unref(result);
1466 fail_if(ui_action != NULL);
1467 fail_if(store == NULL);
1469 fail_if(g_hash_table_size(store) != 2);
1470 token = gsignond_dictionary_new_from_variant(
1471 gsignond_dictionary_get(store, "megaclient"));
1472 fail_if(token == NULL);
1473 realm = gsignond_dictionary_get_string(token, "Realm");
1474 token_s = gsignond_dictionary_get_string(token, "AccessToken");
1475 secret = gsignond_dictionary_get_string(token, "TokenSecret");
1476 fail_if(g_strcmp0(realm, "megarealm") != 0);
1477 fail_if(g_strcmp0(token_s, "j49ddk933skd9dks") != 0);
1478 fail_if(g_strcmp0(secret, "ll399dj47dskfjdk") != 0);
1479 gsignond_dictionary_unref(token);
1481 gsignond_dictionary_unref(store);
1483 fail_if(error != NULL);
1485 // valid response for RSA-SHA1
1486 gsignond_dictionary_remove(tokens, "megaclient");
1487 gsignond_dictionary_remove(data, "_OauthTemporaryToken");
1488 gsignond_dictionary_remove(data, "_OauthTemporaryTokenSecret");
1489 gsignond_dictionary_remove(data, "_OauthVerifier");
1490 gsignond_dictionary_set_string(data, "Callback", "http://localhost/somegsignondoauthcallback");
1492 gsignond_dictionary_set_string(data, "SignatureMethod", "RSA-SHA1");
1494 fail_unless(g_file_get_contents("privkey.pem", &privkey, NULL, NULL));
1495 gsignond_dictionary_set_string(data, "RSAPrivateKey", privkey);
1498 gsignond_plugin_request_initial(plugin, data, tokens, "oauth1");
1500 fail_if(result != NULL);
1501 fail_if(ui_action != NULL);
1502 fail_if(store != NULL);
1503 fail_if(error != NULL);
1505 g_main_context_iteration(g_main_context_default(), TRUE);
1506 if(ui_action != NULL)
1509 fail_if(result != NULL);
1510 fail_if(ui_action == NULL);
1511 gsignond_dictionary_unref(ui_action);
1513 fail_if(store != NULL);
1514 fail_if(error != NULL);
1516 gsignond_plugin_user_action_finished(plugin, ui_data);
1517 fail_if(result != NULL);
1518 fail_if(ui_action != NULL);
1519 fail_if(store != NULL);
1520 fail_if(error != NULL);
1522 g_main_context_iteration(g_main_context_default(), TRUE);
1526 fail_if(result == NULL);
1527 realm = gsignond_dictionary_get_string(result, "Realm");
1528 token_s = gsignond_dictionary_get_string(result, "AccessToken");
1529 secret = gsignond_dictionary_get_string(result, "TokenSecret");
1530 fail_if(g_strcmp0(realm, "megarealm") != 0);
1531 fail_if(g_strcmp0(token_s, "j49ddk933skd9dks") != 0);
1532 fail_if(g_strcmp0(secret, "ll399dj47dskfjdk") != 0);
1533 gsignond_dictionary_unref(result);
1535 fail_if(ui_action != NULL);
1536 fail_if(store == NULL);
1538 fail_if(g_hash_table_size(store) != 2);
1539 token = gsignond_dictionary_new_from_variant(
1540 gsignond_dictionary_get(store, "megaclient"));
1541 fail_if(token == NULL);
1542 realm = gsignond_dictionary_get_string(token, "Realm");
1543 token_s = gsignond_dictionary_get_string(token, "AccessToken");
1544 secret = gsignond_dictionary_get_string(token, "TokenSecret");
1545 fail_if(g_strcmp0(realm, "megarealm") != 0);
1546 fail_if(g_strcmp0(token_s, "j49ddk933skd9dks") != 0);
1547 fail_if(g_strcmp0(secret, "ll399dj47dskfjdk") != 0);
1548 gsignond_dictionary_unref(token);
1550 gsignond_dictionary_unref(store);
1552 fail_if(error != NULL);
1555 gsignond_dictionary_unref(data);
1556 gsignond_dictionary_unref(tokens);
1557 gsignond_dictionary_unref(ui_data);
1558 g_object_unref(plugin);
1559 g_object_unref(server);
1565 void add_oauth1_tcase(Suite *s)
1567 TCase *tc_oauth2 = tcase_create ("OAuth 1 tests");
1568 tcase_add_test (tc_oauth2, test_oauth1_request);
1569 tcase_add_test (tc_oauth2, test_oauth1_allowed_realms);
1570 tcase_add_test (tc_oauth2, test_oauth1_request_temporary_token);
1571 tcase_add_test (tc_oauth2, test_oauth1_ui_request);
1572 tcase_add_test (tc_oauth2, test_oauth1_request_access_token);
1573 suite_add_tcase (s, tc_oauth2);