started UI api-key management
Signed-off-by: Michael Kaufmann (d00p) <d00p@froxlor.org>
This commit is contained in:
@@ -393,6 +393,9 @@ if ($page == 'overview') {
|
||||
redirectTo($filename, array('s' => $s));
|
||||
}
|
||||
}
|
||||
elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) {
|
||||
require_once __DIR__ . '/api_keys.php';
|
||||
}
|
||||
elseif ($page == 'apihelp' && Settings::Get('api.enabled') == 1) {
|
||||
require_once __DIR__ . '/apihelp.php';
|
||||
}
|
||||
|
||||
128
api_keys.php
Normal file
128
api_keys.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
if (! defined('AREA')) {
|
||||
header("Location: index.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2018 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> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Panel
|
||||
* @since 0.10.0
|
||||
*
|
||||
*/
|
||||
|
||||
// This file is being included in admin_index and customer_index
|
||||
// and therefore does not need to require lib/init.php
|
||||
|
||||
$log->logAction(USR_ACTION, LOG_NOTICE, "viewed api::api_keys");
|
||||
|
||||
// select all my (accessable) certificates
|
||||
$keys_stmt_query = "SELECT ak.*, c.loginname, a.loginname as adminname
|
||||
FROM `" . TABLE_API_KEYS . "` ak
|
||||
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `ak`.`customerid`
|
||||
LEFT JOIN `" . TABLE_PANEL_ADMINS . "` a ON `a`.`adminid` = `ak`.`adminid`
|
||||
WHERE ";
|
||||
|
||||
$qry_params = array();
|
||||
if (AREA == 'admin' && $userinfo['customers_see_all'] == '0') {
|
||||
// admin with only customer-specific permissions
|
||||
$keys_stmt_query .= "ak.adminid = :adminid ";
|
||||
$qry_params['adminid'] = $userinfo['adminid'];
|
||||
$fields = array(
|
||||
'a.loginname' => $lng['login']['username']
|
||||
);
|
||||
} elseif (AREA == 'customer') {
|
||||
// customer-area
|
||||
$keys_stmt_query .= "ak.customerid = :cid ";
|
||||
$qry_params['cid'] = $userinfo['customerid'];
|
||||
$fields = array(
|
||||
'c.loginname' => $lng['login']['username']
|
||||
);
|
||||
} else {
|
||||
// admin who can see all customers / reseller / admins
|
||||
$keys_stmt_query .= "1 ";
|
||||
$fields = array(
|
||||
'a.loginname' => $lng['login']['username']
|
||||
);
|
||||
}
|
||||
|
||||
$paging = new paging($userinfo, TABLE_API_KEYS, $fields);
|
||||
$keys_stmt_query .= $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit();
|
||||
|
||||
$keys_stmt = Database::prepare($keys_stmt_query);
|
||||
Database::pexecute($keys_stmt, $qry_params);
|
||||
$all_keys = $keys_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$apikeys = "";
|
||||
|
||||
if (count($all_keys) == 0) {
|
||||
$count = 0;
|
||||
$message = $lng['apikeys']['no_api_keys'];
|
||||
$sortcode = "";
|
||||
$searchcode = "";
|
||||
$pagingcode = "";
|
||||
eval("\$apikeys.=\"" . 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' || (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 = htmlentities_array($key);
|
||||
|
||||
// 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('d.m.Y H:i', $row['valid_until']);
|
||||
} else {
|
||||
$row['valid_until'] = "∞";
|
||||
}
|
||||
eval("\$apikeys.=\"" . getTemplate("api_keys/keys_key", true) . "\";");
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
eval("echo \"" . getTemplate("api_keys/keys_list", true) . "\";");
|
||||
@@ -314,6 +314,9 @@ if ($page == 'overview') {
|
||||
redirectTo($filename, array('s' => $s));
|
||||
}
|
||||
}
|
||||
elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) {
|
||||
require_once __DIR__ . '/api_keys.php';
|
||||
}
|
||||
elseif ($page == 'apihelp' && Settings::Get('api.enabled') == 1) {
|
||||
require_once __DIR__ . '/apihelp.php';
|
||||
}
|
||||
|
||||
@@ -595,27 +595,31 @@ class Admins extends ApiCommand implements ResourceEntity
|
||||
standard_error('youcantdeleteyourself', '', true);
|
||||
}
|
||||
|
||||
// delete admin
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
|
||||
// delete the traffic-usage
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_TRAFFIC_ADMINS . "` WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
|
||||
// delete the diskspace usage
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_PANEL_DISKSPACE_ADMINS . "` WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($del_stmt, array(
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
|
||||
// set admin-id of the old admin's customer to current admins
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET
|
||||
`adminid` = :userid WHERE `adminid` = :adminid
|
||||
@@ -624,7 +628,8 @@ class Admins extends ApiCommand implements ResourceEntity
|
||||
'userid' => $this->getUserDetail('adminid'),
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
|
||||
// set admin-id of the old admin's domains to current admins
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
`adminid` = :userid WHERE `adminid` = :adminid
|
||||
@@ -633,7 +638,26 @@ class Admins extends ApiCommand implements ResourceEntity
|
||||
'userid' => $this->getUserDetail('adminid'),
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
|
||||
// delete old admin's api keys if exists (no customer keys)
|
||||
$upd_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_API_KEYS . "` WHERE
|
||||
`adminid` = :userid AND `customerid` = '0'
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
// set admin-id of the old admin's api-keys to current admins
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_API_KEYS . "` SET
|
||||
`adminid` = :userid WHERE `adminid` = :adminid
|
||||
");
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'userid' => $this->getUserDetail('adminid'),
|
||||
'adminid' => $id
|
||||
), true, true);
|
||||
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] deleted admin '" . $result['loginname'] . "'");
|
||||
updateCounters();
|
||||
return $this->response(200, "successfull", $result);
|
||||
|
||||
@@ -857,9 +857,9 @@ class Customers extends ApiCommand implements ResourceEntity
|
||||
// activate/deactivate customer services
|
||||
if ($deactivated != $result['deactivated']) {
|
||||
|
||||
$yesno = (($deactivated) ? 'N' : 'Y');
|
||||
$pop3 = (($deactivated) ? '0' : (int) $result['pop3']);
|
||||
$imap = (($deactivated) ? '0' : (int) $result['imap']);
|
||||
$yesno = ($deactivated ? 'N' : 'Y');
|
||||
$pop3 = ($deactivated ? '0' : (int) $result['pop3']);
|
||||
$imap = ($deactivated ? '0' : (int) $result['imap']);
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_USERS . "` SET `postfix`= :yesno, `pop3` = :pop3, `imap` = :imap WHERE `customerid` = :customerid
|
||||
@@ -923,8 +923,16 @@ class Customers extends ApiCommand implements ResourceEntity
|
||||
// At last flush the new privileges
|
||||
$dbm->getManager()->flushPrivileges();
|
||||
Database::needRoot(false);
|
||||
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] deactivated user '" . $result['loginname'] . "'");
|
||||
|
||||
// reactivate/deactivate api-keys
|
||||
$valid_until = $deactivated ? 0 : - 1;
|
||||
$stmt = Database::prepare("UPDATE `" . TABLE_API_KEYS . "` SET `valid_until` = :vu WHERE `customerid` = :id");
|
||||
Database::pexecute($stmt, array(
|
||||
'id' => $id,
|
||||
'vu' => $valid_until
|
||||
), true, true);
|
||||
|
||||
$this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] " . ($deactivated ? 'deactivated' : 'reactivated') . " user '" . $result['loginname'] . "'");
|
||||
inserttask('1');
|
||||
}
|
||||
|
||||
@@ -1323,6 +1331,12 @@ class Customers extends ApiCommand implements ResourceEntity
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
// remove api-keys
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_API_KEYS . "` WHERE `customerid` = :id");
|
||||
Database::pexecute($stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
// Delete all waiting "create user" -tasks for this user, #276
|
||||
// Note: the WHERE selects part of a serialized array, but it should be safe this way
|
||||
$del_stmt = Database::prepare("
|
||||
|
||||
@@ -38,6 +38,11 @@ return array(
|
||||
'label' => $lng['menue']['main']['changetheme'],
|
||||
'show_element' => (Settings::Get('panel.allow_theme_change_customer') == true)
|
||||
),
|
||||
array(
|
||||
'url' => 'customer_index.php?page=apikeys',
|
||||
'label' => $lng['menue']['main']['apikeys'],
|
||||
'show_element' => (Settings::Get('api.enabled') == true)
|
||||
),
|
||||
array(
|
||||
'url' => 'customer_index.php?page=apihelp',
|
||||
'label' => $lng['menue']['main']['apihelp'],
|
||||
@@ -184,6 +189,11 @@ return array(
|
||||
'label' => $lng['menue']['main']['changetheme'],
|
||||
'show_element' => (Settings::Get('panel.allow_theme_change_admin') == true)
|
||||
),
|
||||
array(
|
||||
'url' => 'admin_index.php?page=apikeys',
|
||||
'label' => $lng['menue']['main']['apikeys'],
|
||||
'show_element' => (Settings::Get('api.enabled') == true)
|
||||
),
|
||||
array(
|
||||
'url' => 'admin_index.php?page=apihelp',
|
||||
'label' => $lng['menue']['main']['apihelp'],
|
||||
|
||||
@@ -2123,3 +2123,6 @@ $lng['admin']['notryfiles']['description'] = 'Say yes here if you want to specif
|
||||
// added in froxlor 0.10.0
|
||||
$lng['panel']['none_value'] = 'None';
|
||||
$lng['menue']['main']['apihelp'] = 'API help';
|
||||
$lng['menue']['main']['apikeys'] = 'API keys';
|
||||
$lng['apikeys']['no_api_keys'] = 'No API keys found';
|
||||
$lng['apikeys']['key_add'] = 'Add new key';
|
||||
|
||||
@@ -1773,3 +1773,6 @@ $lng['admin']['notryfiles']['description'] = 'Wähle "Ja", wenn eine eigene try_
|
||||
// added in froxlor 0.10.0
|
||||
$lng['panel']['none_value'] = 'Keine';
|
||||
$lng['menue']['main']['apihelp'] = 'API Hilfe';
|
||||
$lng['menue']['main']['apikeys'] = 'API Keys';
|
||||
$lng['apikeys']['no_api_keys'] = 'Keine API Keys gefunden';
|
||||
$lng['apikeys']['key_add'] = 'API Key hinzufügen';
|
||||
|
||||
3
templates/Sparkle/api_keys/keys_error.tpl
vendored
Normal file
3
templates/Sparkle/api_keys/keys_error.tpl
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<tr>
|
||||
<td colspan="6"><span class="red">{$message}</span></td>
|
||||
</tr>
|
||||
27
templates/Sparkle/api_keys/keys_key.tpl
vendored
Normal file
27
templates/Sparkle/api_keys/keys_key.tpl
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<tr <if $isMyKey>class="primary-entry"</if>>
|
||||
<td>
|
||||
{$adminCustomerLink}
|
||||
</td>
|
||||
<td>
|
||||
{$row['apikey']}
|
||||
</td>
|
||||
<td>
|
||||
{$row['secret']}
|
||||
</td>
|
||||
<td>
|
||||
{$row['allowed_from']}
|
||||
</td>
|
||||
<td>
|
||||
<if !$isValid><strong><span class="red"></if>
|
||||
{$row['valid_until']}
|
||||
<if !$isValid></span></strong></if>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{$linker->getLink(array('section' => 'index', 'page' => $page, 'action' => 'edit', 'id' => $row['id']))}">
|
||||
<img src="templates/{$theme}/assets/img/icons/edit.png" alt="{$lng['panel']['edit']}" title="{$lng['panel']['edit']}" />
|
||||
</a>
|
||||
<a href="{$linker->getLink(array('section' => 'index', 'page' => $page, 'action' => 'delete', 'id' => $row['id']))}">
|
||||
<img src="templates/{$theme}/assets/img/icons/delete.png" alt="{$lng['panel']['delete']}" title="{$lng['panel']['delete']}" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
68
templates/Sparkle/api_keys/keys_list.tpl
vendored
Normal file
68
templates/Sparkle/api_keys/keys_list.tpl
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
$header
|
||||
<article>
|
||||
<header>
|
||||
<h2>
|
||||
<img src="templates/{$theme}/assets/img/icons/lock_big.png" alt="" />
|
||||
{$lng['menue']['main']['apikeys']}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<if !empty($success_message)>
|
||||
<div class="successcontainer bradius">
|
||||
<div class="successtitle">{$lng['success']['success']}</div>
|
||||
<div class="success">
|
||||
$success_message
|
||||
</div>
|
||||
</div>
|
||||
</if>
|
||||
|
||||
<section>
|
||||
|
||||
<form action="{$linker->getLink(array('section' => 'index', 'page' => $page))}" method="post" enctype="application/x-www-form-urlencoded">
|
||||
<input type="hidden" name="s" value="$s" />
|
||||
<input type="hidden" name="page" value="$page" />
|
||||
|
||||
<div class="overviewsearch">
|
||||
{$searchcode}
|
||||
</div>
|
||||
|
||||
<div class="overviewadd">
|
||||
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />
|
||||
<a href="{$linker->getLink(array('section' => 'index', 'page' => $page, 'action' => 'add'))}">{$lng['apikeys']['key_add']}</a>
|
||||
</div>
|
||||
|
||||
<table class="full hl">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<th>API-keys</th>
|
||||
<th>Secret</th>
|
||||
<th>Allowed from</th>
|
||||
<th>Valid until</th>
|
||||
<th>{$lng['panel']['options']}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<if $pagingcode != ''>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="6">{$pagingcode}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</if>
|
||||
|
||||
<tbody>
|
||||
{$apikeys}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<if 15 < $count >
|
||||
<div class="overviewadd">
|
||||
<img src="templates/{$theme}/assets/img/icons/add.png" alt="" />
|
||||
<a href="{$linker->getLink(array('section' => 'index', 'page' => $page, 'action' => 'add'))}">{$lng['apikeys']['key_add']}</a>
|
||||
</div>
|
||||
</if>
|
||||
</section>
|
||||
</article>
|
||||
$footer
|
||||
4
templates/Sparkle/assets/css/main.css
vendored
4
templates/Sparkle/assets/css/main.css
vendored
@@ -1682,13 +1682,13 @@ fieldset.file {
|
||||
background-color: rgb(242, 222, 222);
|
||||
}
|
||||
|
||||
.domain-hostname {
|
||||
.primary-entry {
|
||||
background-color: rgb(53, 106, 160);
|
||||
color: #ddd;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.hl tbody tr.domain-hostname:hover {
|
||||
table.hl tbody tr.primary-entry:hover {
|
||||
background-color: rgb(64, 150, 238);
|
||||
}
|
||||
|
||||
|
||||
1
templates/Sparkle/header.tpl
vendored
1
templates/Sparkle/header.tpl
vendored
@@ -68,6 +68,7 @@
|
||||
<li><a href="{$linker->getLink(array('section' => 'index', 'page' => 'change_theme'))}">{$lng['panel']['theme']}</a></li>
|
||||
</if>
|
||||
<if Settings::Get('api.enabled') == 1>
|
||||
<li><a href="{$linker->getLink(array('section' => 'index', 'page' => 'apikeys'))}">{$lng['menue']['main']['apikeys']}</a></li>
|
||||
<li><a href="{$linker->getLink(array('section' => 'index', 'page' => 'apihelp'))}">{$lng['menue']['main']['apihelp']}</a></li>
|
||||
</if>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user