REST/NAMESTORE: rework API
[oweals/gnunet.git] / src / reclaim / plugin_rest_openid_connect.c
index 053aa2f4fb87ce7011252335d80b64eaad66656d..753c3fcae82723352217a14f24a2b0ad8e865a4f 100644 (file)
@@ -221,16 +221,6 @@ static char *OIDC_ignored_parameter_array[] = {"display",
  */
 struct GNUNET_CONTAINER_MultiHashMap *OIDC_cookie_jar_map;
 
-/**
- * OIDC authorized identities and times hashmap
- */
-struct GNUNET_CONTAINER_MultiHashMap *OIDC_identity_grants;
-
-/**
- * OIDC Hash map that keeps track of used authorization code(s)
- */
-struct GNUNET_CONTAINER_MultiHashMap *OIDC_used_ticket_map;
-
 /**
  * Hash map that links the issued access token to the corresponding ticket and
  * ego
@@ -990,6 +980,8 @@ oidc_attr_collect (void *cls,
                                                   attr->type,
                                                   attr->data,
                                                   attr->data_size);
+  le->claim->id = attr->id;
+  le->claim->version = attr->version;
   GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
                                handle->attr_list->list_tail,
                                le);
@@ -1608,9 +1600,9 @@ check_authorization (struct RequestHandle *handle,
   return GNUNET_OK;
 }
 
-static int
-ego_exists (struct RequestHandle *handle,
-            struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
+const struct EgoEntry *
+find_ego (struct RequestHandle *handle,
+          struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
 {
   struct EgoEntry *ego_entry;
   struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
@@ -1620,11 +1612,9 @@ ego_exists (struct RequestHandle *handle,
   {
     GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
     if (0 == GNUNET_memcmp (&pub_key, test_key))
-      break;
+      return ego_entry;
   }
-  if (NULL == ego_entry)
-    return GNUNET_NO;
-  return GNUNET_YES;
+  return NULL;
 }
 
 static void
@@ -1658,10 +1648,12 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
                 void *cls)
 {
   struct RequestHandle *handle = cls;
+  const struct EgoEntry *ego_entry;
   struct GNUNET_TIME_Relative expiration_time;
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *cl;
   struct GNUNET_RECLAIM_Ticket ticket;
   struct GNUNET_CRYPTO_EcdsaPublicKey cid;
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
   struct GNUNET_HashCode cache_key;
   struct MHD_Response *resp;
   char *grant_type;
@@ -1671,7 +1663,6 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
   char *access_token;
   char *jwt_secret;
   char *nonce;
-  int i = 1;
 
   /*
    * Check Authorization
@@ -1693,9 +1684,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
   GNUNET_CRYPTO_hash (OIDC_GRANT_TYPE_KEY,
                       strlen (OIDC_GRANT_TYPE_KEY),
                       &cache_key);
-  if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle
-                                                             ->url_param_map,
-                                                           &cache_key))
+  grant_type = get_url_parameter_copy (handle, OIDC_GRANT_TYPE_KEY);
+  if (NULL == grant_type)
   {
     handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
     handle->edesc = GNUNET_strdup ("missing parameter grant_type");
@@ -1703,64 +1693,37 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  grant_type =
-    GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
-                                       &cache_key);
 
-  // REQUIRED code
-  GNUNET_CRYPTO_hash (OIDC_CODE_KEY, strlen (OIDC_CODE_KEY), &cache_key);
-  if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle
-                                                             ->url_param_map,
-                                                           &cache_key))
+  // Check parameter grant_type == "authorization_code"
+  if (0 != strcmp (OIDC_GRANT_TYPE_VALUE, grant_type))
   {
-    handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
-    handle->edesc = GNUNET_strdup ("missing parameter code");
+    handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE);
     handle->response_code = MHD_HTTP_BAD_REQUEST;
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  code = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
-                                            &cache_key);
 
-  // REQUIRED redirect_uri
-  GNUNET_CRYPTO_hash (OIDC_REDIRECT_URI_KEY,
-                      strlen (OIDC_REDIRECT_URI_KEY),
-                      &cache_key);
-  if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle
-                                                             ->url_param_map,
-                                                           &cache_key))
+  // REQUIRED code
+  code = get_url_parameter_copy (handle, OIDC_CODE_KEY);
+  if (NULL == code)
   {
     handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
-    handle->edesc = GNUNET_strdup ("missing parameter redirect_uri");
-    handle->response_code = MHD_HTTP_BAD_REQUEST;
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
-  }
-
-  // Check parameter grant_type == "authorization_code"
-  if (0 != strcmp (OIDC_GRANT_TYPE_VALUE, grant_type))
-  {
-    handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE);
+    handle->edesc = GNUNET_strdup ("missing parameter code");
     handle->response_code = MHD_HTTP_BAD_REQUEST;
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_CRYPTO_hash (code, strlen (code), &cache_key);
-  if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (
-                         OIDC_used_ticket_map,
-                         &cache_key,
-                         &i,
-                         GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
+  ego_entry = find_ego (handle, &cid);
+  if (NULL == ego_entry)
   {
     handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
-    handle->edesc = GNUNET_strdup ("Cannot use the same code more than once");
+    handle->edesc = GNUNET_strdup ("Unknown client");
     handle->response_code = MHD_HTTP_BAD_REQUEST;
     GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
   }
-
+  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
   // decode code
-  if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, &ticket, &cl, &nonce))
+  if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, &ticket, &cl, &nonce))
   {
     handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
     handle->edesc = GNUNET_strdup ("invalid code");
@@ -1784,13 +1747,6 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
 
 
   // TODO OPTIONAL acr,amr,azp
-  if (GNUNET_NO == ego_exists (handle, &ticket.audience))
-  {
-    handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
-    handle->edesc = GNUNET_strdup ("invalid code...");
-    handle->response_code = MHD_HTTP_BAD_REQUEST;
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-  }
   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
                                                           "reclaim-rest-plugin",
                                                           "jwt_secret",
@@ -1802,7 +1758,6 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  // TODO We should collect the attributes here. cl always empty
   id_token = OIDC_id_token_new (&ticket.audience,
                                 &ticket.identity,
                                 cl,
@@ -1873,9 +1828,8 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
   char *authorization_type;
   char *authorization_access_token;
   struct GNUNET_RECLAIM_Ticket *ticket;
+  const struct EgoEntry *ego_entry;
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
-  struct GNUNET_CRYPTO_EcdsaPublicKey pk;
-
 
   GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY,
                       strlen (OIDC_AUTHORIZATION_HEADER_KEY),
@@ -1934,15 +1888,8 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
   ticket =
     GNUNET_CONTAINER_multihashmap_get (OIDC_access_token_map, &cache_key);
   GNUNET_assert (NULL != ticket);
-
-  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
-       handle->ego_entry = handle->ego_entry->next)
-  {
-    GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &pk);
-    if (0 == GNUNET_memcmp (&pk, &ticket->audience))
-      break; // Found
-  }
-  if (NULL == handle->ego_entry)
+  ego_entry = find_ego (handle, &ticket->audience);
+  if (NULL == ego_entry)
   {
     handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN);
     handle->edesc = GNUNET_strdup ("The access token expired");
@@ -1956,9 +1903,8 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
   handle->oidc->response = json_object ();
   json_object_set_new (handle->oidc->response,
                        "sub",
-                       json_string (handle->ego_entry->keystring));
-  privkey = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
-
+                       json_string (ego_entry->keystring));
+  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
   handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
                                                   privkey,
                                                   ticket,
@@ -2110,10 +2056,6 @@ rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
   handle->oidc = GNUNET_new (struct OIDC_Variables);
   if (NULL == OIDC_cookie_jar_map)
     OIDC_cookie_jar_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
-  if (NULL == OIDC_identity_grants)
-    OIDC_identity_grants = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
-  if (NULL == OIDC_used_ticket_map)
-    OIDC_used_ticket_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
   if (NULL == OIDC_access_token_map)
     OIDC_access_token_map =
       GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
@@ -2166,7 +2108,7 @@ libgnunet_plugin_rest_openid_connect_init (void *cls)
                    MHD_HTTP_METHOD_OPTIONS);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              _ ("Identity Provider REST API initialized\n"));
+              _ ("OpenID Connect REST API initialized\n"));
   return api;
 }
 
@@ -2193,20 +2135,6 @@ libgnunet_plugin_rest_openid_connect_done (void *cls)
     GNUNET_free_non_null (value);
   GNUNET_CONTAINER_multihashmap_destroy (OIDC_cookie_jar_map);
 
-  hashmap_it =
-    GNUNET_CONTAINER_multihashmap_iterator_create (OIDC_identity_grants);
-  while (GNUNET_YES ==
-         GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value))
-    GNUNET_free_non_null (value);
-  GNUNET_CONTAINER_multihashmap_destroy (OIDC_identity_grants);
-
-  hashmap_it =
-    GNUNET_CONTAINER_multihashmap_iterator_create (OIDC_used_ticket_map);
-  while (GNUNET_YES ==
-         GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value))
-    GNUNET_free_non_null (value);
-  GNUNET_CONTAINER_multihashmap_destroy (OIDC_used_ticket_map);
-
   hashmap_it =
     GNUNET_CONTAINER_multihashmap_iterator_create (OIDC_access_token_map);
   while (GNUNET_YES ==
@@ -2217,8 +2145,8 @@ libgnunet_plugin_rest_openid_connect_done (void *cls)
   GNUNET_free_non_null (allow_methods);
   GNUNET_free (api);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Identity Provider REST plugin is finished\n");
+              "OpenID Connect REST plugin is finished\n");
   return NULL;
 }
 
-/* end of plugin_rest_identity_provider.c */
+/* end of plugin_rest_openid_connect.c */