diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c738164c..acb8e7a6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -104,7 +104,7 @@ vendor/bin/phpcs --standard=web/modules/contrib/apigee_edge/phpcs.xml.dist web/m
git push -u origin patch-2:patch-2
```
-## Running tests
+## Set up environment variables
Before you could start testing this module some environment variables
needs to be set on your system. These variables are:
@@ -124,6 +124,23 @@ You can set these environment variables multiple ways, either by defining them
with `export` or `set` in the terminal or creating a copy of the `core/phpunit.xml.dist`
file as `core/phpunit.xml` and specifying them in that file.
+### Notes for testing using a Hybrid organization
+
+If testing with a Hybrid organization, only the following three environment variables are required:
+
+* `APIGEE_EDGE_INSTANCE_TYPE`: should be `hybrid`.
+* `APIGEE_EDGE_ORGANIZATION`
+* `APIGEE_EDGE_ACCOUNT_JSON_KEY`: the JSON encoded GCP service account key.
+
+If you wish to run tests both against a Public and a Hybrid instance:
+
+1. First configure the credentials to the public org as described above.
+2. Add the `APIGEE_EDGE_ACCOUNT_JSON_KEY` environment variable.
+3. Add a`APIGEE_EDGE_HYBRID_ORGANIZATION` environment variable, which specifies the Hybrid organization to use for tests.
+
+
+## Running tests
+
After you have these environment variables set you can execute tests of this
module with the following command (note the location of the `phpunit` executable
may vary):
diff --git a/README.md b/README.md
index 1afbf207..1bfcd469 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,12 @@ some submodules are marked as "Experimental". They are provided for evaluation a
considered to be in development. Experimental modules are included in the "Apigee (Experimental)" package
on the "Extend" page of a Drupal site (/admin/modules).
+## Support for Apigee Hybrid Cloud: Alpha Release
+
+Support for [Apigee hybrid API](https://docs.apigee.com/hybrid/reference-overview) has been added but is considered to
+be an alpha. If you run into any problems, add an issue to our [GitHub issue queue](https://github.com/apigee/apigee-edge-drupal/issues).
+Please note that Team APIs and Monetization APIs are not currently supported on Apigee hybrid.
+
## Requirements
* The Apigee Edge module requires **Drupal 8.7.x** or higher and PHP 7.1 or higher.
diff --git a/apigee_edge.install b/apigee_edge.install
index d38f4a7c..891e2398 100644
--- a/apigee_edge.install
+++ b/apigee_edge.install
@@ -23,11 +23,9 @@
* Install, update and uninstall functions for Apigee Edge.
*/
-use Drupal\apigee_edge\Plugin\KeyType\ApigeeAuthKeyType;
+use Apigee\Edge\Utility\OrganizationFeatures;
use Drupal\apigee_edge\OauthTokenFileStorage;
-use Drupal\Component\Serialization\Json;
use Drupal\Core\Url;
-use Drupal\key\Plugin\KeyProviderSettableValueInterface;
use Drupal\user\RoleInterface;
/**
@@ -35,6 +33,7 @@ use Drupal\user\RoleInterface;
*/
function apigee_edge_requirements($phase) {
$requirements = [];
+ $hybrid_support_message = t('Support for Apigee hybrid in the Apigee modules is in Alpha. Connecting to a hybrid organization is appropriate for evaluation and testing purposes during this pre-production stage.');
if ($phase === 'install') {
// This should be checked only if Drupal is installed.
@@ -51,12 +50,26 @@ function apigee_edge_requirements($phase) {
];
}
}
+
+ \Drupal::messenger()->addWarning($hybrid_support_message);
}
elseif ($phase === 'runtime') {
/** @var \Drupal\apigee_edge\SDKConnectorInterface $sdk_connector */
$sdk_connector = \Drupal::service('apigee_edge.sdk_connector');
try {
$sdk_connector->testConnection();
+
+ // Hybrid support warning.
+ $org_controller = \Drupal::service('apigee_edge.controller.organization');
+ /* @var \Apigee\Edge\Api\Management\Entity\Organization $organization */
+ $organization = $org_controller->load($sdk_connector->getOrganization());
+ if ($organization && OrganizationFeatures::isHybridEnabled($organization)) {
+ $requirements['apigee_edge_hybrid_support'] = [
+ 'title' => t('Apigee Edge'),
+ 'description' => $hybrid_support_message,
+ 'severity' => REQUIREMENT_WARNING,
+ ];
+ }
}
catch (\Exception $exception) {
$requirements['apigee_edge_connection_error'] = [
@@ -166,15 +179,6 @@ function apigee_edge_update_8001() {
* Update defaults on Apigee Auth Keys.
*/
function apigee_edge_update_8002() {
- $keys = \Drupal::service('key.repository')->getKeys();
- foreach ($keys as $key) {
- /* @var \Drupal\key\Entity\Key $key */
- if ($key->getKeyType() instanceof ApigeeAuthKeyType && $key->getKeyProvider() instanceof KeyProviderSettableValueInterface) {
- $values = $key->getKeyValues();
- $values['endpoint_type'] = $values['endpoint'] ? 'custom' : 'default';
- $values['authorization_server_type'] = $values['authorization_server'] ? 'custom' : 'default';
- $key->setKeyValue(Json::encode($values));
- $key->save();
- }
- }
+ // Empty.
+ // Removed because Hybrid support makes this update hook unneeded.
}
diff --git a/composer.json b/composer.json
index e0e3ec25..423ad320 100644
--- a/composer.json
+++ b/composer.json
@@ -5,7 +5,7 @@
"description": "Apigee Edge for Drupal.",
"require": {
"php": ">=7.1",
- "apigee/apigee-client-php": "^2.0.1",
+ "apigee/apigee-client-php": "^2.0.4",
"cweagans/composer-patches": "^1.6.5",
"drupal/core": "~8.7.0",
"drupal/entity": "^1.0",
diff --git a/modules/apigee_edge_teams/apigee_edge_teams.install b/modules/apigee_edge_teams/apigee_edge_teams.install
new file mode 100644
index 00000000..2310e0ea
--- /dev/null
+++ b/modules/apigee_edge_teams/apigee_edge_teams.install
@@ -0,0 +1,61 @@
+load($sdk_connector->getOrganization());
+ if ($organization && !OrganizationFeatures::isCompaniesFeatureAvailable($organization)) {
+ $url = [
+ ':url' => 'https://docs.apigee.com/hybrid/compare-hybrid-edge#unsupported-apis',
+ ];
+ $message = ($phase == 'runtime') ?
+ t("The Apigee Edge Teams module functionality is not available for your org and should be uninstalled, because Edge company APIs are not supported in Apigee hybrid orgs.", $url) :
+ t("The Apigee Edge Teams module functionality is not available for your org because Edge company APIs are not supported in Apigee hybrid orgs.", $url);
+ $requirements['apigee_edge_teams_not_supported'] = [
+ 'title' => t('Apigee Edge Teams'),
+ 'description' => $message,
+ 'severity' => REQUIREMENT_ERROR,
+ ];
+ }
+ }
+ catch (\Exception $exception) {
+ // Do nothing if connection to Edge is not available.
+ }
+ }
+
+ return $requirements;
+}
diff --git a/src/Connector/HybridAuthentication.php b/src/Connector/HybridAuthentication.php
new file mode 100644
index 00000000..9ef7bbfd
--- /dev/null
+++ b/src/Connector/HybridAuthentication.php
@@ -0,0 +1,41 @@
+buildClient(new NullAuthentication(), $this->getAuthServer());
+ }
+
+}
diff --git a/src/Connector/HybridCredentials.php b/src/Connector/HybridCredentials.php
new file mode 100644
index 00000000..40193227
--- /dev/null
+++ b/src/Connector/HybridCredentials.php
@@ -0,0 +1,54 @@
+getKeyType() instanceof EdgeKeyTypeInterface
+ && ($auth_type = $key->getKeyType()->getAuthenticationType($key))
+ && $auth_type === EdgeKeyTypeInterface::EDGE_AUTH_TYPE_JWT
+ ) {
+ parent::__construct($key);
+ }
+ else {
+ throw new InvalidArgumentException("The `{$key->id()}` key is not configured for Hybrid Authentication.");
+ }
+ }
+
+}
diff --git a/src/Credentials.php b/src/Credentials.php
index 910966c5..ee21acaa 100644
--- a/src/Credentials.php
+++ b/src/Credentials.php
@@ -25,6 +25,8 @@
/**
* The API credentials.
+ *
+ * @todo: move to \Drupal\apigee_edge\Connector namespace.
*/
class Credentials implements CredentialsInterface {
diff --git a/src/CredentialsInterface.php b/src/CredentialsInterface.php
index dd77c256..160b586b 100644
--- a/src/CredentialsInterface.php
+++ b/src/CredentialsInterface.php
@@ -25,6 +25,8 @@
/**
* Defines an interface for credentials classes.
+ *
+ * @todo: move to \Drupal\apigee_edge\Connector namespace.
*/
interface CredentialsInterface {
diff --git a/src/KeyEntityFormEnhancer.php b/src/KeyEntityFormEnhancer.php
index b4d4ff97..2ba0ee95 100644
--- a/src/KeyEntityFormEnhancer.php
+++ b/src/KeyEntityFormEnhancer.php
@@ -21,8 +21,11 @@
namespace Drupal\apigee_edge;
use Apigee\Edge\Exception\ApiRequestException;
+use Apigee\Edge\Exception\HybridOauth2AuthenticationException;
use Apigee\Edge\Exception\OauthAuthenticationException;
use Apigee\Edge\HttpClient\Plugin\Authentication\Oauth;
+use DomainException;
+use Drupal\apigee_edge\Exception\AuthenticationKeyException;
use Drupal\apigee_edge\Exception\InvalidArgumentException;
use Drupal\apigee_edge\Exception\KeyProviderRequirementsException;
use Drupal\apigee_edge\Plugin\EdgeKeyTypeInterface;
@@ -246,9 +249,16 @@ public function alterForm(array &$form, FormStateInterface $form_state): void {
],
'#states' => [
'enabled' => [
- ':input[name="key_input_settings[password]"]' => ['filled' => TRUE],
- ':input[name="key_input_settings[organization]"]' => ['filled' => TRUE],
- ':input[name="key_input_settings[username]"]' => ['filled' => TRUE],
+ [
+ ':input[name="key_input_settings[organization]"]' => ['empty' => FALSE],
+ ':input[name="key_input_settings[password]"]' => ['empty' => FALSE],
+ ':input[name="key_input_settings[username]"]' => ['empty' => FALSE],
+ ],
+ [
+ ':input[name="key_input_settings[instance_type]"]' => ['value' => EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID],
+ ':input[name="key_input_settings[organization]"]' => ['empty' => FALSE],
+ ':input[name="key_input_settings[account_json_key]"]' => ['empty' => FALSE],
+ ],
],
],
];
@@ -326,7 +336,7 @@ public function validateForm(array &$form, FormStateInterface $form_state): void
$test_key_type = $test_key->getKeyType();
$test_auth_type = $test_key_type->getAuthenticationType($test_key);
try {
- if ($test_auth_type === EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH) {
+ if (in_array($test_auth_type, [EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH, EdgeKeyTypeInterface::EDGE_AUTH_TYPE_JWT])) {
// Check the requirements first.
$this->oauthTokenStorage->checkRequirements();
// Clear existing OAuth token data.
@@ -352,7 +362,9 @@ public function validateForm(array &$form, FormStateInterface $form_state): void
// still not clear the submitted value.
// \Drupal\apigee_edge\Plugin\KeyInput\ApigeeAuthKeyInput::buildConfigurationForm()
// does not get called in this case.
- $form['settings']['input_section']['key_input_settings']['password']['#attributes']['value'] = $test_key_type->getPassword($test_key);
+ if ($test_key_type->getInstanceType($test_key) != EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ $form['settings']['input_section']['key_input_settings']['password']['#attributes']['value'] = $test_key_type->getPassword($test_key);
+ }
}
finally {
// Clear Oauth token data that may have been saved during testing
@@ -452,8 +464,29 @@ private function createSuggestion(\Exception $exception, KeyInterface $key): Mar
/** @var \Drupal\apigee_edge\Plugin\KeyType\ApigeeAuthKeyType $key_type */
$key_type = $key->getKeyType();
+ if ($exception instanceof AuthenticationKeyException) {
+ $suggestion = $this->t('@fail_text Verify the Apigee Edge connection settings.', [
+ '@fail_text' => $fail_text,
+ ]);
+ }
+
+ elseif ($exception instanceof HybridOauth2AuthenticationException) {
+ $fail_text = $this->t('Failed to connect to the authorization server.');
+ // General error message.
+ $suggestion = $this->t('@fail_text Check the debug information below for more details.', [
+ '@fail_text' => $fail_text,
+ ]);
+
+ // Invalid key / OpenSSL unable to sign data.
+ if ($exception->getPrevious() && $exception->getPrevious() instanceof DomainException) {
+ $suggestion = $this->t('@fail_text The private key in the GCP service account key JSON is invalid.', [
+ '@fail_text' => $fail_text,
+ ]);
+ }
+ }
+
// Failed to connect to the Oauth authorization server.
- if ($exception instanceof OauthAuthenticationException) {
+ elseif ($exception instanceof OauthAuthenticationException) {
$fail_text = $this->t('Failed to connect to the OAuth authorization server.');
// General error message.
$suggestion = $this->t('@fail_text Check the debug information below for more details.', [
@@ -510,9 +543,8 @@ private function createSuggestion(\Exception $exception, KeyInterface $key): Mar
// the MGMT server returns HTTP 500 with an error instead of HTTP 401.
if ($exception->getCode() === 401 || ($exception->getCode() === 500 && $exception->getEdgeErrorCode() === 'usersandroles.SsoInternalServerError')) {
- // If on public cloud (using the default endpoint), the username should
- // be an email.
- if ($key_type->getEndpointType($key) === EdgeKeyTypeInterface::EDGE_ENDPOINT_TYPE_DEFAULT && !$this->emailValidator->isValid($key_type->getUsername($key))) {
+ // If on public cloud, the username should be an email.
+ if ($key_type->getInstanceType($key) === EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC && !$this->emailValidator->isValid($key_type->getUsername($key))) {
$suggestion = $this->t('@fail_text The organization username should be a valid email.', [
'@fail_text' => $fail_text,
]);
@@ -580,22 +612,27 @@ private function createSuggestion(\Exception $exception, KeyInterface $key): Mar
*/
private function createDebugText(\Exception $exception, KeyInterface $key): string {
$key_type = $key->getKeyType();
-
- $credentials = !($key_type instanceof EdgeKeyTypeInterface) ? [] : [
- 'endpoint' => $key_type->getEndpoint($key),
- 'organization' => $key_type->getOrganization($key),
- 'username' => $key_type->getUsername($key),
- ];
-
+ $credentials = [];
$keys = [
'auth_type' => ($key_type instanceof EdgeKeyTypeInterface) ? $key_type->getAuthenticationType($key) : 'invalid credentials',
'key_provider' => get_class($key->getKeyProvider()),
];
- if (!empty($credentials) && $keys['auth_type'] === EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH) {
- $credentials['authorization_server'] = $key_type->getAuthorizationServer($key);
- $credentials['client_id'] = $key_type->getClientId($key);
- $credentials['client_secret'] = $key_type->getClientSecret($key) === Oauth::DEFAULT_CLIENT_SECRET ? Oauth::DEFAULT_CLIENT_SECRET : '***client-secret***';
+ if ($key_type instanceof EdgeKeyTypeInterface) {
+ $credentials = [
+ 'endpoint' => $key_type->getEndpoint($key),
+ 'organization' => $key_type->getOrganization($key),
+ ];
+
+ if ($key_type->getInstanceType($key) != EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ $credentials['username'] = $key_type->getUsername($key);
+ }
+
+ if ($key_type->getAuthenticationType($key) === EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH) {
+ $credentials['authorization_server'] = $key_type->getAuthorizationServer($key);
+ $credentials['client_id'] = $key_type->getClientId($key);
+ $credentials['client_secret'] = $key_type->getClientSecret($key) === Oauth::DEFAULT_CLIENT_SECRET ? Oauth::DEFAULT_CLIENT_SECRET : '***client-secret***';
+ }
}
// Sanitize exception text.
diff --git a/src/OauthAuthentication.php b/src/OauthAuthentication.php
index 17edb239..48a833c7 100644
--- a/src/OauthAuthentication.php
+++ b/src/OauthAuthentication.php
@@ -26,6 +26,8 @@
/**
* Decorator for OAuth authentication plugin.
+ *
+ * @todo: move to \Drupal\apigee_edge\Connector namespace.
*/
class OauthAuthentication extends Oauth {
@@ -35,7 +37,7 @@ class OauthAuthentication extends Oauth {
protected function authClient(): ClientInterface {
/** @var \Drupal\apigee_edge\SDKConnectorInterface $sdk_connector */
$sdk_connector = \Drupal::service('apigee_edge.sdk_connector');
- return $sdk_connector->buildClient(new BasicAuth($this->clientId, $this->clientSecret), $this->auth_server);
+ return $sdk_connector->buildClient(new BasicAuth($this->clientId, $this->clientSecret), $this->getAuthServer());
}
}
diff --git a/src/OauthCredentials.php b/src/OauthCredentials.php
index c00e79e5..5d1b8ada 100644
--- a/src/OauthCredentials.php
+++ b/src/OauthCredentials.php
@@ -26,6 +26,8 @@
/**
* The API credentials for OAuth.
+ *
+ * @todo: move to \Drupal\apigee_edge\Connector namespace.
*/
class OauthCredentials extends Credentials {
diff --git a/src/OauthTokenFileStorage.php b/src/OauthTokenFileStorage.php
index a38c82fa..7fb6b4c0 100644
--- a/src/OauthTokenFileStorage.php
+++ b/src/OauthTokenFileStorage.php
@@ -26,6 +26,8 @@
/**
* Stores OAuth token data in a file.
+ *
+ * @todo: move to \Drupal\apigee_edge\Connector namespace.
*/
final class OauthTokenFileStorage implements OauthTokenStorageInterface {
diff --git a/src/OauthTokenStorageInterface.php b/src/OauthTokenStorageInterface.php
index 0519d460..682adeea 100644
--- a/src/OauthTokenStorageInterface.php
+++ b/src/OauthTokenStorageInterface.php
@@ -24,6 +24,8 @@
/**
* Base definition of the OAuth token storage service implementations.
+ *
+ * @todo: move to \Drupal\apigee_edge\Connector namespace.
*/
interface OauthTokenStorageInterface extends EdgeOauthTokenStorageInterface {
diff --git a/src/Plugin/EdgeKeyTypeBase.php b/src/Plugin/EdgeKeyTypeBase.php
index f55158d5..acbf789a 100644
--- a/src/Plugin/EdgeKeyTypeBase.php
+++ b/src/Plugin/EdgeKeyTypeBase.php
@@ -20,6 +20,7 @@
namespace Drupal\apigee_edge\Plugin;
use Apigee\Edge\Client;
+use Apigee\Edge\ClientInterface;
use Apigee\Edge\HttpClient\Plugin\Authentication\Oauth;
use Drupal\apigee_edge\Exception\AuthenticationKeyValueMalformedException;
use Drupal\Component\Serialization\Json;
@@ -49,6 +50,10 @@ public function unserialize($value) {
* {@inheritdoc}
*/
public function getAuthenticationType(KeyInterface $key): string {
+ if ($this->getInstanceType($key) === EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ return EdgeKeyTypeInterface::EDGE_AUTH_TYPE_JWT;
+ }
+
if (!isset($key->getKeyValues()['auth_type'])) {
throw new AuthenticationKeyValueMalformedException('auth_type');
}
@@ -59,24 +64,43 @@ public function getAuthenticationType(KeyInterface $key): string {
* {@inheritdoc}
*/
public function getEndpoint(KeyInterface $key): string {
- return $key->getKeyValues()['endpoint'] ?? Client::DEFAULT_ENDPOINT;
+ if ($this->getInstanceType($key) === EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ return ClientInterface::HYBRID_ENDPOINT;
+ }
+ elseif ($this->getInstanceType($key) === EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC) {
+ return Client::DEFAULT_ENDPOINT;
+ }
+ return $key->getKeyValues()['endpoint'];
}
/**
* {@inheritdoc}
*/
public function getEndpointType(KeyInterface $key): string {
- if (isset($key->getKeyValues()['endpoint_type'])) {
- return $key->getKeyValues()['endpoint_type'];
- }
-
- if (empty($key->getKeyValues()['endpoint']) || $key->getKeyValues()['endpoint'] === Client::DEFAULT_ENDPOINT) {
+ if ($this->getInstanceType($key) === EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC) {
return EdgeKeyTypeInterface::EDGE_ENDPOINT_TYPE_DEFAULT;
}
return EdgeKeyTypeInterface::EDGE_ENDPOINT_TYPE_CUSTOM;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getInstanceType(KeyInterface $key): string {
+ $key_values = $key->getKeyValues();
+ if (isset($key_values['instance_type'])) {
+ return $key_values['instance_type'];
+ }
+
+ // Backwards compatibility, before Hybrid support.
+ if (empty($key_values['endpoint']) || $key_values['endpoint'] === ClientInterface::DEFAULT_ENDPOINT) {
+ return EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC;
+ }
+
+ return EdgeKeyTypeInterface::INSTANCE_TYPE_PRIVATE;
+ }
+
/**
* {@inheritdoc}
*/
@@ -128,4 +152,16 @@ public function getClientSecret(KeyInterface $key): string {
return $key->getKeyValues()['client_secret'] ?? Oauth::DEFAULT_CLIENT_SECRET;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getAccountKey(KeyInterface $key): array {
+ $value = $key->getKeyValues()['account_json_key'] ?? '';
+ $json = json_decode($value, TRUE);
+ if (empty($json['private_key']) || empty($json['client_email'])) {
+ throw new AuthenticationKeyValueMalformedException('account_json_key');
+ }
+ return $json;
+ }
+
}
diff --git a/src/Plugin/EdgeKeyTypeInterface.php b/src/Plugin/EdgeKeyTypeInterface.php
index 8e83ded2..aa5c2697 100644
--- a/src/Plugin/EdgeKeyTypeInterface.php
+++ b/src/Plugin/EdgeKeyTypeInterface.php
@@ -27,6 +27,26 @@
*/
interface EdgeKeyTypeInterface extends KeyTypeMultivalueInterface, KeyTypeAuthenticationMethodInterface {
+ /**
+ * Apigee instance on public cloud.
+ *
+ * @var string
+ */
+ public const INSTANCE_TYPE_PUBLIC = 'public';
+
+ /**
+ * Apigee instance on private cloud.
+ *
+ * @var string
+ */
+ public const INSTANCE_TYPE_PRIVATE = 'private';
+
+ /**
+ * Apigee instance on hybrid cloud.
+ *
+ * @var string
+ */
+ public const INSTANCE_TYPE_HYBRID = 'hybrid';
/**
* ID of the basic authentication method.
*
@@ -41,10 +61,22 @@ interface EdgeKeyTypeInterface extends KeyTypeMultivalueInterface, KeyTypeAuthen
*/
const EDGE_AUTH_TYPE_OAUTH = 'oauth';
+ /**
+ * ID of the JWT authentication method.
+ *
+ * @var string
+ */
+ const EDGE_AUTH_TYPE_JWT = 'jwt';
+
/**
* The endpoint type for default.
*
* @var string
+ *
+ * @deprecated Deprecated in apigee_edge:8.x-1.2 and is removed from
+ * apigee_edge:8.x-2.0. Check for endpoint type instead.
+ *
+ * @see EdgeKeyTypeInterface::getEndpointType().
*/
const EDGE_ENDPOINT_TYPE_DEFAULT = 'default';
@@ -52,6 +84,11 @@ interface EdgeKeyTypeInterface extends KeyTypeMultivalueInterface, KeyTypeAuthen
* The endpoint type for custom.
*
* @var string
+ *
+ * @deprecated Deprecated in apigee_edge:8.x-1.2 and is removed from
+ * apigee_edge:8.x-2.0. Check for endpoint type instead.
+ *
+ * @see EdgeKeyTypeInterface::getEndpointType().
*/
const EDGE_ENDPOINT_TYPE_CUSTOM = 'custom';
@@ -77,17 +114,32 @@ public function getAuthenticationType(KeyInterface $key): string;
*/
public function getEndpoint(KeyInterface $key): string;
+ /**
+ * Gets the instance type (public, private or hybrid).
+ *
+ * @param \Drupal\key\KeyInterface $key
+ * The key entity.
+ *
+ * @return string
+ * The instance type, either `public`, `private` or `hybrid`.
+ */
+ public function getInstanceType(KeyInterface $key): string;
+
/**
* Gets the API endpoint type (default or custom).
*
- * If the "endpoint_type" property is empty, it returns "default" if the
- * "endpoint" is empty or the same as the default endpoint.
+ * It returns "default" on a public cloud instance, otherwise "custom".
*
* @param \Drupal\key\KeyInterface $key
* The key entity.
*
* @return string
* The API endpoint type.
+ *
+ * @deprecated Deprecated in apigee_edge:8.x-1.2 and is removed from
+ * apigee_edge:8.x-2.0. Use getInstanceType() instead.
+ *
+ * @see https://github.com/apigee/apigee-edge-drupal/issues/268
*/
public function getEndpointType(KeyInterface $key): string;
@@ -157,4 +209,15 @@ public function getClientId(KeyInterface $key): string;
*/
public function getClientSecret(KeyInterface $key): string;
+ /**
+ * Return the JSON account key decoded as an array.
+ *
+ * @param \Drupal\key\KeyInterface $key
+ * The key entity.
+ *
+ * @return array
+ * The account key as an array.
+ */
+ public function getAccountKey(KeyInterface $key): array;
+
}
diff --git a/src/Plugin/KeyInput/ApigeeAuthKeyInput.php b/src/Plugin/KeyInput/ApigeeAuthKeyInput.php
index 2d430ca2..2f75dc93 100644
--- a/src/Plugin/KeyInput/ApigeeAuthKeyInput.php
+++ b/src/Plugin/KeyInput/ApigeeAuthKeyInput.php
@@ -20,7 +20,6 @@
namespace Drupal\apigee_edge\Plugin\KeyInput;
use Apigee\Edge\HttpClient\Plugin\Authentication\Oauth;
-use Apigee\Edge\ClientInterface;
use Drupal\apigee_edge\Plugin\EdgeKeyTypeInterface;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Form\FormStateInterface;
@@ -63,9 +62,41 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
// Could be an empty array.
$values = Json::decode($key_value);
- $values['endpoint_type'] = empty($values['endpoint']) ? EdgeKeyTypeInterface::EDGE_ENDPOINT_TYPE_DEFAULT : EdgeKeyTypeInterface::EDGE_ENDPOINT_TYPE_CUSTOM;
$values['authorization_server_type'] = empty($values['authorization_server']) ? 'default' : 'custom';
+ $state_for_public = [
+ ':input[name="key_input_settings[instance_type]"]' => ['value' => EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC],
+ ];
+ $state_for_private = [
+ ':input[name="key_input_settings[instance_type]"]' => ['value' => EdgeKeyTypeInterface::INSTANCE_TYPE_PRIVATE],
+ ];
+ $state_for_hybrid = [
+ ':input[name="key_input_settings[instance_type]"]' => ['value' => EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID],
+ ];
+
+ $form['instance_type'] = [
+ '#type' => 'radios',
+ '#title' => $this->t('Apigee instance type'),
+ '#description' => $this->t('Select the Apigee instance type you are connecting to. More information can be found in the Apigee documentation.', [
+ '@link' => 'https://www.drupal.org/docs/8/modules/apigee-edge/configure-the-connection-to-apigee-edge',
+ ]),
+ '#required' => TRUE,
+ '#options' => [
+ EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC => $this->t('Public Cloud'),
+ EdgeKeyTypeInterface::INSTANCE_TYPE_PRIVATE => $this->t('Private Cloud'),
+ EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID => $this->t('Hybrid Cloud'),
+ ],
+ '#default_value' => $values['instance_type'] ?? 'public',
+ ];
+ $form['hybrid_support_info'] = [
+ '#type' => 'fieldset',
+ '#title' => $this->t('Support for Apigee hybrid'),
+ '#description' => $this->t('Support for Apigee hybrid in the Apigee modules is in Alpha. Connecting to a hybrid organization is appropriate for evaluation and testing purposes during this pre-production stage.'),
+
+ '#states' => [
+ 'visible' => $state_for_hybrid,
+ ],
+ ];
$form['auth_type'] = [
'#type' => 'select',
'#title' => $this->t('Authentication type'),
@@ -76,8 +107,11 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
EdgeKeyTypeInterface::EDGE_AUTH_TYPE_BASIC => $this->t('HTTP basic'),
],
'#default_value' => $values['auth_type'] ?? EdgeKeyTypeInterface::EDGE_AUTH_TYPE_BASIC,
+ '#states' => [
+ 'visible' => [$state_for_public, $state_for_private],
+ 'required' => [$state_for_public, $state_for_private],
+ ],
];
-
$form['organization'] = [
'#type' => 'textfield',
'#title' => $this->t('Organization'),
@@ -90,51 +124,50 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
'#type' => 'textfield',
'#title' => $this->t('Username'),
'#description' => $this->t("Apigee user's email address or identity provider username that is used for authenticating with the endpoint."),
- '#required' => TRUE,
'#default_value' => $values['username'] ?? '',
'#attributes' => ['autocomplete' => 'off'],
+ '#states' => [
+ 'visible' => [$state_for_public, $state_for_private],
+ 'required' => [$state_for_public, $state_for_private],
+ ],
];
$form['password'] = [
'#type' => 'password',
'#title' => $this->t('Password'),
'#description' => $this->t("Organization user's password that is used for authenticating with the endpoint."),
- '#required' => TRUE,
'#attributes' => [
'autocomplete' => 'off',
// Password field should not forget the submitted value.
'value' => $values['password'] ?? '',
],
+ '#states' => [
+ 'visible' => [$state_for_public, $state_for_private],
+ 'required' => [$state_for_public, $state_for_private],
+ ],
];
- $form['endpoint_type'] = [
- '#title' => $this->t('Apigee Edge endpoint'),
- '#type' => 'radios',
- '#required' => TRUE,
- '#default_value' => $values['endpoint_type'],
- '#options' => [
- EdgeKeyTypeInterface::EDGE_ENDPOINT_TYPE_DEFAULT => $this->t('Default'),
- EdgeKeyTypeInterface::EDGE_ENDPOINT_TYPE_CUSTOM => $this->t('Custom'),
+ $form['account_json_key'] = [
+ '#type' => 'textarea',
+ '#title' => $this->t('GCP service account key'),
+ '#description' => $this->t("Paste the contents of the GCP service account key JSON file."),
+ '#default_value' => $values['account_json_key'] ?? '',
+ '#rows' => '8',
+ '#states' => [
+ 'visible' => $state_for_hybrid,
+ 'required' => $state_for_hybrid,
],
- '#description' => $this->t('Apigee Edge endpoint where the API calls are being sent. Use the default (%endpoint) when pointing to an organization on Public Cloud, or custom when using Private Cloud.', [
- '%endpoint' => ClientInterface::DEFAULT_ENDPOINT,
- '@link' => 'https://docs.apigee.com/api-platform/get-started/what-apigee-edge#cloudvonprem',
- ]),
];
$form['endpoint'] = [
'#type' => 'textfield',
- '#title' => $this->t('Custom Apigee Edge endpoint'),
- '#description' => $this->t('For a Private Cloud installation, it is in the form: %form_a or %form_b.', [
+ '#title' => $this->t('Apigee Edge endpoint'),
+ '#description' => $this->t('Apigee Edge endpoint where the API calls are being sent. For a Private Cloud installation it is in the form: %form_a or %form_b.', [
'%form_a' => 'http://ms_IP_or_DNS:8080/v1',
'%form_b' => 'https://ms_IP_or_DNS:TLSport/v1',
]),
'#default_value' => $values['endpoint'] ?? '',
'#attributes' => ['autocomplete' => 'off'],
'#states' => [
- 'visible' => [
- ':input[name="key_input_settings[endpoint_type]"]' => ['value' => 'custom'],
- ],
- 'required' => [
- ':input[name="key_input_settings[endpoint_type]"]' => ['value' => 'custom'],
- ],
+ 'visible' => $state_for_private,
+ 'required' => $state_for_private,
],
];
$form['authorization_server_type'] = [
@@ -151,6 +184,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
]),
'#states' => [
'visible' => [
+ [$state_for_public, $state_for_private],
':input[name="key_input_settings[auth_type]"]' => ['value' => EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH],
],
],
@@ -165,10 +199,13 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
'#attributes' => ['autocomplete' => 'off'],
'#states' => [
'visible' => [
+ [$state_for_public, $state_for_private],
':input[name="key_input_settings[auth_type]"]' => ['value' => EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH],
':input[name="key_input_settings[authorization_server_type]"]' => ['value' => 'custom'],
],
'required' => [
+ [$state_for_public, $state_for_private],
+ ':input[name="key_input_settings[auth_type]"]' => ['value' => EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH],
':input[name="key_input_settings[authorization_server_type]"]' => ['value' => 'custom'],
],
],
@@ -183,6 +220,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
'#attributes' => ['autocomplete' => 'off'],
'#states' => [
'visible' => [
+ [$state_for_public, $state_for_private],
':input[name="key_input_settings[auth_type]"]' => ['value' => EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH],
],
],
@@ -197,6 +235,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
'#attributes' => ['autocomplete' => 'off'],
'#states' => [
'visible' => [
+ [$state_for_public, $state_for_private],
':input[name="key_input_settings[auth_type]"]' => ['value' => EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH],
],
],
@@ -210,6 +249,21 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
return $form;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+ $input_values = $form_state->getUserInput()['key_input_settings'];
+
+ if ($input_values['instance_type'] == EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ $account_key = $input_values['account_json_key'] ?? '';
+ $json = json_decode($account_key, TRUE);
+ if (empty($json['private_key']) || empty($json['client_email'])) {
+ $form_state->setErrorByName('key_input_settings][account_json_key', $this->t('GCP service account key JSON file is invalid.'));
+ }
+ }
+ }
+
/**
* {@inheritdoc}
*/
@@ -217,16 +271,37 @@ public function processSubmittedKeyValue(FormStateInterface $form_state) {
// Get input values.
$input_values = $form_state->getValues();
- // Make sure the endpoint defaults are not overridden by other values.
- if (empty($input_values['endpoint_type']) || $input_values['endpoint_type'] == EdgeKeyTypeInterface::EDGE_ENDPOINT_TYPE_DEFAULT) {
- $input_values['endpoint'] = '';
- }
- if (empty($input_values['authorization_server_type']) || $input_values['authorization_server_type'] == 'default') {
- $input_values['authorization_server'] = '';
+ if (!empty($input_values)) {
+ $instance_type = $input_values['instance_type'] ?? NULL;
+
+ // Make sure the endpoint defaults are not overridden by other values.
+ if ($instance_type == EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC) {
+ $input_values['endpoint'] = '';
+ }
+ if (empty($input_values['authorization_server_type']) || $input_values['authorization_server_type'] == 'default') {
+ $input_values['authorization_server'] = '';
+ }
+
+ // Remove unneeded values if on a Hybrid instance.
+ if ($instance_type == EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ $input_values['auth_type'] = '';
+ $input_values['username'] = '';
+ $input_values['password'] = '';
+ $input_values['endpoint'] = '';
+ $input_values['authorization_server_type'] = '';
+ $input_values['authorization_server'] = '';
+ $input_values['client_id'] = '';
+ $input_values['client_secret'] = '';
+ }
+ // Remove unneeded values if on a Public or Private instance.
+ else {
+ $input_values['account_json_key'] = '';
+ }
+
+ // Remove `key_value` so it doesn't get double encoded.
+ unset($input_values['key_value']);
}
- // Remove `key_value` so it doesn't get double encoded.
- unset($input_values['key_value']);
// Reset values to just `key_value`.
$form_state->setValues(['key_value' => Json::encode(array_filter($input_values))]);
return parent::processSubmittedKeyValue($form_state);
diff --git a/src/Plugin/KeyType/ApigeeAuthKeyType.php b/src/Plugin/KeyType/ApigeeAuthKeyType.php
index 4495201e..f7dd5d35 100644
--- a/src/Plugin/KeyType/ApigeeAuthKeyType.php
+++ b/src/Plugin/KeyType/ApigeeAuthKeyType.php
@@ -19,6 +19,7 @@
namespace Drupal\apigee_edge\Plugin\KeyType;
+use Drupal\apigee_edge\Connector\HybridAuthentication;
use Drupal\apigee_edge\OauthAuthentication;
use Drupal\apigee_edge\Plugin\EdgeKeyTypeBase;
use Drupal\apigee_edge\Plugin\EdgeKeyTypeInterface;
@@ -41,9 +42,13 @@
* multivalue = {
* "enabled" = true,
* "fields" = {
+ * "instance_type" = {
+ * "label" = @Translation("Instance type"),
+ * "required" = false
+ * },
* "auth_type" = {
* "label" = @Translation("Authentication type"),
- * "required" = true
+ * "required" = false
* },
* "organization" = {
* "label" = @Translation("Organization"),
@@ -51,11 +56,11 @@
* },
* "username" = {
* "label" = @Translation("Username"),
- * "required" = true
+ * "required" = false
* },
* "password" = {
* "label" = @Translation("Password"),
- * "required" = true
+ * "required" = false
* },
* "endpoint" = {
* "label" = @Translation("Apigee Edge endpoint"),
@@ -72,6 +77,10 @@
* "client_secret" = {
* "label" = @Translation("Client secret"),
* "required" = false
+ * },
+ * "account_json_key" = {
+ * "label" = @Translation("Account JSON key"),
+ * "required" = false
* }
* }
* }
@@ -121,7 +130,13 @@ public function validateKeyValue(array $form, FormStateInterface $form_state, $k
*/
public function getAuthenticationMethod(KeyInterface $key): Authentication {
$values = $key->getKeyValues();
- if ($values['auth_type'] === EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH) {
+
+ if ($this->getInstanceType($key) === EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ $account_key = $this->getAccountKey($key);
+ return new HybridAuthentication($account_key['client_email'], $account_key['private_key'], \Drupal::service('apigee_edge.authentication.oauth_token_storage'));
+ }
+
+ elseif ($values['auth_type'] === EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH) {
// Use Oauth authentication.
return new OauthAuthentication($this->getUsername($key), $this->getPassword($key), \Drupal::service('apigee_edge.authentication.oauth_token_storage'), NULL, $this->getClientId($key), $this->getClientSecret($key), NULL, $this->getAuthorizationServer($key));
}
diff --git a/src/SDKConnector.php b/src/SDKConnector.php
index c383ff00..ce0985ae 100644
--- a/src/SDKConnector.php
+++ b/src/SDKConnector.php
@@ -23,6 +23,7 @@
use Apigee\Edge\Client;
use Apigee\Edge\ClientInterface;
use Apigee\Edge\HttpClient\Utility\Builder;
+use Drupal\apigee_edge\Connector\HybridCredentials;
use Drupal\apigee_edge\Exception\AuthenticationKeyException;
use Drupal\apigee_edge\Exception\AuthenticationKeyNotFoundException;
use Drupal\apigee_edge\Exception\InvalidArgumentException;
@@ -231,7 +232,10 @@ private function setCredentials(CredentialsInterface $credentials) {
private function buildCredentials(KeyInterface $key): CredentialsInterface {
/** @var \Drupal\apigee_edge\Plugin\EdgeKeyTypeInterface $key */
if ($key->getKeyType() instanceof EdgeKeyTypeInterface) {
- if ($key->getKeyType()->getAuthenticationType($key) === EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH) {
+ if ($key->getKeyType()->getInstanceType($key) === EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ return new HybridCredentials($key);
+ }
+ elseif ($key->getKeyType()->getAuthenticationType($key) === EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH) {
return new OauthCredentials($key);
}
return new Credentials($key);
diff --git a/tests/src/FunctionalJavascript/Form/AuthenticationFormJsTest.php b/tests/src/FunctionalJavascript/Form/AuthenticationFormJsTest.php
index 86dc8dc0..15dc6a27 100644
--- a/tests/src/FunctionalJavascript/Form/AuthenticationFormJsTest.php
+++ b/tests/src/FunctionalJavascript/Form/AuthenticationFormJsTest.php
@@ -21,6 +21,7 @@
use Drupal\apigee_edge\Form\AuthenticationForm;
use Drupal\apigee_edge\OauthTokenFileStorage;
+use Drupal\apigee_edge\Plugin\EdgeKeyTypeInterface;
use Drupal\Core\Url;
use Drupal\key\Entity\Key;
use Drupal\Tests\apigee_edge\FunctionalJavascript\ApigeeEdgeFunctionalJavascriptTestBase;
@@ -61,6 +62,20 @@ class AuthenticationFormJsTest extends ApigeeEdgeFunctionalJavascriptTestBase {
*/
private $endpoint;
+ /**
+ * The Apigee instance type.
+ *
+ * @var string
+ */
+ private $instanceType;
+
+ /**
+ * The account JSON key.
+ *
+ * @var string
+ */
+ private $account_key;
+
/**
* {@inheritdoc}
*/
@@ -70,10 +85,17 @@ protected function setUp() {
/** @var \Drupal\apigee_edge\Plugin\EdgeKeyTypeInterface $test_key_type */
$test_key = Key::load($this->config(AuthenticationForm::CONFIG_NAME)->get('active_key'));
$test_key_type = $test_key->getKeyType();
- $this->username = $test_key_type->getUsername($test_key);
- $this->password = $test_key_type->getPassword($test_key);
+ $this->instanceType = $test_key_type->getInstanceType($test_key);
+
$this->organization = $test_key_type->getOrganization($test_key);
- $this->endpoint = $test_key_type->getEndpoint($test_key);
+ if ($this->instanceType != EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ $this->username = $test_key_type->getUsername($test_key);
+ $this->password = $test_key_type->getPassword($test_key);
+ $this->endpoint = $test_key_type->getEndpoint($test_key);
+ }
+ else {
+ $this->account_key = $test_key_type->getAccountKey($test_key);
+ }
// Restore the default HTTP timeout set by the testing module because
// we would like to run a test that tries to connect to an invalid
// endpoint and we should not wait 6 minutes for the result.
@@ -84,6 +106,10 @@ protected function setUp() {
* Tests the Authentication form.
*/
public function testAuthenticationForm() {
+ if ($this->instanceType == EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ $this->markTestSkipped('Skipping "testAuthenticationForm": can only be tested with public/private cloud credentials.');
+ }
+
$web_assert = $this->assertSession();
// Test the authentication form using the default key stored by environment
@@ -102,7 +128,6 @@ public function testAuthenticationForm() {
$web_assert->fieldValueEquals('Organization', $this->organization);
$web_assert->fieldValueEquals('Username', $this->username);
$web_assert->fieldValueEquals('Password', $this->password);
- $web_assert->fieldValueEquals('Custom Apigee Edge endpoint', $this->endpoint);
}
/**
@@ -113,6 +138,10 @@ public function testAuthenticationForm() {
* form is a customized Key edit form.
*/
public function testKeyAddForm() {
+ if ($this->instanceType == EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
+ $this->markTestSkipped('Skipping "testKeyAddForm": can only be tested with public/private cloud credentials.');
+ }
+
$web_assert = $this->assertSession();
// Test the authentication form using the default key stored by environment
@@ -141,6 +170,42 @@ public function testKeyAddForm() {
$this->validateForm([$this, 'visitKeyAddForm']);
}
+ /**
+ * Tests the Authentication form using Hybrid auth.
+ *
+ * @group hybrid
+ */
+ public function testUsingHybridForm() {
+ // We have to structure the key variables so that this test class can
+ // be run both against a Public and Hybrid cloud orgs. Because of this,
+ // if the APIGEE_EDGE_HYBRID_ORGANIZATION environment var is set, it will
+ // use it as the Hybrid org for this test.
+ // Similarly, if the configured key credentials are for a Public/Private
+ // cloud org, then retrieve the account key directly from the environment.
+ $organization = getenv('APIGEE_EDGE_HYBRID_ORGANIZATION') ?: $this->organization;
+ $account_key = $this->account_key ? json_encode($this->account_key) : getenv('APIGEE_EDGE_ACCOUNT_JSON_KEY');
+
+ if (!$organization || !$account_key) {
+ $this->markTestSkipped('Skipping "testUsingHybridForm": missing test environment variables APIGEE_EDGE_HYBRID_ORGANIZATION and/or APIGEE_EDGE_ACCOUNT_JSON_KEY.');
+ }
+
+ $web_assert = $this->assertSession();
+
+ // Test the authentication form.
+ $this->drupalLogin($this->rootUser);
+ $this->drupalGet(Url::fromRoute('entity.key.add_form'));
+ $this->visitKeyAddForm();
+
+ $page = $this->getSession()->getPage();
+
+ $page->selectFieldOption('key_input_settings[instance_type]', EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID);
+ $page->fillField('Organization', $organization);
+ $page->fillField('GCP service account key', $account_key);
+
+ $this->assertSendRequestMessage('.messages--status', 'Connection successful.');
+ $web_assert->elementNotExists('css', 'details[data-drupal-selector="edit-debug"]');
+ }
+
/**
* Visits the Authentication form for testing.
*/
@@ -219,11 +284,10 @@ protected function validateForm(callable $visitFormAsAdmin): void {
$this->assertFalse($this->cssSelect('input[name="key_input_settings[client_secret]"]')[0]->isVisible());
// Test the connection with basic auth.
+ $page->selectFieldOption('key_input_settings[instance_type]', EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC);
$page->fillField('Username', $this->username);
$page->fillField('Password', $this->password);
$page->fillField('Organization', $this->organization);
- $page->selectFieldOption('key_input_settings[endpoint_type]', 'custom');
- $page->fillField('Custom Apigee Edge endpoint', $this->endpoint);
$this->assertSession()->pageTextContains('Send request using the given API credentials.');
$this->assertSendRequestMessage('.messages--status', 'Connection successful.');
$web_assert->elementNotExists('css', 'details[data-drupal-selector="edit-debug"]');
@@ -263,11 +327,10 @@ protected function validateForm(callable $visitFormAsAdmin): void {
// page on success therefore we have to re-visit the form again.
$visitFormAsAdmin();
// Setup valid credentials again.
+ $page->selectFieldOption('key_input_settings[instance_type]', EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC);
$page->fillField('Username', $this->username);
$page->fillField('Password', $this->password);
$page->fillField('Organization', $this->organization);
- $page->selectFieldOption('key_input_settings[endpoint_type]', 'custom');
- $page->fillField('Custom Apigee Edge endpoint', $this->endpoint);
// Test invalid password.
$random_pass = $this->randomString();
@@ -282,8 +345,8 @@ protected function validateForm(callable $visitFormAsAdmin): void {
$web_assert->elementNotContains('css', 'textarea[data-drupal-selector="edit-debug-text"]', $random_pass);
$page->fillField('Password', $this->password);
- // Test invalid username when using default endpoint.
- $page->selectFieldOption('key_input_settings[endpoint_type]', 'default');
+ // Test invalid username when using public cloud endpoint.
+ $page->selectFieldOption('key_input_settings[instance_type]', EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC);
$page->fillField('Username', $this->randomMachineName());
$this->assertSendRequestMessage('.messages--error', "Failed to connect to Apigee Edge. The organization username should be a valid email. Error message: ");
$page->fillField('Username', $this->username);
@@ -297,27 +360,27 @@ protected function validateForm(callable $visitFormAsAdmin): void {
$page->fillField('Organization', $this->organization);
// Test invalid endpoint.
- $page->selectFieldOption('key_input_settings[endpoint_type]', 'custom');
+ $page->selectFieldOption('key_input_settings[instance_type]', EdgeKeyTypeInterface::INSTANCE_TYPE_PRIVATE);
$invalid_domain = "{$this->randomGenerator->word(16)}.example.com";
- $page->fillField('Custom Apigee Edge endpoint', "http://{$invalid_domain}/");
+ $page->fillField('Apigee Edge endpoint', "http://{$invalid_domain}/");
$this->assertSendRequestMessage('.messages--error', "Failed to connect to Apigee Edge. The given endpoint (http://{$invalid_domain}/) is incorrect or something is wrong with the connection. Error message: ");
$web_assert->elementContains('css', 'textarea[data-drupal-selector="edit-debug-text"]', "\"endpoint\": \"http:\/\/{$invalid_domain}\/\"");
- $web_assert->fieldValueEquals('Custom Apigee Edge endpoint', "http://{$invalid_domain}/");
- $page->fillField('Custom Apigee Edge endpoint', '');
- $page->selectFieldOption('key_input_settings[endpoint_type]', 'default');
+ $web_assert->fieldValueEquals('Apigee Edge endpoint', "http://{$invalid_domain}/");
+ $page->fillField('Apigee Edge endpoint', '');
+ $page->selectFieldOption('key_input_settings[instance_type]', EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC);
// Test another invalid endpoint scenario:
// This endpoint is not a Management API endpoint, but still returns
// HTTP 200 with a JSON response.
$invalid_endpoint = 'enterprise.apigee.com/platform/orgname';
- $page->selectFieldOption('key_input_settings[endpoint_type]', 'custom');
+ $page->selectFieldOption('key_input_settings[instance_type]', EdgeKeyTypeInterface::INSTANCE_TYPE_PRIVATE);
$page->fillField('Apigee Edge endpoint', "https://{$invalid_endpoint}/");
$this->assertSendRequestMessage('.messages--error', "Failed to connect to Apigee Edge. The given endpoint (https://{$invalid_endpoint}/) is incorrect or something is wrong with the connection. Error message: ");
$invalid_endpoint_escaped = str_replace('/', '\/', $invalid_endpoint);
$web_assert->elementContains('css', 'textarea[data-drupal-selector="edit-debug-text"]', "\"endpoint\": \"https:\/\/{$invalid_endpoint_escaped}\/\"");
- $web_assert->fieldValueEquals('Custom Apigee Edge endpoint', "https://{$invalid_endpoint}/");
- $page->fillField('Custom Apigee Edge endpoint', '');
- $page->selectFieldOption('key_input_settings[endpoint_type]', 'default');
+ $web_assert->fieldValueEquals('Apigee Edge endpoint', "https://{$invalid_endpoint}/");
+ $page->fillField('Apigee Edge endpoint', '');
+ $page->selectFieldOption('key_input_settings[instance_type]', EdgeKeyTypeInterface::INSTANCE_TYPE_PUBLIC);
// Test invalid authorization server.
$this->cssSelect('select[data-drupal-selector="edit-key-input-settings-auth-type"]')[0]->setValue('oauth');