summaryrefslogblamecommitdiffstats
path: root/modules-available/remoteaccess/page.inc.php
blob: ba248b4d6636cd4614c9b1ffb4703a8a3989e737 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12

     









                                                                
                                               


                                                                                   
                                                            

                                                                                                            
                                                           


                                                                
                 

                                                             




                                                                                                                 



                                                                                 

                                   


                                                               

                                                                                                                          
                                                                                                          
                                                              

                                                             
                                                                                      





                                                                                                                         
                         



                                                                                      
                                                                                          


                                                                                                                          







                                                                                                                                                            
                                                                     





                                                           










                                                                                                             





                                                                                                          
                                                                                                    

                                                                                           




                                                                                                                                
                                                                                              

                                                    
                                                                                                   
                                                                                                                                        





















                                                                                                                           
                                                                                       






                                                                    


                                                                    
                                                                  
                                                                      
                                                                                      
                                                                                




                                                                                   
                                                               












                                                                                                           


                 



                                                                                     
                                                                









                                                                                                                           













                                                                                             
 
<?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;
			}
		}
	}

}