testing api-key listing
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
92
api_keys.php
92
api_keys.php
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
if (! defined('AREA')) {
|
if (!defined('AREA')) {
|
||||||
header("Location: index.php");
|
header("Location: index.php");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,7 @@ if (! defined('AREA')) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use Froxlor\Database\Database;
|
use Froxlor\Database\Database;
|
||||||
|
use Froxlor\UI\Panel\UI;
|
||||||
use Froxlor\UI\Request;
|
use Froxlor\UI\Request;
|
||||||
|
|
||||||
// This file is being included in admin_index and customer_index
|
// This file is being included in admin_index and customer_index
|
||||||
@@ -86,10 +87,10 @@ if ($action == 'delete') {
|
|||||||
} elseif ($action == 'jqEditApiKey') {
|
} elseif ($action == 'jqEditApiKey') {
|
||||||
$keyid = isset($_POST['id']) ? (int) $_POST['id'] : 0;
|
$keyid = isset($_POST['id']) ? (int) $_POST['id'] : 0;
|
||||||
$allowed_from = isset($_POST['allowed_from']) ? $_POST['allowed_from'] : "";
|
$allowed_from = isset($_POST['allowed_from']) ? $_POST['allowed_from'] : "";
|
||||||
$valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : - 1;
|
$valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : -1;
|
||||||
|
|
||||||
// validate allowed_from
|
// validate allowed_from
|
||||||
if (! empty($allowed_from)) {
|
if (!empty($allowed_from)) {
|
||||||
$ip_list = array_map('trim', explode(",", $allowed_from));
|
$ip_list = array_map('trim', explode(",", $allowed_from));
|
||||||
$_check_list = $ip_list;
|
$_check_list = $ip_list;
|
||||||
foreach ($_check_list as $idx => $ip) {
|
foreach ($_check_list as $idx => $ip) {
|
||||||
@@ -101,8 +102,8 @@ if ($action == 'delete') {
|
|||||||
$allowed_from = implode(",", array_unique($ip_list));
|
$allowed_from = implode(",", array_unique($ip_list));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($valid_until <= 0 || ! is_numeric($valid_until)) {
|
if ($valid_until <= 0 || !is_numeric($valid_until)) {
|
||||||
$valid_until = - 1;
|
$valid_until = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$upd_stmt = Database::prepare("
|
$upd_stmt = Database::prepare("
|
||||||
@@ -128,7 +129,7 @@ if ($action == 'delete') {
|
|||||||
|
|
||||||
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed api::api_keys");
|
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed api::api_keys");
|
||||||
|
|
||||||
// select all my (accessible) certificates
|
// select all my (accessible) api-keys
|
||||||
$keys_stmt_query = "SELECT ak.*, c.loginname, a.loginname as adminname
|
$keys_stmt_query = "SELECT ak.*, c.loginname, a.loginname as adminname
|
||||||
FROM `" . TABLE_API_KEYS . "` ak
|
FROM `" . TABLE_API_KEYS . "` ak
|
||||||
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `ak`.`customerid`
|
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `ak`.`customerid`
|
||||||
@@ -158,13 +159,11 @@ if (AREA == 'admin' && $userinfo['customers_see_all'] == '0') {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$paging = new \Froxlor\UI\Paging($userinfo, TABLE_API_KEYS, $fields);
|
//$keys_stmt_query .= $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit();
|
||||||
$keys_stmt_query .= $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit();
|
|
||||||
|
|
||||||
$keys_stmt = Database::prepare($keys_stmt_query);
|
$keys_stmt = Database::prepare($keys_stmt_query);
|
||||||
Database::pexecute($keys_stmt, $qry_params);
|
Database::pexecute($keys_stmt, $qry_params);
|
||||||
$all_keys = $keys_stmt->fetchAll(PDO::FETCH_ASSOC);
|
$all_keys = $keys_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
$apikeys = "";
|
|
||||||
|
|
||||||
if (count($all_keys) == 0) {
|
if (count($all_keys) == 0) {
|
||||||
$count = 0;
|
$count = 0;
|
||||||
@@ -173,64 +172,19 @@ if (count($all_keys) == 0) {
|
|||||||
$searchcode = "";
|
$searchcode = "";
|
||||||
$pagingcode = "";
|
$pagingcode = "";
|
||||||
eval("\$apikeys.=\"" . \Froxlor\UI\Template::getTemplate("api_keys/keys_error", true) . "\";");
|
eval("\$apikeys.=\"" . \Froxlor\UI\Template::getTemplate("api_keys/keys_error", true) . "\";");
|
||||||
} else {
|
|
||||||
$count = count($all_keys);
|
|
||||||
$paging->setEntries($count);
|
|
||||||
$sortcode = $paging->getHtmlSortCode($lng);
|
|
||||||
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
|
|
||||||
$searchcode = $paging->getHtmlSearchCode($lng);
|
|
||||||
$pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s);
|
|
||||||
|
|
||||||
foreach ($all_keys as $idx => $key) {
|
|
||||||
if ($paging->checkDisplay($idx)) {
|
|
||||||
|
|
||||||
// my own key
|
|
||||||
$isMyKey = false;
|
|
||||||
if ($key['adminid'] == $userinfo['adminid'] && ((AREA == 'admin' && $key['customerid'] == 0) || (AREA == 'customer' && $key['customerid'] == $userinfo['customerid']))) {
|
|
||||||
// this is mine
|
|
||||||
$isMyKey = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$adminCustomerLink = "";
|
|
||||||
if (AREA == 'admin') {
|
|
||||||
if ($isMyKey) {
|
|
||||||
$adminCustomerLink = $key['adminname'];
|
|
||||||
} else {
|
|
||||||
$adminCustomerLink = '<a href="' . $linker->getLink(array(
|
|
||||||
'section' => (empty($key['customerid']) ? 'admins' : 'customers'),
|
|
||||||
'page' => (empty($key['customerid']) ? 'admins' : 'customers'),
|
|
||||||
'action' => 'su',
|
|
||||||
'id' => (empty($key['customerid']) ? $key['adminid'] : $key['customerid'])
|
|
||||||
)) . '" rel="external">' . (empty($key['customerid']) ? $key['adminname'] : $key['loginname']) . '</a>';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// customer do not need links
|
|
||||||
$adminCustomerLink = $key['loginname'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// escape stuff
|
|
||||||
$row = \Froxlor\PhpHelper::htmlentitiesArray($key);
|
|
||||||
|
|
||||||
// shorten keys
|
|
||||||
$row['_apikey'] = substr($row['apikey'], 0, 20) . '...';
|
|
||||||
$row['_secret'] = substr($row['secret'], 0, 20) . '...';
|
|
||||||
|
|
||||||
// check whether the api key is not valid anymore
|
|
||||||
$isValid = true;
|
|
||||||
if ($row['valid_until'] >= 0) {
|
|
||||||
if ($row['valid_until'] < time()) {
|
|
||||||
$isValid = false;
|
|
||||||
}
|
|
||||||
// format
|
|
||||||
$row['valid_until'] = date('Y-m-d', $row['valid_until']);
|
|
||||||
} else {
|
|
||||||
// infinity
|
|
||||||
$row['valid_until'] = "";
|
|
||||||
}
|
|
||||||
eval("\$apikeys.=\"" . \Froxlor\UI\Template::getTemplate("api_keys/keys_key", true) . "\";");
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
eval("echo \"" . \Froxlor\UI\Template::getTemplate("api_keys/keys_list", true) . "\";");
|
|
||||||
|
$apikeys_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/tablelisting.apikeys.php';
|
||||||
|
$collection = [
|
||||||
|
'data' => $all_keys,
|
||||||
|
'pagination' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
UI::twigBuffer('user/table.html.twig', [
|
||||||
|
'listing' => \Froxlor\UI\Listing::formatFromArray($collection, $apikeys_list_data['apikeys_list']),
|
||||||
|
'actions_links' => (int)$userinfo['api_allowed'] == 1 ? [[
|
||||||
|
'href' => $linker->getLink(['section' => 'index', 'page' => $page, 'action' => 'add']),
|
||||||
|
'label' => $lng['apikeys']['key_add']
|
||||||
|
]] : null
|
||||||
|
]);
|
||||||
|
UI::twigOutputBuffer();
|
||||||
|
|||||||
@@ -58,4 +58,38 @@ class Impersonate
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function apiAdminCustomerLink(array $attributes)
|
||||||
|
{
|
||||||
|
// my own key
|
||||||
|
$isMyKey = false;
|
||||||
|
if (
|
||||||
|
$attributes['fields']['adminid'] == UI::getCurrentUser()['adminid']
|
||||||
|
&& ((AREA == 'admin' && $attributes['fields']['customerid'] == 0)
|
||||||
|
|| (AREA == 'customer' && $attributes['fields']['customerid'] == UI::getCurrentUser()['customerid'])
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// this is mine
|
||||||
|
$isMyKey = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$adminCustomerLink = "";
|
||||||
|
if (AREA == 'admin') {
|
||||||
|
if ($isMyKey) {
|
||||||
|
$adminCustomerLink = $attributes['fields']['adminname'];
|
||||||
|
} else {
|
||||||
|
if (empty($attributes['fields']['customerid'])) {
|
||||||
|
$adminCustomerLink = self::admin($attributes);
|
||||||
|
} else {
|
||||||
|
$attributes['data'] = $attributes['fields']['loginname'];
|
||||||
|
$adminCustomerLink = self::customer($attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// customer do not need links
|
||||||
|
$adminCustomerLink = $attributes['fields']['loginname'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $adminCustomerLink;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,18 @@ class Style
|
|||||||
return $attributes['fields']['deactivated'] ? 'bg-danger' : '';
|
return $attributes['fields']['deactivated'] ? 'bg-danger' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function invalidApiKey(array $attributes): string
|
||||||
|
{
|
||||||
|
// check whether the api key is not valid anymore
|
||||||
|
$isValid = true;
|
||||||
|
if ($attributes['fields']['valid_until'] >= 0) {
|
||||||
|
if ($attributes['fields']['valid_until'] < time()) {
|
||||||
|
$isValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $isValid ? '' : 'bg-danger';
|
||||||
|
}
|
||||||
|
|
||||||
public static function diskspaceWarning(array $attributes): string
|
public static function diskspaceWarning(array $attributes): string
|
||||||
{
|
{
|
||||||
return self::getWarningStyle('diskspace', $attributes['fields'], (int)Settings::Get('system.report_webmax'));
|
return self::getWarningStyle('diskspace', $attributes['fields'], (int)Settings::Get('system.report_webmax'));
|
||||||
|
|||||||
@@ -47,8 +47,18 @@ class Text
|
|||||||
return (int)$attributes['data'] > 0 ? date('d.m.Y H:i', (int)$attributes['data']) : UI::getLng('panel.never');
|
return (int)$attributes['data'] > 0 ? date('d.m.Y H:i', (int)$attributes['data']) : UI::getLng('panel.never');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function timestampUntil(array $attributes): string
|
||||||
|
{
|
||||||
|
return (int)$attributes['data'] > 0 ? date('d.m.Y H:i', (int)$attributes['data']) : UI::getLng('panel.unlimited');
|
||||||
|
}
|
||||||
|
|
||||||
public static function crondesc(array $attributes): string
|
public static function crondesc(array $attributes): string
|
||||||
{
|
{
|
||||||
return UI::getLng('crondesc.' . $attributes['data']);
|
return UI::getLng('crondesc.' . $attributes['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function shorten(array $attributes): string
|
||||||
|
{
|
||||||
|
return substr($attributes['data'], 0, 20) . '...';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,20 @@ class Listing
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function formatFromArray(array $collection, array $tabellisting): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'title' => $tabellisting['title'],
|
||||||
|
'icon' => $tabellisting['icon'],
|
||||||
|
'table' => [
|
||||||
|
'th' => self::generateTableHeadings($tabellisting),
|
||||||
|
'tr' => self::generateTableRows($collection['data'], $tabellisting),
|
||||||
|
],
|
||||||
|
'pagination' => $collection['pagination'],
|
||||||
|
'empty_msg' => $tabellisting['empty_msg'] ?? null
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
private static function generateTableHeadings(array $tabellisting): array
|
private static function generateTableHeadings(array $tabellisting): array
|
||||||
{
|
{
|
||||||
$heading = [];
|
$heading = [];
|
||||||
@@ -92,7 +106,7 @@ class Listing
|
|||||||
} elseif ($field) {
|
} elseif ($field) {
|
||||||
$rows[$row]['td'][$col]['data'] = $data;
|
$rows[$row]['td'][$col]['data'] = $data;
|
||||||
} else {
|
} else {
|
||||||
throw new Exception('The visible column "'. $visible_column .'" has neither a "callback" nor a "field" set.');
|
throw new Exception('The visible column "' . $visible_column . '" has neither a "callback" nor a "field" set.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set class for table-row if defined
|
// Set class for table-row if defined
|
||||||
|
|||||||
85
lib/tablelisting/tablelisting.apikeys.php
Normal file
85
lib/tablelisting/tablelisting.apikeys.php
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is part of the Froxlor project.
|
||||||
|
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the COPYING
|
||||||
|
* file that was distributed with this source code. You can also view the
|
||||||
|
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||||
|
*
|
||||||
|
* @copyright (c) the authors
|
||||||
|
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||||
|
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||||
|
* @package Tabellisting
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Froxlor\UI\Callbacks\Impersonate;
|
||||||
|
use Froxlor\UI\Callbacks\Style;
|
||||||
|
use Froxlor\UI\Callbacks\Text;
|
||||||
|
use Froxlor\UI\Listing;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'apikeys_list' => [
|
||||||
|
'title' => $lng['menue']['main']['apikeys'],
|
||||||
|
'icon' => 'fa-solid fa-key',
|
||||||
|
'columns' => [
|
||||||
|
'a.loginname' => [
|
||||||
|
'label' => $lng['login']['username'],
|
||||||
|
'field' => 'loginname',
|
||||||
|
'callback' => [Impersonate::class, 'apiAdminCustomerLink']
|
||||||
|
],
|
||||||
|
'ak.apikey' => [
|
||||||
|
'label' => 'API-key',
|
||||||
|
'field' => 'apikey',
|
||||||
|
'callback' => [Text::class, 'shorten'],
|
||||||
|
],
|
||||||
|
'ak.secret' => [
|
||||||
|
'label' => 'Secret',
|
||||||
|
'field' => 'secret',
|
||||||
|
'callback' => [Text::class, 'shorten'],
|
||||||
|
],
|
||||||
|
'ak.allowed_from' => [
|
||||||
|
'label' => $lng['apikeys']['allowed_from'],
|
||||||
|
'field' => 'allowed_from',
|
||||||
|
],
|
||||||
|
'ak.valid_until' => [
|
||||||
|
'label' => $lng['apikeys']['valid_until'],
|
||||||
|
'field' => 'valid_until',
|
||||||
|
'callback' => [Text::class, 'timestampUntil'],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'visible_columns' => Listing::getVisibleColumnsForListing('apikeys_list', [
|
||||||
|
'a.loginname',
|
||||||
|
'ak.apikey',
|
||||||
|
'ak.secret',
|
||||||
|
'ak.allowed_from',
|
||||||
|
'ak.valid_until'
|
||||||
|
]),
|
||||||
|
'actions' => [
|
||||||
|
'show' => [
|
||||||
|
'icon' => 'fa fa-eye',
|
||||||
|
'title' => $lng['apikeys']['clicktoview'],
|
||||||
|
'href' => [
|
||||||
|
'page' => 'apikeys',
|
||||||
|
'action' => '#',
|
||||||
|
'id' => ':id'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'delete' => [
|
||||||
|
'icon' => 'fa fa-trash',
|
||||||
|
'title' => $lng['panel']['delete'],
|
||||||
|
'class' => 'text-danger',
|
||||||
|
'href' => [
|
||||||
|
'page' => 'apikeys',
|
||||||
|
'action' => 'delete',
|
||||||
|
'id' => ':id'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'callback' => [
|
||||||
|
[Style::class, 'invalidApiKey']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
Reference in New Issue
Block a user