From ec3ca777b678de56e082a951dd6b00b125b0c2d4 Mon Sep 17 00:00:00 2001 From: Sonia Zorba Date: Mon, 9 Sep 2019 16:24:51 +0200 Subject: [PATCH] Improved admin panel and services list --- classes/JWKSHandler.php | 2 +- classes/UserSearchResult.php | 88 ------------------- classes/Util.php | 40 --------- classes/datalayer/OAuth2ClientDAO.php | 4 +- classes/datalayer/UserDAO.php | 2 + .../datalayer/mysql/MySQLOAuth2ClientDAO.php | 23 +++-- classes/datalayer/mysql/MySQLUserDAO.php | 15 ++++ classes/model/InternalClient.php | 4 + classes/model/OAuth2Client.php | 2 + include/admin.php | 7 +- include/front-controller.php | 7 +- js/admin.js | 2 + sql/setup-database.sql | 8 ++ views/account-management.php | 9 ++ views/admin/index.php | 23 ++++- views/services-list.php | 30 +++---- 16 files changed, 105 insertions(+), 161 deletions(-) delete mode 100644 classes/UserSearchResult.php delete mode 100644 classes/Util.php diff --git a/classes/JWKSHandler.php b/classes/JWKSHandler.php index 4c2ca9b..feffd90 100644 --- a/classes/JWKSHandler.php +++ b/classes/JWKSHandler.php @@ -5,7 +5,7 @@ namespace RAP; use phpseclib\Crypt\RSA; /** - * Manages the JWT Key Sets (currently only RSA . + * Manages the JWT Key Sets (currently only RSA). */ class JWKSHandler { diff --git a/classes/UserSearchResult.php b/classes/UserSearchResult.php deleted file mode 100644 index c1d49d9..0000000 --- a/classes/UserSearchResult.php +++ /dev/null @@ -1,88 +0,0 @@ -user = $user; - - $nameAndSurname = null; - $email = null; - $identityTypes = []; - foreach ($user->identities as $identity) { - array_push($identityTypes, $identity->getUIType()); - if ($nameAndSurname === null && $identity->name !== null && $identity->surname !== null) { - $nameAndSurname = $identity->name . ' ' . $identity->surname; - } - if ($email === null) { - $email = $identity->email; - } - } - - // Building display text string - $displayText = ""; - - if ($nameAndSurname !== null) { - $displayText .= $nameAndSurname; - } else { - $displayText .= $email; - } - - $displayText .= ' ('; - $firstIdentity = true; - foreach ($identityTypes as $type) { - if (!$firstIdentity) { - $displayText .= '+'; - } - $displayText .= $type; - $firstIdentity = false; - } - $displayText .= ')'; - - $usr->userDisplayText = $displayText; - - return $usr; - } - - public function getUser() { - return $this->user; - } - -} diff --git a/classes/Util.php b/classes/Util.php deleted file mode 100644 index 4879b9b..0000000 --- a/classes/Util.php +++ /dev/null @@ -1,40 +0,0 @@ -getDBHandler(); // Load clients info - $queryClient = "SELECT id, title, icon, client, secret, redirect_url, scope FROM oauth2_client"; + $queryClient = "SELECT id, title, icon, client, secret, redirect_url, scope, home_page, show_in_home FROM oauth2_client"; $stmtClients = $dbh->prepare($queryClient); $stmtClients->execute(); @@ -27,6 +27,8 @@ class MySQLOAuth2ClientDAO extends BaseMySQLDAO implements OAuth2ClientDAO { $client->secret = $row['secret']; $client->redirectUrl = $row['redirect_url']; $client->scope = $row['scope']; + $client->homePage = $row['home_page']; + $client->showInHome = boolval($row['show_in_home']); $clientsMap[$client->id] = $client; } @@ -49,14 +51,14 @@ class MySQLOAuth2ClientDAO extends BaseMySQLDAO implements OAuth2ClientDAO { return $clients; } - function createOAuth2Client($client): OAuth2Client { + function createOAuth2Client(OAuth2Client $client): OAuth2Client { $dbh = $this->getDBHandler(); try { $dbh->beginTransaction(); - $stmt = $dbh->prepare("INSERT INTO `oauth2_client`(`title`, `icon`, `client`, `secret`, `redirect_url`, `scope`)" - . " VALUES(:title, :icon, :client, :secret, :redirect_url, :scope)"); + $stmt = $dbh->prepare("INSERT INTO `oauth2_client`(`title`, `icon`, `client`, `secret`, `redirect_url`, `scope`, home_page, show_in_home)" + . " VALUES(:title, :icon, :client, :secret, :redirect_url, :scope, :home_page, :show_in_home)"); $stmt->bindParam(':title', $client->title); $stmt->bindParam(':icon', $client->icon); @@ -64,6 +66,8 @@ class MySQLOAuth2ClientDAO extends BaseMySQLDAO implements OAuth2ClientDAO { $stmt->bindParam(':secret', $client->secret); $stmt->bindParam(':redirect_url', $client->redirectUrl); $stmt->bindParam(':scope', $client->scope); + $stmt->bindParam(':home_page', $client->homePage); + $stmt->bindParam(':show_in_home', $client->showInHome, \PDO::PARAM_INT); $stmt->execute(); @@ -88,14 +92,15 @@ class MySQLOAuth2ClientDAO extends BaseMySQLDAO implements OAuth2ClientDAO { return $client; } - function updateOAuth2Client($client): OAuth2Client { + function updateOAuth2Client(OAuth2Client $client): OAuth2Client { $dbh = $this->getDBHandler(); try { $dbh->beginTransaction(); $stmt = $dbh->prepare("UPDATE `oauth2_client` SET `title` = :title, `icon` = :icon, " - . " `client` = :client, `secret` = :secret, `redirect_url` = :redirect_url, `scope` = :scope " + . " `client` = :client, `secret` = :secret, `redirect_url` = :redirect_url, `scope` = :scope, " + . " `home_page` = :home_page, `show_in_home` = :show_in_home" . " WHERE id = :id"); $stmt->bindParam(':title', $client->title); @@ -104,6 +109,8 @@ class MySQLOAuth2ClientDAO extends BaseMySQLDAO implements OAuth2ClientDAO { $stmt->bindParam(':secret', $client->secret); $stmt->bindParam(':redirect_url', $client->redirectUrl); $stmt->bindParam(':scope', $client->scope); + $stmt->bindParam(':home_page', $client->homePage); + $stmt->bindParam(':show_in_home', $client->showInHome, \PDO::PARAM_INT); $stmt->bindParam(':id', $client->id); $stmt->execute(); @@ -158,7 +165,7 @@ class MySQLOAuth2ClientDAO extends BaseMySQLDAO implements OAuth2ClientDAO { $dbh = $this->getDBHandler(); // Load clients info - $queryClient = "SELECT id, title, icon, client, secret, redirect_url, scope FROM oauth2_client WHERE client = :client"; + $queryClient = "SELECT id, title, icon, client, secret, redirect_url, scope, home_page, show_in_home FROM oauth2_client WHERE client = :client"; $stmtClient = $dbh->prepare($queryClient); $stmtClient->bindParam(':client', $clientId); $stmtClient->execute(); @@ -182,6 +189,8 @@ class MySQLOAuth2ClientDAO extends BaseMySQLDAO implements OAuth2ClientDAO { $client->secret = $row['secret']; $client->redirectUrl = $row['redirect_url']; $client->scope = $row['scope']; + $client->homePage = $row['home_page']; + $client->showInHome = $row['show_in_home']; // Load authentication methods info $queryAuthNMethods = "SELECT auth_method FROM oauth2_client_auth_methods WHERE client_id = :id"; diff --git a/classes/datalayer/mysql/MySQLUserDAO.php b/classes/datalayer/mysql/MySQLUserDAO.php index cc1adaa..14f8c0d 100644 --- a/classes/datalayer/mysql/MySQLUserDAO.php +++ b/classes/datalayer/mysql/MySQLUserDAO.php @@ -266,4 +266,19 @@ class MySQLUserDAO extends BaseMySQLDAO implements UserDAO { } } + function isAdmin($userId): bool { + + $dbh = $this->getDBHandler(); + + $query = "SELECT user_id FROM rap_permissions WHERE permission = 'ADMIN' AND user_id = :userId"; + + $stmt = $dbh->prepare($query); + $stmt->bindParam(':userId', $userId); + $stmt->execute(); + + $result = $stmt->fetchAll(); + + return count($result) === 1; + } + } diff --git a/classes/model/InternalClient.php b/classes/model/InternalClient.php index 36a81aa..f91f7d0 100644 --- a/classes/model/InternalClient.php +++ b/classes/model/InternalClient.php @@ -2,6 +2,10 @@ namespace RAP; +/** + * Represents a client that connects to parts of RAP itself (e.g. Account Manager). + * It doesn't use OAuth2, instead stores data directly into the PHP session. + */ class InternalClient extends RAPClient { public $action; diff --git a/classes/model/OAuth2Client.php b/classes/model/OAuth2Client.php index ba6f43f..254fefe 100644 --- a/classes/model/OAuth2Client.php +++ b/classes/model/OAuth2Client.php @@ -34,6 +34,8 @@ class OAuth2Client extends RAPClient { public $secret; public $redirectUrl; public $scope; + public $homePage; + public $showInHome; public function getIconBasePath() { return 'client-icons/'; diff --git a/include/admin.php b/include/admin.php index 2c344df..3e3b7fa 100644 --- a/include/admin.php +++ b/include/admin.php @@ -16,7 +16,10 @@ function checkUser() { die("You must be registered to perform this action"); } - // TODO: check is admin + $dao = $locator->getUserDAO(); + if (!$dao->isAdmin($session->getUser()->id)) { + die("You must be an admin to perform this action"); + } } Flight::route('GET /admin', function() { @@ -94,6 +97,8 @@ function buildOAuth2ClientFromData() { $client->secret = $data['secret']; $client->redirectUrl = $data['redirectUrl']; $client->scope = $data['scope']; + $client->homePage = $data['homePage']; + $client->showInHome = $data['showInHome']; } if (isset($data['authMethods'])) { foreach ($data['authMethods'] as $method) { diff --git a/include/front-controller.php b/include/front-controller.php index 90a9da3..fc172e2 100644 --- a/include/front-controller.php +++ b/include/front-controller.php @@ -56,8 +56,10 @@ Flight::route('/', function() { break; default: session_destroy(); + $clients = $locator->getOAuth2ClientDAO()->getOAuth2Clients(); Flight::render('services-list.php', array('title' => 'RAP', 'version' => $locator->getVersion(), + 'clients' => $clients, 'action' => $locator->getBasePath() . '/')); break; } @@ -308,11 +310,14 @@ Flight::route('GET /account', function () { session_start(); global $locator; - if ($locator->getSession()->getUser() === null) { + $user = $locator->getSession()->getUser(); + if ($user === null) { Flight::redirect('/'); } else { + $admin = $locator->getUserDAO()->isAdmin($user->id); Flight::render('account-management.php', array('title' => 'RAP Account Management', 'version' => $locator->getVersion(), 'session' => $locator->getSession(), + 'admin' => $admin, 'contextRoot' => $locator->config->contextRoot)); } }); diff --git a/js/admin.js b/js/admin.js index fd34841..d07d56d 100644 --- a/js/admin.js +++ b/js/admin.js @@ -54,6 +54,8 @@ secret: null, redirectUrl: null, scope: null, + homePage: null, + showInHome: false, authMethods: {}, edit: true }; diff --git a/sql/setup-database.sql b/sql/setup-database.sql index f561c33..af10551 100644 --- a/sql/setup-database.sql +++ b/sql/setup-database.sql @@ -6,6 +6,8 @@ CREATE TABLE `oauth2_client` ( `secret` varchar(255) NOT NULL, `redirect_url` text NOT NULL, `scope` varchar(255) NOT NULL, + `home_page` varchar(255), + `show_in_home` boolean DEFAULT FALSE, PRIMARY KEY (`id`), UNIQUE(client) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -64,6 +66,12 @@ CREATE TABLE `rsa_keypairs` ( PRIMARY KEY (`id`) ); +CREATE TABLE `rap_permissions` ( + `user_id` bigint NOT NULL, + `permission` varchar(255) NOT NULL, + PRIMARY KEY (`user_id`, `permission`) +); + CREATE EVENT login_tokens_cleanup ON SCHEDULE EVERY 1 MINUTE diff --git a/views/account-management.php b/views/account-management.php index 372bab5..5cb798c 100644 --- a/views/account-management.php +++ b/views/account-management.php @@ -25,6 +25,15 @@ include 'include/header.php';
Logout
+ +
+

+ + + Admin + +
+ Add client -

OAuth2 clients

+

OAuth2/OIDC clients


@@ -39,6 +39,7 @@ include 'include/header.php';

{{client.icon}}

+
@@ -69,6 +70,26 @@ include 'include/header.php';
+
+ +
+

{{client.homePage}}

+ +
+
+
+ +
+

+ +

+
+ +
+
+
diff --git a/views/services-list.php b/views/services-list.php index bc441d1..5929fd7 100644 --- a/views/services-list.php +++ b/views/services-list.php @@ -1,37 +1,27 @@

Please choose the service where you want to login: