From 9cc0d91f469eae9c40ff0b9242694ad2b3dfd7d5 Mon Sep 17 00:00:00 2001 From: Andy Holmes Date: Tue, 30 Apr 2024 09:53:50 -0700 Subject: [PATCH 1/2] ms_graph: get identity from /v1.0/me Instead of trying to read the user identity from `/v1.0/me/drive`, get it from `/v1.0/me` where it is guaranteed to be the signed in user. See: https://learn.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http#example-2-signed-in-user-request closes #327 --- src/goabackend/goamsgraphprovider.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/goabackend/goamsgraphprovider.c b/src/goabackend/goamsgraphprovider.c index bd32f920..605a6824 100644 --- a/src/goabackend/goamsgraphprovider.c +++ b/src/goabackend/goamsgraphprovider.c @@ -135,17 +135,18 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, { JsonParser *parser = NULL; JsonObject *json_object = NULL; + JsonNode *json_member = NULL; RestProxy *proxy = NULL; RestProxyCall *call = NULL; GError *identity_error = NULL; gchar *authorization = NULL; gchar *presentation_identity = NULL; - gchar *id = NULL; + const char *id = NULL; gchar *ret = NULL; authorization = g_strconcat ("Bearer ", access_token, NULL); - proxy = goa_rest_proxy_new ("https://graph.microsoft.com/v1.0/me/drive", FALSE); + proxy = goa_rest_proxy_new ("https://graph.microsoft.com/v1.0/me", FALSE); call = rest_proxy_new_call (proxy); rest_proxy_call_set_method (call, "GET"); rest_proxy_call_add_header (call, "Authorization", authorization); @@ -182,30 +183,30 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, goto out; } - json_object = json_node_get_object (json_parser_get_root (parser)); - if (!json_object_has_member (json_object, "owner")) + json_member = json_parser_get_root (parser); + if (json_member == NULL || !JSON_NODE_HOLDS_OBJECT (json_member)) { - g_debug ("Did not find owner in JSON data"); + g_debug ("%s(): expected root node to be an object", G_STRFUNC); g_set_error (error, GOA_ERROR, GOA_ERROR_FAILED, _("Could not parse response")); goto out; } + json_object = json_node_get_object (json_member); - json_object = json_object_get_object_member (json_object, "owner"); - if (!json_object_has_member (json_object, "user")) + // Use the "id" field as the "Identity" + json_member = json_object_get_member (json_object, "id"); + if (json_member == NULL || json_node_get_value_type (json_member) != G_TYPE_STRING) { - g_debug ("Did not find user in JSON data"); + g_debug ("%s(): expected \"id\" field holding a string", G_STRFUNC); g_set_error (error, GOA_ERROR, GOA_ERROR_FAILED, _("Could not parse response")); goto out; } - json_object = json_object_get_object_member (json_object, "user"); - - id = g_strdup (json_object_get_string_member (json_object, "id")); + id = json_node_get_string (json_member); if (json_object_has_member (json_object, "email")) { @@ -216,8 +217,7 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, presentation_identity = g_strdup (json_object_get_string_member (json_object, "displayName")); } - ret = id; - id = NULL; + ret = g_strdup (id); if (out_presentation_identity != NULL) { *out_presentation_identity = presentation_identity; @@ -230,7 +230,6 @@ out: g_clear_object (&call); g_clear_object (&proxy); g_free (authorization); - g_free (id); g_free (presentation_identity); return ret; } -- GitLab From b4c8d07bf700718a5aac1da8afa3e16c02087edb Mon Sep 17 00:00:00 2001 From: Andy Holmes Date: Tue, 30 Apr 2024 10:11:29 -0700 Subject: [PATCH 2/2] ms_graph: fix incorrect field name When parsing the response, check for "mail" rather than "email" before falling back to "displayName". Use more caution with value types and print better debug information. --- src/goabackend/goamsgraphprovider.c | 30 +++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/goabackend/goamsgraphprovider.c b/src/goabackend/goamsgraphprovider.c index 605a6824..d55a4ddb 100644 --- a/src/goabackend/goamsgraphprovider.c +++ b/src/goabackend/goamsgraphprovider.c @@ -140,8 +140,8 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, RestProxyCall *call = NULL; GError *identity_error = NULL; gchar *authorization = NULL; - gchar *presentation_identity = NULL; const char *id = NULL; + const char *presentation_identity = NULL; gchar *ret = NULL; authorization = g_strconcat ("Bearer ", access_token, NULL); @@ -208,20 +208,35 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, } id = json_node_get_string (json_member); - if (json_object_has_member (json_object, "email")) + // Prefer "mail" then "displayName" for "PresentationIdentity", failing if neither is available + json_member = json_object_get_member (json_object, "mail"); + if (json_member != NULL && json_node_get_value_type (json_member) == G_TYPE_STRING) { - presentation_identity = g_strdup (json_object_get_string_member (json_object, "email")); + presentation_identity = json_node_get_string (json_member); } - else + + if (presentation_identity == NULL) { - presentation_identity = g_strdup (json_object_get_string_member (json_object, "displayName")); + json_member = json_object_get_member (json_object, "displayName"); + if (json_member != NULL && json_node_get_value_type (json_member) == G_TYPE_STRING) + { + presentation_identity = json_node_get_string (json_member); + } + else + { + g_debug ("%s(): expected \"mail\" or \"displayName\" field holding a string", G_STRFUNC); + g_set_error (error, + GOA_ERROR, + GOA_ERROR_FAILED, + _("Could not parse response")); + goto out; + } } ret = g_strdup (id); if (out_presentation_identity != NULL) { - *out_presentation_identity = presentation_identity; - presentation_identity = NULL; + *out_presentation_identity = g_strdup (presentation_identity); } out: @@ -230,7 +245,6 @@ out: g_clear_object (&call); g_clear_object (&proxy); g_free (authorization); - g_free (presentation_identity); return ret; } -- GitLab