Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#416] Myapps endpoint toggle password. #434

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apigee_edge.libraries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ apigee_edge.app_view:
css/apigee_edge.app_view.css: {}
js:
js/apigee_edge.app_view.js: {}
dependencies:
- core/jquery
- core/jquery.once
- core/drupal
- core/drupalSettings

apiproduct_access_admin:
version: 1.0
Expand Down
30 changes: 24 additions & 6 deletions apigee_edge.module
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,17 @@ function apigee_edge_field_formatter_info_alter(array &$info) {
*/
function apigee_edge_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
if ($entity instanceof AppInterface) {
if ($build['#view_mode'] === 'full') {
// Add some required assets to an app's full entity view mode.
$build['#attached']['library'][] = 'apigee_edge/apigee_edge.components';
$build['#attached']['library'][] = 'apigee_edge/apigee_edge.app_view';
// Add some required assets to an app's full entity view mode.
$build['#attached']['library'][] = 'apigee_edge/apigee_edge.components';
$build['#attached']['library'][] = 'apigee_edge/apigee_edge.app_view';

if (\Drupal::moduleHandler()->moduleExists('apigee_edge_teams')) {
if ($team = \Drupal::routeMatch()->getParameter('team')) {
$team_app_name = $team->getName();
}
}
if ($user = \Drupal::routeMatch()->getParameter('user')) {
$build['#attached']['drupalSettings']['currentUser'] = $user->id();
}

if ($display->getComponent('credentials')) {
Expand All @@ -379,6 +386,8 @@ function apigee_edge_entity_view(array &$build, EntityInterface $entity, EntityV
$build['credentials'][] = [
'#type' => 'app_credential',
'#credential' => $credential,
'#app_name' => $entity->getName(),
'#team_app_name' => isset($team_app_name) ? $team_app_name : '',
'#attributes' => [
'class' => 'items--inline',
],
Expand Down Expand Up @@ -1013,6 +1022,10 @@ function template_preprocess_app_credential_product_list(array &$variables) {
* Properties used:
* - #credential: A \Apigee\Edge\Api\Management\Entity\AppCredential object.
* A developer app credential.
* - #app_name: string.
* App name.
* - #team_app_name: string.
* Team app name.
* - attributes: HTML attributes for the containing element.
*/
function template_preprocess_app_credential(array &$variables) {
Expand Down Expand Up @@ -1055,10 +1068,15 @@ function template_preprocess_app_credential(array &$variables) {
$variables['primary_wrapper'] = [
'#type' => 'container',
'#attributes' => [
'class' => 'wrapper--primary',
'class' => 'wrapper--primary app-details-wrapper',
'data-app' => $variables['elements']['#app_name'],
],
];

if (!empty($variables['elements']['#team_app_name'])) {
$variables['primary_wrapper']['#attributes']['data-team'] = $variables['elements']['#team_app_name'];
}

foreach ($properties_in_primary as $property => $def) {
$variables['primary_wrapper'][$property] = [
'#type' => 'container',
Expand Down Expand Up @@ -1103,7 +1121,7 @@ function template_preprocess_app_credential(array &$variables) {
'class' => 'secret',
'data-secret-type' => $property,
],
'#value' => Xss::filter($value),
'#value' => '',
];
}
elseif ($def['value_type'] === 'status') {
Expand Down
58 changes: 47 additions & 11 deletions js/apigee_edge.app_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* @file
* Javascript functions related to the Apigee Edge Drupal Module.
*/
(function ($, Drupal) {
(function ($, Drupal, drupalSettings) {

'use strict';

Expand All @@ -32,25 +32,61 @@
Drupal.apigeeEdgeDetails = {
editActions: function (context, settings) {
var secrets = $('.secret', context);
var appElWrapper = '.app-details-wrapper';
var showHideEl = 'a.secret-show-hide';
var pClass = 'processing';
var loader = '<img src="' + drupalSettings.path.baseUrl + 'core/misc/throbber-active.gif" border="0" />';
for (var i = 0; i < secrets.length; i++) {
var secret = secrets[i];
$(secret).addClass('secret-hidden').attr('data-value', $(secret).html()).html('<span>&#149;&#149;&#149;&#149;&#149;&#149;&#149;&#149;<br><a href="#" class="secret-show-hide">' + Drupal.t('Show') + '</a></span>').show();
$(secret)
.addClass('secret-hidden')
.attr('data-value', $(secret).html())
.html('<span>&#149;&#149;&#149;&#149;&#149;&#149;&#149;&#149;<br><a href="#" class="secret-show-hide">' + Drupal.t('Show') + '</a></span>')
.show();
}

$('.item-property', context).on('click', 'a.secret-show-hide', function (event) {
secretToggle(event, $(this).parent().parent());
$('.item-property', context).on('click', showHideEl, function (event) {
event.preventDefault();
var $wrapper = $(this).closest(appElWrapper);
if (!$(this).hasClass(pClass)) {
$(showHideEl).addClass(pClass);
secretToggle(
$(this).parent().parent(),
$wrapper.data('team'),
$wrapper.data('app'),
$wrapper.closest('fieldset').parent().find('fieldset').index($(this).closest('fieldset')),
$wrapper.find(showHideEl).index(this)
);
}
});

function secretToggle(event, secret) {
event.preventDefault();
if ($(secret).hasClass('secret-hidden')) {
$(secret).html(secret.attr('data-value') + '<br><span><a href="#" class="secret-show-hide">' + Drupal.t('Hide') + '</a></span>');
function secretToggle(el, teamAppName, appName, wrapperIndex, keyIndex) {
if ($(el).hasClass('secret-hidden')) {
$(el).html(loader);
callEndpoint(teamAppName, appName, function(data) {
$(el).html(data[wrapperIndex][keyIndex] + '<br><span><a href="#" class="secret-show-hide">' + Drupal.t('Hide') + '</a></span>');
$(showHideEl).removeClass(pClass);
});
}
else {
$(secret).html('<span>&#149;&#149;&#149;&#149;&#149;&#149;&#149;&#149;<br><a href="#" class="secret-show-hide">' + Drupal.t('Show') + '</a></span>');
$(el).html('<span>&#149;&#149;&#149;&#149;&#149;&#149;&#149;&#149;<br><a href="#" class="secret-show-hide">' + Drupal.t('Show') + '</a></span>');
}
$(secret).toggleClass('secret-hidden');
$(el).toggleClass('secret-hidden');
}
}
};
})(jQuery, Drupal);

/**
* Get credentials based on the app name.
*/
function callEndpoint(teamApp, app, callback) {
var endpoint = drupalSettings.path.baseUrl + 'user/' + drupalSettings.currentUser + '/apps/' + app + '/api-keys';
if (teamApp !== undefined) {
endpoint = drupalSettings.path.baseUrl + 'teams/' + teamApp + '/apps/' + app + '/api-keys';
}
$.get(endpoint, function(data) {
callback(data);
});
};

})(jQuery, Drupal, drupalSettings);
52 changes: 52 additions & 0 deletions modules/apigee_edge_teams/src/Controller/TeamAppKeysController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/**
* Copyright 2020 Google Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace Drupal\apigee_edge_teams\Controller;

use Symfony\Component\HttpFoundation\JsonResponse;
use Drupal\apigee_edge\Controller\DeveloperAppKeysController;

/**
* Controller for the team app credentials.
*/
class TeamAppKeysController extends DeveloperAppKeysController {

/**
* Returns app credentials.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* The app credentials.
*/
public function teamAppKeys($team, $app): JsonResponse {
$payload = [];
if ($team) {
$app_storage = $this->entityTypeManager->getStorage('team_app');
$app_ids = $app_storage->getQuery()
->condition('companyName', $team->id())
->condition('name', $app->getName())
->execute();
if (!empty($app_ids)) {
$app_id = reset($app_ids);
$payload = $this->getAppKeys($app_storage->load($app_id));
}
}
return new JsonResponse($payload);
}

}
1 change: 1 addition & 0 deletions modules/apigee_edge_teams/src/Entity/TeamApp.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
* "edit-form" = "/teams/{team}/apps/{app}/edit",
* "delete-form" = "/teams/{team}/apps/{app}/delete",
* "analytics" = "/teams/{team}/apps/{app}/analytics",
* "api-keys" = "/teams/{team}/apps/{app}/api-keys",
* },
* entity_keys = {
* "id" = "appId",
Expand Down
25 changes: 25 additions & 0 deletions modules/apigee_edge_teams/src/Entity/TeamAppRouteProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Drupal\apigee_edge\Entity\AppRouteProvider;
use Drupal\apigee_edge\Entity\AppTitleProvider;
use Drupal\apigee_edge_teams\Entity\ListBuilder\TeamAppListByTeam;
use Drupal\apigee_edge_teams\Controller\TeamAppKeysController;
use Drupal\Core\Entity\EntityTypeInterface;
use Symfony\Component\Routing\Route;

Expand Down Expand Up @@ -53,6 +54,10 @@ public function getRoutes(EntityTypeInterface $entity_type) {
$collection->add("entity.{$entity_type_id}.collection_by_team", $collection_by_team);
}

if ($api_keys = $this->getTeamApiKeysRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.api_keys", $api_keys);
}

return $collection;
}

Expand Down Expand Up @@ -118,6 +123,26 @@ protected function getCollectionRouteByTeam(EntityTypeInterface $entity_type) {
}
}

/**
* Gets APpi Keys for team app.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getTeamApiKeysRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('api-keys')) {
$route = new Route($entity_type->getLinkTemplate('api-keys'));
$route->setDefault('_controller', TeamAppKeysController::class . '::teamAppKeys');
$route->setDefault('_title_callback', AppTitleProvider::class . '::title');
$this->ensureTeamParameter($route);
$route->setRequirement('_app_access_check_by_app_name', 'view');
return $route;
}
}

/**
* Alters routers with {app} and not {team_app}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class AccessTest extends ApigeeEdgeTeamsFunctionalTestBase {
'member.edit',
'member.remove',
],
'team_app_view' => ['canonical', 'collection_by_team'],
'team_app_view' => ['canonical', 'collection_by_team', 'api_keys'],
'team_app_create' => ['add_form_for_team'],
'team_app_update' => ['edit_form'],
'team_app_delete' => ['delete_form'],
Expand Down
98 changes: 98 additions & 0 deletions src/Controller/DeveloperAppKeysController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

/**
* Copyright 2020 Google Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace Drupal\apigee_edge\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
* Controller for the developer app credentials.
*/
class DeveloperAppKeysController extends ControllerBase {

/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;

/**
* DeveloperAppKeysController constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager')
);
}

/**
* Returns app credentials.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* The app credentials.
*/
public function developerAppKeys($user, $app): JsonResponse {
$payload = [];
if ($user) {
if ($developer_id = $user->get('apigee_edge_developer_id')->value) {
$app_storage = $this->entityTypeManager->getStorage('developer_app');
$app_ids = $app_storage->getQuery()
->condition('developerId', $developer_id)
->condition('name', $app->getName())
->execute();
if (!empty($app_ids)) {
$app_id = reset($app_ids);
$payload = $this->getAppKeys($app_storage->load($app_id));
}
}
}
return new JsonResponse($payload);
}

/**
* Get app credentials by app object.
*/
protected function getAppKeys($app) {
$keys = [];
if ($credentials = $app->getCredentials()) {
foreach ($credentials as $item) {
$keys[] = [
$item->getConsumerKey(),
$item->getConsumerSecret(),
];
}
}
return $keys;
}

}
1 change: 1 addition & 0 deletions src/Entity/DeveloperApp.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
* "edit-form-for-developer" = "/user/{user}/apps/{app}/edit",
* "delete-form-for-developer" = "/user/{user}/apps/{app}/delete",
* "analytics-for-developer" = "/user/{user}/apps/{app}/analytics",
* "api-keys" = "/user/{user}/apps/{app}/api-keys",
* },
* entity_keys = {
* "id" = "appId",
Expand Down
Loading