This is an automated email from the ASF dual-hosted git repository. matthiasblaesing pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans-tools.git
The following commit(s) were added to refs/heads/master by this push: new 7509031 Implement OAuth2/OpenID based/inspired login flows new 2a1ed5a Merge pull request #15 from matthiasblaesing/pp3-oauth-login 7509031 is described below commit 7509031320a082243b96c38cf40cd27535c7a7a8 Author: Matthias Bläsing <mblaes...@doppel-helix.eu> AuthorDate: Sat Oct 26 20:40:26 2019 +0200 Implement OAuth2/OpenID based/inspired login flows - Implemented frontend and backend implementation for OAuth2 Code flow (or similar implementations) - Added sample configuration for the currently supported identity providers: GitHub, Google and Amazon. - Don't use email as user id, but introduce user table, that maps authentication to email/name - Add bootstrap configuration, that does not swallow exceptions, but logs them to the Apache error log - Updated composer.json to project data and not generic ZendFrame work information - Removed google sign-in library - Removed image files copied from ZendFramework (unsed) --- pp3/composer.json | 17 +- pp3/config/pp3.sql | 108 ++------ pp3/module/Application/Module.php | 19 +- .../Application/config/module.config.php.dist | 33 ++- .../src/Application/Controller/AdminController.php | 83 ++++-- .../Controller/AuthenticatedController.php | 22 ++ .../src/Application/Controller/BaseController.php | 42 ++- .../src/Application/Controller/IndexController.php | 6 +- .../src/Application/Controller/LoginController.php | 302 ++++++++++++++++++--- .../Application/Controller/PluginController.php | 44 ++- .../Controller/PluginVersionController.php | 11 +- .../Controller/VerificationController.php | 33 ++- .../src/Application/Entity/Base/Plugin.php | 10 +- .../src/Application/Entity/Base/User.php | 134 +++++++++ .../src/Application/Entity/Base/Verification.php | 3 + .../Entity/Base/VerificationRequest.php | 2 +- .../src/Application/Entity/Base/Verifier.php | 50 ---- .../Application/src/Application/Entity/Plugin.php | 7 +- .../Application/Entity/{Verifier.php => User.php} | 4 +- .../src/Application/Entity/Verification.php | 7 +- .../src/Application/Entity/VerificationRequest.php | 5 +- .../Application/Factory/AdminControllerFactory.php | 16 +- .../Application/Factory/LoginControllerFactory.php | 8 +- .../Factory/PluginControllerFactory.php | 8 +- .../Factory/VerificationControllerFactory.php | 8 +- .../Application/src/Application/Pp/Catalog.php | 2 +- .../Application/Repository/NbVersionRepository.php | 5 +- .../Application/Repository/PluginRepository.php | 26 +- .../src/Application/Repository/UserRepository.php | 64 +++++ .../Repository/VerificationRequestRepository.php | 2 +- .../Application/Repository/VerifierRepository.php | 23 -- .../view/application/admin/_plugin-listrow.phtml | 9 +- .../view/application/admin/_pluginRowItem.phtml | 2 +- .../view/application/admin/verifiers.phtml | 83 +++++- .../view/application/index/catalogue.phtml | 2 +- .../Application/view/application/index/index.phtml | 6 +- .../Application/view/application/login/index.phtml | 33 +-- .../view/application/plugin/_plugin-form.phtml | 4 - pp3/module/Application/view/layout/layout.phtml | 48 ++-- .../view/partials/_categories-select.phtml | 2 + pp3/public/img/favicon.ico | Bin 1406 -> 0 bytes pp3/public/img/login/amazon.svg | 30 ++ pp3/public/img/login/github.svg | 30 ++ pp3/public/img/login/google.svg | 30 ++ pp3/public/img/zf2-logo.png | Bin 738 -> 0 bytes pp3/public/js/script.js | 54 ---- pp3/public/scss/style.css | 69 ++--- pp3/public/scss/style.css.map | 14 +- pp3/public/scss/style.scss | 24 ++ 49 files changed, 1026 insertions(+), 518 deletions(-) diff --git a/pp3/composer.json b/pp3/composer.json index 6eb73f0..4cfd5f8 100755 --- a/pp3/composer.json +++ b/pp3/composer.json @@ -1,23 +1,22 @@ { - "name": "zendframework/skeleton-application", - "description": "Skeleton Application for ZF2", + "name": "apache/netbeans-pp3", + "description": "NetBeans Plugin Portal 3", "license": "BSD-3-Clause", "keywords": [ - "framework", - "zf2" + "apache", + "netbeans", + "pluginportal" ], "config": { "discard-changes": true - }, - "homepage": "http://framework.zend.com/", + }, + "homepage": "https://github.com/apache/netbeans-tools/pp3", "require": { "php": ">=5.5", "zendframework/zendframework": "~2.5", "zendframework/zend-developer-tools": "dev-master", "doctrine/doctrine-orm-module": "^0.9.1", "ezyang/htmlpurifier": "^4.10", - "zendframework/zendoauth": "2.0.*", - "knplabs/knp-paginator-bundle": "^3.0", - "google/apiclient": "^2.4" + "knplabs/knp-paginator-bundle": "^3.0" } } diff --git a/pp3/config/pp3.sql b/pp3/config/pp3.sql index 03fdfd9..77b3b1c 100644 --- a/pp3/config/pp3.sql +++ b/pp3/config/pp3.sql @@ -18,15 +18,17 @@ SET time_zone = "+00:00"; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; --- --- Databáze: `pp3` --- - --- -------------------------------------------------------- - --- --- Struktura tabulky `category` --- +CREATE TABLE IF NOT EXISTS `user` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `idp_provider_id` varchar(20) COLLATE utf8_czech_ci NOT NULL, + `idp_user_id` varchar(100) COLLATE utf8_czech_ci NOT NULL, + `email` varchar(255) COLLATE utf8_czech_ci NOT NULL, + `name` varchar(255) COLLATE utf8_czech_ci NOT NULL, + `admin` boolean DEFAULT false NOT NULL, + `verifier` boolean DEFAULT false NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY(idp_provider_id, idp_user_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; CREATE TABLE IF NOT EXISTS `category` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -34,12 +36,6 @@ CREATE TABLE IF NOT EXISTS `category` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; --- -------------------------------------------------------- - --- --- Struktura tabulky `nb_version` --- - CREATE TABLE IF NOT EXISTS `nb_version` ( `id` int(11) NOT NULL AUTO_INCREMENT, `version` varchar(255) COLLATE utf8_czech_ci NOT NULL, @@ -47,32 +43,12 @@ CREATE TABLE IF NOT EXISTS `nb_version` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; --- -------------------------------------------------------- - --- --- Struktura tabulky `nb_version_plugin_version` --- - -CREATE TABLE IF NOT EXISTS `nb_version_plugin_version` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `nb_version_id` int(11) NOT NULL, - `plugin_version_id` int(11) NOT NULL, - `verification_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; - --- -------------------------------------------------------- - --- --- Struktura tabulky `plugin` --- - CREATE TABLE IF NOT EXISTS `plugin` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) COLLATE utf8_czech_ci NOT NULL, `artifactid` varchar(255) COLLATE utf8_czech_ci DEFAULT NULL, `license` varchar(255) COLLATE utf8_czech_ci DEFAULT NULL, - `author` varchar(255) COLLATE utf8_czech_ci DEFAULT NULL, + `author_id` int(11) NOT NULL REFERENCES user(id), `added_at` datetime DEFAULT CURRENT_TIMESTAMP, `last_updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `approved_at` datetime DEFAULT NULL, @@ -89,52 +65,39 @@ CREATE TABLE IF NOT EXISTS `plugin` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; --- -------------------------------------------------------- - --- --- Struktura tabulky `plugin_category` --- - -CREATE TABLE IF NOT EXISTS `plugin_category` ( - `plugin_id` int(11) NOT NULL, - `category_id` int(11) NOT NULL, - PRIMARY KEY (`plugin_id`,`category_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; - --- -------------------------------------------------------- - --- --- Struktura tabulky `plugin_version` --- - CREATE TABLE IF NOT EXISTS `plugin_version` ( `id` int(11) NOT NULL AUTO_INCREMENT, `version` varchar(255) COLLATE utf8_czech_ci NOT NULL, `url` varchar(255) COLLATE utf8_czech_ci DEFAULT NULL, `relnotes` text COLLATE utf8_czech_ci, - `plugin_id` int(11) DEFAULT NULL, + `plugin_id` int(11) NOT NULL REFERENCES plugin(id), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; --- -------------------------------------------------------- - --- --- Struktura tabulky `verification` --- - CREATE TABLE IF NOT EXISTS `verification` ( `id` int(11) NOT NULL AUTO_INCREMENT, `status` int(11) DEFAULT NULL, `created_at` datetime DEFAULT CURRENT_TIMESTAMP, - `plugin_version_id` int(11) DEFAULT NULL, + `plugin_version_id` int(11) NOT NULL REFERENCES plugin_version(id), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; --- -------------------------------------------------------- --- --- Struktura tabulky `verification_request` --- +CREATE TABLE IF NOT EXISTS `nb_version_plugin_version` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `nb_version_id` int(11) NOT NULL REFERENCES nb_version(id), + `plugin_version_id` int(11) NOT NULL REFERENCES plugin_version(id), + `verification_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; + + +CREATE TABLE IF NOT EXISTS `plugin_category` ( + `plugin_id` int(11) NOT NULL REFERENCES plugin(id), + `category_id` int(11) NOT NULL REFERENCES category(id), + PRIMARY KEY (`plugin_id`,`category_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; + CREATE TABLE IF NOT EXISTS `verification_request` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -143,21 +106,10 @@ CREATE TABLE IF NOT EXISTS `verification_request` ( `voted_at` datetime DEFAULT NULL, `comment` text COLLATE utf8_czech_ci, `verification_id` int(11) DEFAULT NULL, - `verifier_id` int(11) DEFAULT NULL, + `verifier_id` int(11) NOT NULL REFERENCES user(id), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; --- -------------------------------------------------------- - --- --- Struktura tabulky `verifier` --- - -CREATE TABLE IF NOT EXISTS `verifier` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` varchar(255) COLLATE utf8_czech_ci DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; COMMIT; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/pp3/module/Application/Module.php b/pp3/module/Application/Module.php index 7021063..7e197da 100755 --- a/pp3/module/Application/Module.php +++ b/pp3/module/Application/Module.php @@ -27,7 +27,24 @@ class Module { 'remember_me_seconds' => 180, 'use_cookies' => true, //'cookie_httponly' => true, - ]); + ]); + + // Why this code is necessary will be the secret of the Zend Developers + // instead of logging, they hide exception and just show meaningless + // error messages + // + //Attach render errors + $eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, function($e) { + if ($e->getParam('exception')) { + error_log($e->getParam('exception')); //Custom error render function. + } + }); + //Attach dispatch errors + $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, function($e) { + if ($e->getParam('exception')) { + error_log($e->getParam('exception')); //Custom error render function. + } + }); } public function getConfig() { diff --git a/pp3/module/Application/config/module.config.php.dist b/pp3/module/Application/config/module.config.php.dist index 13fd914..c0a3c2d 100755 --- a/pp3/module/Application/config/module.config.php.dist +++ b/pp3/module/Application/config/module.config.php.dist @@ -15,13 +15,34 @@ return array( 'mavenRepoUrl' => 'https://repo1.maven.org/maven2/', 'catalogSavepath' => '/home/honza/checkout/pp3/public/data', 'catalogUrlPath' => 'http://localhost/checkout/pp3/public/data', - 'dtdPath' => 'http://localhost/checkout/pp3/public/data/autoupdate-catalog-2_6.dtd', - 'admin' => array( - 'jan.pi...@gmail.com', - 'jiri.koval...@gmail.com' + 'dtdPath' => 'http://localhost/checkout/pp3/public/data/autoupdate-catalog-2_6.dtd' + ), + 'loginConfig' => array ( + array( + 'id' => 'github', + 'name' => 'GitHub', + 'icon' => '/img/login/github.svg', + 'clientId' => 'DO_NOT_COMMIT', + 'clientSecret' => 'DO_NOT_COMMIT', + 'type' => 'github' + ), + array( + 'id' => 'google', + 'name' => 'Google', + 'icon' => '/img/login/google.svg', + 'clientId' => 'DO_NOT_COMMIT', + 'clientSecret' => 'DO_NOT_COMMIT', + 'type' => 'google' ), - 'googleClientId' => '432862904114-ierlf9j6qmmuhtd44ecmlfqivlirq7uc.apps.googleusercontent.com', - ), + array( + 'id' => 'amazon', + 'name' => 'Amazon', + 'icon' => '/img/login/amazon.svg', + 'clientId' => 'DO_NOT_COMMIT', + 'clientSecret' => 'DO_NOT_COMMIT', + 'type' => 'amazon' + ) + ), 'router' => array( 'routes' => array( 'home' => array( diff --git a/pp3/module/Application/src/Application/Controller/AdminController.php b/pp3/module/Application/src/Application/Controller/AdminController.php index 215fbb5..70075cf 100644 --- a/pp3/module/Application/src/Application/Controller/AdminController.php +++ b/pp3/module/Application/src/Application/Controller/AdminController.php @@ -2,43 +2,44 @@ namespace Application\Controller; -use Application\Controller\BaseController; use Zend\View\Model\ViewModel; use Application\Entity\Plugin; -use Zend\Session\Container; use Application\Pp\MavenDataLoader; use Application\Pp\Catalog; -use Application\Entity\Verifier; +use Application\Entity\User; use Application\Entity\NbVersion; use Application\Entity\Category; -use Zend\Mvc\MvcEvent; use HTMLPurifier; use HTMLPurifier_Config; -use Zend\Http\Response; +use Zend\Http\PhpEnvironment\Response; -class AdminController extends BaseController { +class AdminController extends AuthenticatedController { private $_pluginRepository; private $_pluginVersionRepository; private $_nbVersionPluginVersionRepository; private $_verificationRepository; - private $_verifierRepository; private $_verificationRequestRepository; + /** + * @var \Application\Repository\UserRepository + */ + private $_userRepository; private $_nbVersionRepository; private $_categoryRepository; public function __construct($pluginRepository, $nbVersionPluginVersionRepo, $verificationRepo, - $verifierRepository, $verificationRequestRepository, $nbVersionRepository, - $pluginVersionRepository, $config, $categoryRepository) { + $verificationRequestRepository, $nbVersionRepository, + $pluginVersionRepository, $config, $categoryRepository, + $userRepository) { parent::__construct($config); $this->_pluginRepository = $pluginRepository; $this->_pluginVersionRepository = $pluginVersionRepository; $this->_nbVersionPluginVersionRepository = $nbVersionPluginVersionRepo; $this->_verificationRepository = $verificationRepo; - $this->_verifierRepository = $verifierRepository; $this->_verificationRequestRepository = $verificationRequestRepository; $this->_nbVersionRepository = $nbVersionRepository; $this->_categoryRepository = $categoryRepository; + $this->_userRepository = $userRepository; } public function deletePendingAction() { @@ -166,30 +167,58 @@ class AdminController extends BaseController { ]); } + public function searchUserByEmailAction() { + /* @var $response Response */ + $response = $this->getResponse(); + $response->getHeaders()->addHeaderLine("Content-Type", "application/json"); + $email = $this->params()->fromQuery('email'); + $result = array(); + if(! empty($email)) { + foreach($this->_userRepository->findByEmail($email) as $user) { + $result[] = array( + 'id' => $user->getId(), + 'name' => $user->getName(), + 'email' => $user->getEmail(), + 'idpProviderId' => $user->getIdpProviderId(), + 'verifier' => !!$user->isVerifier(), + 'admin' => !!$user->isVerifier() + ); + } + } + $response->setContent(json_encode($result)); + return $response; + } + public function verifiersAction() { $this->_checkAdminUser(); - $req = $this->request; - $id = $this->params()->fromQuery('id'); - if (!empty($id)) { - $verifier = $this->_verifierRepository->find($id); + $removeVerifierStatusId = $this->params()->fromPost('removeVerifierStatusId'); + if (!empty($removeVerifierStatusId)) { + /* @var $verifier User */ + $verifier = $this->_userRepository->find($removeVerifierStatusId); if ($verifier) { - $this->_verifierRepository->remove($verifier);$this->flashMessenger()->setNamespace('success')->addMessage('Verifier '.$verifier->getUserId().' deleted.'); + $verifier->setVerifier(false); + $this->_userRepository->persist($verifier); + $this->flashMessenger()->setNamespace('success')->addMessage('Verifier '.$verifier->getName().' removed.'); return $this->redirect()->toRoute('admin', array( 'action' => 'verifiers' )); } } - if ($req->isPost() && $this->params()->fromPost('userId')) { - $verifier = new Verifier(); - $verifier->setUserId($this->params()->fromPost('userId')); - $this->_verifierRepository->persist($verifier); - $this->flashMessenger()->setNamespace('success')->addMessage('Verifier '.$verifier->getUserId().' added.'); + $addVerifierStatusId = $this->params()->fromPost('addVerifierStatusId'); + if (!empty($addVerifierStatusId)) { + /* @var $verifier User */ + $verifier = $this->_userRepository->find($addVerifierStatusId); + if ($verifier) { + $verifier->setVerifier(true); + $this->_userRepository->persist($verifier); + $this->flashMessenger()->setNamespace('success')->addMessage('Verifier '.$verifier->getName().' added.'); return $this->redirect()->toRoute('admin', array( 'action' => 'verifiers' )); + } } return new ViewModel([ - 'verifiers' => $this->_verifierRepository->findAll() + 'verifiers' => $this->_userRepository->findVerifier() ]); } @@ -301,7 +330,7 @@ class AdminController extends BaseController { } private function _checkAdminUser() { - if (!$this->_isAdmin) { + if (!$this->isAdmin()) { return $this->redirect()->toRoute('plugin', array( 'action' => 'index' )); @@ -318,7 +347,6 @@ class AdminController extends BaseController { $req = $this->request; if ($req->isPost()) { $validatedData = $this->_validateAndCleanPluginData( - $this->params()->fromPost('author'), $this->params()->fromPost('name'), $this->params()->fromPost('license'), $this->params()->fromPost('description'), @@ -326,7 +354,6 @@ class AdminController extends BaseController { $this->params()->fromPost('category') ); if ($validatedData) { - $plugin->setAuthor($validatedData['author']); $plugin->setName($validatedData['name']); $plugin->setLicense($validatedData['license']); $plugin->setDescription($validatedData['description']); @@ -359,7 +386,7 @@ class AdminController extends BaseController { $this->_pluginRepository->persist($plugin); $this->flashMessenger()->setNamespace('success')->addMessage('Plugin updated.'); } else { - $this->flashMessenger()->setNamespace('error')->addMessage('Missing required data or Author email not in correct format.'); + $this->flashMessenger()->setNamespace('error')->addMessage('Missing required data.'); } return $this->redirect()->toUrl('./edit?id='.$plugin->getId()); } @@ -370,15 +397,13 @@ class AdminController extends BaseController { )); } - private function _validateAndCleanPluginData($author, $name, $license, $description, $shortDescription, $category) { - if (empty($author) || empty($name) || empty($license) || empty($category) || empty($shortDescription) - || !filter_var($author, FILTER_VALIDATE_EMAIL)) { + private function _validateAndCleanPluginData($name, $license, $description, $shortDescription, $category) { + if (empty($name) || empty($license) || empty($category) || empty($shortDescription)) { return false; } $config = HTMLPurifier_Config::createDefault(); $purifier = new HTMLPurifier($config); return array( - 'author' => $purifier->purify($author), 'name' => $purifier->purify($name), 'license' => $purifier->purify($license), 'description' => $purifier->purify($description), diff --git a/pp3/module/Application/src/Application/Controller/AuthenticatedController.php b/pp3/module/Application/src/Application/Controller/AuthenticatedController.php new file mode 100644 index 0000000..04937e2 --- /dev/null +++ b/pp3/module/Application/src/Application/Controller/AuthenticatedController.php @@ -0,0 +1,22 @@ +<?php + +namespace Application\Controller; + +use Zend\Mvc\MvcEvent; + +class AuthenticatedController extends BaseController { + + function __construct($config) { + parent::__construct($config); + } + + + public function onDispatch(MvcEvent $e) { + if (!$this->isAuthenticated()) { + return $this->redirect()->toRoute('home', array( + 'action' => 'index' + )); + } + return parent::onDispatch($e); + } +} diff --git a/pp3/module/Application/src/Application/Controller/BaseController.php b/pp3/module/Application/src/Application/Controller/BaseController.php index 3ea84e1..b2a116e 100644 --- a/pp3/module/Application/src/Application/Controller/BaseController.php +++ b/pp3/module/Application/src/Application/Controller/BaseController.php @@ -14,7 +14,6 @@ class BaseController extends AbstractActionController { protected $_session; protected $_config; protected $_isAdmin; - protected $_sessionUserId; public function __construct($config) { $this->_config = $config; @@ -22,23 +21,40 @@ class BaseController extends AbstractActionController { } public function onDispatch(MvcEvent $e) { - if (!$this->isAuthenticated()) { - return $this->redirect()->toRoute('home', array( - 'action' => 'index' - )); + $idp = null; + $idpProviderId = array_key_exists('sessionIdpProviderId', $_SESSION) ? $_SESSION['sessionIdpProviderId'] : false; + if($idpProviderId) { + foreach($this->_config['loginConfig'] as $lc) { + if($lc['id'] === $idpProviderId) { + $idp = $lc['name']; + break; + } + } } - $this->_sessionUserId = $_SESSION['sessionUserId']; - $this->layout()->setVariable('sessionUserId', $this->_sessionUserId); - $this->isAdmin(); + + $this->layout()->setVariable('sessionUserId', array_key_exists('sessionUserId', $_SESSION) ? $_SESSION['sessionUserId'] : null); + $this->layout()->setVariable('sessionUserName', array_key_exists('sessionUserName', $_SESSION) ? $_SESSION['sessionUserName'] : null); + $this->layout()->setVariable('sessionIdp', $idp); + $this->layout()->setVariable('sessionUserEmail', array_key_exists('sessionUserEmail', $_SESSION) ? $_SESSION['sessionUserEmail'] : false); + $this->layout()->setVariable('isAdmin', $this->isAdmin()); + $this->layout()->setVariable('isAuthenticated', $this->isAuthenticated()); + $this->layout()->setVariable('isVerifier', $this->isVerifier()); return parent::onDispatch($e); } - private function isAuthenticated() { + protected function isAdmin() { + return array_key_exists('isAdmin', $_SESSION) && $_SESSION['isAdmin']; + } + + protected function isAuthenticated() { return !empty($_SESSION['sessionUserId']); } - - private function isAdmin() { - $this->_isAdmin = $_SESSION['isAdmin']; - $this->layout()->setVariable('isAdmin', $this->_isAdmin); + + protected function isVerifier() { + return array_key_exists('isVerifier', $_SESSION) && $_SESSION['isVerifier']; + } + + protected function getAuthenticatedUserId() { + return empty($_SESSION['sessionUserId']) ? false : $_SESSION['sessionUserId']; } } \ No newline at end of file diff --git a/pp3/module/Application/src/Application/Controller/IndexController.php b/pp3/module/Application/src/Application/Controller/IndexController.php index 9397657..182f59b 100755 --- a/pp3/module/Application/src/Application/Controller/IndexController.php +++ b/pp3/module/Application/src/Application/Controller/IndexController.php @@ -2,23 +2,21 @@ namespace Application\Controller; -use Zend\Mvc\Controller\AbstractActionController; use Knp\Component\Pager\PaginatorInterface; use Zend\View\Model\ViewModel; use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as DoctrineAdapter; use Doctrine\ORM\Tools\Pagination\Paginator as ORMPaginator; use Zend\Paginator\Paginator; -class IndexController extends AbstractActionController { +class IndexController extends BaseController { - private $_config; private $_pluginRepository; private $_paginator; private $_categoryRepository; private $_nbVersionRepository; public function __construct($pluginRepo, $config, PaginatorInterface $paginator, $nbVersionRepository, $categoryRepository, $pvRepo) { - $this->_config = $config; + parent::__construct($config); $this->_pluginRepository = $pluginRepo; $this->_paginator = $paginator; $this->_nbVersionRepository = $nbVersionRepository; diff --git a/pp3/module/Application/src/Application/Controller/LoginController.php b/pp3/module/Application/src/Application/Controller/LoginController.php index 52ce609..c53cd2a 100644 --- a/pp3/module/Application/src/Application/Controller/LoginController.php +++ b/pp3/module/Application/src/Application/Controller/LoginController.php @@ -1,71 +1,285 @@ <?php - namespace Application\Controller; -use Zend\Mvc\Controller\AbstractActionController; -use Zend\View\Model\ViewModel; use Zend\Session\Container; -// use \Google\Apiclient\Client; +use Application\Entity\User; +use Zend\View\Model\ViewModel; -class LoginController extends AbstractActionController { +class LoginController extends BaseController { - private $_config; - private $_session; - private $_verifierRepository; + /** + * @var \Application\Repository\UserRepository + */ + private $_userRepository; - public function __construct($config, $verifierRepository) { - $this->_config = $config; + public function __construct($config, $userRepository) { + parent::__construct($config); $this->_session = new Container(); - $this->_verifierRepository = $verifierRepository; + $this->_userRepository = $userRepository; + } + + public function indexAction() { + $providers = array(); + foreach($this->_config['loginConfig'] as $loginConfig) { + $iconUrl = $loginConfig['icon']; + if(strpos($iconUrl, '/') === 0) { + $iconUrl = $this->url()->fromRoute("home", array(), array('force_canonical'=>true)) . substr($iconUrl, 1); + } + $loginUrl = $this->url()->fromRoute('login', array('action' => 'login-start'), array('force_canonical'=>true)); + $loginUrl .= '?'; + $loginUrl .= http_build_query(array('id' => $loginConfig['id'])); + $providers[] = array( + 'id' => $loginConfig['id'], + 'name' => $loginConfig['name'], + 'iconUrl' => $iconUrl, + 'loginUrl' => $loginUrl + ); + } + return new ViewModel([ + 'providers' => $providers + ]); + } + + private function findLoginConfig(string $id) { + if(! $id) { + return null; + } + foreach($this->_config['loginConfig'] as $loginConfig) { + if($loginConfig['id'] === $id) { + return $loginConfig; + } + } + return null; + } + + public function loginStartAction() { + $loginConfig = $this->findLoginConfig($this->params()->fromQuery('id')); + if (!$loginConfig) { + $response = $this->getResponse(); + $response->setStatusCode(404); + $response->setContent("Unknown authentication provider"); + return $response; + } + + $stateBytes = random_bytes(64); + $state = bin2hex($stateBytes); + $_SESSION['oauthState'] = $state; + $_SESSION['oauthConfig'] = $loginConfig['id']; + $scopeData = self::scopesFromType($loginConfig['type']); + $queryData = array( + 'client_id' => $loginConfig['clientId'], + 'state' => $state, + 'response_type' => 'code', + 'redirect_uri' => $this->redirectUrl() + ); + if($scopeData) { + $queryData['scope'] = $scopeData; + } + $url = self::authenticationUrlFromType($loginConfig['type']); + $url .= '?'; + $url .= http_build_query($queryData); + return $this->redirect()->toUrl($url); } - - public function onGoogleSignInAjaxAction() { + + public function callbackAction() { $response = $this->getResponse(); - // user info passed from Google auth - $req = $this->request; - if($_SESSION['sessionUserId']) { - $response->setContent(''); - } else { - if ($req->isPost()) { - $client = new \Google_Client(['client_id' => $this->_config['pp3']['googleClientId']]); // Specify the CLIENT_ID of the app that accesses the backend - $idToken = $this->params()->fromPost('idtoken'); - $payload = $client->verifyIdToken($idToken); - if ($payload) { - $email = $payload['email']; - $_SESSION['sessionUserId'] = $email; - $_SESSION['sessionUserEmail'] = $email; - $this->checkVerifier($email); - $this->checkAdmin($email); - $response->setContent('reload'); - } else { - // Invalid ID token - $response->setContent('Failure'); + $response->getHeaders()->addHeaderLine('Content-Type', 'application/json'); + + $parameters = $this->params()->fromQuery(); + $state = $this->params()->fromQuery('state'); + $code = $this->params()->fromQuery('code'); + + if((!array_key_exists('oauthState', $_SESSION)) || $_SESSION['oauthState'] != $state) { + error_log('Invalid / no state was transfered - received: ' . json_encode($parameters)); + $response->setStatusCode(400); + $response->setContent(json_encode(array('success' => false, 'reason' => 'INVALID_STATE'))); + return $response; + } + + $loginConfig = $this->findLoginConfig($_SESSION['oauthConfig']); + + if (!$loginConfig) { + error_log("Login Config was not found for: " . $_SESSION['oauthConfig'] . " received: " . json_encode($parameters)); + $response->setStatusCode(400); + $response->setContent(json_encode(array('success' => false, 'reason' => 'INVALID_LOGIN_CONFIG'))); + return $response; + } + + $tokenRequest = self::tokenRequest($code, $loginConfig); + $queryTokenResult = file_get_contents(self::tokenUrlFromType($loginConfig['type']), false, stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => ["Content-type: application/json", "Accept: application/json"], + 'content' => json_encode($tokenRequest) + ] + ])); + + if(!$queryTokenResult) { + error_log("Empty response"); + $response->setStatusCode(500); + $response->setContent(json_encode(array('success' => false, 'reason' => 'INVALID_TOKEN'))); + return $response; + } + + $tokenData = json_decode($queryTokenResult, true); + + if((! $tokenData) || (! $tokenData['access_token']) || (strtolower($tokenData['token_type']) != 'bearer')) { + error_log("Failed to decode token data: " . $queryTokenResult); + $response->setStatusCode(500); + $response->setContent(json_encode(array('success' => false, 'reason' => 'INVALID_TOKEN'))); + return $response; + } + + $queryProfileResult = file_get_contents(self::profileUrlFromType($loginConfig['type']), false, stream_context_create([ + 'http' => [ + 'header' => ['Accept: application/json', 'Authorization: Bearer ' . $tokenData['access_token'], 'User-Agent: Netbeans Plugin Portal'], + "ignore_errors" => true, + ] + ])); + + $userinfo = $this->extractUserInfo($loginConfig['type'], $loginConfig['id'], $queryProfileResult); + + if($userinfo == null) { + error_log("Failed to parse: " . $queryProfileResult); + $response->setStatusCode(500); + $response->setContent(json_encode(array('success' => false, 'reason' => 'INVALID_USERINFO'))); + return $response; + } + + if(!$userinfo['email']) { + $emailQueryUrl = self::emailQueryUrl($loginConfig['type']); + if ($emailQueryUrl) { + $queryEmailResult = file_get_contents($emailQueryUrl, false, stream_context_create([ + 'http' => [ + 'header' => ['Accept: application/json', 'Authorization: Bearer ' . $tokenData['access_token'], 'User-Agent: Netbeans Plugin Portal'], + "ignore_errors" => true, + ] + ])); + $queryEmail = json_decode($queryEmailResult, true); + foreach($queryEmail as $emailInfo) { + if(array_key_exists('email', $emailInfo) && $emailInfo['email']) { + $userinfo['email'] = $emailInfo['email']; + break; + } } } + + if (!$userinfo['email']) { + error_log("Userinfo did not contain email"); + $response->setStatusCode(500); + $response->setContent(json_encode(array('success' => false, 'reason' => 'NO_EMAIL'))); + return $response; + } + } + + $user = $this->_userRepository->findByIdpData($userinfo['providerId'], $userinfo['id']); + if($user == null) { + $user = new User(); } - return $response; + + $user->setEmail($userinfo['email']); + $user->setIdpProviderId($userinfo['providerId']); + $user->setIdpUserId($userinfo['id']); + $user->setName($userinfo['name']); + $this->_userRepository->persist($user); + + $_SESSION['sessionUserId'] = $user->getId(); + $_SESSION['sessionUserEmail'] = $user->getEmail(); + $_SESSION['sessionIdpProviderId'] = $user->getIdpProviderId(); + $_SESSION['sessionUserName'] = $user->getName(); + $_SESSION['isVerifier'] = $user->isVerifier(); + $_SESSION['isAdmin'] = $user->isAdmin(); + + return $this->redirect()->toRoute("home"); + } + + private function redirectUrl() { + return $this->url()->fromRoute("login", array("action" => "callback"), array('force_canonical'=>true)); } - public function onGoogleSignOutAjaxAction() { + public function logoutAction() { $_SESSION['sessionUserId'] = null; $_SESSION['sessionUserEmail'] = null; + $_SESSION['sessionIdpProviderId'] = null; + $_SESSION['sessionUserName'] = null; $_SESSION['isVerifier'] = null; $_SESSION['isAdmin'] = null; - die(); + $response = $this->getResponse(); + return $this->redirect()->toRoute("home"); } - private function checkVerifier($userId) { - if (!empty($userId)) { - $verifier = $this->_verifierRepository->findOneBy('user_id', $userId); - if ($verifier) { - $_SESSION['isVerifier'] = true; - } + private static function authenticationUrlFromType($type) { + switch ($type) { + case 'github': return 'https://github.com/login/oauth/authorize'; + case 'google': return 'https://accounts.google.com/o/oauth2/v2/auth'; + case 'amazon': return 'https://www.amazon.com/ap/oa'; + } + } + + private static function tokenUrlFromType($type) { + switch ($type) { + case 'github': return 'https://github.com/login/oauth/access_token'; + case 'google': return 'https://oauth2.googleapis.com/token'; + case 'amazon': return 'https://api.amazon.com/auth/o2/token'; + } + } + + private static function profileUrlFromType($type) { + switch ($type) { + case 'github': return 'https://api.github.com/user'; + case 'google': return 'https://openidconnect.googleapis.com/v1/userinfo'; + case 'amazon': return 'https://api.amazon.com/user/profile'; + } + } + + private static function emailQueryUrl($type) { + switch($type) { + case 'github': return 'https://api.github.com/user/emails'; + default: return false; + } + } + + private static function scopesFromType($type) { + switch ($type) { + case 'github': return 'user:email'; + case 'google': return 'openid email profile'; + case 'amazon': return 'profile'; + } + } + + private function tokenRequest( $code, $loginConfig) { + $data = array('code' => $code, 'client_id' => $loginConfig['clientId'], 'client_secret' => $loginConfig['clientSecret']); + if($loginConfig['type'] != 'github') { + $data['redirect_uri'] = $this->redirectUrl(); + $data['grant_type'] = 'authorization_code'; } + return $data; } - private function checkAdmin($userId) { - $admins = $this->_config['pp3']['admin']; - $_SESSION['isAdmin'] = in_array($userId, $admins); + private function extractUserInfo($type, $providerId, $data) { + if(! $data) { + return null; + } + $json = json_decode($data, true); + if(! $json) { + return null; + } + $userinfo = array(); + $userinfo['providerId'] = $providerId; + if($type == 'github') { + $userinfo['id'] = "" . $json['id']; + $userinfo['email'] = "" . $json['email']; + $userinfo['name'] = "" . $json['name']; + } else if ($type == 'google') { + $userinfo['id'] = "" . $json['sub']; + $userinfo['email'] = "" . $json['email']; + $userinfo['name'] = "" . $json['name']; + } else if ($type == 'amazon') { + $userinfo['id'] = "" . $json['user_id']; + $userinfo['email'] = "" . $json['email']; + $userinfo['name'] = "" . $json['name']; + } + return $userinfo; } } diff --git a/pp3/module/Application/src/Application/Controller/PluginController.php b/pp3/module/Application/src/Application/Controller/PluginController.php index 8e03082..735cb14 100644 --- a/pp3/module/Application/src/Application/Controller/PluginController.php +++ b/pp3/module/Application/src/Application/Controller/PluginController.php @@ -2,7 +2,6 @@ namespace Application\Controller; -use Application\Controller\BaseController; use Zend\View\Model\ViewModel; use Zend\Session\Container; use Application\Pp\MavenDataLoader; @@ -15,28 +14,31 @@ use HTMLPurifier_Config; define('PLUGIN_SESSION_NAMESPACE', 'pp3_plugin_session'); -class PluginController extends BaseController { +class PluginController extends AuthenticatedController { private $_pluginRepository; private $_pluginVersionRepository; private $_categoryRepository; - private $_verifierRepository; private $_nbVersionRepository; + /** + * @var \Application\Repository\UserRepository + */ + private $_userRepository; - public function __construct($pluginRepo, $pvRepo, $categRepository, $config, $verifierRepository, $nbVersionRepository) { + public function __construct($pluginRepo, $pvRepo, $categRepository, $config, $nbVersionRepository, $userRepository) { parent::__construct($config); $this->_pluginRepository = $pluginRepo; $this->_pluginVersionRepository = $pvRepo; $this->_categoryRepository = $categRepository; - $this->_verifierRepository = $verifierRepository; $this->_nbVersionRepository = $nbVersionRepository; + $this->_userRepository = $userRepository; } public function syncAction() { $pId = $this->params()->fromQuery('id'); $plugin = $this->_pluginRepository->find($pId); $plugin->setDataLoader(new MavenDataLoader()); - if (!$plugin->isOwnedBy($this->_sessionUserId)) { + if (!$plugin->isOwnedBy($this->getAuthenticatedUserId())) { return $this->redirect()->toRoute('plugin', array( 'action' => 'list' )); @@ -78,11 +80,12 @@ class PluginController extends BaseController { if (!empty($groupId) && !empty($artifactId)) { $url = $this->_config['pp3']['mavenRepoUrl'].str_replace('.','/', $groupId).'/'.$artifactId.'/maven-metadata.xml'; + $user = $this->_userRepository->find($this->getAuthenticatedUserId()); $plugin->setUrl($url); $plugin->setArtifactId($artifactId); $plugin->setGroupId($groupId); $plugin->setStatus(Plugin::STATUS_PRIVATE); - $plugin->setAuthor($this->_sessionUserId); + $plugin->setAuthor($user); $plugin->setDataLoader(new MavenDataLoader()); try { if ($plugin->loadData()) { @@ -125,7 +128,6 @@ class PluginController extends BaseController { $req = $this->request; if ($req->isPost()) { $validatedData = $this->_validateAndCleanPluginData( - $this->params()->fromPost('author'), $this->params()->fromPost('name'), $this->params()->fromPost('license'), $this->params()->fromPost('description'), @@ -134,7 +136,8 @@ class PluginController extends BaseController { $this->params()->fromPost('homepage') ); if ($validatedData) { - $plugin->setAuthor($validatedData['author']); + $user = $this->_userRepository->find($this->getAuthenticatedUserId()); + $plugin->setAuthor($user); $plugin->setName($validatedData['name']); $plugin->setLicense($validatedData['license']); $plugin->setDescription($validatedData['description']); @@ -199,7 +202,7 @@ class PluginController extends BaseController { } public function listAction() { - $plugins = $this->_pluginRepository->getPluginsByAuthor($this->_sessionUserId); + $plugins = $this->_pluginRepository->getPluginsByAuthorId($this->getAuthenticatedUserId()); return new ViewModel(array( 'plugins' => $plugins, )); @@ -208,7 +211,7 @@ class PluginController extends BaseController { public function editAction() { $pId = $this->params()->fromQuery('id'); $plugin = $this->_pluginRepository->find($pId); - if (!$plugin || empty($pId) || !$plugin->isOwnedBy($this->_sessionUserId)) { + if (!$plugin || empty($pId) || !$plugin->isOwnedBy($this->getAuthenticatedUserId())) { return $this->redirect()->toRoute('plugin', array( 'action' => 'list' )); @@ -216,7 +219,6 @@ class PluginController extends BaseController { $req = $this->request; if ($req->isPost()) { $validatedData = $this->_validateAndCleanPluginData( - $this->params()->fromPost('author'), $this->params()->fromPost('name'), $this->params()->fromPost('license'), $this->params()->fromPost('description'), @@ -225,7 +227,6 @@ class PluginController extends BaseController { $this->params()->fromPost('homepage') ); if ($validatedData) { - $plugin->setAuthor($validatedData['author']); $plugin->setName($validatedData['name']); $plugin->setLicense($validatedData['license']); $plugin->setDescription($validatedData['description']); @@ -273,7 +274,7 @@ class PluginController extends BaseController { public function deleteAction() { $pId = $this->params()->fromQuery('id'); $plugin = $this->_pluginRepository->find($pId); - if (!$plugin || empty($pId) || !$plugin->isOwnedBy($this->_sessionUserId)) { + if (!$plugin || empty($pId) || !$plugin->isOwnedBy($this->getAuthenticatedUserId())) { return $this->redirect()->toRoute('plugin', array( 'action' => 'list' )); @@ -311,14 +312,13 @@ class PluginController extends BaseController { return $_SERVER["REQUEST_SCHEME"].'://'.$_SERVER["HTTP_HOST"].$this->url()->fromRoute('catalogue', array('action' => 'download')).'?id='; } - private function _validateAndCleanPluginData($author, $name, $license, $description, $shortDescription, $category, $homepage) { - if (empty($author) || empty($name) || empty($license) || empty($category) || empty($shortDescription)) { + private function _validateAndCleanPluginData($name, $license, $description, $shortDescription, $category, $homepage) { + if (empty($name) || empty($license) || empty($category) || empty($shortDescription)) { return false; } $config = HTMLPurifier_Config::createDefault(); $purifier = new HTMLPurifier($config); return array( - 'author' => $purifier->purify($author), 'name' => $purifier->purify($name), 'license' => $purifier->purify($license), 'description' => $purifier->purify($description), @@ -348,14 +348,8 @@ P.S.: This is an automatic email. DO NOT REPLY to this email. '); $mail->setFrom('webmas...@netbeans.apache.org', 'NetBeans webmaster'); $mail->setSubject('NetBeans plugin waiting for approval: '.$plugin->getName()); $transport = new Mail\Transport\Sendmail(); - $i=0; - foreach($this->_verifierRepository->findAll() as $verifier) { - if ($i == 0) { - $mail->addTo($verifier->getUserId()); - $i++; - } else { - $mail->addBcc($verifier->getUserId()); - } + foreach($this->_userRepository->findAdmins() as $verifier) { + $mail->addBcc($verifier->getEmail()); } $transport->send($mail); } diff --git a/pp3/module/Application/src/Application/Controller/PluginVersionController.php b/pp3/module/Application/src/Application/Controller/PluginVersionController.php index 236b6d7..4468887 100644 --- a/pp3/module/Application/src/Application/Controller/PluginVersionController.php +++ b/pp3/module/Application/src/Application/Controller/PluginVersionController.php @@ -2,12 +2,7 @@ namespace Application\Controller; -use Application\Controller\BaseController; use Zend\View\Model\ViewModel; -use Zend\Session\Container; -use Application\Pp\MavenDataLoader; -use Application\Entity\Plugin; -use Application\Entity\PluginVersion; use Application\Entity\NbVersionPluginVersion; use Application\Pp\Catalog; use HTMLPurifier; @@ -15,7 +10,7 @@ use HTMLPurifier_Config; define('PLUGIN_SESSION_NAMESPACE', 'pp3_plugin_session'); -class PluginVersionController extends BaseController { +class PluginVersionController extends AuthenticatedController { public function __construct($pluginRepo, $pvRepo, $nbvRepo, $nbVersionPluginVersionRepo, $config, $verificationRepo) { parent::__construct($config); @@ -29,7 +24,7 @@ class PluginVersionController extends BaseController { public function editAction() { $pvId = $this->params()->fromQuery('id'); $pluginVersion = $this->_pluginVersionRepository->find($pvId); - if (!$pluginVersion || empty($pvId) || !$pluginVersion->getPlugin()->isOwnedBy($this->_sessionUserId)) { + if (!$pluginVersion || empty($pvId) || !$pluginVersion->getPlugin()->isOwnedBy($this->getAuthenticatedUserId())) { return $this->redirect()->toRoute('plugin', array( 'action' => 'list' )); @@ -115,7 +110,7 @@ class PluginVersionController extends BaseController { public function deleteAction() { $pId = $this->params()->fromQuery('id'); $pluginVersion = $this->_pluginVersionRepository->find($pId); - if (!$pluginVersion || empty($pId) || !$pluginVersion->getPlugin()->isOwnedBy($this->_sessionUserId)) { + if (!$pluginVersion || empty($pId) || !$pluginVersion->getPlugin()->isOwnedBy($this->getAuthenticatedUserId())) { return $this->redirect()->toRoute('plugin', array( 'action' => 'list' )); diff --git a/pp3/module/Application/src/Application/Controller/VerificationController.php b/pp3/module/Application/src/Application/Controller/VerificationController.php index 0b37463..bb396b2 100644 --- a/pp3/module/Application/src/Application/Controller/VerificationController.php +++ b/pp3/module/Application/src/Application/Controller/VerificationController.php @@ -2,7 +2,6 @@ namespace Application\Controller; -use Application\Controller\BaseController; use Zend\View\Model\ViewModel; use Application\Entity\Verification; use Application\Pp\Catalog; @@ -11,31 +10,31 @@ use Zend\Mail; use HTMLPurifier; use HTMLPurifier_Config; -class VerificationController extends BaseController { +class VerificationController extends AuthenticatedController { private $_nbVersionPluginVersionRepository; private $_verificationRepository; - private $_verifierRepository; + /** + * @var \Application\Repository\UserRepository + */ + private $_userRepository; private $_verificationRequestRepository; private $_pluginVersionRepository; public function __construct($nbVersionPluginVersionRepo, $verificationRepo, - $verifierRepository, $verificationRequestRepository, $config, + $userRepository, $verificationRequestRepository, $config, $pluginVersionRepository) { parent::__construct($config); $this->_nbVersionPluginVersionRepository = $nbVersionPluginVersionRepo; $this->_verificationRepository = $verificationRepo; - $this->_verifierRepository = $verifierRepository; + $this->_userRepository = $userRepository; $this->_verificationRequestRepository = $verificationRequestRepository; $this->_pluginVersionRepository = $pluginVersionRepository; - - $session = new Container(); - $this->_sessionUserId = $session->userId ? $session->userId : ANONUSER; } public function listAction() { return new ViewModel([ - 'verificationRequests' => $this->_verificationRequestRepository->getVerificationRequestsForVerifier($this->_sessionUserId), + 'verificationRequests' => $this->_verificationRequestRepository->getVerificationRequestsForVerifier($this->getAuthenticatedUserId()), 'isAdmin' => $this->_isAdmin, ]); } @@ -59,7 +58,7 @@ class VerificationController extends BaseController { $bailOut = true; } $req = $this->_verificationRequestRepository->find($reqId); - if (!$req || $req->getVerifier()->getUserId() !== $this->_sessionUserId) { + if (!$req || $req->getVerifier()->getId() !== $this->getAuthenticatedUserId()) { $bailOut = true; } if ($bailOut) { @@ -148,12 +147,13 @@ class VerificationController extends BaseController { if (empty($nbvPvId)) { $bailOut = true; } + /** @var \Application\Entity\NbVersionPluginVersion $nbVersionPluginVersion */ $nbVersionPluginVersion = $this->_nbVersionPluginVersionRepository->find($nbvPvId); if (!$nbVersionPluginVersion) { $bailOut = true; } $plugin = $nbVersionPluginVersion->getPluginVersion()->getPlugin(); - if (!$plugin->isOwnedBy($this->_sessionUserId)) { + if (!$plugin->isOwnedBy($this->getAuthenticatedUserId())) { $bailOut = true; } if ($bailOut) { @@ -165,14 +165,19 @@ class VerificationController extends BaseController { $verification = new Verification(); $verification->setStatus(Verification::STATUS_REQUESTED); $verification->setCreatedAt(new \DateTime('now')); + $verification->setPluginVersionId($nbvPvId); $this->_verificationRepository->persist($verification); // join it to nbVersionPluginVersion $nbVersionPluginVersion->setVerification($verification); $this->_nbVersionPluginVersionRepository->persist($nbVersionPluginVersion); + $verification->setNbVersionPluginVersion($nbVersionPluginVersion); // generate requests for all verifiers - $verifiers = $this->_verifierRepository->findAll(); + $verifiers = $this->_userRepository->findVerifier(); $verification->createRequests($verifiers, $plugin); $this->_verificationRepository->persist($verification); + foreach($verification->getVerificationRequests() as $req) { + $req->sendVerificationMail($plugin); + } $this->flashMessenger()->setNamespace('success')->addMessage('Verification Requested.'); return $this->redirect()->toUrl('../plugin-version/edit?id='.$nbVersionPluginVersion->getPluginVersion()->getId()); } @@ -182,7 +187,7 @@ class VerificationController extends BaseController { $nbVersion = $verification->getNbVersionPluginVersion()->getNbVersion()->getVersion(); $pluginVersion = $verification->getNbVersionPluginVersion()->getPluginVersion()->getVersion(); $mail = new Mail\Message(); - $mail->addTo($plugin->getAuthor()); + $mail->addTo($plugin->getAuthor()->getEmail()); $mail->setFrom('webmas...@netbeans.apache.org', 'NetBeans webmaster'); $mail->setSubject('Verification of your '.$plugin->getName().' is complete'); $mail->setBody('Hello plugin owner, @@ -212,7 +217,7 @@ P.S.: This is an automatic email. DO NOT REPLY to this email.'); $nbVersion = $verification->getNbVersionPluginVersion()->getNbVersion()->getVersion(); $pluginVersion = $verification->getNbVersionPluginVersion()->getPluginVersion()->getVersion(); $mail = new Mail\Message(); - $mail->addTo($plugin->getAuthor()); + $mail->addTo($plugin->getAuthor()->getEmail()); $mail->setFrom('webmas...@netbeans.apache.org', 'NetBeans webmaster'); $mail->setSubject('Verification of your '.$plugin->getName().' is complete'); $mail->setBody('Hello plugin owner, diff --git a/pp3/module/Application/src/Application/Entity/Base/Plugin.php b/pp3/module/Application/src/Application/Entity/Base/Plugin.php index 30b7f3b..1379187 100644 --- a/pp3/module/Application/src/Application/Entity/Base/Plugin.php +++ b/pp3/module/Application/src/Application/Entity/Base/Plugin.php @@ -32,7 +32,9 @@ class Plugin { /** @ORM\Column(type="string", length=255) */ protected $license; - /** @ORM\Column(type="string", length=255) */ + /** + * @ORM\ManyToOne(targetEntity="User") + */ protected $author; /** @ORM\Column(type="datetime") */ @@ -138,10 +140,16 @@ class Plugin { $this->license = $license; } + /** + * @return User + */ public function getAuthor() { return $this->author; } + /** + * @param User $author + */ public function setAuthor($author) { $this->author = $author; } diff --git a/pp3/module/Application/src/Application/Entity/Base/User.php b/pp3/module/Application/src/Application/Entity/Base/User.php new file mode 100644 index 0000000..1fb3b18 --- /dev/null +++ b/pp3/module/Application/src/Application/Entity/Base/User.php @@ -0,0 +1,134 @@ +<?php + +namespace Application\Entity\Base; + +use Doctrine\ORM\Mapping as ORM; + +class User { + + /** + * @ORM\Id + * @ORM\GeneratedValue(strategy="AUTO") + * @ORM\Column(type="integer") + */ + protected $id; + + /** @ORM\Column(name="idp_provider_id", type="string", length=20) */ + protected $idpProviderId; + + /** @ORM\Column(name="idp_user_id", type="string", length=100) */ + protected $idpUserId; + + /** @ORM\Column(name="name", type="string", length=255) */ + protected $name; + + /** @ORM\Column(name="email", type="string", length=100) */ + protected $email; + + /** @ORM\Column(name="admin", type="boolean") */ + protected $admin = false; + + /** @ORM\Column(name="verifier", type="boolean") */ + protected $verifier = false; + + public function __construct() { + return $this; + } + + /** + * @return integer + */ + function getId() { + return $this->id; + } + + /** + * @return string + */ + function getIdpProviderId() { + return $this->idpProviderId; + } + + /** + * @return string + */ + function getIdpUserId() { + return $this->idpUserId; + } + + /** + * @return string + */ + function getName() { + return $this->name; + } + + /** + * @return string + */ + function getEmail() { + return $this->email; + } + + /** + * @param string $idpProviderId + * @return void + */ + function setIdpProviderId($idpProviderId): void { + $this->idpProviderId = $idpProviderId; + } + + /** + * @param string $idpUserId + * @return void + */ + function setIdpUserId($idpUserId): void { + $this->idpUserId = $idpUserId; + } + + /** + * @param string $name + * @return void + */ + function setName($name): void { + $this->name = $name; + } + + /** + * @param string $email + * @return void + */ + function setEmail($email): void { + $this->email = $email; + } + + /** + * @return boolean + */ + function isAdmin() { + return $this->admin; + } + + /** + * @return boolean + */ + function isVerifier() { + return $this->verifier; + } + + /** + * @param boolean $admin + * @return void + */ + function setAdmin($admin): void { + $this->admin = $admin; + } + + /** + * @param boolean $verifier + * @return void + */ + function setVerifier($verifier): void { + $this->verifier = $verifier; + } +} diff --git a/pp3/module/Application/src/Application/Entity/Base/Verification.php b/pp3/module/Application/src/Application/Entity/Base/Verification.php index df8d157..33cd939 100644 --- a/pp3/module/Application/src/Application/Entity/Base/Verification.php +++ b/pp3/module/Application/src/Application/Entity/Base/Verification.php @@ -82,4 +82,7 @@ class Verification { return $this->nbVersionPluginVersion; } + function setNbVersionPluginVersion($nbVersionPluginVersion): void { + $this->nbVersionPluginVersion = $nbVersionPluginVersion; + } } diff --git a/pp3/module/Application/src/Application/Entity/Base/VerificationRequest.php b/pp3/module/Application/src/Application/Entity/Base/VerificationRequest.php index 9badafa..9adeddf 100644 --- a/pp3/module/Application/src/Application/Entity/Base/VerificationRequest.php +++ b/pp3/module/Application/src/Application/Entity/Base/VerificationRequest.php @@ -38,7 +38,7 @@ class VerificationRequest { protected $verification; /** - * @ORM\ManyToOne(targetEntity="Verifier", inversedBy="verification_requests") + * @ORM\ManyToOne(targetEntity="User", inversedBy="verification_requests") * @ORM\JoinColumn(name="verifier_id", referencedColumnName="id") */ protected $verifier; diff --git a/pp3/module/Application/src/Application/Entity/Base/Verifier.php b/pp3/module/Application/src/Application/Entity/Base/Verifier.php deleted file mode 100644 index 176e551..0000000 --- a/pp3/module/Application/src/Application/Entity/Base/Verifier.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -namespace Application\Entity\Base; - -use Doctrine\ORM\Mapping as ORM; -use Doctrine\Common\Collections\ArrayCollection; - -class Verifier { - - /** - * @ORM\Id - * @ORM\GeneratedValue(strategy="AUTO") - * @ORM\Column(type="integer") - */ - protected $id; - - /** @ORM\Column(type="string", length=255) */ - protected $user_id; - - /** - * @ORM\OneToMany(targetEntity="VerificationRequest", mappedBy="verifier") - */ - protected $verification_requests; - - public function __construct() { - $this->verification_requests = new ArrayCollection(); - return $this; - } - - public function getId() { - return $this->id; - } - - public function setId($id) { - $this->id = $id; - } - - public function getUserId() { - return $this->user_id; - } - - public function setUserId($uid) { - $this->user_id = $uid; - } - - public function getVerificationRequests() { - return $this->verification_requests; - } - -} diff --git a/pp3/module/Application/src/Application/Entity/Plugin.php b/pp3/module/Application/src/Application/Entity/Plugin.php index 9e24daf..1ebffd9 100644 --- a/pp3/module/Application/src/Application/Entity/Plugin.php +++ b/pp3/module/Application/src/Application/Entity/Plugin.php @@ -133,11 +133,6 @@ class Plugin extends Base\Plugin { } } - public function getAuthorName() { - $split = explode('@', $this->getAuthor()); - return $split[0]; - } - public function incrementDownloadCounter() { $this->downloads++; } @@ -147,7 +142,7 @@ class Plugin extends Base\Plugin { } public function isOwnedBy($userId) { - return $this->author == $userId; + return $this->getAuthor()->getId() == $userId; } public function setUrl($url) { diff --git a/pp3/module/Application/src/Application/Entity/Verifier.php b/pp3/module/Application/src/Application/Entity/User.php similarity index 58% rename from pp3/module/Application/src/Application/Entity/Verifier.php rename to pp3/module/Application/src/Application/Entity/User.php index 6e183fd..755ef79 100644 --- a/pp3/module/Application/src/Application/Entity/Verifier.php +++ b/pp3/module/Application/src/Application/Entity/User.php @@ -6,8 +6,8 @@ use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity - * @ORM\Table(name="verifier") + * @ORM\Table(name="user") */ -class Verifier extends Base\Verifier { +class User extends Base\User { } diff --git a/pp3/module/Application/src/Application/Entity/Verification.php b/pp3/module/Application/src/Application/Entity/Verification.php index c003f89..71da1a3 100644 --- a/pp3/module/Application/src/Application/Entity/Verification.php +++ b/pp3/module/Application/src/Application/Entity/Verification.php @@ -21,7 +21,11 @@ class Verification extends Base\Verification { public function addVerificationRequest($req) { $this->verification_requests[] = $req; } - + + /** + * @param User[] $verifiers + * @param Plugin $plugin + */ public function createRequests($verifiers, $plugin) { foreach($verifiers as $verifier) { $req = new VerificationRequest(); @@ -30,7 +34,6 @@ class Verification extends Base\Verification { $req->setVerifier($verifier); $req->setVote(VerificationRequest::VOTE_UNDECIDED); $this->addVerificationRequest($req); - $req->sendVerificationMail($plugin); } } diff --git a/pp3/module/Application/src/Application/Entity/VerificationRequest.php b/pp3/module/Application/src/Application/Entity/VerificationRequest.php index e2525d2..86a8a8d 100644 --- a/pp3/module/Application/src/Application/Entity/VerificationRequest.php +++ b/pp3/module/Application/src/Application/Entity/VerificationRequest.php @@ -16,9 +16,6 @@ class VerificationRequest extends Base\VerificationRequest { const VOTE_UNDECIDED = 0; public function sendVerificationMail($plugin) { - // TODO - remove when we have auth ready - return; - $body = 'Hello verifier, this is to inform you about new verification request requiring your immediate attention. @@ -38,7 +35,7 @@ P.S.: This is an automatic email. DO NOT REPLY to this email.'; $mail = new Mail\Message(); $mail->setBody($body); $mail->setFrom('webmas...@netbeans.apache.org', 'NetBeans webmaster'); - $mail->addTo($this->getVerifier()->getUserId()); + $mail->addTo($this->getVerifier()->getEmail()); $mail->setSubject('Verification request for NetBeans plugin: '.$plugin->getName()); $transport = new Mail\Transport\Sendmail(); diff --git a/pp3/module/Application/src/Application/Factory/AdminControllerFactory.php b/pp3/module/Application/src/Application/Factory/AdminControllerFactory.php index bcb8f72..cff79e7 100755 --- a/pp3/module/Application/src/Application/Factory/AdminControllerFactory.php +++ b/pp3/module/Application/src/Application/Factory/AdminControllerFactory.php @@ -9,7 +9,7 @@ use Application\Repository\PluginRepository; use Application\Repository\PluginVersionRepository; use Application\Repository\NbVersionPluginVersionRepository; use Application\Repository\VerificationRepository; -use Application\Repository\VerifierRepository; +use Application\Repository\UserRepository; use Application\Repository\VerificationRequestRepository; use Application\Repository\NbVersionRepository; use Application\Repository\CategoryRepository; @@ -24,9 +24,9 @@ class AdminControllerFactory implements FactoryInterface $vrepository = new VerificationRepository(); $vrepository->setEntityManager($em); - - $verifierRepository = new VerifierRepository(); - $verifierRepository->setEntityManager($em); + + $userRepository = new UserRepository(); + $userRepository->setEntityManager($em); $verificationRequestRepository = new VerificationRequestRepository(); $verificationRequestRepository->setEntityManager($em); @@ -42,11 +42,13 @@ class AdminControllerFactory implements FactoryInterface $categoryRepository = new CategoryRepository(); $categoryRepository->setEntityManager($em); - + $config = $serviceLocator->getServiceLocator()->get('config'); return new AdminController($pluginRepository, $repository, $vrepository, - $verifierRepository, $verificationRequestRepository, - $nbVersionRepository, $pluginVersionRepository, $config, $categoryRepository); + $verificationRequestRepository, + $nbVersionRepository, + $pluginVersionRepository, $config, + $categoryRepository, $userRepository); } } diff --git a/pp3/module/Application/src/Application/Factory/LoginControllerFactory.php b/pp3/module/Application/src/Application/Factory/LoginControllerFactory.php index f0e2431..3b49893 100755 --- a/pp3/module/Application/src/Application/Factory/LoginControllerFactory.php +++ b/pp3/module/Application/src/Application/Factory/LoginControllerFactory.php @@ -5,7 +5,7 @@ namespace Application\Factory; use Zend\ServiceManager\ServiceLocatorInterface; use Zend\ServiceManager\FactoryInterface; use Application\Controller\LoginController; -use Application\Repository\VerifierRepository; +use Application\Repository\UserRepository; class LoginControllerFactory implements FactoryInterface { @@ -14,9 +14,9 @@ class LoginControllerFactory implements FactoryInterface $config = $serviceLocator->getServiceLocator()->get('config'); $em = $serviceLocator->getServiceLocator()->get('Doctrine\ORM\EntityManager'); - $verifierRepository = new VerifierRepository(); - $verifierRepository->setEntityManager($em); + $userRepository = new UserRepository(); + $userRepository->setEntityManager($em); - return new LoginController($config, $verifierRepository); + return new LoginController($config, $userRepository); } } diff --git a/pp3/module/Application/src/Application/Factory/PluginControllerFactory.php b/pp3/module/Application/src/Application/Factory/PluginControllerFactory.php index bd35002..66f0455 100755 --- a/pp3/module/Application/src/Application/Factory/PluginControllerFactory.php +++ b/pp3/module/Application/src/Application/Factory/PluginControllerFactory.php @@ -8,7 +8,7 @@ use Application\Repository\PluginRepository; use Application\Repository\PluginVersionRepository; use Application\Repository\CategoryRepository; use Application\Controller\PluginController; -use Application\Repository\VerifierRepository; +use Application\Repository\UserRepository; use Application\Repository\NbVersionRepository; class PluginControllerFactory implements FactoryInterface @@ -27,12 +27,12 @@ class PluginControllerFactory implements FactoryInterface $config = $serviceLocator->getServiceLocator()->get('config'); - $verifierRepository = new VerifierRepository(); - $verifierRepository->setEntityManager($em); + $userRepository = new UserRepository(); + $userRepository->setEntityManager($em); $nbVersionRepository = new NbVersionRepository(); $nbVersionRepository->setEntityManager($em); - return new PluginController($repository, $pvRepository, $categRepository, $config, $verifierRepository, $nbVersionRepository); + return new PluginController($repository, $pvRepository, $categRepository, $config, $nbVersionRepository, $userRepository); } } diff --git a/pp3/module/Application/src/Application/Factory/VerificationControllerFactory.php b/pp3/module/Application/src/Application/Factory/VerificationControllerFactory.php index 64dc946..853fef2 100755 --- a/pp3/module/Application/src/Application/Factory/VerificationControllerFactory.php +++ b/pp3/module/Application/src/Application/Factory/VerificationControllerFactory.php @@ -7,7 +7,7 @@ use Zend\ServiceManager\FactoryInterface; use Application\Controller\VerificationController; use Application\Repository\NbVersionPluginVersionRepository; use Application\Repository\VerificationRepository; -use Application\Repository\VerifierRepository; +use Application\Repository\UserRepository; use Application\Repository\VerificationRequestRepository; use Application\Repository\PluginVersionRepository; @@ -22,8 +22,8 @@ class VerificationControllerFactory implements FactoryInterface $vrepository = new VerificationRepository(); $vrepository->setEntityManager($em); - $verifierRepository = new VerifierRepository(); - $verifierRepository->setEntityManager($em); + $userRepository = new UserRepository(); + $userRepository->setEntityManager($em); $verificationRequestRepository = new VerificationRequestRepository(); $verificationRequestRepository->setEntityManager($em); @@ -32,6 +32,6 @@ class VerificationControllerFactory implements FactoryInterface $pluginVersionRepository = new PluginVersionRepository(); $pluginVersionRepository->setEntityManager($em); - return new VerificationController($repository, $vrepository, $verifierRepository, $verificationRequestRepository, $config, $pluginVersionRepository); + return new VerificationController($repository, $vrepository, $userRepository, $verificationRequestRepository, $config, $pluginVersionRepository); } } diff --git a/pp3/module/Application/src/Application/Pp/Catalog.php b/pp3/module/Application/src/Application/Pp/Catalog.php index 2a805d9..649c1ae 100644 --- a/pp3/module/Application/src/Application/Pp/Catalog.php +++ b/pp3/module/Application/src/Application/Pp/Catalog.php @@ -46,7 +46,7 @@ class Catalog { $moduleElement->setAttribute(self::REQ_ATTRS_MODULE_distribution, $this->_downloadPath.$item->getId()); $moduleElement->setAttribute(self::REQ_ATTRS_MODULE_downloadsize, '1024'); $moduleElement->setAttribute('targetcluster', 'nbms'); - $moduleElement->setAttribute('moduleauthor', $item->getPlugin()->getAuthor()); + $moduleElement->setAttribute('moduleauthor', $item->getPlugin()->getAuthor()->getEmail()); $manifestElement =$xml->createElement('manifest'); $manifestElement->setAttribute(self::REQ_ATTRS_MANIFEST_OpenIDE_Module, $item->getPlugin()->getArtifactId()); diff --git a/pp3/module/Application/src/Application/Repository/NbVersionRepository.php b/pp3/module/Application/src/Application/Repository/NbVersionRepository.php index 73c2a2c..c5fee31 100644 --- a/pp3/module/Application/src/Application/Repository/NbVersionRepository.php +++ b/pp3/module/Application/src/Application/Repository/NbVersionRepository.php @@ -27,12 +27,11 @@ class NbVersionRepository extends DoctrineEntityRepository { ->from('Application\Entity\NbVersion', 'nbv') ->join('nbv.nbVersionsPluginVersions', 'nbvpv') ->join('nbvpv.pluginVersion', 'pv') - ->join('pv.plugin p WITH p.id = :pid') - ->join('nbvpv.verification v WITH v.status >= 0') + ->join('pv.plugin', 'p', 'WITH', 'p.id = :pid') + ->join('nbvpv.verification', 'v', 'WITH', 'v.status >= 0') ->setParameter('pid', $pluginId) ->groupBy('nbv.id'); return $queryBuilder->getQuery()->getResult(); - // return $queryBuilder->getQuery()->getSQL(); } } diff --git a/pp3/module/Application/src/Application/Repository/PluginRepository.php b/pp3/module/Application/src/Application/Repository/PluginRepository.php index c743b47..d25e2a5 100644 --- a/pp3/module/Application/src/Application/Repository/PluginRepository.php +++ b/pp3/module/Application/src/Application/Repository/PluginRepository.php @@ -48,16 +48,18 @@ class PluginRepository extends DoctrineEntityRepository { return $queryBuilder->getQuery()->getResult(); } - public function getPluginsByAuthor($author) { + public function getPluginsByAuthorId($author) { $queryBuilder = $this->getEntityManager()->createQueryBuilder(); $queryBuilder->select('p, v, nbvPv, nbv, verif') - ->from('Application\Entity\Plugin', 'p') - ->leftJoin('p.versions', 'v') - ->leftJoin('v.nbVersionsPluginVersions', 'nbvPv') - ->leftJoin('nbvPv.nbVersion', 'nbv') - ->leftJoin('nbvPv.verification', 'verif') - ->where('p.author = :author')->orderBy('p.id', 'DESC') - ->setParameter('author', $author); + ->from('Application\Entity\Plugin', 'p') + ->leftJoin('p.versions', 'v') + ->leftJoin('v.nbVersionsPluginVersions', 'nbvPv') + ->leftJoin('nbvPv.nbVersion', 'nbv') + ->leftJoin('nbvPv.verification', 'verif') + ->leftJoin('p.author', 'a') + ->where('a.id = :author') + ->orderBy('p.id', 'DESC') + ->setParameter('author', $author); return $queryBuilder->getQuery()->getResult(); } @@ -79,8 +81,9 @@ class PluginRepository extends DoctrineEntityRepository { ->from('Application\Entity\Plugin', 'p') ->leftJoin('p.versions', 'v') ->leftJoin('v.nbVersionsPluginVersions', 'nbvPv') - ->leftJoin('nbvPv.nbVersion', 'nbv') - ->where('(p.name LIKE :name) OR (p.author LIKE :name)')->orderBy('p.id', 'ASC') + ->leftJoin('nbvPv.nbVersion', 'nbv') + ->leftJoin('p.author', 'a') + ->where('(p.name LIKE :name) OR (a.email LIKE :name)')->orderBy('p.id', 'ASC') ->setParameter('name', '%'.$name.'%'); return $queryBuilder->getQuery()->getResult(); } @@ -94,10 +97,11 @@ class PluginRepository extends DoctrineEntityRepository { ->leftJoin('nbvPv.verification', 'verif') ->leftJoin('nbvPv.nbVersion', 'nbv') ->leftJoin('p.categories', 'cat') + ->leftJoin('p.author', 'a') ->where('p.status = :status') ->setParameter('status', \Application\Entity\Plugin::STATUS_PUBLIC); if ($name) { - $queryBuilder->andWhere('(p.name LIKE :name OR p.artifactid LIKE :name OR p.author LIKE :name OR p.short_description LIKE :name OR p.description LIKE :name + $queryBuilder->andWhere('(p.name LIKE :name OR p.artifactid LIKE :name OR a.email LIKE :name OR p.short_description LIKE :name OR p.description LIKE :name OR p.license LIKE :name OR nbv.version LIKE :name OR cat.name LIKE :name)')->setParameter('name', '%'.$name.'%'); } //$queryBuilder->orderBy('p.name', 'ASC'); diff --git a/pp3/module/Application/src/Application/Repository/UserRepository.php b/pp3/module/Application/src/Application/Repository/UserRepository.php new file mode 100644 index 0000000..fc15126 --- /dev/null +++ b/pp3/module/Application/src/Application/Repository/UserRepository.php @@ -0,0 +1,64 @@ +<?php + +namespace Application\Repository; + +use Application\Entity\User; + +class UserRepository extends DoctrineEntityRepository { + + public function getEntityRepository() { + if (null === $this->entityRepository) { + $this->setEntityRepository($this->getEntityManager()->getRepository('Application\Entity\User')); + } + return $this->entityRepository; + } + + /** + * @param string $idpProviderId id of the identity provider + * @param string $idpUserId id of the user in the scope of the provider + * @return User + */ + public function findByIdpData($idpProviderId, $idpUserId) { + $queryBuilder = $this->getEntityManager()->createQueryBuilder(); + $queryBuilder->select('user') + ->from('Application\Entity\User', 'user') + ->where('user.idpProviderId = :idpProviderId AND user.idpUserId = :idpUserId') + ->setParameter('idpProviderId', $idpProviderId) + ->setParameter('idpUserId', $idpUserId); + return $queryBuilder->getQuery()->getOneOrNullResult(); + } + + /** + * @return User[] list of users, that have verifier status + */ + public function findVerifier() { + $queryBuilder = $this->getEntityManager()->createQueryBuilder(); + $queryBuilder->select('user') + ->from('Application\Entity\User', 'user') + ->where('user.verifier = true'); + return $queryBuilder->getQuery()->getResult(); + } + + /** + * @return User[] list of users, that have admin status + */ + public function findAdmins() { + $queryBuilder = $this->getEntityManager()->createQueryBuilder(); + $queryBuilder->select('user') + ->from('Application\Entity\User', 'user') + ->where('user.admin = true'); + return $queryBuilder->getQuery()->getResult(); + } + + /** + * @return User[] list of users, that are registered with the supplied email + */ + public function findByEmail($email) { + $queryBuilder = $this->getEntityManager()->createQueryBuilder(); + $queryBuilder->select('user') + ->from('Application\Entity\User', 'user') + ->where('lower(user.email) = :email') + ->setParameter('email', mb_strtolower($email, 'UTF-8')); + return $queryBuilder->getQuery()->getResult(); + } +} diff --git a/pp3/module/Application/src/Application/Repository/VerificationRequestRepository.php b/pp3/module/Application/src/Application/Repository/VerificationRequestRepository.php index 186e10a..1332016 100644 --- a/pp3/module/Application/src/Application/Repository/VerificationRequestRepository.php +++ b/pp3/module/Application/src/Application/Repository/VerificationRequestRepository.php @@ -29,7 +29,7 @@ class VerificationRequestRepository extends DoctrineEntityRepository { ->join('nbVersionPluginVersion.pluginVersion', 'pluginVersion') ->join('nbVersionPluginVersion.nbVersion', 'nbVersion') ->join('pluginVersion.plugin', 'plugin') - ->where('verifier.user_id = :userId') + ->where('verifier.id = :userId') ->andWhere('verification.status IN (:status)') ->orderBy('vrq.created_at', 'DESC') ->setParameter('status', array(\Application\Entity\Verification::STATUS_REQUESTED, \Application\Entity\Verification::STATUS_PENDING)) diff --git a/pp3/module/Application/src/Application/Repository/VerifierRepository.php b/pp3/module/Application/src/Application/Repository/VerifierRepository.php deleted file mode 100644 index fb7e468..0000000 --- a/pp3/module/Application/src/Application/Repository/VerifierRepository.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -namespace Application\Repository; - -class VerifierRepository extends DoctrineEntityRepository { - - public function getEntityRepository() { - if (null === $this->entityRepository) { - $this->setEntityRepository($this->getEntityManager()->getRepository('Application\Entity\Verifier')); - } - return $this->entityRepository; - } - - public function findOneBy($column, $value) { - $queryBuilder = $this->getEntityManager()->createQueryBuilder(); - $queryBuilder->select('verifier') - ->from('Application\Entity\Verifier', 'verifier') - ->where('verifier.'.$column.' = :value') - ->setParameter('value', $value); - - return $queryBuilder->getQuery()->getOneOrNullResult(); - } -} diff --git a/pp3/module/Application/view/application/admin/_plugin-listrow.phtml b/pp3/module/Application/view/application/admin/_plugin-listrow.phtml index 646b64b..f6cf3a7 100644 --- a/pp3/module/Application/view/application/admin/_plugin-listrow.phtml +++ b/pp3/module/Application/view/application/admin/_plugin-listrow.phtml @@ -24,7 +24,7 @@ echo '<tr> <p>Status: <b>'.$plugin->getStatusTitle().'</b></p> <div> <p>ArtifactId: <b>'.$plugin->getArtifactId().'</b><p> - <p>Author: <b>'.$plugin->getAuthor().'</b><p> + <p>Author: <b>'.$plugin->getAuthor()->getName().'</b><p> <p> <i class="fas fa-asterisk"></i> '.$plugin->getAddedAt()->format('Y-m-d').' <i class="fas fa-edit"></i> '.$plugin->getLastUpdatedAt()->format('Y-m-d').' @@ -78,7 +78,12 @@ foreach ($plugin->getVersions() as $version) { <table class="table table-striped">'; foreach($nbvPv->getVerification()->getVerificationRequests() as $vrq) { echo '<tr> - <td>'.$vrq->getVerifier()->getuserId().'</td> + <td>' + . htmlentities($vrq->getVerifier()->getName(), ENT_HTML5, 'UTF-8') + . ' <' + . htmlentities($vrq->getVerifier()->getEmail(), ENT_HTML5, 'UTF-8') + . '>' + .'</td> <td><span class="badge '.$vrq->getVoteBadgeClass().'" title="'.$vrq->getVoteBadgeTitle().'">'.$vrq->getVoteBadgeTitle().'</span></td> <td>'.($vrq->getVotedAt() ? $vrq->getVotedAt()->format('Y-m-d') : '').'</td> </tr>'; diff --git a/pp3/module/Application/view/application/admin/_pluginRowItem.phtml b/pp3/module/Application/view/application/admin/_pluginRowItem.phtml index b4d0d0e..f7c0fca 100644 --- a/pp3/module/Application/view/application/admin/_pluginRowItem.phtml +++ b/pp3/module/Application/view/application/admin/_pluginRowItem.phtml @@ -12,7 +12,7 @@ echo ' <p>ArtifactId: <b>'.$plugin->getArtifactId().'</b><p> <p> <p>Status: <b>'.$plugin->getStatusTitle().'</b></p> -<i class="fas fa-user"></i> '.$plugin->getAuthorName().' +<i class="fas fa-user"></i> '.$plugin->getAuthor()->getName().' <i class="fas fa-asterisk"></i> '.$plugin->getAddedAt()->format('Y-m-d').' <i class="fas fa-edit"></i> '.$plugin->getLastUpdatedAt()->format('Y-m-d').' <i class="fas fa-file-contract"></i> '.$plugin->getLicense().' diff --git a/pp3/module/Application/view/application/admin/verifiers.phtml b/pp3/module/Application/view/application/admin/verifiers.phtml index 00bd346..222a652 100644 --- a/pp3/module/Application/view/application/admin/verifiers.phtml +++ b/pp3/module/Application/view/application/admin/verifiers.phtml @@ -1,29 +1,82 @@ <?= $this->partial('_nav.phtml'); ?> -<h4>Verifiers</h4> +<h4>New verifier</h4> <p> <?= $this->partial('layout/flash.phtml'); ?> </p> <p> <form class="form-inline" method="post" action=""> <div class="form-group"> - <label for="exampleInputName2">New verifier: </label> - <input type="text" class="form-control" name="userId" id="search" placeholder="User ID" style="width: 300px;" value=""> + <label for="search">Search: </label> + <input type="text" class="form-control" name="email" id="search" placeholder="Email" style="width: 300px;" value=""> </div> - <button type="submit" class="btn btn-primary">Add Verifier</button> + <button type="button" id="searchAccount" class="btn btn-primary">Search Account</button> + <table class="table table-striped table-hover" id="addVerifierStatusList" style="margin-top: 1ex; margin-bottom: 1ex"> + + </table> </form> </p> -<br/> -<table class="table table-striped table-hover" style="width: 50%"> +<h4>Existing verifiers</h4> +<table class="table table-striped table-hover"> <?php foreach ($this->verifiers as $v) { - echo '<tr> - <td><h5>'.$v->getUserId().'</h5></td> - <td> - <a class="btn btn-danger" href="'.$this->url('admin',array('action'=>'verifiers'),array('query' => array('id'=>$v->getId()))).'" role="button" title="Delete"> - Delete - </a> - </td> - </tr>'; + printf(' + <tr> + <td>%s <%s> (ID: %d, IdP: %s)</td> + <td> + <form action="%s" method="POST"> + <button type="submit" class="btn btn-danger" role="button" name="removeVerifierStatusId" value="%d"> + Remove verifier status + </button> + </form> + </td> + </tr>', + htmlentities($v->getName(), ENT_HTML5, 'UTF-8'), + htmlentities($v->getEmail(), ENT_HTML5, 'UTF-8'), + $v->getId(), + htmlentities($v->getIdpProviderId(), ENT_HTML5, 'UTF-8'), + $this->url('admin',array('action'=>'verifiers')), + $v->getId() + ); } ?> -</table> \ No newline at end of file +</table> + +<script> + $(document).ready(function() { + var inputField = $('#search'); + var searchButton = $('#searchAccount'); + var resultList = $('#addVerifierStatusList'); + + function updateAddVerifierStatusList() { + var url = BASE_URL; + url += 'admin/search-user-by-email?email='; + url += encodeURIComponent(inputField.val()); + $.ajax(url, {dataType: 'json'}).done(function(data) { + resultList.empty(); + for(var idx in data) { + var row = data[idx]; + if(row['verifier']) { + continue; + } + resultList + .append( + $("<tr></tr>").append( + $('<td></td>') + .text(row['name'] + "<" + row['email'] + "> (ID: " + row['id'] + ", IdP: " + row['idpProviderId'] + ")"), + $('<td></td>') + .append($('<form action="%s" method="POST"></form>') + .attr('action', BASE_URL + "admin/verifiers") + .append($('<button type="submit" class="btn btn-success" role="button" name="addVerifierStatusId">') + .attr('value', row['id']) + .text('Add verifier status') + ) + ) + ) + ); + } + }); + } + + searchButton.click(updateAddVerifierStatusList); + }); +</script> \ No newline at end of file diff --git a/pp3/module/Application/view/application/index/catalogue.phtml b/pp3/module/Application/view/application/index/catalogue.phtml index 545eb9d..d61c271 100644 --- a/pp3/module/Application/view/application/index/catalogue.phtml +++ b/pp3/module/Application/view/application/index/catalogue.phtml @@ -18,7 +18,7 @@ if ($plugin) { } echo '</p> - <p>Author: <b>'.$plugin->getAuthorName().'</b></p> + <p>Author: <b>'.$plugin->getAuthor()->getName().'</b></p> <p>License: <b>'.$plugin->getLicense().'</b></p> <p>Homepage: <a href="'.$plugin->getHomepage().'">'.$plugin->getHomepage().'</a></p> <p> diff --git a/pp3/module/Application/view/application/index/index.phtml b/pp3/module/Application/view/application/index/index.phtml index f622f65..5f1f61d 100755 --- a/pp3/module/Application/view/application/index/index.phtml +++ b/pp3/module/Application/view/application/index/index.phtml @@ -52,7 +52,7 @@ <option value="">Any</option> <?php foreach($this->versions as $version) { - $sel = ($_GET['nbv'] == $version->getVersion())? 'selected' : ''; + $sel = (array_key_exists('nbv', $_GET) && $_GET['nbv'] == $version->getVersion()) ? 'selected' : ''; echo '<option value="'.$version->getVersion().'" '.$sel.'>'.$version->getVersion().'</option>'; } ?> @@ -64,7 +64,7 @@ <option value="">Any</option> <?php foreach($this->categories as $cat) { - $sel = ($_GET['cat'] == $cat->getName())? 'selected' : ''; + $sel = (array_key_exists('cat', $_GET) && $_GET['cat'] == $cat->getName()) ? 'selected' : ''; echo '<option value="'.$cat->getName().'" '.$sel.'>'.$cat->getName().'</option>'; } ?> @@ -96,7 +96,7 @@ <td> <h4 class="text-primary"><a href="'.$this->url('catalogue', array(), array('query' => array('id'=>$plugin->getId()))).'">'.$plugin->getName().'</a></h4> <p>ArtifactId: <b>'.$plugin->getArtifactId().'</b> <i class="fas fa-download"></i> '.number_format($plugin->getDownloads()).' <p> - <p>Author: <b>'.$plugin->getAuthorName().'</b></p> + <p>Author: <b>'.$plugin->getAuthor()->getName().'</b></p> <p>License: <b>'.$plugin->getLicense().'</b></p> <p>'.implode(' ', $versionBadges).'</p> </td> diff --git a/pp3/module/Application/view/application/login/index.phtml b/pp3/module/Application/view/application/login/index.phtml index 319bed5..0c622ba 100644 --- a/pp3/module/Application/view/application/login/index.phtml +++ b/pp3/module/Application/view/application/login/index.phtml @@ -1,16 +1,17 @@ - - <div class="row"> - <div class="col-sm-3"> - <form action="" method="post"> - <div class="form-group"> - <label for="exampleInputEmail1">Email</label> - <input type="email" class="form-control" id="email" aria-describedby="emailHelp" placeholder="Email"> - </div> - <div class="form-group"> - <label for="exampleInputPassword1">Heslo</label> - <input type="password" class="form-control" id="password" placeholder="Heslo"> - </div> - <button type="submit" class="btn btn-primary">Přihlásit</button> - </form> - </div> - </div> +<div class="panel panel-default"> + <div class="panel-heading"> + <h3 class="panel-title">Login Provider</h3> + </div> + <div class="panel-body"> + <ul class="list-group" id="loginProviderList"> + <?php foreach ($this->providers as $p) { ?> + <li class="list-group-item"> + <a href='<?= htmlentities($p['loginUrl'], ENT_HTML5, 'UTF-8') ?>' style='display: block'> + <div style='background-image: url(<?= htmlentities($p['iconUrl'], ENT_HTML5, 'UTF-8') ?>);' class="providerIcon"></div> + <?= htmlentities($p['name'], ENT_HTML5, 'UTF-8') ?> + </a> + </li> + <?php } ?> + </ul> + </div> +</div> \ No newline at end of file diff --git a/pp3/module/Application/view/application/plugin/_plugin-form.phtml b/pp3/module/Application/view/application/plugin/_plugin-form.phtml index ea07e10..794e29d 100644 --- a/pp3/module/Application/view/application/plugin/_plugin-form.phtml +++ b/pp3/module/Application/view/application/plugin/_plugin-form.phtml @@ -1,9 +1,5 @@ <div class="form-group"> - <label for="url">Author <span class="text-primary">*</span></label> - <input type="email" class="form-control" id="author" name="author" required placeholder="Author" value="<?= $this->plugin->getAuthor() ?>" xreadonly="true"> - </div> - <div class="form-group"> <label for="urgroupIdl">GroupId</label> <input type="text" class="form-control" id="groupId" name="groupid" placeholder="Enter groupId" value="<?= $this->plugin->getGroupId() ?>" readonly="true"> </div> diff --git a/pp3/module/Application/view/layout/layout.phtml b/pp3/module/Application/view/layout/layout.phtml index 3bef292..fa29238 100755 --- a/pp3/module/Application/view/layout/layout.phtml +++ b/pp3/module/Application/view/layout/layout.phtml @@ -3,7 +3,6 @@ <html lang="en"> <head> <meta charset="utf-8"> - <meta name="google-signin-client_id" content="432862904114-ierlf9j6qmmuhtd44ecmlfqivlirq7uc.apps.googleusercontent.com"> <?php echo $this->headTitle('Apache NetBeans Plugin Portal ') ?> <?php @@ -41,7 +40,6 @@ array('conditional' => 'lt IE 9',)) ; ?> - <script src="https://apis.google.com/js/platform.js?onload=onLoad" async defer></script> <script type="text/javascript"> const BASE_URL = '<?= $this->url('home')?>'; </script> @@ -62,36 +60,34 @@ <div class="collapse navbar-collapse"> <ul class="nav navbar-nav" id="mynav"> <li><a href="<?= $this->url('home') ?>">Plugin Catalog</a></li> - <?php if ($_SESSION['sessionUserId']) { ?> + <?php if ($this->isAuthenticated) { ?> <li><a href="<?= $this->url('plugin') ?>">Add plugin</a></li> - <li ><a href="<?= $this->url('plugin', array('action' => 'list'))?>">My plugins</a></li> - - <?php - if ($_SESSION['isVerifier']) { - echo '<li><a href="'.$this->url('verification', array('action' => 'list')).'">Verification requests</a></li>'; - } - ?> - <?php } ?> - <?php - if ($_SESSION['isAdmin']) { - echo '<li><a href="'.$this->url('admin').'">Admin</a></li>'; - } - ?> + <li><a href="<?= $this->url('plugin', array('action' => 'list'))?>">My plugins</a></li> + + <?php } ?> + <?php if ($this->isVerifier) { ?> + <li><a href="<?= $this->url('verification', array('action' => 'list')) ?>">Verification requests</a></li> + <?php } ?> + <?php if ($this->isAdmin) { ?> + <li><a href="<?= $this->url('admin') ?>">Admin</a></li>'; + <?php } ?> <li><a href="https://cwiki.apache.org/confluence/display/NETBEANS/How+to+get+plugin+on+Plugin+Portal+Update+Center">Help</a></li> </ul> - <div class="pull-right"> - <div style="margin: 7px 20px;"> - <?php - if (!$_SESSION['sessionUserId']) { - echo '<div class="g-signin2" data-onsuccess="onSignIn" approvalprompt="force" ></div>'; + <ul class="nav navbar-nav pull-right"> + <li> + <?php + if (!(array_key_exists('sessionUserId', $_SESSION) && $_SESSION['sessionUserId'])) { + echo '<a href="'.$this->url('login').'">Login</a>'; } else { - echo '<div style = "display:none" align="middle" class="g-signin2" data-cookiepolicy=\'single_host_origin\' data-onsuccess="onSignIn"></div>'; - echo '<a href="#" onclick="signOut();" class="btn btn-default" role="button">Sign out '.$_SESSION['sessionUserId'].'</a>'; - // echo '<span class="badge" style="display:inline-block;margin-top: 10px;">'.$_SESSION['sessionUserId'].'</a>'; + printf('<a href="%s" style="text-align: right; padding: 0.5ex">Logout %s (%s)<br />%s</a>', + $this->url('login', array('action' => 'logout')), + htmlentities($this->sessionUserName, ENT_HTML5, 'UTF-8'), + htmlentities($this->sessionIdp, ENT_HTML5, 'UTF-8'), + htmlentities($this->sessionUserEmail, ENT_HTML5, 'UTF-8')); } ?> - </div> - </div> + </li> + </ul> </div><!--/.nav-collapse --> </div> diff --git a/pp3/module/Application/view/partials/_categories-select.phtml b/pp3/module/Application/view/partials/_categories-select.phtml index 758495e..896e5d2 100644 --- a/pp3/module/Application/view/partials/_categories-select.phtml +++ b/pp3/module/Application/view/partials/_categories-select.phtml @@ -4,6 +4,8 @@ foreach ($this->categories as $cat) { if ($this->selected) { $sel = $cat->getId() == $this->selected->getId() ? 'selected' : ''; + } else { + $sel = ''; } echo '<option value="'.$cat->getId().'" '.$sel.'>'.$cat->getName().'</option>'; } diff --git a/pp3/public/img/favicon.ico b/pp3/public/img/favicon.ico deleted file mode 100755 index 17f1199..0000000 Binary files a/pp3/public/img/favicon.ico and /dev/null differ diff --git a/pp3/public/img/login/amazon.svg b/pp3/public/img/login/amazon.svg new file mode 100644 index 0000000..80a1358 --- /dev/null +++ b/pp3/public/img/login/amazon.svg @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> +<!-- +- Icon was downloaded from https://github.com/simple-icons/simple-icons/blob/4b882220efc78dc824c7647a81b47dd1d4fdd3d8/icons/amazon.svg +- License is CC0 1.0 Universal: https://github.com/simple-icons/simple-icons/blob/7d037d95f91847634536a592f1126c4ff040fc4d/LICENSE.md +- File was relicensed to ALv2 +--> +<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> + <title>Amazon icon</title> + <path d="M.045 18.02c.072-.116.187-.124.348-.022 3.636 2.11 7.594 3.166 11.87 3.166 2.852 0 5.668-.533 8.447-1.595l.315-.14c.138-.06.234-.1.293-.13.226-.088.39-.046.525.13.12.174.09.336-.12.48-.256.19-.6.41-1.006.654-1.244.743-2.64 1.316-4.185 1.726-1.53.406-3.045.61-4.516.61-2.265 0-4.41-.396-6.435-1.187-2.02-.794-3.82-1.91-5.43-3.35-.1-.074-.15-.15-.15-.22 0-.047.02-.09.05-.13zm6.565-6.218c0-1.005.247-1.863.743-2.577.495-.71 1.17-1.25 2.04-1.615.796-.335 1.756-.575 2.912-.72.39-.04 [...] +</svg> \ No newline at end of file diff --git a/pp3/public/img/login/github.svg b/pp3/public/img/login/github.svg new file mode 100644 index 0000000..c2f1fe4 --- /dev/null +++ b/pp3/public/img/login/github.svg @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> +<!-- +- Icon was downloaded from https://github.com/simple-icons/simple-icons/blob/4b882220efc78dc824c7647a81b47dd1d4fdd3d8/icons/github.svg +- License is CC0 1.0 Universal: https://github.com/simple-icons/simple-icons/blob/7d037d95f91847634536a592f1126c4ff040fc4d/LICENSE.md +- File was relicensed to ALv2 +--> +<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> + <title>GitHub icon</title> + <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.2 [...] +</svg> \ No newline at end of file diff --git a/pp3/public/img/login/google.svg b/pp3/public/img/login/google.svg new file mode 100644 index 0000000..5a30d9b --- /dev/null +++ b/pp3/public/img/login/google.svg @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> +<!-- +- Icon was downloaded from https://github.com/simple-icons/simple-icons/blob/4b882220efc78dc824c7647a81b47dd1d4fdd3d8/icons/google.svg +- License is CC0 1.0 Universal: https://github.com/simple-icons/simple-icons/blob/7d037d95f91847634536a592f1126c4ff040fc4d/LICENSE.md +- File was relicensed to ALv2 +--> +<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> + <title>Google icon</title> + <path d="M12.24 10.285V14.4h6.806c-.275 1.765-2.056 5.174-6.806 5.174-4.095 0-7.439-3.389-7.439-7.574s3.345-7.574 7.439-7.574c2.33 0 3.891.989 4.785 1.849l3.254-3.138C18.189 1.186 15.479 0 12.24 0c-6.635 0-12 5.365-12 12s5.365 12 12 12c6.926 0 11.52-4.869 11.52-11.726 0-.788-.085-1.39-.189-1.989H12.24z"/> +</svg> \ No newline at end of file diff --git a/pp3/public/img/zf2-logo.png b/pp3/public/img/zf2-logo.png deleted file mode 100755 index 03c8dae..0000000 Binary files a/pp3/public/img/zf2-logo.png and /dev/null differ diff --git a/pp3/public/js/script.js b/pp3/public/js/script.js index 97e5797..40d4faa 100755 --- a/pp3/public/js/script.js +++ b/pp3/public/js/script.js @@ -17,57 +17,3 @@ $(function () { }, false); }); - - -function onLoad() { - // gapi.load('auth2', function() { - // //gapi.auth2.init(); - // }); - } - -function onSignIn(googleUser) { - var profile = googleUser.getBasicProfile(); - var auth2 = gapi.auth2.getAuthInstance(); - id_token = googleUser.getAuthResponse().id_token; - googleUser.disconnect() - auth2.disconnect(); - $.ajax({ - type: 'post', - url: `${BASE_URL}login/on-google-sign-in-ajax`, - data: { - name: profile.getName(), - email: profile.getEmail(), - idtoken: id_token, - }, - success: (response) => { - if(response === 'reload') { - location.reload(); - } - }, - failure: () => { - console.log('Error processing login data') - }, - }); - // console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead. - // console.log('Name: ' + profile.getName()); - // console.log('Image URL: ' + profile.getImageUrl()); - // console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present. -} - -function signOut() { - var auth2 = gapi.auth2.getAuthInstance(); - auth2.signOut().then(function () { - $.ajax({ - type: 'post', - url: `${BASE_URL}login/on-google-sign-out-ajax`, - data: {}, - success: (response) => { - location.reload(); - console.log('User signed out.'); - }, - failure: () => { - console.log('Error processing login data') - }, - }); - }); -} diff --git a/pp3/public/scss/style.css b/pp3/public/scss/style.css index 736832f..088b86d 100644 --- a/pp3/public/scss/style.css +++ b/pp3/public/scss/style.css @@ -1,69 +1,72 @@ body { - padding-bottom: 20px; -} + padding-bottom: 20px; } .navbar { - margin-bottom: 10px; -} + margin-bottom: 10px; } .navbar-brand .fa { margin-right: 5px; - color: white; -} + color: white; } .navbar-nav { - margin: 5px; -} + margin: 5px; } .navbar-fixed-top { - z-index: 1; -} + z-index: 1; } .badge-red { - background-color: #c12e2a; -} + background-color: #c12e2a; } .badge-green { - background-color: #099c09; -} + background-color: #099c09; } .badge-blue { - background-color: #269eda; -} + background-color: #269eda; } .badge-brown { - background-color: #b59c70; -} + background-color: #b59c70; } .color-red { - color: #c12e2a; -} + color: #c12e2a; } .color-green { - color: #099c09; -} + color: #099c09; } .admin-nav a { display: inline-block; - margin-right: 20px; -} + margin-right: 20px; } .r-white { - color: white; -} + color: white; } .navbar-inverse .navbar-nav > li > a { - color: #c7c7c7; -} + color: #c7c7c7; } .pp-footer { border-top: 1px solid #ddd; padding-top: 20px; text-align: center; - margin-top: 20px; -} + margin-top: 20px; } #pp-navbar { - position: relative; -} -/*# sourceMappingURL=style.css.map */ \ No newline at end of file + position: relative; } + +#loginProviderList .providerIcon { + display: inline-block; + vertical-align: middle; + width: 32px; + height: 32px; + background-size: contain; + margin-right: 1ex; + background-repeat: no-repeat; } + +#loginProviderList .list-group-item { + padding: 0; } + #loginProviderList .list-group-item a { + padding: 10px 15px; + text-decoration: none; + color: black; + background-color: white; } + #loginProviderList .list-group-item a:hover, #loginProviderList .list-group-item a:focus { + color: black; + background-color: #e8e8e8; } diff --git a/pp3/public/scss/style.css.map b/pp3/public/scss/style.css.map index d68979f..1fce345 100644 --- a/pp3/public/scss/style.css.map +++ b/pp3/public/scss/style.css.map @@ -1,9 +1,7 @@ { - "version": 3, - "mappings": "AAAA,AAAA,IAAI,CAAC;EAED,cAAc,EAAE,IAAI;CACvB;;AAED,AAAA,OAAO,CAAC;EACJ,aAAa,EAAE,IAAI;CACtB;;AACD,AAAA,aAAa,CAAC,GAAG,CAAC;EACd,YAAY,EAAE,GAAG;EACjB,KAAK,EAAE,KAAK;CACf;;AACD,AAAA,WAAW,CAAC;EACR,MAAM,EAAE,GAAG;CACd;;AACD,AAAA,iBAAiB,CAAC;EACd,OAAO,EAAE,CAAC;CACb;;AACD,AAAA,UAAU,CAAC;EACP,gBAAgB,EAAE,OAAO;CAC5B;;AACD,AAAA,YAAY,CAAC;EACT,gBAAgB,EAAE,OAAO;CAC5B;;AACD,AAAA,WAAW,CAAC;EACR,gBAAgB,EAAC,OAAO;CAC3B;;AACD,AAAA,YAAY,CAAC;EAET,gBAAgB,EAAE,OAAO;CAC5B;;AAED,AAAA,UAAU [...] - "sources": [ - "style.scss" - ], - "names": [], - "file": "style.css" -} \ No newline at end of file +"version": 3, +"mappings": "AAAA,IAAK;EAED,cAAc,EAAE,IAAI;;AAGxB,OAAQ;EACJ,aAAa,EAAE,IAAI;;AAEvB,iBAAkB;EACd,YAAY,EAAE,GAAG;EACjB,KAAK,EAAE,KAAK;;AAEhB,WAAY;EACR,MAAM,EAAE,GAAG;;AAEf,iBAAkB;EACd,OAAO,EAAE,CAAC;;AAEd,UAAW;EACP,gBAAgB,EAAE,OAAO;;AAE7B,YAAa;EACT,gBAAgB,EAAE,OAAO;;AAE7B,WAAY;EACR,gBAAgB,EAAC,OAAO;;AAE5B,YAAa;EAET,gBAAgB,EAAE,OAAO;;AAG7B,UAAW;EACP,KAAK,EAAE,OAAO;;AAElB,YAAa;EACT,KAAK,EAAE,OAAO;;AAElB,YAAa;EACT,OAAO,EAAE,YAAY;EACrB,YAAY,EAAE,IAAI;;AAEtB,QAAS;EACL,KAAK,EAAE,KAAK;;AAEhB,oCAAiC [...] +"sources": ["style.scss"], +"names": [], +"file": "style.css" +} diff --git a/pp3/public/scss/style.scss b/pp3/public/scss/style.scss index fb7f87f..2f9fed0 100755 --- a/pp3/public/scss/style.scss +++ b/pp3/public/scss/style.scss @@ -54,4 +54,28 @@ body { } #pp-navbar { position: relative; +} + +#loginProviderList .providerIcon { + display: inline-block; + vertical-align: middle; + width: 32px; + height: 32px; + background-size: contain; + margin-right: 1ex; + background-repeat: no-repeat; +} + +#loginProviderList .list-group-item { + padding: 0; + a { + padding: 10px 15px; + text-decoration: none; + color: black; + background-color: white; + &:hover, &:focus { + color: black; + background-color: #e8e8e8; + } + } } \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists