<?php
class Page_RemoteAccess extends Page
{
protected function doPreprocess()
{
User::load();
if (!User::isLoggedIn()) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
User::assertPermission('view');
$action = Request::post('action', false, 'string');
// Add group adds a DB row and then falls through to regular saving
if ($action === 'add-group') {
User::assertPermission('group.add');
Database::exec("INSERT INTO remoteaccess_group (groupname, wolcount, passwd, active)
VALUES ('.new', 0, '', 0)");
Message::addSuccess('group-added');
if (User::hasPermission('group.edit')) {
$action = 'save-groups';
}
}
if ($action === 'save-groups') {
User::assertPermission('group.edit');
$groups = Request::post('group', [], 'array');
foreach ($groups as $id => $group) {
Database::exec("UPDATE remoteaccess_group SET groupname = :name, wolcount = :wol,
passwd = :passwd, active = :active WHERE groupid = :id", [
'id' => $id,
'name' => isset($group['groupname']) ? $group['groupname'] : $id,
'wol' => isset($group['wolcount']) ? $group['wolcount'] : 0,
'passwd' => isset($group['passwd']) ? $group['passwd'] : 0,
'active' => isset($group['active']) && $group['active'] ? 1 : 0,
]);
}
Message::addSuccess('settings-saved');
} elseif ($action === 'save-settings') {
User::assertPermission('set-proxy-ip');
Property::set(RemoteAccess::PROP_ALLOWED_VNC_NET, Request::post('allowed-source', '', 'string'));
Property::set(RemoteAccess::PROP_TRY_VIRT_HANDOVER, Request::post('virt-handover', false, 'int'));
Property::set(RemoteAccess::PROP_VNC_PORT, Request::post('vncport', 5900, 'int'));
Message::addSuccess('settings-saved');
} elseif ($action === 'delete-group') {
User::assertPermission('group.edit');
$groupid = Request::post('groupid', Request::REQUIRED, 'int');
$group = $this->groupNameOrFail($groupid);
if (!$this->checkGroupLocations($groupid)) {
Message::addError('locations-not-allowed', $group);
} else {
Database::exec("DELETE FROM remoteaccess_group WHERE groupid = :id", ['id' => $groupid]);
Message::addSuccess('group-deleted', $group);
}
} elseif ($action === 'set-locations') {
User::assertPermission('group.locations');
$groupid = Request::post('groupid', Request::REQUIRED, 'int');
$group = $this->groupNameOrFail($groupid);
$locations = array_values(Request::post('location', [], 'array'));
// Merge what's already set where we don't have permission
$locations = Permission::mergeWithDisallowed($locations, 'group.locations',
"SELECT locationid FROM remoteaccess_x_location WHERE groupid = :id", ['id' => $groupid]);
if (empty($locations)) {
Database::exec("DELETE FROM remoteaccess_x_location WHERE groupid = :id", ['id' => $groupid]);
} else {
Database::exec("INSERT IGNORE INTO remoteaccess_x_location (groupid, locationid)
VALUES :values", ['values' => array_map(function($item) use ($groupid) { return [$groupid, $item]; }, $locations)]);
Database::exec("DELETE FROM remoteaccess_x_location WHERE groupid = :id AND locationid NOT IN (:locations)",
['id' => $groupid, 'locations' => $locations]);
}
Message::addSuccess('group-updated', $group);
}
if (Request::isPost()) {
Util::redirect('?do=remoteaccess');
}
}
private function groupNameOrFail($groupid)
{
$group = Database::queryFirst("SELECT groupname FROM remoteaccess_group WHERE groupid = :id",
['id' => $groupid]);
if ($group === false) {
Message::addError('group-not-found', $groupid);
Util::redirect('?do=remoteaccess');
}
return $group['groupname'];
}
protected function doRender()
{
$groupid = Request::get('groupid', false, 'int');
if ($groupid === false) {
// Edit list of groups and their settings
$groups = Database::queryAll("SELECT g.groupid, g.groupname, g.wolcount, g.passwd,
Count(l.locationid) AS locs, If(g.active, 'checked', '') AS checked
FROM remoteaccess_group g LEFT JOIN remoteaccess_x_location l USING (groupid)
GROUP BY g.groupid, g.groupname
ORDER BY g.groupname ASC");
$data = [
'allowed-source' => Property::get(RemoteAccess::PROP_ALLOWED_VNC_NET),
'virt-handover_checked' => Property::get(RemoteAccess::PROP_TRY_VIRT_HANDOVER) ? 'checked' : '',
'vncport' => Property::get(RemoteAccess::PROP_VNC_PORT, 5900),
'groups' => $groups,
];
$data['plugin_version'] = Property::get(RemoteAccess::PROP_PLUGIN_VERSION);
Permission::addGlobalTags($data['perms'], null, ['group.locations', 'group.add', 'group.edit', 'set-proxy-ip']);
Render::addTemplate('edit-settings', $data);
} else {
// Edit locations for group
$group = $this->groupNameOrFail($groupid);
$locationList = Location::getLocationsAssoc();
$enabled = RemoteAccess::getEnabledLocations($groupid);
$allowed = User::getAllowedLocations('group.locations');
foreach ($enabled as $lid) {
if (isset($locationList[$lid])) {
$locationList[$lid]['checked'] = 'checked';
}
}
foreach ($locationList as $lid => &$loc) {
if (!in_array($lid, $allowed)) {
$loc['disabled'] = 'disabled';
}
}
$data = [
'groupid' => $groupid,
'groupname' => $group,
'locations' => array_values($locationList),
'disabled' => empty($allowed) ? 'disabled' : '',
];
Permission::addGlobalTags($data['perms'], null, ['group.locations', 'group.edit']);
Render::addTemplate('edit-group', $data);
}
}
/**
* @param int $groupid group to check
* @return bool if we have permission for all the locations assigned to group
*/
private function checkGroupLocations($groupid)
{
$allowed = User::getAllowedLocations('group.locations');
if (in_array(0, $allowed))
return true;
$hasLocs = Database::queryColumnArray("SELECT locationid FROM remoteaccess_x_location WHERE groupid = :id",
['id' => $groupid]);
$diff = array_diff($hasLocs, $allowed);
return empty($diff);
}
}