diff options
-rw-r--r-- | apis/cron.inc.php | 3 | ||||
-rw-r--r-- | inc/property.inc.php | 58 | ||||
-rw-r--r-- | inc/render.inc.php | 1 | ||||
-rw-r--r-- | modules-available/dozmod/lang/de/template-tags.json | 3 | ||||
-rw-r--r-- | modules-available/dozmod/lang/en/template-tags.json | 3 | ||||
-rw-r--r-- | modules-available/dozmod/page.inc.php | 49 | ||||
-rw-r--r-- | modules-available/dozmod/templates/runtimeconfig.html | 35 | ||||
-rw-r--r-- | modules-available/roomplanner/inc/pvsgenerator.inc.php | 19 | ||||
-rw-r--r-- | modules-available/sysconfig/addmodule_adauth.inc.php | 11 | ||||
-rw-r--r-- | modules-available/sysconfig/inc/ldap.inc.php | 14 | ||||
-rw-r--r-- | modules-available/sysconfig/templates/branding-check.html | 7 | ||||
-rw-r--r-- | script/install.js | 6 |
12 files changed, 158 insertions, 51 deletions
diff --git a/apis/cron.inc.php b/apis/cron.inc.php index 8068eb2e..470c70e6 100644 --- a/apis/cron.inc.php +++ b/apis/cron.inc.php @@ -26,6 +26,9 @@ foreach (glob('modules/*/hooks/cron.inc.php') as $file) { } switch (mt_rand(1, 10)) { +case 2: + Database::exec("DELETE FROM property_list WHERE dateline <> 0 AND dateline < UNIX_TIMESTAMP()"); + break; case 3: Database::exec("DELETE FROM property WHERE dateline <> 0 AND dateline < UNIX_TIMESTAMP()"); break; diff --git a/inc/property.inc.php b/inc/property.inc.php index ec3c0612..ba8cb8e1 100644 --- a/inc/property.inc.php +++ b/inc/property.inc.php @@ -36,7 +36,7 @@ class Property * Set value in property store. * * @param string $key key of value to set - * @param type $value the value to store for $key + * @param string $value the value to store for $key * @param int $maxAgeMinutes how long to keep this entry around at least, in minutes. 0 for infinite */ public static function set($key, $value, $maxAgeMinutes = 0) @@ -54,6 +54,61 @@ class Property } } + /** + * Retrieve property list from the store. + * + * @param string $key Key of list to get all items for + * @return array All the items matching the key + */ + public static function getList($key) + { + $res = Database::simpleQuery("SELECT dateline, value FROM property_list WHERE name = :key", compact('key')); + $NOW = time(); + $return = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($row['dateline'] != 0 && $row['dateline'] < $NOW) + continue; + $return[] = $row['value']; + } + return $return; + } + + /** + * Add item to property list. + * + * @param string $key key of value to set + * @param string $value the value to add for $key + * @param int $maxAgeMinutes how long to keep this entry around at least, in minutes. 0 for infinite + */ + public static function addToList($key, $value, $maxAgeMinutes = 0) + { + Database::exec("INSERT INTO property_list (name, value, dateline) VALUES (:key, :value, :dateline)", array( + 'key' => $key, + 'value' => $value, + 'dateline' => ($maxAgeMinutes === 0 ? 0 : time() + ($maxAgeMinutes * 60)) + )); + } + + /** + * Remove given item from property list. If the list contains this item + * multiple times, they will all be removed. + * + * @param string $key Key of list + * @param string $value item to remove + * @return int number of items removed + */ + public static function removeFromList($key, $value) + { + return Database::exec("DELETE FROM property_list WHERE name = :key AND value = :value", array( + 'key' => $key, + 'value' => $value, + )); + } + + /* + * Legacy getters/setters + */ + public static function getServerIp() { return self::get('server-ip', 'none'); @@ -185,7 +240,6 @@ class Property return self::get('password-type', 'password'); } - public static function getIpxeDefault() { return self::get('default-ipxe'); diff --git a/inc/render.inc.php b/inc/render.inc.php index 10419d6f..5515c659 100644 --- a/inc/render.inc.php +++ b/inc/render.inc.php @@ -88,6 +88,7 @@ class Render <script src="script/bootstrap.min.js"></script> <script src="script/taskmanager.js"></script> <script src="script/fileselect.js"></script> + <script src="script/collapse.js"></script> '; foreach ($modules as $module) { $file = $module->getDir() . '/clientscript.js'; diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index a7a91e11..b980e011 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -1,5 +1,7 @@ { "lang_actionTarget": "Aktionsziel", + "lang_allowLoginByDefault": "Login standardm\u00e4\u00dfig erlauben", + "lang_allowLoginDescription": "Wenn diese Option aktiviert ist, k\u00f6nnen sich alle Mitarbeiter der Einrichtung \u00fcber die bwLehrpool-Suite anmelden und VMs\/Veranstaltungen verwalten. Wenn Sie diese Option deaktivieren, m\u00fcssen Sie in der Untersektion \"Benutzer und Berechtigungen\" jeden Benutzer nach dem ersten Loginversuch manuell freischalten.", "lang_asteriskRequired": "Felder mit (*) sind erforderlich", "lang_blockCount": "Anzahl Bl\u00f6cke", "lang_canLogin": "Nutzer dieser Einrichtung k\u00f6nnen sich am Satelliten anmelden", @@ -42,6 +44,7 @@ "lang_maxImageValidity": "G\u00fcltigkeitsdauer neuer VM-Versionen (Tage)", "lang_maxLectureVisibility": "Sp\u00e4testes Enddatum einer Veranstaltung (Tage in der Zukunft)", "lang_maxTransfers": "Maximale Zahl gleichzeitiger Up-\/Downloads pro Benutzer", + "lang_miscOptions": "Verschiedene Einstellungen", "lang_name": "Name", "lang_organization": "Einrichtung", "lang_organizationList": "Liste der Einrichtungen", diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json index 6e1a3996..0dfd1825 100644 --- a/modules-available/dozmod/lang/en/template-tags.json +++ b/modules-available/dozmod/lang/en/template-tags.json @@ -1,5 +1,7 @@ { "lang_actionTarget": "Action target", + "lang_allowLoginByDefault": "Allow all staff members to login and use the bwLehrpool-Suite", + "lang_allowLoginDescription": "If this option is enabled, all members of the organization marked as staff or employee are allowed to login to this server and manage VMs\/courses. Otherwise, new users need to be individually allowed access after their first login attempt by visiting the sub page \"users and permissions\" in this web interface.", "lang_asteriskRequired": "Fields marked with (*) are required", "lang_blockCount": "Block count", "lang_canLogin": "Members of this organization can login", @@ -42,6 +44,7 @@ "lang_maxImageValidity": "New VM validity (days)", "lang_maxLectureVisibility": "Max time lecture end date may lie in the future (days)", "lang_maxTransfers": "Max concurrent transfers per user", + "lang_miscOptions": "Misc options", "lang_name": "Name", "lang_organization": "Organization", "lang_organizationList": "List of organizations", diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index 6c0c8a6b..7f1e6ee3 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -89,29 +89,32 @@ class Page_DozMod extends Page if ($section === 'runtimeconfig') { // Runtime config $runtimeConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'runtimelimits')); - if ($runtimeConf != null) { + if ($runtimeConf !== false) { $runtimeConf = json_decode($runtimeConf['value'], true); /* convert some value to corresponding "selected" texts */ if ($runtimeConf['defaultLecturePermissions']['edit']) { - $runtimeConf['defaultLecturePermissions']['edit'] = 'checked="checked"'; + $runtimeConf['defaultLecturePermissions']['edit'] = 'checked'; } if ($runtimeConf['defaultLecturePermissions']['admin']) { - $runtimeConf['defaultLecturePermissions']['admin'] = 'checked="checked"'; + $runtimeConf['defaultLecturePermissions']['admin'] = 'checked'; } if ($runtimeConf['defaultImagePermissions']['edit']) { - $runtimeConf['defaultImagePermissions']['edit'] = 'checked="checked"'; + $runtimeConf['defaultImagePermissions']['edit'] = 'checked'; } if ($runtimeConf['defaultImagePermissions']['admin']) { - $runtimeConf['defaultImagePermissions']['admin'] = 'checked="checked"'; + $runtimeConf['defaultImagePermissions']['admin'] = 'checked'; } if ($runtimeConf['defaultImagePermissions']['link']) { - $runtimeConf['defaultImagePermissions']['link'] = 'checked="checked"'; + $runtimeConf['defaultImagePermissions']['link'] = 'checked'; } if ($runtimeConf['defaultImagePermissions']['download']) { - $runtimeConf['defaultImagePermissions']['download'] = 'checked="checked"'; + $runtimeConf['defaultImagePermissions']['download'] = 'checked'; } + if ($runtimeConf['allowLoginByDefault']) { + $runtimeConf['allowLoginByDefault'] = 'checked'; + } } Render::addTemplate('runtimeconfig', $runtimeConf); } @@ -310,14 +313,29 @@ class Page_DozMod extends Page $data['defaultLecturePermissions'] = Request::post('defaultLecturePermissions', NULL, "array"); $data['defaultImagePermissions'] = Request::post('defaultImagePermissions', NULL, "array"); - $intParams = [ - 'maxImageValidityDays' => array('min' => 7, 'max' => 999), - 'maxLectureValidityDays' => array('min' => 7, 'max' => 999), - 'maxTransfers' => array('min' => 1, 'max' => 10), + $params = [ + 'int' => [ + 'maxImageValidityDays' => array('min' => 7, 'max' => 999), + 'maxLectureValidityDays' => array('min' => 7, 'max' => 999), + 'maxTransfers' => array('min' => 1, 'max' => 10), + ], + 'bool' => [ + 'allowLoginByDefault' => array('default' => true) + ], ]; - foreach($intParams as $field => $limits) { - $value = Request::post($field, 0, 'int'); - $data[$field] = max(min($value, $limits['max']), $limits['min']); + foreach ($params as $type => $list) { + foreach ($list as $field => $limits) { + $default = isset($limits['default']) ? $limits['default'] : false; + $value = Request::post($field, $default); + settype($value, $type); + if (isset($limits['min']) && $value < $limits['min']) { + $value = $limits['min']; + } + if (isset($limits['max']) && $value > $limits['max']) { + $value = $limits['max']; + } + $data[$field] = $value; + } } /* ensure types */ @@ -327,9 +345,6 @@ class Page_DozMod extends Page settype($data['defaultImagePermissions']['admin'], 'boolean'); settype($data['defaultImagePermissions']['link'], 'boolean'); settype($data['defaultImagePermissions']['download'], 'boolean'); - settype($data['maxImageValidityDays'], 'int'); - settype($data['maxLectureValidityDays'], 'int'); - settype($data['maxTransfers'], 'int'); $data = json_encode($data); Database::exec('INSERT INTO sat.configuration (parameter, value)' diff --git a/modules-available/dozmod/templates/runtimeconfig.html b/modules-available/dozmod/templates/runtimeconfig.html index e538dee8..9bdc44b0 100644 --- a/modules-available/dozmod/templates/runtimeconfig.html +++ b/modules-available/dozmod/templates/runtimeconfig.html @@ -91,6 +91,17 @@ </table> </fieldset> + <fieldset> + <h3>{{lang_miscOptions}}</h3> + <div class="checkbox"> + <input type="hidden" name="allowLoginByDefault" value="0"> + <input type="checkbox" name="allowLoginByDefault" value="1" {{allowLoginByDefault}} id ="allowLoginByDefault" class="form-control"> + <label> + {{lang_allowLoginByDefault}} + </label> + <p><i>{{lang_allowLoginDescription}}</i></p> + </div> + </fieldset> <br> <input type="hidden" name="token" value="{{token}}"> @@ -99,27 +110,3 @@ </form> </div> </div> - -<script type="text/javascript"><!-- -function slxTestConfig() { - $('#test-button').prop('disabled', true); - $('#test-spin').css('display', ''); - var str = $('#mailconf').serialize(); - str += '&button=test'; - console.log(str); - $.post('?do=DozMod', str).done(function(data) { - console.log('Success'); - console.log(data); - checkRes(data); - }).fail(function() { - checkRes('DozMod refused the connection'); - }).always(function() { - $('#test-button').prop('disabled', false); - $('#test-spin').css('display', 'none'); - }); - } - - function checkRes(text) { - $('#test-output').css('display', '').text(text); - } -// --> </script> diff --git a/modules-available/roomplanner/inc/pvsgenerator.inc.php b/modules-available/roomplanner/inc/pvsgenerator.inc.php index c00d5439..d61e826b 100644 --- a/modules-available/roomplanner/inc/pvsgenerator.inc.php +++ b/modules-available/roomplanner/inc/pvsgenerator.inc.php @@ -16,6 +16,8 @@ class PvsGenerator /* get all rooms */ $rooms = array(); + // Use left joins everywhere so we still have the complete list of locations below + // for figuring out which locations are leafs and which aren't $ret = Database::simpleQuery( 'SELECT l.locationid, l.parentlocationid, l.locationname, lr.locationid AS notnull, lr.managerip, lr.tutoruuid, m.clientip as tutorip ' . 'FROM location l ' @@ -27,12 +29,27 @@ class PvsGenerator settype($row['parentlocationid'], 'int'); $rooms[$row['locationid']] = $row; } + // Mark all non-leafs as skip foreach ($rooms as &$room) { if ($room['parentlocationid'] > 0 && isset($rooms[$room['parentlocationid']])) { $rooms[$room['parentlocationid']]['skip'] = true; // Don't just unset, might be wrong order } } - unset($room); // refd! + // Now un-mark all where there's at least one child without valid room plan + foreach ($rooms as &$room) { + if (!isset($room['skip']) && (is_null($room['notnull']) || empty($room['managerip']))) { + $room['skip'] = true; + $r2 =& $room; + while ($r2['parentlocationid'] > 0) { + $r2 =& $rooms[$r2['parentlocationid']]; + if (!(is_null($room['notnull']) || empty($room['managerip']))) { + unset($r2['skip']); + break; + } + } + } + } + unset($room, $r2); // refd! /* collect names and build room blocks - filter empty rooms while at it */ $roomNames = array(); diff --git a/modules-available/sysconfig/addmodule_adauth.inc.php b/modules-available/sysconfig/addmodule_adauth.inc.php index 666c36d1..266327a8 100644 --- a/modules-available/sysconfig/addmodule_adauth.inc.php +++ b/modules-available/sysconfig/addmodule_adauth.inc.php @@ -140,10 +140,12 @@ class AdAuth_SelfSearch extends AddModule_Base } else { $uri = "ldap://$server:3268/"; } + + $selfSearchBase = Ldap::getSelfSearchBase($binddn, $searchbase); // Set up selfSearch task $taskData = array( 'server' => $uri, - 'searchbase' => $searchbase, + 'searchbase' => $selfSearchBase, 'bindpw' => $bindpw, ); if (preg_match(AD_SHORT_REGEX, $binddn, $out) && !empty($out[2])) { @@ -153,12 +155,12 @@ class AdAuth_SelfSearch extends AddModule_Base $this->originalBindDn = $binddn; $taskData['filter'] = 'sAMAccountName=' . $out[1]; } elseif (preg_match('/^cn\=([^\=]+),.*?,dc\=([^\=]+),/i', Ldap::normalizeDn($binddn), $out)) { - if (empty($searchbase)) { + if (empty($selfSearchBase)) { $this->originalBindDn = $out[2] . '\\' . $out[1]; $taskData['filter'] = 'sAMAccountName=' . $out[1]; } else { $this->originalBindDn = $binddn; - $taskData['filter'] = "distinguishedName=$binddn"; + $taskData['filter'] = 'distinguishedName=' . Ldap::normalizeDn($binddn); } } else { Message::addError('could-not-determine-binddn', $binddn); @@ -232,11 +234,12 @@ class AdAuth_HomeAttrCheck extends AddModule_Base } else { $uri = "ldap://$server:$port/"; } + $selfSearchBase = Ldap::getSelfSearchBase($binddn, $searchbase); preg_match('#^(\w+\=[^\=]+),#', $binddn, $out); $filter = $out[1]; $data = array( 'server' => $uri, - 'searchbase' => $searchbase, + 'searchbase' => $selfSearchBase, 'binddn' => $binddn, 'bindpw' => $bindpw, 'filter' => $filter diff --git a/modules-available/sysconfig/inc/ldap.inc.php b/modules-available/sysconfig/inc/ldap.inc.php index ed471f31..23b24885 100644 --- a/modules-available/sysconfig/inc/ldap.inc.php +++ b/modules-available/sysconfig/inc/ldap.inc.php @@ -8,4 +8,18 @@ class Ldap return trim(preg_replace('/[,;]\s*/', ',', $dn)); } + public static function getSelfSearchBase($binddn, $searchbase) + { + // To find ourselves we try to figure out the proper search base, since the given one + // might be just for users, not for functional or utility accounts + if (preg_match('/,(OU=.*DC=.*)$/i', Ldap::normalizeDn($binddn), $out)) { + // Get OU from binddn; works if not given short form of DOMAIN\user or user@domain.fqdn.com + $searchbase = $out[1]; + } elseif (preg_match('/,(DC=.*)$/i', Ldap::normalizeDn($searchbase), $out)) { + // Otherwise, shorten search base enough to only consider the DC=..,DC=.. part at the end + $searchbase = $out[1]; + } + return $searchbase; + } + } diff --git a/modules-available/sysconfig/templates/branding-check.html b/modules-available/sysconfig/templates/branding-check.html index 8f6ef055..1a021309 100644 --- a/modules-available/sysconfig/templates/branding-check.html +++ b/modules-available/sysconfig/templates/branding-check.html @@ -21,6 +21,11 @@ <label for="title-id">{{lang_title}}</label> <input type="text" name="title" value="{{title}}" id ="title-id" class="form-control" placeholder="Name des Moduls"> </div> - <button type="submit" class="btn btn-primary">{{lang_save}}</button> + <div class="btn-group"> + <a class="btn btn-default" href="?do=SysConfig&action=addmodule&step=Branding_Start">{{lang_cancel}}</a> + </div> + <div class="btn-group pull-right"> + <button type="submit" class="btn btn-primary">{{lang_save}}</button> + </div> </form> </div> diff --git a/script/install.js b/script/install.js index a85f869c..9738f1a2 100644 --- a/script/install.js +++ b/script/install.js @@ -77,7 +77,7 @@ var slxTrigger = function (elem, moduleName) { //alert('always: ' + moduleName + ', status: ' + slxModules[moduleName] + ', current: ' + slxCurrent); if (slxModules[moduleName] === 'WORKING') { slxModules[moduleName] = 'UPDATE_FAILED'; - $('#mod-' + moduleName).text('UPDATE_FAILED (No response from server)'); + $('#mod-' + moduleName).text('UPDATE_FAILED (No response from server)').css('color', '#c00'); } if (slxCurrent === moduleName) { slxCurrent = false; @@ -112,7 +112,9 @@ function slxRunNext(lastModule) { slxRun(next); } else { slxCancelTimer(); - alert('Done.'); + setTimeout(function() { + alert('Done.'); + }, 10); } } |