diff options
Diffstat (limited to 'modules-available/remoteaccess/page.inc.php')
-rw-r--r-- | modules-available/remoteaccess/page.inc.php | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/modules-available/remoteaccess/page.inc.php b/modules-available/remoteaccess/page.inc.php new file mode 100644 index 00000000..ba248b4d --- /dev/null +++ b/modules-available/remoteaccess/page.inc.php @@ -0,0 +1,196 @@ +<?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' => $group['groupname'] ?? $id, + 'wol' => $group['wolcount'] ?? 0, + 'passwd' => $group['passwd'] ?? 0, + 'active' => (int)($group['active'] ?? 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, unwoken + 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']); + // List of locations used in at least one group + $res = Database::simpleQuery("SELECT l.locationid, l.locationname, g.groupid, g.groupname, g.active + FROM location l + INNER JOIN remoteaccess_x_location rxl USING (locationid) + INNER JOIN remoteaccess_group g USING (groupid) + ORDER BY locationname, locationid"); + $data['locations'] = []; + $last = null; + foreach ($res as $row) { + if ($last === null || $last['locationid'] !== $row['locationid']) { + unset($last); + $last = [ + 'locationid' => $row['locationid'], + 'locationname' => $row['locationname'], + 'lclass' => 'slx-strike', + 'groups' => [], + ]; + $data['locations'][] =& $last; + } + $last['groups'][] = [ + 'groupid' => $row['groupid'], + 'groupname' => $row['groupname'], + 'gclass' => $row['active'] ? '' : 'slx-strike', + ]; + if ($row['active']) { + $last['lclass'] = ''; + } + } + unset($last); + $this->addSchedulerTags($data['locations']); + Render::addTemplate('edit-settings', $data); + } else { + // Edit locations for group + $group = $this->groupNameOrFail($groupid); + $locationList = Location::getLocationsAssoc(); + $enabled = RemoteAccess::getEnabledLocations($groupid, false); + $allowed = User::getAllowedLocations('group.locations'); + foreach ($enabled as $lid) { + if (isset($locationList[$lid])) { + $locationList[$lid]['checked'] = 'checked'; + } + } + $this->addSchedulerTags($locationList); + 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(int $groupid): bool + { + $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); + } + + private function addSchedulerTags(array &$locationList) + { + if (!Module::isAvailable('rebootcontrol')) + return; + foreach ($locationList as $lid => &$loc) { + $options = Scheduler::getLocationOptions($loc['locationid'] ?? $lid); + if ($options['ra-mode'] === Scheduler::RA_SELECTIVE) { + $loc['ra_selective'] = true; + } elseif ($options['ra-mode'] === Scheduler::RA_NEVER) { + $loc['ra_never'] = true; + } + } + } + +} |