summaryrefslogblamecommitdiffstats
path: root/modules-available/locations/pages/locations.inc.php
blob: 788183286ee15f28b1462357e867b4762474856e (plain) (tree)
1
2
3
4
5
6




             
                                                          







                                                 
                                                         


















                                                                                                 
                                                    
























































                                                                                                                                              
                                                                             
 
                                                                                 
 








                                                                                                                            
                                         

                                 
                 










                                                                               
                         
                 


                                                         
                                                                                   
                         
                 



                                                                        










                                                                             


                                                            
                                                              


                                                                
                                                                          
                  

                                                                                                  
                                                               

         
                                                                                                                        



                                                  
                                                                         
                                                                    






                                                                                                                        
                         
                                                                         




                                              
<?php

class SubPage
{

	public static function doPreprocess($action): bool
	{
		if ($action === 'addlocations') {
			self::addLocations();
			return true;
		}
		return false;
	}

	public static function doRender($getAction): bool
	{
		if ($getAction === false) {
			if (User::hasPermission('location.view')) {
				// OK
			} elseif (User::hasPermission('subnets.edit')) {
				// Fallback to something else?
				Util::redirect('?do=locations&page=subnets');
			} else {
				// Trigger permission denied by asserting non-existent permission
				User::assertPermission('location.view');
			}
		}
		if ($getAction === false) {
			self::showLocationList();
			return true;
		}
		return false;
	}

	public static function doAjax($action): bool
	{
		return false;
	}

	private static function addLocations()
	{
		$names = Request::post('newlocation', false);
		$parents = Request::post('newparent', []);
		if (!is_array($names) || !is_array($parents)) {
			Message::addError('main.empty-field');
			Util::redirect('?do=Locations');
		}
		$locs = Location::getLocations();
		$count = 0;
		foreach ($names as $idx => $name) {
			$name = trim($name);
			if (empty($name))
				continue;
			$parent = isset($parents[$idx]) ? (int)$parents[$idx] : 0;
			if (!User::hasPermission("location.add", $parent)) {
				Message::addError('no-permission-location', isset($locs[$parent]) ? $locs[$parent]['locationname'] : $parent);
				continue;
			}
			if ($parent !== 0) {
				$ok = false;
				foreach ($locs as $loc) {
					if ($loc['locationid'] == $parent) {
						$ok = true;
					}
				}
				if (!$ok) {
					Message::addWarning('main.value-invalid', 'parentlocationid', $parent);
					continue;
				}
			}
			Database::exec("INSERT INTO location (parentlocationid, locationname)"
				. " VALUES (:parent, :name)", array(
				'parent' => $parent,
				'name' => $name
			));
			$count++;
		}
		Message::addSuccess('added-x-entries', $count);
		Util::redirect('?do=Locations');
	}

	public static function showLocationList()
	{
		// Warn admin about overlapping subnet definitions
		$overlapSelf = $overlapOther = true;
		LocationUtil::getOverlappingSubnets($overlapSelf, $overlapOther);
		// Find machines assigned to a room with a UUID mismatch
		$mismatchMachines = LocationUtil::getMachinesWithLocationMismatch(0, true);
		$locationList = Location::getLocationsAssoc();
		unset($locationList[0]);
		// Statistics: Count machines for each subnet
		$unassigned = false;
		$unassignedIdle = $unassignedLoad = $unassignedOverrides = 0;

		$allowedLocationIds = User::getAllowedLocations("location.view");

		$plugins = [];
		foreach (Hook::load('locations-column') as $hook) {
			$c = @include($hook->file);
			if ($c instanceof AbstractLocationColumn) {
				$plugins[sprintf('%04d.%s', $c->priority(), $hook->moduleId)] = $c;
			} elseif (is_array($c)) {
				foreach ($c as $i => $cc) {
					if ($cc instanceof AbstractLocationColumn) {
						$plugins[sprintf('%04d.%d.%s', $cc->priority(), $i, $hook->moduleId)] = $cc;
					}
				}
			}
		}
		ksort($plugins);
		foreach ($locationList as $lid => &$loc) {
			$loc['plugins'] = [];
			foreach ($plugins as $pk => $plugin) {
				$loc['plugins'][$pk] = [
					'url' => $plugin->getEditUrl($lid),
					'html' => $plugin->getColumnHtml($lid),
				];
			}
			if (!in_array($lid, $allowedLocationIds)) {
				$locationList[$lid]['show-only'] = true;
			}
		}
		unset($loc);
		foreach ($plugins as $pk => $plugin) {
			if ($plugin->propagateColumn()) {
				self::propagateFields($locationList, $plugin, $pk);
			}
		}
		foreach ($locationList as &$loc) {
			$loc['plugins'] = array_values($loc['plugins']);
		}
		unset($loc);

		$addAllowedLocs = User::getAllowedLocations("location.add");
		$addAllowedList = Location::getLocations(0, 0, true);
		foreach ($addAllowedList as &$loc) {
			if (!in_array($loc["locationid"], $addAllowedLocs)) {
				$loc["disabled"] = "disabled";
			}
		}
		unset($loc);

		// Output
		$data = [
			'colspan' => (2 + count($plugins)),
			'plugins' => array_values($plugins),
			'list' => array_values($locationList),
			'overlapSelf' => $overlapSelf,
			'overlapOther' => $overlapOther,
			'mismatchMachines' => $mismatchMachines,
			'addAllowedList' => array_values($addAllowedList),
		];
		Permission::addGlobalTags($data['perms'], NULL, ['subnets.edit', 'location.add']);
		Render::addTemplate('locations', $data);
		Module::isAvailable('js_ip'); // For CIDR magic
	}

	private static function propagateFields(array &$locationList, AbstractLocationColumn $plugin, string $pluginKey)
	{
		$depth = array();
		foreach ($locationList as &$loc) {
			$d = $loc['depth'];
			if (empty($loc['plugins'][$pluginKey]['html'])) {
				// Has no explicit config assignment
				$loc['plugins'][$pluginKey]['html'] = $depth[$d - 1] ?? $plugin->propagateDefaultHtml();
				$loc['plugins'][$pluginKey]['class'] = 'gray';
			} elseif (empty($loc['plugins'][$pluginKey]['class'])) {
				$loc['plugins'][$pluginKey]['class'] = 'slx-bold';
				$loc['plugins'][$pluginKey]['html'] =
					$plugin->propagationOverride($depth[$d - 1] ?? $plugin->propagateDefaultHtml(),
						$loc['plugins'][$pluginKey]['html']);
			}
			$depth[$d] = $loc['plugins'][$pluginKey]['html'];
			unset($depth[$d + 1]);
		}
	}

}