summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/CMakeLists.txt59
-rwxr-xr-xsrc/oauth2.pc.in13
-rw-r--r--src/oauth2_error.c103
-rw-r--r--src/oauth2_manager.c1617
-rw-r--r--src/oauth2_private.h141
-rw-r--r--src/oauth2_request.c711
-rw-r--r--src/oauth2_response.c254
-rw-r--r--src/oauth2_util.c137
-rw-r--r--src/oauth2_util.h70
9 files changed, 3105 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100755
index 0000000..e1ae46b
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,59 @@
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(VERSION_MAJOR 0)
+SET(VERSION "${VERSION_MAJOR}.0.1")
+
+SET(SRCS
+ oauth2_error.c
+ oauth2_manager.c
+ oauth2_request.c
+ oauth2_response.c
+ oauth2_util.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
+
+INCLUDE(FindPkgConfig)
+if(DEFINED EXCLUDE_EWK_ERR)
+ add_definitions(-DWITHOUT_EWK_ERROR)
+endif()
+
+if(USE_CHROMIUM_EFL)
+ add_definitions(-DWITH_CHROMIUM)
+ pkg_check_modules(clientpkgs REQUIRED dlog glib-2.0 gio-2.0 gio-unix-2.0 capi-base-common capi-system-info security-privilege-checker libcurl efl-extension ecore evas chromium-efl json-glib-1.0 elementary)
+else()
+ pkg_check_modules(clientpkgs REQUIRED dlog glib-2.0 gio-2.0 gio-unix-2.0 capi-base-common capi-system-info security-privilege-checker libcurl efl-extension ecore evas ewebkit2 json-glib-1.0 elementary)
+endif()
+
+FOREACH(flag ${clientpkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror")
+SET(CMAKE_LDFLAGS "-Wl,-zdefs")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+ADD_DEFINITIONS("-DSLP_DEBUG")
+
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${clientpkgs_LDFLAGS})
+
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR}/oauth2)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIBDIR}/pkgconfig)
+
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/oauth2.h DESTINATION include)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/oauth2_manager.h DESTINATION include)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/oauth2_request.h DESTINATION include)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/oauth2_response.h DESTINATION include)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/oauth2_error.h DESTINATION include)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/oauth2_types.h DESTINATION include)
diff --git a/src/oauth2.pc.in b/src/oauth2.pc.in
new file mode 100755
index 0000000..17e7fef
--- /dev/null
+++ b/src/oauth2.pc.in
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: oauth2
+Description: Tizen oauth 2.0 Framework
+Version: @VERSION@
+#Requires: capi-base-common
+Libs: -L${libdir} -loauth2
+Cflags: -I${includedir}
diff --git a/src/oauth2_error.c b/src/oauth2_error.c
new file mode 100644
index 0000000..5ae196d
--- /dev/null
+++ b/src/oauth2_error.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "oauth2_error.h"
+#include "oauth2_private.h"
+#include "oauth2_util.h"
+
+OAUTH2_API
+int oauth2_error_get_code(oauth2_error_h handle, int *server_error_code,
+ int *platform_error_code)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_error_s *request_data_temp = (oauth2_error_s *)handle;
+
+ char *server_error_str = NULL;
+ char *platform_error_str = NULL;
+
+ bundle_get_str(request_data_temp->error_data,
+ OAUTH2_PARAMETER_KEY_ERROR_CODE, &server_error_str);
+ bundle_get_str(request_data_temp->error_data,
+ OAUTH2_PARAMETER_KEY_ERROR_CODE_PLATFORM, &platform_error_str);
+
+ if (!server_error_str && !platform_error_str)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ if (server_error_str)
+ sscanf(server_error_str, "%d", server_error_code);
+
+ if (platform_error_str)
+ sscanf(platform_error_str, "%d", platform_error_code);
+
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API
+int oauth2_error_get_description(oauth2_error_h handle, char **description)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_error_s *error_data_temp = (oauth2_error_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(error_data_temp->error_data,
+ OAUTH2_PARAMETER_KEY_ERROR_DESCRIPTION, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *description = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API
+int oauth2_error_get_uri(oauth2_error_h handle, char **uri)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_error_s *error_data_temp = (oauth2_error_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(error_data_temp->error_data,
+ OAUTH2_PARAMETER_KEY_ERROR_URI, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *uri = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API
+int oauth2_error_get_custom_data(oauth2_error_h handle, const char *custom_key,
+ char **custom_value)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_error_s *error_data_temp = (oauth2_error_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(error_data_temp->error_data, custom_key, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *custom_value = val;
+ return OAUTH2_ERROR_NONE;
+}
diff --git a/src/oauth2_manager.c b/src/oauth2_manager.c
new file mode 100644
index 0000000..06e377f
--- /dev/null
+++ b/src/oauth2_manager.c
@@ -0,0 +1,1617 @@
+/*
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <efl_extension.h>
+#include <system_info.h>
+#include <privilege_checker.h>
+#include <Ecore_X.h>
+
+#include "oauth2_manager.h"
+#include "oauth2_util.h"
+#include "oauth2_private.h"
+
+#define NETWORK_FEATURE "tizen.org/feature/network.internet"
+#define INTERNET_PRIVILEGE "http://tizen.org/privilege/internet"
+
+static void __send_response_to_caller(oauth2_manager_s *mgr_handle);
+static void __convert_tizen_error_to_oauth_error(int tizen_error,
+ char *error_desc, oauth2_response_s **response_handle);
+static void __handle_back_key(void *data, Evas_Object *p, void *info);
+
+OAUTH2_API int
+oauth2_manager_create(oauth2_manager_h *handle)
+{
+ OAUTH2_LOG_I("oauth2_manager_create");
+
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "Null Input");
+
+ oauth2_manager_s *mgr_impl = (oauth2_manager_s *) calloc(1,
+ sizeof(oauth2_manager_s));
+ OAUTH2_RETURN_VAL(mgr_impl, {}, OAUTH2_ERROR_OUT_OF_MEMORY,
+ "Out of memory");
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ /* g_type_init(); */
+
+ mgr_impl->parser_handle = json_parser_new();
+ OAUTH2_RETURN_VAL(mgr_impl->parser_handle, { OAUTH2_FREE(mgr_impl); },
+ OAUTH2_ERROR_OUT_OF_MEMORY, "Out of memory");
+
+ mgr_impl->is_active = FALSE;
+
+ *handle = (oauth2_manager_h)mgr_impl;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_manager_destroy(oauth2_manager_h handle)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "Null Input");
+
+ OAUTH2_FREE(handle);
+ return OAUTH2_ERROR_NONE;
+}
+
+static bool
+__is_feature_supported(void)
+{
+ bool supported = FALSE;
+ int ret = system_info_get_platform_bool(NETWORK_FEATURE, &supported);
+ OAUTH2_RETURN_VAL(ret == SYSTEM_INFO_ERROR_NONE, {}, false, "network feature support check failed");
+
+ return supported;
+}
+
+static bool
+__check_privilege(void)
+{
+ int ret = privilege_checker_check_privilege(INTERNET_PRIVILEGE);
+ OAUTH2_RETURN_VAL(ret == PRIVILEGE_CHECKER_ERR_NONE, {}, FALSE, "internet privilege check failed");
+
+ return TRUE;
+
+}
+
+static void
+__hide_web_view(oauth2_manager_s *mgr_handle)
+{
+ mgr_handle->is_webview_active = false;
+
+ if (mgr_handle->ewk_view) {
+ ewk_view_stop(mgr_handle->ewk_view);
+ evas_object_hide(mgr_handle->ewk_view);
+ evas_object_hide(mgr_handle->login_win);
+ }
+
+ if (mgr_handle->loading_popup) {
+ evas_object_hide(mgr_handle->loading_popup);
+ mgr_handle->loading_popup = NULL;
+ }
+}
+
+static void
+__reset_all_cb(oauth2_manager_s *mgr_handle)
+{
+ mgr_handle->token_cb = NULL;
+ mgr_handle->grant_cb = NULL;
+ mgr_handle->access_token_cb = NULL;
+ mgr_handle->refresh_cb = NULL;
+ mgr_handle->user_data = NULL;
+ mgr_handle->is_active = FALSE;
+}
+
+static void
+__convert_tizen_error_to_oauth_error(int tizen_error, char *error_desc,
+ oauth2_response_s **response_handle)
+{
+ if (*response_handle == NULL) {
+ *response_handle = (oauth2_response_s *)calloc(1,
+ sizeof(oauth2_response_s));
+ if (*response_handle == NULL) {
+ OAUTH2_LOG_E("Out of memory");
+ return;
+ }
+ }
+
+ (*response_handle)->error = (oauth2_error_s *)calloc(1,
+ sizeof(oauth2_error_s));
+ (*response_handle)->error->error_data = bundle_create();
+
+ char error_code_str[128] = {0,};
+ char error_desc_str[128] = {0,};
+
+ snprintf(error_code_str, 127, "%d", tizen_error);
+ snprintf(error_desc_str, 127, "%s", error_desc);
+
+ bundle_add_str((*response_handle)->error->error_data,
+ OAUTH2_PARAMETER_KEY_ERROR_CODE, error_code_str);
+ bundle_add_str((*response_handle)->error->error_data,
+ OAUTH2_PARAMETER_KEY_ERROR_DESCRIPTION, error_desc_str);
+}
+
+
+static char*
+__get_grant_type(char *grant_type_str)
+{
+ OAUTH2_LOG_I("__get_grant_type");
+ if (!grant_type_str)
+ return NULL;
+
+ char *str_val = NULL;
+ int grant_type = OAUTH2_GRANT_TYPE_AUTH_CODE;
+ sscanf(grant_type_str, "%d", &grant_type);
+
+ if (grant_type < OAUTH2_GRANT_TYPE_AUTH_CODE
+ || grant_type > OAUTH2_GRANT_TYPE_REFRESH) {
+ OAUTH2_LOG_E("Invalid grant_type [%d]", grant_type);
+ return NULL;
+ } else if (grant_type == OAUTH2_GRANT_TYPE_AUTH_CODE)
+ str_val = OAUTH2_PARAMETER_VAL_GRANT_TYPE_AUTH_CODE;
+ else if (grant_type == OAUTH2_GRANT_TYPE_PASSWORD)
+ str_val = OAUTH2_PARAMETER_VAL_GRANT_TYPE_PASSWORD;
+ else if (grant_type == OAUTH2_GRANT_TYPE_CLIENT_CREDENTIALS)
+ str_val = OAUTH2_PARAMETER_VAL_GRANT_TYPE_CLIENT_CREDENTIALS;
+ else if (grant_type == OAUTH2_GRANT_TYPE_REFRESH)
+ str_val = OAUTH2_PARAMETER_VAL_GRANT_TYPE_REFRESH_TOKEN;
+
+ return str_val;
+}
+
+static char*
+__get_response_type(char *response_type_str)
+{
+ OAUTH2_LOG_I("__get_response_type");
+ if (!response_type_str)
+ return NULL;
+
+ char *str_val = NULL;
+ int response_type = OAUTH2_RESPONSE_TYPE_CODE;
+ sscanf(response_type_str, "%d", &response_type);
+
+ if (response_type < OAUTH2_RESPONSE_TYPE_CODE
+ || response_type > OAUTH2_RESPONSE_TYPE_TOKEN) {
+ OAUTH2_LOG_E("Invalid response_type [%d]", response_type);
+ return NULL;
+ } else if (response_type == OAUTH2_RESPONSE_TYPE_CODE)
+ str_val = OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_CODE;
+ else if (response_type == OAUTH2_RESPONSE_TYPE_TOKEN)
+ str_val = OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_TOKEN;
+
+ return str_val;
+}
+
+
+static void
+__handle_back_key(void *data, Evas_Object *p, void *info)
+{
+ if (data) {
+ oauth2_manager_s *mgr_handle = (oauth2_manager_s *)data;
+ __convert_tizen_error_to_oauth_error(
+ OAUTH2_ERROR_USER_CANCELLED,
+ "User cancelled the operation",
+ &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+ }
+}
+
+static void
+__send_response_to_caller(oauth2_manager_s *mgr_handle)
+{
+ OAUTH2_LOG_I("__send_response_to_caller start");
+
+ mgr_handle->is_active = FALSE;
+ __hide_web_view(mgr_handle);
+
+ if (mgr_handle->token_cb) {
+ if (mgr_handle->response) {
+ OAUTH2_LOG_I("__send_response_to_caller calling \
+ application cb");
+ (mgr_handle->token_cb)((oauth2_response_h)
+ (mgr_handle->response), mgr_handle->user_data);
+ } else
+ (mgr_handle->token_cb)(NULL, mgr_handle->user_data);
+ } else if (mgr_handle->grant_cb) {
+ if (mgr_handle->response) {
+ (mgr_handle->grant_cb)((oauth2_response_h)
+ (mgr_handle->response), mgr_handle->user_data);
+ } else
+ (mgr_handle->grant_cb)(NULL, mgr_handle->user_data);
+ } else if (mgr_handle->access_token_cb) {
+ if (mgr_handle->response) {
+ (mgr_handle->access_token_cb)((oauth2_response_h)
+ (mgr_handle->response), mgr_handle->user_data);
+ } else {
+ (mgr_handle->access_token_cb)(NULL,
+ mgr_handle->user_data);
+ }
+ } else if (mgr_handle->refresh_cb) {
+ if (mgr_handle->response) {
+ (mgr_handle->refresh_cb)((oauth2_response_h)
+ (mgr_handle->response), mgr_handle->user_data);
+ } else
+ (mgr_handle->refresh_cb)(NULL, mgr_handle->user_data);
+ }
+ __reset_all_cb(mgr_handle);
+
+ eext_object_event_callback_del(mgr_handle->login_win,
+ EEXT_CALLBACK_BACK, __handle_back_key);
+
+ OAUTH2_LOG_I("__send_response_to_caller end");
+ return;
+}
+
+static bool
+__is_auth_grant_request_param(const char *param_key)
+{
+ if (strcmp(param_key, OAUTH2_PARAMETER_KEY_AUTHORIZATION_URL)
+ && strcmp(param_key, OAUTH2_PARAMETER_KEY_ACCESS_TOKEN_URL)
+ && strcmp(param_key, OAUTH2_PARAMETER_KEY_REFRESH_TOKEN_URL)
+ && strcmp(param_key, OAUTH2_PARAMETER_KEY_GRANT_TYPE)
+ && strcmp(param_key, OAUTH2_PARAMETER_KEY_CLIENT_SECRET)
+ && strcmp(param_key, OAUTH2_PARAMETER_KEY_CLIENT_AUTH_TYPE))
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+__request_data_iter_cb(const char *key, const int type,
+ const bundle_keyval_t *kv, void *user_data)
+{
+ if (__is_auth_grant_request_param(key)) {
+ OAUTH2_LOG_I("__is_auth_grant_request_param TRUE");
+
+ char **final_url = (char **)user_data;
+ if (final_url) {
+ char *value = NULL;
+ size_t value_len = 0;
+ bundle_keyval_get_basic_val((bundle_keyval_t *)kv,
+ (void **)&value, &value_len);
+ if (value) {
+ OAUTH2_LOG_I("Appending val=[%s]", value);
+
+ strncat(*final_url, key, strlen(key));
+ strncat(*final_url, "=", 1);
+
+ if (strcmp(key,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE) == 0)
+ value = __get_grant_type(value);
+ else if (strcmp(key,
+ OAUTH2_PARAMETER_KEY_RESPONSE_TYPE)
+ == 0)
+ value = __get_response_type(value);
+
+ if (value != NULL) {
+ strncat(*final_url, value, strlen(value));
+ strncat(*final_url, "&", 1);
+ }
+ }
+ }
+ }
+}
+
+static char *
+__get_authorization_url(oauth2_request_s *request_impl)
+{
+ OAUTH2_LOG_I("__get_authorization_url");
+
+ if (!request_impl)
+ return NULL;
+
+ char *authorization_url = NULL;
+ bundle_get_str(request_impl->request_data,
+ OAUTH2_PARAMETER_KEY_AUTHORIZATION_URL, &authorization_url);
+ if (!authorization_url) {
+ OAUTH2_LOG_E("Missing mandatory [%s]",
+ OAUTH2_PARAMETER_KEY_AUTHORIZATION_URL);
+ return NULL;
+ }
+
+ char *final_url = (char *) calloc(1, 1024);
+ strncat(final_url, authorization_url, 1023);
+ strncat(final_url, "?", 1023);
+
+ bundle_foreach(request_impl->request_data, __request_data_iter_cb,
+ &final_url);
+
+ if (final_url[strlen(final_url) - 1] == '&')
+ final_url[strlen(final_url) - 1] = '\0';
+ OAUTH2_LOG_I("Final url for auth grant = [%s]", final_url);
+
+ return final_url;
+}
+
+static void
+__exit_back_cb(void *data, Evas_Object *p, void *info)
+{
+ if (data) {
+ oauth2_manager_s *mgr_handle = (oauth2_manager_s *)data;
+ evas_object_hide(mgr_handle->ewk_view);
+ evas_object_hide(mgr_handle->login_win);
+ }
+}
+
+static void
+__append_to_post_data(CURL *curl_handle, char *post_data, const char *key,
+ const char *value, bool append_delim)
+{
+ OAUTH2_LOG_I("__append_to_post_data start");
+
+ char *encoded_key = curl_easy_escape(curl_handle, key, 0);
+ if (encoded_key == NULL) {
+ OAUTH2_LOG_I("curl encoded key null");
+ return;
+ }
+
+ char *encoded_val = curl_easy_escape(curl_handle, value, 0);
+ if (encoded_val == NULL) {
+ OAUTH2_LOG_I("curl encoded value null");
+ return;
+ }
+
+ strncat(post_data, encoded_key, strlen(encoded_key));
+ strncat(post_data, "=", 1);
+ strncat(post_data, encoded_val, strlen(encoded_val));
+ if (append_delim)
+ strncat(post_data, "&", 1);
+ OAUTH2_LOG_I("__append_to_post_data end");
+}
+
+static size_t
+__store_curl_response(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ char **result = (char **)data;
+
+ if (NULL == *result) {
+ *result = calloc(size * nmemb + 1, sizeof(char));
+ OAUTH2_RETURN_VAL(*result, {}, OAUTH2_ERROR_OUT_OF_MEMORY,
+ "Out of memory");
+ memcpy(*result, ptr, size * nmemb);
+ } else {
+ size_t len = strlen(*result);
+ *result = realloc(*result, len + size * nmemb + 1);
+ OAUTH2_RETURN_VAL(*result, {}, OAUTH2_ERROR_OUT_OF_MEMORY,
+ "Out of memory");
+ memcpy(*result + len, ptr, size * nmemb);
+ (*result)[len+size*nmemb] = '\0';
+ }
+ return size * nmemb;
+}
+
+static void
+__iterate_json_response(JsonObject *object, const gchar *member_name,
+ JsonNode *member_node, gpointer user_data)
+{
+ if (object) {
+ bundle *response_bundle = user_data;
+
+ if (json_node_get_node_type(member_node) != JSON_NODE_VALUE)
+ return;
+
+ if (json_node_get_value_type(member_node) == G_TYPE_STRING) {
+ OAUTH2_LOG_I("bundle_add_str with string");
+ if (json_node_get_string(member_node) != NULL)
+ bundle_add_str(response_bundle, member_name,
+ json_node_get_string(member_node));
+ } else if (json_node_get_value_type(member_node)
+ == G_TYPE_INT64) {
+ char int_str[128] = {0,};
+ int int_val = json_node_get_int(member_node);
+ snprintf(int_str, 128, "%d", int_val);
+ OAUTH2_LOG_I("bundle_add_str with int");
+ bundle_add_str(response_bundle, member_name, int_str);
+ }
+ }
+}
+
+static void
+__parse_acc_token_response(const char *response_json,
+ oauth2_response_s **response)
+{
+ OAUTH2_LOG_I("__parse_acc_token_response start=[%s]", response_json);
+
+ if (*response)
+ OAUTH2_FREE(*response);
+
+ oauth2_response_s *response_temp = (oauth2_response_s *)calloc(1,
+ sizeof(oauth2_response_s));
+ if (!response_temp) {
+ OAUTH2_LOG_E("Out of memory");
+ return;
+ }
+ /*
+ * First find if error key is there, if present only fillup
+ * oauth2_error_s else fillup oauth2_response_s without
+ * oauth2_error_s component
+ */
+
+ JsonParser *parser = json_parser_new();
+ GError *error = NULL;
+ if (json_parser_load_from_data(parser, response_json,
+ strlen(response_json), &error) == FALSE) {
+ OAUTH2_LOG_I("json_parser_load_from_data() failed [%d][%s]",
+ error->code, error->message);
+
+ /*
+ * Some svc providers (example: GitHub) do not send json
+ * response, which violates
+ * http://tools.ietf.org/html/rfc6749#section-4.1.4 and
+ * http://tools.ietf.org/html/rfc6749#section-5.1
+ */
+ /* Handling those violations */
+ bundle *params = NULL;
+ params = bundle_create();
+ int ret = oauth2_util_get_params(response_json, &params);
+ if (ret != OAUTH2_ERROR_NONE && params == NULL) {
+ OAUTH2_LOG_E("Server response parse failed");
+
+ goto CATCH;
+ }
+ response_temp->response_data = params;
+ response_temp->error = NULL;
+ *response = response_temp;
+
+ g_object_unref(parser);
+
+ return;
+ }
+
+ JsonNode *root_node;
+ root_node = json_parser_get_root(parser);
+ if (root_node == NULL) {
+ OAUTH2_LOG_E("json_parser_get_root() failed");
+
+ goto CATCH;
+ }
+
+ JsonObject *root_obj = NULL;
+ root_obj = json_node_get_object((JsonNode *) root_node);
+ if (root_obj == NULL) {
+ OAUTH2_LOG_E("json_node_get_object() failed");
+
+ goto CATCH;
+ }
+
+ if (json_object_has_member(root_obj, OAUTH2_PARAMETER_KEY_ERROR)) {
+ oauth2_error_s *error = (oauth2_error_s *) calloc(1,
+ sizeof(oauth2_error_s));
+ error->error_data = bundle_create();
+
+ json_object_foreach_member(root_obj, __iterate_json_response,
+ error->error_data);
+ response_temp->error = error;
+ } else {
+ OAUTH2_LOG_I("Filling up response struct");
+ response_temp->response_data = bundle_create();
+ json_object_foreach_member(root_obj, __iterate_json_response,
+ response_temp->response_data);
+ response_temp->error = NULL;
+ }
+
+ OAUTH2_LOG_I("__parse_acc_token_response parse finished");
+
+ *response = response_temp;
+ response_temp = NULL;
+
+CATCH:
+ g_object_unref(parser);
+ if (response_temp != NULL)
+ oauth2_response_destroy((oauth2_response_h)response_temp);
+
+ OAUTH2_LOG_I("__parse_acc_token_response end");
+}
+
+static char *
+__curl_post_request(oauth2_manager_s *mgr_handle, const char *url,
+ const char *post_body, int *curl_err, long *http_code)
+{
+ OAUTH2_LOG_I("__curl_post_request start");
+ if (post_body)
+ OAUTH2_LOG_I("__curl_post_request post body=[%s]", post_body);
+
+ curl_easy_setopt(mgr_handle->curl_handle, CURLOPT_URL, url);
+ curl_easy_setopt(mgr_handle->curl_handle, CURLOPT_POSTFIELDS,
+ post_body);
+ char *data = NULL;
+ curl_easy_setopt(mgr_handle->curl_handle, CURLOPT_WRITEDATA, &data);
+ curl_easy_setopt(mgr_handle->curl_handle, CURLOPT_WRITEFUNCTION,
+ __store_curl_response);
+ curl_easy_setopt(mgr_handle->curl_handle, CURLOPT_SSL_VERIFYPEER,
+ FALSE);
+
+ *curl_err = curl_easy_perform(mgr_handle->curl_handle);
+ OAUTH2_LOG_I("Response id curl code=[%d]", *curl_err);
+ if (*curl_err != CURLE_OK) {
+ curl_easy_cleanup(mgr_handle->curl_handle);
+ return NULL;
+ }
+ *http_code = 0;
+ curl_easy_getinfo(mgr_handle->curl_handle, CURLINFO_RESPONSE_CODE,
+ http_code);
+ OAUTH2_LOG_I("Response id curl http_code=[%ld]", *http_code);
+ if (*http_code != 200) {
+ OAUTH2_LOG_I("http_code=[%ld]", *http_code);
+ curl_easy_cleanup(mgr_handle->curl_handle);
+ return NULL;
+ }
+ curl_easy_cleanup(mgr_handle->curl_handle);
+ mgr_handle->curl_handle = NULL;
+
+ OAUTH2_LOG_I("__curl_post_request end");
+
+ return data;
+}
+
+/* It shoud be called after all param adding is done */
+static void
+__add_client_authentication_post_body(oauth2_manager_s *mgr_handle,
+ char **post_body)
+{
+ char *client_secret = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_SECRET, &client_secret);
+ if (client_secret) {
+ __append_to_post_data(mgr_handle->curl_handle, *post_body,
+ OAUTH2_PARAMETER_KEY_CLIENT_SECRET, client_secret,
+ TRUE);
+ }
+
+ char *client_id = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_ID, &client_id);
+ __append_to_post_data(mgr_handle->curl_handle, *post_body,
+ OAUTH2_PARAMETER_KEY_CLIENT_ID, client_id, FALSE);
+}
+
+static void
+__add_client_authentication_others(oauth2_manager_s *mgr_handle,
+ long curl_auth_type)
+{
+ OAUTH2_LOG_I("__add_client_authentication_others start");
+
+ curl_easy_setopt(mgr_handle->curl_handle, CURLOPT_HTTPAUTH,
+ curl_auth_type);
+ char *client_secret = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_SECRET, &client_secret);
+ if (client_secret) {
+ OAUTH2_LOG_I("__add_client_authentication_others pwd=[%s]",
+ client_secret);
+ curl_easy_setopt(mgr_handle->curl_handle, CURLOPT_PASSWORD,
+ client_secret);
+ }
+
+ char *client_id = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_ID, &client_id);
+ if (client_id) {
+ OAUTH2_LOG_I("__add_client_authentication_others user=[%s]",
+ client_id);
+ curl_easy_setopt(mgr_handle->curl_handle, CURLOPT_USERNAME,
+ client_id);
+ }
+ OAUTH2_LOG_I("__add_client_authentication_others end");
+}
+
+static void
+__add_client_authentication(oauth2_manager_s *mgr_handle, char **post_body)
+{
+ OAUTH2_LOG_I("__add_client_authentication start");
+
+ /*
+ * TODO:
+ * Default is post-body, but there is no RFC point for the default
+ */
+ int client_auth_type = OAUTH2_CLIENT_AUTHENTICATION_TYPE_REQUEST_BODY;
+ char *client_auth_type_str = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_AUTH_TYPE, &client_auth_type_str);
+ if (client_auth_type_str)
+ sscanf(client_auth_type_str, "%d", &client_auth_type);
+
+ if (client_auth_type == OAUTH2_CLIENT_AUTHENTICATION_TYPE_REQUEST_BODY)
+ __add_client_authentication_post_body(mgr_handle, post_body);
+ else if (client_auth_type == OAUTH2_CLIENT_AUTHENTICATION_TYPE_BASIC)
+ __add_client_authentication_others(mgr_handle, CURLAUTH_BASIC);
+ else if (client_auth_type == OAUTH2_CLIENT_AUTHENTICATION_TYPE_DIGEST)
+ __add_client_authentication_others(mgr_handle, CURLAUTH_DIGEST);
+ else {
+ /*
+ * TODO: Support for other http auth types
+ * __add_client_authentication_others(mgr_handle,
+ * CURLAUTH_DIGEST);
+ */
+ }
+ OAUTH2_LOG_I("_add_client_authentication end");
+}
+
+static void
+_request_access_token_by_code(oauth2_manager_s *mgr_handle, const char *code)
+{
+ OAUTH2_LOG_I("_request_access_token_by_code start [%s]", code);
+
+ char *post_body = (char *)calloc(1, 2048);
+ if (post_body == NULL) {
+ OAUTH2_LOG_E("Out of memory");
+ return;
+ }
+
+ mgr_handle->curl_handle = curl_easy_init();
+
+ __append_to_post_data(mgr_handle->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_AUTH_CODE, TRUE);
+ __append_to_post_data(mgr_handle->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_CODE, code, TRUE);
+
+ char *redirect_url = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_REDIRECT_URI, &redirect_url);
+ __append_to_post_data(mgr_handle->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_REDIRECT_URI, redirect_url, TRUE);
+
+ __add_client_authentication(mgr_handle, &post_body);
+
+ char *token_url = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_ACCESS_TOKEN_URL, &token_url);
+
+ OAUTH2_LOG_I("token_url = [%s]", token_url);
+
+ int curl_err = CURLE_OK;
+ long http_code = 200;
+ char *data = __curl_post_request(mgr_handle, token_url, post_body,
+ &curl_err, &http_code);
+
+ if (curl_err == CURLE_OK && http_code == 200 && data != NULL) {
+ __parse_acc_token_response(data, &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+ } else {
+ OAUTH2_LOG_E("curl error=[%d]", http_code);
+ __convert_tizen_error_to_oauth_error(http_code, "Network error",
+ &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+ }
+ OAUTH2_FREE(post_body);
+
+ OAUTH2_LOG_I("_request_access_token_by_code end");
+}
+
+static void
+__request_access_token_for_client_cred(oauth2_manager_s *mgr_handle)
+{
+ mgr_handle->curl_handle = curl_easy_init();
+
+ char *post_body = (char *)calloc(1, 2048);
+ if (post_body == NULL) {
+ OAUTH2_LOG_E("Out of memory");
+ return;
+ }
+
+ __append_to_post_data(mgr_handle->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_CLIENT_CREDENTIALS, TRUE);
+
+ char *scope = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_SCOPE, &scope);
+ if (scope)
+ __append_to_post_data(mgr_handle->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_SCOPE, scope, FALSE);
+
+ __add_client_authentication(mgr_handle, &post_body);
+
+ OAUTH2_LOG_I("post_body[strlen(post_body) - 1]=%c",
+ post_body[strlen(post_body) - 1]);
+
+ if (post_body[strlen(post_body) - 1] == '&')
+ post_body[strlen(post_body) - 1] = '\0';
+
+ char *token_url = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_ACCESS_TOKEN_URL, &token_url);
+
+ int curl_err = CURLE_OK;
+ long http_code = 200;
+ char *data = __curl_post_request(mgr_handle, token_url, post_body,
+ &curl_err, &http_code);
+
+ if (curl_err == CURLE_OK && http_code == 200 && data != NULL) {
+ __parse_acc_token_response(data, &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+ } else {
+ OAUTH2_LOG_E("curl error=[%d]", http_code);
+ __convert_tizen_error_to_oauth_error(http_code,
+ "Network error", &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+ }
+ OAUTH2_FREE(post_body);
+}
+
+static void
+_request_access_token_for_grant_type_pwd(oauth2_manager_s *mgr_handle)
+{
+ mgr_handle->curl_handle = curl_easy_init();
+
+ char *post_body = (char *)calloc(1, 2048);
+ if (post_body == NULL) {
+ OAUTH2_LOG_E("Out of memory");
+ return;
+ }
+
+ __append_to_post_data(mgr_handle->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_PASSWORD, TRUE);
+
+ char *user_name = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_USER_NAME, &user_name);
+ if (user_name)
+ __append_to_post_data(mgr_handle->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_USER_NAME, user_name, TRUE);
+
+ char *password = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_PASSWORD, &password);
+ if (password)
+ __append_to_post_data(mgr_handle->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_PASSWORD, password, TRUE);
+
+ char *scope = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_SCOPE, &scope);
+ if (scope)
+ __append_to_post_data(mgr_handle->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_SCOPE, scope, TRUE);
+
+ __add_client_authentication(mgr_handle, &post_body);
+
+ char *token_url = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_ACCESS_TOKEN_URL, &token_url);
+
+ int curl_err = CURLE_OK;
+ long http_code = 200;
+ char *data = __curl_post_request(mgr_handle, token_url, post_body,
+ &curl_err, &http_code);
+
+ if (curl_err == CURLE_OK && http_code == 200 && data != NULL) {
+ __parse_acc_token_response(data, &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+ } else {
+ OAUTH2_LOG_E("curl error=[%d]", http_code);
+ __convert_tizen_error_to_oauth_error(http_code, "Network error",
+ &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+ }
+ OAUTH2_FREE(post_body);
+}
+
+static void
+_on_auth_grant_received(oauth2_manager_s *mgr_handle, const char *response_url)
+{
+ int ret = OAUTH2_ERROR_NONE;
+ char *response_type_str = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_RESPONSE_TYPE, &response_type_str);
+ char *response_type = __get_response_type(response_type_str);
+ if (!response_type) {
+ mgr_handle->is_active = FALSE;
+
+ OAUTH2_LOG_E("Missing response_type");
+ __convert_tizen_error_to_oauth_error(
+ OAUTH2_ERROR_INVALID_PARAMETER,
+ "Missing response_type in request",
+ &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+
+ return;
+ }
+
+ bundle *params = NULL;
+ params = bundle_create();
+ bool is_two_step = FALSE;
+ if (strcmp(response_type, OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_CODE)
+ == 0) {
+ char *query = NULL;
+ ret = oauth2_util_get_query(response_url, &query);
+ if (ret != OAUTH2_ERROR_NONE && query == NULL) {
+ __convert_tizen_error_to_oauth_error(
+ OAUTH2_ERROR_SERVER,
+ "Server response does not contain query",
+ &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+
+ bundle_free(params);
+
+ return;
+ }
+
+ ret = oauth2_util_get_params(query, &params);
+ if (ret != OAUTH2_ERROR_NONE && params == NULL) {
+ __convert_tizen_error_to_oauth_error(
+ OAUTH2_ERROR_PARSE_FAILED,
+ "Server response parse failed",
+ &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+ OAUTH2_FREE(query);
+
+ return;
+ }
+
+ /* step 2 */
+ if (mgr_handle->request_func == REQUEST_ACCESS_TOKEN)
+ is_two_step = TRUE;
+
+ OAUTH2_FREE(query);
+
+ } else if (strcmp(response_type,
+ OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_TOKEN) == 0) {
+ char *fragment = NULL;
+ ret = oauth2_util_get_fragment(response_url, &fragment);
+ if (ret != OAUTH2_ERROR_NONE && fragment == NULL) {
+ __convert_tizen_error_to_oauth_error(
+ OAUTH2_ERROR_SERVER,
+ "Server response does not contain fragment",
+ &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+
+ if (params)
+ bundle_free(params);
+
+ return;
+ }
+
+ ret = oauth2_util_get_params(fragment, &params);
+ if (ret != OAUTH2_ERROR_NONE && params == NULL) {
+ __convert_tizen_error_to_oauth_error(
+ OAUTH2_ERROR_PARSE_FAILED,
+ "Server response parse failed",
+ &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+
+ OAUTH2_FREE(fragment);
+
+ return;
+ }
+ OAUTH2_FREE(fragment);
+
+ } else {
+ /* TODO: Handle custom response_type (for eg, Facebook,
+ * Soundcloud supports "token_and_code") */
+ }
+
+ if (is_two_step) {
+ char *code_val = NULL;
+ bundle_get_str(params, OAUTH2_PARAMETER_KEY_CODE, &code_val);
+ if (!code_val) {
+ OAUTH2_LOG_E("Error in response: [%s] not found",
+ OAUTH2_PARAMETER_KEY_CODE);
+
+ /* Server Error response handling */
+
+ /*
+ * google sample error: error=access_denied&
+ * state=security_token%3D138r5719ru3e1%26
+ * url%3Dhttps://oa2cb.example.com/myHome
+ */
+
+ if (mgr_handle->response == NULL) {
+ mgr_handle->response = (oauth2_response_s *)
+ calloc(1, sizeof(oauth2_response_s));
+ }
+
+ mgr_handle->response->error = (oauth2_error_s *)
+ calloc(1, sizeof(oauth2_error_s));
+ mgr_handle->response->error->error_data = params;
+
+ __send_response_to_caller(mgr_handle);
+ return;
+ }
+ _request_access_token_by_code(mgr_handle, code_val);
+
+ if (params)
+ bundle_free(params);
+
+ } else {
+ mgr_handle->is_active = FALSE;
+ mgr_handle->response = (oauth2_response_s *)calloc(1,
+ sizeof(oauth2_response_s));
+
+ /* Check if its error response or success resopnse */
+ /*
+ * FB sample error: YOUR_REDIRECT_URI?error_reason=user_denied&
+ * error=access_denied&
+ * error_description=The+user+denied+your+request.
+ */
+
+ char *error = NULL;
+ char *error_desc = NULL;
+ char *error_uri = NULL;
+
+ bundle_get_str(params, OAUTH2_PARAMETER_KEY_ERROR, &error);
+ bundle_get_str(params, OAUTH2_PARAMETER_KEY_ERROR_DESCRIPTION,
+ &error_desc);
+ bundle_get_str(params, OAUTH2_PARAMETER_KEY_ERROR_URI,
+ &error_uri);
+
+ if (!error && !error_desc && !error_uri) {
+ /* Success */
+ mgr_handle->response->response_data = params;
+ } else {
+ /* Error */
+ mgr_handle->response->error = (oauth2_error_s *)calloc(
+ 1, sizeof(oauth2_error_s));
+ mgr_handle->response->error->error_data = params;
+ }
+ __send_response_to_caller(mgr_handle);
+ }
+}
+
+static void
+on_web_url_load_error(void *data, Evas_Object *obj, void *event_info)
+{
+ /* wearable webkit does not have ewk_error defined */
+#ifndef WITHOUT_EWK_ERROR
+ oauth2_manager_s *mgr_handle = data;
+ const Ewk_Error *error = (const Ewk_Error *)event_info;
+
+ if (mgr_handle && mgr_handle->is_webview_active == true
+ && (ewk_error_code_get(error) != EWK_ERROR_CODE_CANCELED)) {
+ __convert_tizen_error_to_oauth_error(OAUTH2_ERROR_NETWORK_ERROR,
+ "Network Error", &(mgr_handle->response));
+ __send_response_to_caller(mgr_handle);
+ }
+#endif
+}
+
+static void
+on_web_url_load_finished(void *data, Evas_Object *obj, void *event_info)
+{
+ oauth2_manager_s *mgr_handle = data;
+
+ if (mgr_handle->loading_popup) {
+ evas_object_hide(mgr_handle->loading_popup);
+ mgr_handle->loading_popup = NULL;
+ }
+}
+
+static void
+on_web_url_change(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *uri = event_info;
+
+ oauth2_manager_s *mgr_handle = data;
+ char *redirect_uri = NULL;
+ bundle_get_str(mgr_handle->request->request_data,
+ OAUTH2_PARAMETER_KEY_REDIRECT_URI, &redirect_uri);
+
+ if (!g_str_has_prefix(uri, redirect_uri)) {
+ if (mgr_handle->loading_popup == NULL) {
+ mgr_handle->loading_popup = elm_popup_add(mgr_handle->login_win);
+ elm_popup_content_text_wrap_type_set(mgr_handle->loading_popup, ELM_WRAP_MIXED);
+ elm_object_text_set(mgr_handle->loading_popup, OAUTH2_LOADING_POP_UP_TEXT);
+ elm_popup_orient_set(mgr_handle->loading_popup, ELM_POPUP_ORIENT_BOTTOM);
+ evas_object_show(mgr_handle->loading_popup);
+ }
+ return;
+ }
+
+ __hide_web_view(mgr_handle);
+
+ char *oauth_response = strdup(uri);
+ OAUTH2_LOG_I("Response oauth_response=[%s]", oauth_response);
+
+ _on_auth_grant_received(mgr_handle, oauth_response);
+ OAUTH2_FREE(oauth_response);
+}
+
+static int
+__start_auth_grant_request(oauth2_manager_s *mgr_handle)
+{
+ char *authorization_url = __get_authorization_url(mgr_handle->request);
+ if (!authorization_url) {
+ OAUTH2_LOG_E("Failed to form authorization url");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ mgr_handle->login_win = elm_win_util_standard_add("main_win", "");
+ eext_object_event_callback_add(mgr_handle->login_win,
+ EEXT_CALLBACK_BACK, __exit_back_cb, mgr_handle);
+
+ mgr_handle->loading_popup = elm_popup_add(mgr_handle->login_win);
+ elm_popup_content_text_wrap_type_set(mgr_handle->loading_popup, ELM_WRAP_MIXED);
+ elm_object_text_set(mgr_handle->loading_popup, OAUTH2_LOADING_POP_UP_TEXT);
+ elm_popup_orient_set(mgr_handle->loading_popup, ELM_POPUP_ORIENT_BOTTOM);
+
+ ewk_init();
+
+ Evas *canvas = NULL;
+
+ mgr_handle->content_box = elm_box_add(mgr_handle->login_win);
+ elm_box_padding_set(mgr_handle->content_box, 0, 3);
+ evas_object_size_hint_weight_set(mgr_handle->content_box,
+ EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(mgr_handle->content_box, 0.0, 0.0);
+ evas_object_show(mgr_handle->content_box);
+
+ canvas = evas_object_evas_get(mgr_handle->login_win);
+
+ mgr_handle->ewk_view = ewk_view_add(canvas);
+ if (NULL == mgr_handle->ewk_view) {
+ LOGE("ewk_view_add() failed");
+ __send_response_to_caller(mgr_handle);
+
+ return OAUTH2_ERROR_UNKNOWN;
+ }
+
+ mgr_handle->is_webview_active = true;
+
+ eext_object_event_callback_add(mgr_handle->login_win,
+ EEXT_CALLBACK_BACK, __handle_back_key, mgr_handle);
+
+ ewk_view_url_set(mgr_handle->ewk_view, authorization_url);
+
+ Ecore_X_Screen *screen = ecore_x_default_screen_get();
+ if (screen != NULL) {
+ int w = 0;
+ int h = 0;
+ ecore_x_screen_size_get (screen, &w, &h);
+ LOGI("Screen info = [%d][%d]", w, h);
+
+ evas_object_size_hint_min_set(mgr_handle->ewk_view, w, h);
+ }
+
+ evas_object_size_hint_weight_set(mgr_handle->ewk_view,
+ EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(mgr_handle->ewk_view,
+ EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ evas_object_smart_callback_add(mgr_handle->ewk_view, "url,changed",
+ on_web_url_change, mgr_handle);
+ evas_object_smart_callback_add(mgr_handle->ewk_view, "load,error",
+ on_web_url_load_error, mgr_handle);
+ evas_object_smart_callback_add(mgr_handle->ewk_view, "load,finished",
+ on_web_url_load_finished, mgr_handle);
+
+ elm_box_pack_end(mgr_handle->content_box, mgr_handle->ewk_view);
+ evas_object_show(mgr_handle->ewk_view);
+
+ evas_object_show(mgr_handle->login_win);
+
+ evas_object_show(mgr_handle->loading_popup);
+
+ return OAUTH2_ERROR_NONE;
+}
+
+
+OAUTH2_API int
+oauth2_manager_request_token(oauth2_manager_h handle, oauth2_request_h request,
+ oauth2_token_cb callback, void *user_data)
+{
+ OAUTH2_RETURN_VAL(callback, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "callback is Null");
+
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "handle is Null");
+
+ OAUTH2_RETURN_VAL(request, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "request is Null");
+
+ OAUTH2_RETURN_VAL(__is_feature_supported(), {}, OAUTH2_ERROR_NOT_SUPPORTED,
+ "network feature not supported");
+
+ OAUTH2_RETURN_VAL(__check_privilege(), {}, OAUTH2_ERROR_PERMISSION_DENIED,
+ "permission denied, no internet privilege");
+
+ oauth2_manager_s *mgr_impl = (oauth2_manager_s *)handle;
+ OAUTH2_RETURN_VAL(!mgr_impl->is_active, {},
+ OAUTH2_ERROR_ALREADY_IN_PROGRESS, "Already in progress");
+
+ mgr_impl->request = (oauth2_request_s *)request;
+
+ __reset_all_cb(mgr_impl);
+
+ char *redirect_uri = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_REDIRECT_URI, &redirect_uri);
+ if (!redirect_uri) {
+ OAUTH2_LOG_E("Missing mandatory field [%s]",
+ OAUTH2_PARAMETER_KEY_REDIRECT_URI);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ char *grant_type_str = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE, &grant_type_str);
+ char *grant_type = __get_grant_type(grant_type_str);
+
+ char *response_type_str = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_RESPONSE_TYPE, &response_type_str);
+ char *response_type = __get_response_type(response_type_str);
+
+ if (!grant_type && !response_type) {
+ OAUTH2_LOG_E("[%s] or [%s] must be specified",
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE,
+ OAUTH2_PARAMETER_KEY_RESPONSE_TYPE);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ mgr_impl->token_cb = callback;
+ mgr_impl->user_data = user_data;
+
+ mgr_impl->is_active = TRUE;
+
+ /* For authorization code and implicit, response_type is mentioned */
+ if (response_type) {
+ if (!strcmp(response_type,
+ OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_CODE) ||
+ !strcmp(response_type,
+ OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_TOKEN)) {
+ mgr_impl->request_func = REQUEST_ACCESS_TOKEN;
+ int ret = __start_auth_grant_request(mgr_impl);
+ if (ret != OAUTH2_ERROR_NONE) {
+ __reset_all_cb(mgr_impl);
+ return ret;
+ }
+ return OAUTH2_ERROR_NONE;
+ }
+ }
+ /*
+ * For resource owner pwd and client credentials, grant_type
+ * is mentioned
+ */
+ else {
+ /*
+ * Here authorization grant handling is out of oauth 2.0 RFC, so
+ * unless a custom auth grant handler is set, we will proceed
+ * with access token request directly
+ */
+ if (!strcmp(grant_type,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_PASSWORD) ||
+ !strcmp(grant_type,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_CLIENT_CREDENTIALS)) {
+ /* For pwd: grant_type, username, password, scope */
+ if (!strcmp(grant_type,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_PASSWORD)) {
+ _request_access_token_for_grant_type_pwd(
+ mgr_impl);
+ } else {
+ /*For client cred: grant_type, scope */
+ __request_access_token_for_client_cred(
+ mgr_impl);
+ }
+
+ /* _request_access_token() */
+ return OAUTH2_ERROR_NONE;
+ } else {
+ /*
+ * TODO:
+ * TBD, extension grant_type / response_type support
+ */
+ return OAUTH2_ERROR_NOT_SUPPORTED;
+ }
+ }
+
+ /* TODO: TBD, extension grant_type / response_type support */
+ return OAUTH2_ERROR_NOT_SUPPORTED;
+}
+
+OAUTH2_API int
+oauth2_manager_request_authorization_grant(oauth2_manager_h handle,
+ oauth2_request_h request, oauth2_auth_grant_cb callback,
+ void *user_data)
+{
+ OAUTH2_RETURN_VAL(callback, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "callback is Null");
+
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "handle is Null");
+
+ OAUTH2_RETURN_VAL(request, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "request is Null");
+
+ OAUTH2_RETURN_VAL(__is_feature_supported(), {}, OAUTH2_ERROR_NOT_SUPPORTED,
+ "network feature not supported");
+
+ OAUTH2_RETURN_VAL(__check_privilege(), {}, OAUTH2_ERROR_PERMISSION_DENIED,
+ "permission denied, no internet privilege");
+
+ oauth2_manager_s *mgr_impl = (oauth2_manager_s *)handle;
+ OAUTH2_RETURN_VAL(!mgr_impl->is_active, {},
+ OAUTH2_ERROR_ALREADY_IN_PROGRESS, "Already in progress");
+
+ mgr_impl->request = (oauth2_request_s *)request;
+
+ __reset_all_cb(mgr_impl);
+
+ char *redirect_uri = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_REDIRECT_URI, &redirect_uri);
+ if (!redirect_uri) {
+ OAUTH2_LOG_E("Missing mandatory field [%s]",
+ OAUTH2_PARAMETER_KEY_REDIRECT_URI);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ char *grant_type_str = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE, &grant_type_str);
+ char *grant_type = __get_grant_type(grant_type_str);
+
+ char *response_type_str = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_RESPONSE_TYPE, &response_type_str);
+ char *response_type = __get_response_type(response_type_str);
+
+ if (!grant_type && !response_type) {
+ OAUTH2_LOG_E("[%s] or [%s] must be specified",
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE,
+ OAUTH2_PARAMETER_KEY_RESPONSE_TYPE);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ mgr_impl->grant_cb = callback;
+ mgr_impl->user_data = user_data;
+
+ mgr_impl->is_active = TRUE;
+
+ /* For authorization code and implicit, response_type is mentioned */
+ if (response_type) {
+ if (!strcmp(response_type,
+ OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_CODE) ||
+ !strcmp(response_type,
+ OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_TOKEN)) {
+ mgr_impl->request_func = REQUEST_AUTHORIZATION_CODE;
+ int ret = __start_auth_grant_request(mgr_impl);
+ if (ret != OAUTH2_ERROR_NONE) {
+ __reset_all_cb(mgr_impl);
+ return ret;
+ }
+ return OAUTH2_ERROR_NONE;
+ }
+ } else if (!strcmp(grant_type, OAUTH2_PARAMETER_VAL_GRANT_TYPE_PASSWORD)
+ || !strcmp(grant_type,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_CLIENT_CREDENTIALS)) {
+ /*
+ * No additional grant request needed as per RFC
+ * (http://tools.ietf.org/html/rfc6749#section-4.3.1 and
+ * http://tools.ietf.org/html/rfc6749#section-4.4.1)
+ */
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ /* TODO: TBD, extension grant_type / response_type support */
+ return OAUTH2_ERROR_NOT_SUPPORTED;
+}
+
+OAUTH2_API int
+oauth2_manager_request_access_token(oauth2_manager_h handle,
+ oauth2_request_h request, oauth2_access_token_cb callback,
+ void *user_data)
+{
+ OAUTH2_RETURN_VAL(callback, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "callback is Null");
+
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "handle is Null");
+
+ OAUTH2_RETURN_VAL(request, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "request is Null");
+
+ OAUTH2_RETURN_VAL(__is_feature_supported(), {}, OAUTH2_ERROR_NOT_SUPPORTED,
+ "network feature not supported");
+
+ OAUTH2_RETURN_VAL(__check_privilege(), {}, OAUTH2_ERROR_PERMISSION_DENIED,
+ "permission denied, no internet privilege");
+
+ oauth2_manager_s *mgr_impl = (oauth2_manager_s *)handle;
+ OAUTH2_RETURN_VAL(!mgr_impl->is_active, {},
+ OAUTH2_ERROR_ALREADY_IN_PROGRESS, "Already in progress");
+
+ mgr_impl->request = (oauth2_request_s *)request;
+
+ __reset_all_cb(mgr_impl);
+
+ char *response_type_str = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_RESPONSE_TYPE, &response_type_str);
+ char *response_type = __get_response_type(response_type_str);
+ if (response_type) {
+ if (!strcmp(response_type,
+ OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_TOKEN)) {
+ OAUTH2_LOG_E("Obtain token directly with authorization \
+ grant for implicit type");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+ }
+
+ char *grant_type_str = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE, &grant_type_str);
+ char *grant_type = __get_grant_type(grant_type_str);
+
+ if (!grant_type) {
+ OAUTH2_LOG_E("[%s] must be specified",
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ mgr_impl->access_token_cb = callback;
+ mgr_impl->user_data = user_data;
+
+ mgr_impl->is_active = TRUE;
+
+ if (!strcmp(grant_type, OAUTH2_PARAMETER_VAL_GRANT_TYPE_AUTH_CODE)) {
+ char *code = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_CODE, &code);
+ if (code) {
+ _request_access_token_by_code(mgr_impl, code);
+ return OAUTH2_ERROR_NONE;
+ }
+
+ } else {
+ /*
+ * For resource owner pwd and client credentials, grant_type
+ * is mentioned
+ */
+
+ /*
+ * Here authorization grant handling is out of oauth 2.0 RFC, so
+ * unless a custom auth grant handler is set, we will proceed
+ * with access token request directly
+ */
+ if (!strcmp(grant_type,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_PASSWORD) ||
+ !strcmp(grant_type,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_CLIENT_CREDENTIALS)) {
+ /* For pwd: grant_type, username, password, scope */
+ if (!strcmp(grant_type,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_PASSWORD)) {
+ _request_access_token_for_grant_type_pwd(
+ mgr_impl);
+ } else {
+ /* For client cred: grant_type, scope */
+ __request_access_token_for_client_cred(
+ mgr_impl);
+ }
+
+ /* _request_access_token() */
+ return OAUTH2_ERROR_NONE;
+ } else {
+ /*
+ * TODO:
+ * TBD, extension grant_type / response_type support
+ */
+ return OAUTH2_ERROR_NOT_SUPPORTED;
+ }
+ }
+
+ return OAUTH2_ERROR_NOT_SUPPORTED;
+}
+
+static void
+_request_refresh_token(oauth2_manager_s *mgr_impl)
+{
+ char *refresh_uri = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN_URL, &refresh_uri);
+
+ char *refresh_token_input = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN, &refresh_token_input);
+
+ char *scope = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_SCOPE, &scope);
+
+ char *post_body = (char *)calloc(1, 2048);
+ if (post_body == NULL) {
+ OAUTH2_LOG_E("Out of memory");
+ OAUTH2_FREE(refresh_uri);
+ OAUTH2_FREE(refresh_token_input);
+ OAUTH2_FREE(scope);
+ return;
+ }
+
+ mgr_impl->curl_handle = curl_easy_init();
+
+ __append_to_post_data(mgr_impl->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE,
+ OAUTH2_PARAMETER_VAL_GRANT_TYPE_REFRESH_TOKEN, TRUE);
+ __append_to_post_data(mgr_impl->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN, refresh_token_input, TRUE);
+ if (scope) {
+ __append_to_post_data(mgr_impl->curl_handle, post_body,
+ OAUTH2_PARAMETER_KEY_SCOPE, scope, TRUE);
+ }
+
+ __add_client_authentication(mgr_impl, &post_body);
+
+ int curl_err = CURLE_OK;
+ long http_code = 200;
+ char *data = __curl_post_request(mgr_impl, refresh_uri, post_body,
+ &curl_err, &http_code);
+
+ if (curl_err == CURLE_OK && http_code == 200 && data != NULL) {
+ __parse_acc_token_response(data, &(mgr_impl->response));
+ __send_response_to_caller(mgr_impl);
+ } else {
+ /* TODO __convert_tizen_error_to_oauth_error */
+ OAUTH2_LOG_E("curl error=[%d]", http_code);
+ __convert_tizen_error_to_oauth_error(http_code, "Network error",
+ &(mgr_impl->response));
+ __send_response_to_caller(mgr_impl);
+ }
+ OAUTH2_FREE(post_body);
+}
+
+OAUTH2_API int
+oauth2_manager_refresh_access_token(oauth2_manager_h handle,
+ oauth2_request_h request, oauth2_refresh_token_cb callback,
+ void *user_data)
+{
+ OAUTH2_RETURN_VAL(callback, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "callback is Null");
+
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "handle is Null");
+
+ OAUTH2_RETURN_VAL(request, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "request is Null");
+
+ OAUTH2_RETURN_VAL(__is_feature_supported(), {}, OAUTH2_ERROR_NOT_SUPPORTED,
+ "network feature not supported");
+
+ OAUTH2_RETURN_VAL(__check_privilege(), {}, OAUTH2_ERROR_PERMISSION_DENIED,
+ "permission denied, no internet privilege");
+
+ oauth2_manager_s *mgr_impl = (oauth2_manager_s *)handle;
+ OAUTH2_RETURN_VAL(!mgr_impl->is_active, {},
+ OAUTH2_ERROR_ALREADY_IN_PROGRESS, "Already in progress");
+
+ mgr_impl->request = (oauth2_request_s *)request;
+
+ __reset_all_cb(mgr_impl);
+
+ mgr_impl->refresh_cb = callback;
+
+ char *refresh_uri = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN_URL, &refresh_uri);
+ if (!refresh_uri) {
+ OAUTH2_LOG_E("Missing mandatory field [%s]",
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN_URL);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ char *grant_type_str = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE, &grant_type_str);
+ char *grant_type = __get_grant_type(grant_type_str);
+
+ if (!grant_type) {
+ OAUTH2_LOG_E("Missing mandatory field [%s]",
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ char *refresh_token_input = NULL;
+ bundle_get_str(mgr_impl->request->request_data,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN, &refresh_token_input);
+ if (!refresh_token_input) {
+ OAUTH2_LOG_E("Missing mandatory field [%s]",
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ OAUTH2_LOG_I("refresh token request start");
+
+ _request_refresh_token(mgr_impl);
+
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API bool
+oauth2_manager_is_request_in_progress(oauth2_manager_h handle)
+{
+ OAUTH2_RETURN_VAL(handle, {}, FALSE, "handle is Null");
+
+ return ((oauth2_manager_s *)handle)->is_active;
+}
+
+OAUTH2_API int
+oauth2_manager_clear_cookies(oauth2_manager_h handle)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "handle is Null");
+
+ OAUTH2_RETURN_VAL(__is_feature_supported(), {}, OAUTH2_ERROR_NOT_SUPPORTED,
+ "network feature not supported");
+
+ OAUTH2_RETURN_VAL(__check_privilege(), {}, OAUTH2_ERROR_PERMISSION_DENIED,
+ "permission denied, no internet privilege");
+
+ oauth2_manager_s *mgr_impl = (oauth2_manager_s *)handle;
+
+ Evas_Object *web_view = mgr_impl->ewk_view;
+ if (web_view == NULL) {
+ /*
+ * Its possible to call clear_cookies without any prior calls to
+ * request APIs, for these cases we need to add dummy web view
+ */
+ Evas *canvas = evas_object_evas_get(mgr_impl->login_win);
+ if (canvas)
+ web_view = ewk_view_add(canvas);
+ else
+ return OAUTH2_ERROR_UNKNOWN;
+ }
+
+ Ewk_Context *ewk_ctx = ewk_view_context_get(web_view);
+ if (ewk_ctx) {
+ Ewk_Cookie_Manager *cookie_mgr =
+ ewk_context_cookie_manager_get(ewk_ctx);
+ if (cookie_mgr)
+ ewk_cookie_manager_cookies_clear(cookie_mgr);
+ else
+ return OAUTH2_ERROR_UNKNOWN;
+ } else
+ return OAUTH2_ERROR_UNKNOWN;
+
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_manager_clear_cache(oauth2_manager_h handle)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "handle is Null");
+
+ OAUTH2_RETURN_VAL(__is_feature_supported(), {}, OAUTH2_ERROR_NOT_SUPPORTED,
+ "network feature not supported");
+
+ OAUTH2_RETURN_VAL(__check_privilege(), {}, OAUTH2_ERROR_PERMISSION_DENIED,
+ "permission denied, no internet privilege");
+
+ oauth2_manager_s *mgr_impl = (oauth2_manager_s *)handle;
+
+ Evas_Object *web_view = mgr_impl->ewk_view;
+ if (web_view == NULL) {
+ /*
+ * Its possible to call clear_cookies without any prior calls to
+ * request APIs, for these cases we need to add dummy web view
+ */
+ Evas *canvas = evas_object_evas_get(mgr_impl->login_win);
+ if (canvas)
+ web_view = ewk_view_add(canvas);
+ else
+ return OAUTH2_ERROR_UNKNOWN;
+ }
+
+ Ewk_Context *ewk_ctx = ewk_view_context_get(web_view);
+ if (ewk_ctx)
+ ewk_context_resource_cache_clear(ewk_ctx);
+ else
+ return OAUTH2_ERROR_UNKNOWN;
+
+ return OAUTH2_ERROR_NONE;
+}
diff --git a/src/oauth2_private.h b/src/oauth2_private.h
new file mode 100644
index 0000000..3ee9d72
--- /dev/null
+++ b/src/oauth2_private.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef OAUTH2_PRIVATE_H_
+#define OAUTH2_PRIVATE_H_
+
+#include <stdbool.h>
+#include <bundle.h>
+#include <curl/curl.h>
+
+#ifdef WITH_CHROMIUM
+#include <ewk_chromium.h>
+#else
+#include <EWebKit.h>
+#include <ewk_view.h>
+#endif
+
+#include <json-glib/json-glib.h>
+#include "oauth2_manager.h"
+
+#define OAUTH2_PARAMETER_VAL_GRANT_TYPE_AUTH_CODE "authorization_code"
+
+#define OAUTH2_PARAMETER_VAL_GRANT_TYPE_PASSWORD "password"
+
+#define OAUTH2_PARAMETER_VAL_GRANT_TYPE_CLIENT_CREDENTIALS "client_credentials"
+
+#define OAUTH2_PARAMETER_VAL_GRANT_TYPE_REFRESH_TOKEN "refresh_token"
+
+#define OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_CODE "code"
+
+#define OAUTH2_PARAMETER_VAL_RESPONSE_TYPE_TOKEN "token"
+
+#define OAUTH2_PARAMETER_KEY_AUTHORIZATION_URL "auth_url"
+
+#define OAUTH2_PARAMETER_KEY_ACCESS_TOKEN_URL "token_url"
+
+#define OAUTH2_PARAMETER_KEY_REFRESH_TOKEN_URL "refresh_token_url"
+
+#define OAUTH2_PARAMETER_KEY_CLIENT_ID "client_id"
+
+#define OAUTH2_PARAMETER_KEY_CLIENT_SECRET "client_secret"
+
+#define OAUTH2_PARAMETER_KEY_CLIENT_AUTH_TYPE "client_auth_type"
+
+#define OAUTH2_PARAMETER_KEY_RESPONSE_TYPE "response_type"
+
+#define OAUTH2_PARAMETER_KEY_REDIRECT_URI "redirect_uri"
+
+#define OAUTH2_PARAMETER_KEY_SCOPE "scope"
+
+#define OAUTH2_PARAMETER_KEY_STATE "state"
+
+#define OAUTH2_PARAMETER_KEY_CODE "code"
+
+#define OAUTH2_PARAMETER_KEY_ERROR "error"
+
+#define OAUTH2_PARAMETER_KEY_ERROR_CODE "error"
+
+#define OAUTH2_PARAMETER_KEY_ERROR_DESCRIPTION "error_description"
+
+#define OAUTH2_PARAMETER_KEY_ERROR_URI "error_uri"
+
+#define OAUTH2_PARAMETER_KEY_ERROR_CODE_PLATFORM "error_code_platform"
+
+#define OAUTH2_PARAMETER_KEY_GRANT_TYPE "grant_type"
+
+#define OAUTH2_PARAMETER_KEY_ACCESS_TOKEN "access_token"
+
+#define OAUTH2_PARAMETER_KEY_TOKEN_TYPE "token_type"
+
+#define OAUTH2_PARAMETER_KEY_EXPIRES_IN "expires_in"
+
+#define OAUTH2_PARAMETER_KEY_USER_NAME "username"
+
+#define OAUTH2_PARAMETER_KEY_PASSWORD "password"
+
+#define OAUTH2_PARAMETER_KEY_REFRESH_TOKEN "refresh_token"
+
+#define OAUTH2_LOADING_POP_UP_TEXT "Loading..."
+
+typedef enum{
+ REQUEST_ACCESS_TOKEN = 1,
+ REQUEST_AUTHORIZATION_CODE
+} _oauth_request_function;
+
+typedef struct _oauth2_request_s
+{
+ bundle *request_data;
+}oauth2_request_s;
+
+typedef struct _oauth2_error_s
+{
+ bundle *error_data;
+}oauth2_error_s;
+
+typedef struct _oauth2_response_s
+{
+ oauth2_error_s *error;
+ bundle *response_data;
+}oauth2_response_s;
+
+typedef struct _oauth2_manager_s
+{
+ oauth2_request_s *request;
+ Evas_Object *login_win;
+ Evas_Object *content_box;
+ Evas_Object *ewk_view;
+ Evas_Object *loading_popup;
+ CURL *curl_handle;
+ JsonParser *parser_handle;
+ oauth2_response_s *response;
+ _oauth_request_function request_func;
+ bool is_active;
+
+/* callbacks */
+ oauth2_token_cb token_cb;
+ oauth2_auth_grant_cb grant_cb;
+ oauth2_access_token_cb access_token_cb;
+ oauth2_refresh_token_cb refresh_cb;
+ void *user_data;
+ void *temp_data;
+ bool is_webview_active;
+}oauth2_manager_s;
+
+int _oauth2_response_create(oauth2_response_s **response);
+
+#endif /* OAUTH2_PRIVATE_H_ */
diff --git a/src/oauth2_request.c b/src/oauth2_request.c
new file mode 100644
index 0000000..4d5f849
--- /dev/null
+++ b/src/oauth2_request.c
@@ -0,0 +1,711 @@
+/*
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "oauth2_request.h"
+#include "oauth2_private.h"
+#include "oauth2_util.h"
+
+OAUTH2_API int
+oauth2_request_create(oauth2_request_h *handle)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *) calloc(1,
+ sizeof(oauth2_request_s));
+ if (!req_impl) {
+ OAUTH2_LOG_E("Out of memory");
+ return OAUTH2_ERROR_OUT_OF_MEMORY;
+ }
+
+ req_impl->request_data = bundle_create();
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("Out of memory");
+ OAUTH2_FREE(req_impl);
+ return OAUTH2_ERROR_OUT_OF_MEMORY;
+ }
+
+ *handle = (oauth2_request_h)req_impl;
+
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_destroy(oauth2_request_h handle)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *) handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("NULL handle");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (req_impl->request_data)
+ bundle_free(req_impl->request_data);
+
+ OAUTH2_FREE(req_impl);
+ handle = NULL;
+
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_set_auth_end_point_url(oauth2_request_h handle, const char *url)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_AUTHORIZATION_URL, url);
+}
+
+OAUTH2_API int
+oauth2_request_set_token_end_point_url(oauth2_request_h handle, const char *url)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_ACCESS_TOKEN_URL, url);
+}
+
+OAUTH2_API int
+oauth2_request_set_redirection_url(oauth2_request_h handle, const char *url)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_REDIRECT_URI, url);
+}
+
+OAUTH2_API int
+oauth2_request_set_refresh_token_url(oauth2_request_h handle, const char *url)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN_URL, url);
+}
+
+OAUTH2_API int
+oauth2_request_set_refresh_token(oauth2_request_h handle, char *refresh_token)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN, refresh_token);
+}
+
+OAUTH2_API int
+oauth2_request_set_response_type(oauth2_request_h handle,
+ oauth2_response_type_e response_type)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ if (response_type < OAUTH2_RESPONSE_TYPE_CODE
+ || response_type > OAUTH2_RESPONSE_TYPE_TOKEN) {
+ OAUTH2_LOG_E("Invalid response_type [%d]", response_type);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ char response_type_str[128] = {0,};
+ snprintf(response_type_str, 127, "%d", response_type);
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_RESPONSE_TYPE, response_type_str);
+}
+
+OAUTH2_API int
+oauth2_request_set_client_id(oauth2_request_h handle, const char *client_id)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_ID, client_id);
+}
+
+OAUTH2_API int
+oauth2_request_set_client_secret(oauth2_request_h handle,
+ const char *client_secret)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_SECRET, client_secret);
+}
+
+OAUTH2_API int
+oauth2_request_set_client_authentication_type(oauth2_request_h handle,
+ oauth2_client_authentication_type_e client_auth_type)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ if (client_auth_type < OAUTH2_CLIENT_AUTHENTICATION_TYPE_BASIC
+ || client_auth_type > OAUTH2_CLIENT_AUTHENTICATION_TYPE_REQUEST_BODY) {
+ OAUTH2_LOG_E("Invalid client_auth_type [%d]", client_auth_type);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ char client_auth_type_str[128] = {0,};
+ snprintf(client_auth_type_str, 127, "%d", client_auth_type);
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_AUTH_TYPE, client_auth_type_str);
+}
+
+OAUTH2_API int
+oauth2_request_set_scope(oauth2_request_h handle, const char *scope)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_SCOPE, scope);
+}
+
+OAUTH2_API int
+oauth2_request_set_state(oauth2_request_h handle, const char *state)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_STATE, state);
+}
+
+OAUTH2_API int
+oauth2_request_set_grant_type(oauth2_request_h handle,
+ oauth2_grant_type_e grant_type)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ if (grant_type < OAUTH2_GRANT_TYPE_AUTH_CODE
+ || grant_type > OAUTH2_GRANT_TYPE_REFRESH) {
+ OAUTH2_LOG_E("Invalid grant_type [%d]", grant_type);
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ char grant_type_str[128] = {0,};
+ snprintf(grant_type_str, 127, "%d", grant_type);
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE, grant_type_str);
+}
+
+OAUTH2_API int
+oauth2_request_set_authorization_code(oauth2_request_h handle, const char *code)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_CODE, code);
+}
+
+OAUTH2_API int
+oauth2_request_set_user_name(oauth2_request_h handle, const char *user_name)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_USER_NAME, user_name);
+}
+
+OAUTH2_API int
+oauth2_request_set_password(oauth2_request_h handle, const char *password)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data,
+ OAUTH2_PARAMETER_KEY_PASSWORD, password);
+}
+
+OAUTH2_API int
+oauth2_request_add_custom_data(oauth2_request_h handle, const char *key,
+ const char *value)
+{
+ if (!key || !value) {
+ OAUTH2_LOG_E("key and value must not be null");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *req_impl = (oauth2_request_s *)handle;
+ if (!req_impl) {
+ OAUTH2_LOG_E("Null Input");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!req_impl->request_data) {
+ OAUTH2_LOG_E("oauth2_request_h must be created first.");
+ return OAUTH2_ERROR_INVALID_PARAMETER;
+ }
+
+ return bundle_add_str(req_impl->request_data, key, value);
+}
+
+OAUTH2_API int
+oauth2_request_get_auth_end_point_url(oauth2_request_h handle, char **url)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_AUTHORIZATION_URL, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *url = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_token_end_point_url(oauth2_request_h handle, char **url)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_ACCESS_TOKEN_URL, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *url = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_redirection_url(oauth2_request_h handle, char **url)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_REDIRECT_URI, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *url = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_refresh_token_url(oauth2_request_h handle, char **url)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN_URL, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *url = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API
+int oauth2_request_get_refresh_token(oauth2_request_h handle,
+ char **refresh_token)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *refresh_token = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_response_type(oauth2_request_h handle,
+ oauth2_response_type_e *response_type)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ int res;
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_RESPONSE_TYPE, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ sscanf(val, "%d", &res);
+ *response_type = (oauth2_response_type_e) res;
+
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_client_id(oauth2_request_h handle, char **client_id)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_ID, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *client_id = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_client_secret(oauth2_request_h handle, char **client_secret)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_CLIENT_SECRET, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *client_secret = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_scope(oauth2_request_h handle, char **scope)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_SCOPE, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *scope = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_state(oauth2_request_h handle, char **state)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_STATE, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *state = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_grant_type(oauth2_request_h handle,
+ oauth2_grant_type_e *grant_type)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ int res;
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_GRANT_TYPE, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ sscanf(val, "%d", &res);
+ *grant_type = (oauth2_grant_type_e) res;
+
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_authorization_code(oauth2_request_h handle, char **code)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_CODE, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *code = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_user_name(oauth2_request_h handle, char **user_name)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_USER_NAME, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *user_name = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_password(oauth2_request_h handle, char **password)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data,
+ OAUTH2_PARAMETER_KEY_PASSWORD, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *password = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+OAUTH2_API int
+oauth2_request_get_custom_data(oauth2_request_h handle, const char *custom_key,
+ char **custom_value)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+ oauth2_request_s *request_data_temp = (oauth2_request_s *)handle;
+ char *val = NULL;
+ bundle_get_str(request_data_temp->request_data, custom_key, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *custom_value = val;
+ return OAUTH2_ERROR_NONE;
+}
diff --git a/src/oauth2_response.c b/src/oauth2_response.c
new file mode 100644
index 0000000..14ebd6e
--- /dev/null
+++ b/src/oauth2_response.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "oauth2_response.h"
+#include "oauth2_private.h"
+#include "oauth2_util.h"
+
+int
+_oauth2_response_create(oauth2_response_s **response)
+{
+ oauth2_response_s *response_temp =
+ (oauth2_response_s *)calloc(1, sizeof(oauth2_response_s));
+ OAUTH2_RETURN_VAL(response_temp, {}, OAUTH2_ERROR_OUT_OF_MEMORY,
+ "Out of memory");
+ response_temp->error = NULL;
+ response_temp->response_data = bundle_create();
+
+ *response = response_temp;
+ return 0;
+}
+
+OAUTH2_API int
+oauth2_response_destroy(oauth2_response_h handle)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER, "NULL handle");
+
+ oauth2_response_s *response_temp = (oauth2_response_s *)handle;
+ if (response_temp->response_data)
+ bundle_free(response_temp->response_data);
+
+ if (response_temp->error) {
+ bundle_free(response_temp->error->error_data);
+ OAUTH2_FREE(response_temp->error);
+ }
+ OAUTH2_FREE(response_temp);
+ return OAUTH2_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the authorization code.
+ * @since_tizen 2.3
+ */
+OAUTH2_API int
+oauth2_response_get_authorization_code(oauth2_response_h handle, char **code)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_response_s *response_data_temp = (oauth2_response_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(response_data_temp->response_data,
+ OAUTH2_PARAMETER_KEY_CODE, &val);
+
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *code = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+/**
+ * @brief Gets state.
+ * @since_tizen 2.3
+ */
+OAUTH2_API int
+oauth2_response_get_state(oauth2_response_h handle, char **state)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_response_s *response_data_temp = (oauth2_response_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(response_data_temp->response_data,
+ OAUTH2_PARAMETER_KEY_STATE, &val);
+
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *state = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+/**
+ * @brief Gets access token.
+ * @since_tizen 2.3
+ */
+OAUTH2_API int
+oauth2_response_get_access_token(oauth2_response_h handle, char **access_token)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_response_s *response_data_temp = (oauth2_response_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(response_data_temp->response_data,
+ OAUTH2_PARAMETER_KEY_ACCESS_TOKEN, &val);
+
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *access_token = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+/**
+ * @brief Gets token type.
+ * @since_tizen 2.3
+ */
+OAUTH2_API int
+oauth2_response_get_token_type(oauth2_response_h handle, char **token_type)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_response_s *response_data_temp = (oauth2_response_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(response_data_temp->response_data,
+ OAUTH2_PARAMETER_KEY_TOKEN_TYPE, &val);
+
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *token_type = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+/**
+ * @brief Gets expiry time.
+ * @since_tizen 2.3
+ */
+OAUTH2_API int
+oauth2_response_get_expires_in(oauth2_response_h handle,
+ long long int *expires_in)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_response_s *response_data_temp = (oauth2_response_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(response_data_temp->response_data,
+ OAUTH2_PARAMETER_KEY_EXPIRES_IN, &val);
+
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ g_message("oauth2_response_get_expires_in [%s]=[%s]",
+ OAUTH2_PARAMETER_KEY_EXPIRES_IN, val);
+ sscanf(val, "%lld", expires_in);
+ return OAUTH2_ERROR_NONE;
+}
+
+/**
+ * @brief Gets refresh token.
+ * @since_tizen 2.3
+ */
+OAUTH2_API int
+oauth2_response_get_refresh_token(oauth2_response_h handle,
+ char **refresh_token)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_response_s *response_data_temp = (oauth2_response_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(response_data_temp->response_data,
+ OAUTH2_PARAMETER_KEY_REFRESH_TOKEN, &val);
+
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *refresh_token = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+/**
+ * @brief Gets scope.
+ * @since_tizen 2.3
+ */
+OAUTH2_API int
+oauth2_response_get_scope(oauth2_response_h handle, char **scope)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_response_s *response_data_temp = (oauth2_response_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(response_data_temp->response_data,
+ OAUTH2_PARAMETER_KEY_SCOPE, &val);
+
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *scope = val;
+ return OAUTH2_ERROR_NONE;
+}
+
+/**
+ * @brief Gets error.
+ * @see @oauth2_error_h
+ * @since_tizen 2.3
+ */
+OAUTH2_API int
+oauth2_response_get_error(oauth2_response_h handle, oauth2_error_h *error)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "NULL handle");
+
+ oauth2_response_s *response_data_temp = (oauth2_response_s *)handle;
+
+ *error = (oauth2_error_h)response_data_temp->error;
+ return OAUTH2_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the bundle corresponding to the oauth2_response_h handle.
+ * @since_tizen 2.3
+ */
+OAUTH2_API int
+oauth2_response_get_custom_data(oauth2_response_h handle,
+ const char *custom_key, char **custom_value)
+{
+ OAUTH2_RETURN_VAL(handle, {}, OAUTH2_ERROR_INVALID_PARAMETER, "NULL handle");
+
+ oauth2_response_s *response_data_temp = (oauth2_response_s *)handle;
+
+ char *val = NULL;
+ bundle_get_str(response_data_temp->response_data, custom_key, &val);
+ if (!val)
+ return OAUTH2_ERROR_VALUE_NOT_FOUND;
+
+ *custom_value = val;
+ return OAUTH2_ERROR_NONE;
+}
diff --git a/src/oauth2_util.c b/src/oauth2_util.c
new file mode 100644
index 0000000..1bc10bd
--- /dev/null
+++ b/src/oauth2_util.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "oauth2_util.h"
+
+int
+oauth2_util_get_query(const char *url, char **query)
+{
+ OAUTH2_RETURN_VAL(url, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "url is Null");
+ OAUTH2_RETURN_VAL(query, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "query is Null");
+
+ int query_len = 0;
+ char *part = NULL;
+ char *query_end = NULL;
+ char *query_start = strchr(url, '?');
+ if (query_start) {
+ query_start++;
+ query_end = query_start;
+
+ while (*query_end != '\0' && *query_end != '#')
+ query_end++;
+
+ query_len = query_end - query_start;
+ part = (char *) malloc((query_len + 1) * sizeof(char));
+ OAUTH2_RETURN_VAL(part, {}, OAUTH2_ERROR_OUT_OF_MEMORY,
+ "Out of memory");
+ memset(part, '\0', (query_len + 1) * sizeof(char));
+
+ strncpy(part, query_start, query_len);
+ part[query_len] = '\0';
+ }
+ *query = part;
+
+ return OAUTH2_ERROR_NONE;
+}
+
+int
+oauth2_util_get_fragment(const char *url, char **fragment)
+{
+ OAUTH2_RETURN_VAL(url, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "url is Null");
+ OAUTH2_RETURN_VAL(fragment, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "fragment is Null");
+
+ int fragment_len = 0;
+ char *part = NULL;
+ char *fragment_end = NULL;
+ char *fragment_start = strchr(url, '#');
+ if (fragment_start) {
+ fragment_start++;
+ fragment_end = fragment_start;
+
+ while (*fragment_end != '\0')
+ fragment_end++;
+
+ fragment_len = fragment_end - fragment_start;
+ part = (char *) malloc((fragment_len + 1) * sizeof(char));
+ OAUTH2_RETURN_VAL(part, {}, OAUTH2_ERROR_OUT_OF_MEMORY,
+ "Out of memory");
+ memset(part, '\0', (fragment_len + 1) * sizeof(char));
+
+ strncpy(part, fragment_start, fragment_len);
+ part[fragment_len] = '\0';
+ }
+ *fragment = part;
+
+ return OAUTH2_ERROR_NONE;
+}
+
+int
+oauth2_util_get_params(const char *url_part, bundle **params)
+{
+ OAUTH2_RETURN_VAL(url_part, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "url part is Null");
+ OAUTH2_RETURN_VAL(params, {}, OAUTH2_ERROR_INVALID_PARAMETER,
+ "params is Null");
+
+ char *url = (char *) url_part;
+
+ int idx = 0;
+ gchar **pch = g_strsplit_set(url, "&;", -1);
+ while (pch && pch[idx] && strlen(pch[idx])) {
+ char *tmp_start = pch[idx];
+ char *tmp_end = tmp_start;
+ while (*tmp_end != '\0')
+ tmp_end++;
+
+ char *eq_ptr = strchr(tmp_start, '=');
+ int key_size = (eq_ptr - tmp_start) + 1;
+ char *key = (char *) malloc((key_size) * sizeof(char));
+ if (key == NULL) {
+ OAUTH2_LOG_E("Out of memory");
+ return OAUTH2_ERROR_OUT_OF_MEMORY;
+ }
+
+ memset(key, '\0', ((eq_ptr - tmp_start) + 1) * sizeof(char));
+ strncpy(key, tmp_start, (eq_ptr - tmp_start));
+
+ if (eq_ptr != NULL)
+ eq_ptr++;
+
+ key_size = (tmp_end - eq_ptr) + 1;
+ char *val = (char *) malloc((key_size) * sizeof(char));
+ if (val == NULL) {
+ OAUTH2_LOG_E("Out of memory");
+ OAUTH2_FREE(key);
+ return OAUTH2_ERROR_OUT_OF_MEMORY;
+ }
+
+ memset(val, '\0', ((tmp_end - eq_ptr) + 1) * sizeof(char));
+ strncpy(val, eq_ptr, (tmp_end - eq_ptr));
+
+ bundle_add_str(*params, key, val);
+
+ idx++;
+
+ OAUTH2_FREE(key);
+ OAUTH2_FREE(val);
+ }
+
+ return OAUTH2_ERROR_NONE;
+}
diff --git a/src/oauth2_util.h b/src/oauth2_util.h
new file mode 100644
index 0000000..183401a
--- /dev/null
+++ b/src/oauth2_util.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _OAUTH2_UTIL_H_
+#define _OAUTH2_UTIL_H_
+
+#include <stdlib.h>
+#include <bundle.h>
+#include <dlog.h>
+#include <glib.h>
+#include "oauth2_types.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "oauth2"
+
+#ifdef OAUTH2_LOG_E
+#undef OAUTH2_LOG_E
+#endif
+
+#ifdef OAUTH2_LOG_D
+#undef OAUTH2_LOG_D
+#endif
+
+#ifdef OAUTH2_LOG_I
+#undef OAUTH2_LOG_I
+#endif
+
+#define OAUTH2_LOG_E(fmt, args...) LOGE("[%s:%d] "fmt"\n", __func__, \
+ __LINE__, ##args)
+
+#define OAUTH2_LOG_D(fmt, args...) LOGD("[%s:%d] "fmt"\n", __func__, \
+ __LINE__, ##args)
+
+#define OAUTH2_LOG_I(fmt, args...) LOGI("[%s:%d] "fmt"\n", __func__, \
+ __LINE__, ##args)
+
+#define OAUTH2_RETURN_VAL(eval, expr, ret_val, X) \
+ if (!(eval)) { \
+ expr; \
+ OAUTH2_LOG_E(X); \
+ return ret_val; \
+} else {;}
+
+#define OAUTH2_FREE(ptr) \
+ if (ptr != NULL) { \
+ free(ptr); \
+ ptr = NULL; \
+ }
+
+int oauth2_util_get_query(const char *url, char **query);
+int oauth2_util_get_fragment(const char *url, char **fragment);
+int oauth2_util_get_params(const char* url_part, bundle **params);
+
+#endif /* _OAUTH2_UTIL_H_ */