From 8f2a8e23a72d03897eebdccd5213d72d94386e48 Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Mon, 4 Jan 2016 17:37:50 +0100 Subject: [PATCH] Add the refresh-token property --- .../matrix-glib/matrix-glib-sections.txt | 2 + src/matrix-api.c | 53 ++++++++++++++++++ src/matrix-api.h | 9 ++- src/matrix-http-api.c | 55 +++++++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) diff --git a/docs/reference/matrix-glib/matrix-glib-sections.txt b/docs/reference/matrix-glib/matrix-glib-sections.txt index f67ffac..ade3e0e 100644 --- a/docs/reference/matrix-glib/matrix-glib-sections.txt +++ b/docs/reference/matrix-glib/matrix-glib-sections.txt @@ -32,6 +32,8 @@ MatrixAPIReceiptType matrix_api_set_token matrix_api_get_token +matrix_api_set_refresh_token +matrix_api_get_refresh_token matrix_api_media_download diff --git a/src/matrix-api.c b/src/matrix-api.c index 44d03d3..75db2b6 100644 --- a/src/matrix-api.c +++ b/src/matrix-api.c @@ -436,6 +436,21 @@ matrix_api_default_init(MatrixAPIInterface *iface) "The authorization token to use in requests", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * MatrixAPI:refresh-token: + * + * The token to use for refreshing the authorization token. It is + * issued by the server after a successful registration, login, + * and token refresh, but can also be changed with + * matrix_api_set_refresh_token() (or setting this property). + */ + g_object_interface_install_property( + iface, + g_param_spec_string("refresh-token", "Refresh token", + "The token issued by the server for authorization token renewal", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } /* Property getters and setters */ @@ -481,6 +496,44 @@ matrix_api_set_token(MatrixAPI *api, const gchar *token) ->set_token(api, token); } +/** + * matrix_api_get_refresh_token: + * @api: a #MatrixAPI implementation + * + * Get the refresh token currently set. See matrix_api_set_token() for + * limitations. + * + * Returns: (transfer none) (allow-none): the refresh token to be used + * for authorization token refreshment, or %NULL if there is + * none set. The returned value is owned by the @api object + * and should not be freed nor modified + */ +const gchar * +matrix_api_get_refresh_token(MatrixAPI *api) +{ + g_return_if_fail(MATRIX_IS_API(api)); + + return MATRIX_API_GET_IFACE(api) + ->get_refresh_token(api); +} + +/** + * matrix_api_set_refresh_token: + * @api: a #MatrixAPI implementation + * @refresh_token: the refresh token to set + * + * Set the refresh token to be used in subsequent requests. See + * matrix_api_set_token() for limitations. + */ +void +matrix_api_set_refresh_token(MatrixAPI *api, const gchar *refresh_token) +{ + g_return_if_fail(MATRIX_IS_API(api)); + + MATRIX_API_GET_IFACE(api) + ->set_refresh_token(api, refresh_token); +} + /* Media */ /** diff --git a/src/matrix-api.h b/src/matrix-api.h index d5422ca..a8dbe39 100644 --- a/src/matrix-api.h +++ b/src/matrix-api.h @@ -171,6 +171,11 @@ struct _MatrixAPIInterface { const gchar *(*get_token)(MatrixAPI *api); void (*set_token)(MatrixAPI *api, const gchar *token); + const gchar *(*get_refresh_token)(MatrixAPI *api); + void (*set_refresh_token)(MatrixAPI *api, const gchar *refresh_token); + + void *properties_reserved[10]; + /* Media */ void (*media_download)(MatrixAPI *api, MatrixAPICallback callback, @@ -577,8 +582,10 @@ GType matrix_api_get_type(void) G_GNUC_CONST; /* Property getters and setters */ -const gchar *matrix_api_get_token(MatrixAPI *api); void matrix_api_set_token(MatrixAPI *api, const gchar *token); +const gchar *matrix_api_get_token(MatrixAPI *api); +void matrix_api_set_refresh_token(MatrixAPI *api, const gchar *refresh_token); +const gchar *matrix_api_get_refresh_token(MatrixAPI *api); /* API definition */ diff --git a/src/matrix-http-api.c b/src/matrix-http-api.c index 95e287e..90df226 100644 --- a/src/matrix-http-api.c +++ b/src/matrix-http-api.c @@ -52,6 +52,7 @@ typedef struct _MatrixHTTPAPIPrivate { SoupSession *soup_session; SoupURI *uri; gchar *token; + gchar *refresh_token; gboolean validate_certificate; } MatrixHTTPAPIPrivate; @@ -59,6 +60,7 @@ enum { PROP_VALIDATE_CERTIFICATE = 1, PROP_BASE_URL, PROP_TOKEN, + PROP_REFRESH_TOKEN, N_PROPERTIES }; @@ -74,6 +76,8 @@ GParamSpec *obj_properties[N_PROPERTIES] = {NULL,}; static void matrix_http_api_matrix_api_init(MatrixAPIInterface *iface); static void i_set_token(MatrixAPI *api, const gchar *token); static const gchar *i_get_token(MatrixAPI *api); +static void i_set_refresh_token(MatrixAPI *api, const gchar *refresh_token); +static const gchar *i_get_refresh_token(MatrixAPI *api); G_DEFINE_TYPE_WITH_CODE(MatrixHTTPAPI, matrix_http_api, G_TYPE_OBJECT, G_ADD_PRIVATE(MatrixHTTPAPI) @@ -87,6 +91,7 @@ matrix_http_api_finalize(GObject *gobject) MATRIX_HTTP_API(gobject)); g_free(priv->token); + g_free(priv->refresh_token); g_signal_handlers_destroy(gobject); G_OBJECT_CLASS(matrix_http_api_parent_class)->finalize(gobject); @@ -167,6 +172,12 @@ matrix_http_api_set_property(GObject *gobject, break; + case PROP_REFRESH_TOKEN: + i_set_refresh_token(MATRIX_API(api), + g_value_get_string(value)); + + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); } @@ -198,6 +209,11 @@ matrix_http_api_get_property(GObject *gobject, break; + case PROP_REFRESH_TOKEN: + g_value_set_string(value, i_get_refresh_token(MATRIX_API(api))); + + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); } @@ -245,6 +261,9 @@ matrix_http_api_class_init(MatrixHTTPAPIClass *klass) obj_properties[PROP_BASE_URL]); g_object_class_override_property(gobject_class, PROP_TOKEN, "token"); + g_object_class_override_property(gobject_class, + PROP_REFRESH_TOKEN, + "refresh-token"); } static void @@ -254,6 +273,7 @@ matrix_http_api_init(MatrixHTTPAPI *api) priv->uri = NULL; priv->token = NULL; + priv->refresh_token = NULL; priv->validate_certificate = TRUE; priv->soup_session = soup_session_new(); } @@ -295,6 +315,25 @@ i_get_token(MatrixAPI *api) return priv->token; } +static void +i_set_refresh_token(MatrixAPI *api, const gchar *refresh_token) +{ + MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private( + MATRIX_HTTP_API(api)); + + g_free(priv->refresh_token); + priv->token = g_strdup(refresh_token); +} + +static const gchar * +i_get_refresh_token(MatrixAPI *api) +{ + MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private( + MATRIX_HTTP_API(api)); + + return priv->refresh_token; +} + /** * matrix_http_api_set_validate_certificate: * @api: a #MatrixHTTPAPI implementation @@ -376,6 +415,20 @@ _response_callback(SoupSession *session, } } + /* Check if the response holds a refresh token; if it + * does, set it as our new refresh token */ + if ((node = json_object_get_member( + root_object, "refresh_token")) != NULL) { + const gchar *refresh_token; + + if ((refresh_token = json_node_get_string(node)) != NULL) { + g_debug("Got new refresh token: %s", refresh_token); + + i_set_refresh_token(MATRIX_API(api), + refresh_token); + } + } + /* Check if the response holds a homeserver name */ if ((node = json_object_get_member( root_object, "home_server")) != NULL) { @@ -543,5 +596,7 @@ matrix_http_api_matrix_api_init(MatrixAPIInterface *iface) { iface->set_token = i_set_token; iface->get_token = i_get_token; + iface->set_refresh_token = i_set_refresh_token; + iface->get_refresh_token = i_get_refresh_token; iface->login = i_login; }