diff options
Diffstat (limited to 'modules-available/dozmod/api.inc.php')
-rw-r--r-- | modules-available/dozmod/api.inc.php | 170 |
1 files changed, 115 insertions, 55 deletions
diff --git a/modules-available/dozmod/api.inc.php b/modules-available/dozmod/api.inc.php index b37c668c..e5214a55 100644 --- a/modules-available/dozmod/api.inc.php +++ b/modules-available/dozmod/api.inc.php @@ -1,3 +1,4 @@ + <?php /* small API server that acts as a proxy to the dozmod server. * To reduce the number of requests and connections to dozmod-server, results @@ -5,7 +6,7 @@ * * Required Configuration: * CONFIG_DOZMOD_EXPIRE: Expiration time in seconds for the cache -* CONFIG_DOZMOD: URL to the dozmod server +* CONFIG_DOZMOD_URL: URL to the dozmod server * **/ @@ -15,9 +16,9 @@ if (!Module::isAvailable('locations')) { } -define('LIST_URL', CONFIG_DOZMOD . '/vmchooser/list'); -define('VMX_URL', CONFIG_DOZMOD . '/vmchooser/lecture'); -$availableRessources = ['vmx', 'test', 'netrules']; +define('LIST_URL', CONFIG_DOZMOD_URL . '/vmchooser/list'); +define('VMX_URL', CONFIG_DOZMOD_URL . '/vmchooser/lecture'); +$availableRessources = ['list', 'vmx', 'test', 'netrules']; /* BEGIN: A simple caching mechanism ---------------------------- */ @@ -40,9 +41,9 @@ function cache_put($key, $value) function cache_has($key) { $filename = cache_key_to_filename($key); - $mtime = filemtime($filename); + $mtime = @filemtime($filename); - if (!$mtime) { + if ($mtime === false) { return false; // cache miss } if (time() - $mtime > CONFIG_DOZMOD_EXPIRE) { @@ -66,9 +67,9 @@ function cache_get_passthru($key) $fp = fopen($filename, "r"); if ($fp) { fpassthru($fp); - } else { - Util::traceError("cannot open file"); + exit; } + error_log('Cannot passthrough cache file ' . $filename); } /* END: Cache ---------------------------------------------------- */ @@ -81,25 +82,29 @@ function cache_get_passthru($key) **/ -function println($str) { echo "$str\n"; } - -/* return an array of lecutre uuids. -* Parameter: an array with location Ids -* */ -function _getLecturesForLocations($locationIds) +/** + * Get list of active lectures for given locations. + * + * @return string the raw xml data. + */ +function _getLecturesForLocations($locationIds, $examMode) { - - /* if in any of the locations there is an exam active, consider the client - to be in "exam-mode" and only offer him exams (no lectures) */ - $examMode = false; - - if (Module::isAvailable('exams')) { - $examMode = Exams::isInExamMode($locationIds); - } $ids = implode('%20', $locationIds); $url = LIST_URL . "?locations=$ids" . ($examMode ? '&exams' : ''); - $responseXML = Download::asString($url, 60, $code); + return Download::asString($url, 60, $code); +} + +/** + * Takes raw lecture list xml, returns array of uuids. + * + * @param string $responseXML XML from dozmod server + * @return array list of UUIDs, false on error + */ +function xmlToLectureIds($responseXML) +{ $xml = new SimpleXMLElement($responseXML); + if (!isset($xml->eintrag)) + return []; $uuids = []; foreach ($xml->eintrag as $e) { @@ -109,16 +114,48 @@ function _getLecturesForLocations($locationIds) } /** Caching wrapper around _getLecturesForLocations() */ -function getLecturesForLocations($locationIds) +function getListForLocations($locationIds, $raw) { + /* if in any of the locations there is an exam active, consider the client + to be in "exam-mode" and only offer him exams (no lectures) */ $key = 'lectures_' . cache_hash($locationIds); - if (cache_has($key)) { + $examMode = false; + if (Module::isAvailable('exams')) { + $examMode = Exams::isInExamMode($locationIds); + if ($examMode) { + $key .= '_exams'; + } + } + $rawKey = $key . '_raw'; + if ($raw) { + Header('Content-Type: text/xml; charset=utf-8'); + if (cache_has($rawKey)) { + cache_get_passthru($rawKey); + } + } elseif (cache_has($key)) { return unserialize(cache_get($key)); - } else { - $value = _getLecturesForLocations($locationIds); - cache_put($key, serialize($value)); - return $value; } + // Not in cache + $value = _getLecturesForLocations($locationIds, $examMode); + if ($value === false) + return false; + cache_put($rawKey, $value); + $list = xmlToLectureIds($value); + cache_put($key, serialize($list)); + if ($raw) { + die($value); + } + return $list; +} + +function getLectureUuidsForLocations($locationIds) +{ + return getListForLocations($locationIds, false); +} + +function outputLectureXmlForLocation($locationIds) +{ + return getListForLocations($locationIds, true); } function _getVMX($lecture_uuid) @@ -129,58 +166,81 @@ function _getVMX($lecture_uuid) } /** Caching wrapper around _getVMX() **/ -function getVMX($lecture_uuid) +function outputVMX($lecture_uuid) { $key = 'vmx_' . $lecture_uuid; if (cache_has($key)) { cache_get_passthru($key); } else { $value = _getVMX($lecture_uuid); + if ($value === false) + return false; cache_put($key, $value); - return $value; + die($value); } } +function fatalDozmodUnreachable() +{ + Header('HTTP/1.1 504 Gateway Timeout'); + die('Resource not available'); +} -// -----------------------------------------------------------------------------// -$ip = $_SERVER['REMOTE_ADDR']; -if (substr($ip, 0, 7) === '::ffff:') { - $ip = substr($ip, 7); +function readLectureParam() +{ + global $location_ids; + $lecture = Request::get('lecture', false, 'string'); + if ($lecture === false) { + Header('HTTP/1.1 400 Bad Request'); + die('Missing lecture UUID'); + } + $lectures = getLectureUuidsForLocations($location_ids); + if ($lectures === false) { + fatalDozmodUnreachable(); + } + /* check that the user requests a lecture that he is allowed to have */ + if (!in_array($lecture, $lectures)) { + Header('HTTP/1.1 403 Forbidden'); + die("You don't have permission to access this lecture"); + } + return $lecture; } + +// -----------------------------------------------------------------------------// /* request data, don't trust */ $resource = Request::get('resource', false, 'string'); -$lecture = Request::get('lecture', false, 'string'); if ($resource === false) { Util::traceError("you have to specify the 'resource' parameter"); } -if ($lecture === false) { - Util::traceError("you have to specify the 'lecture' parameter"); + +if (!in_array($resource, $availableRessources)) { + Util::traceError("unknown resource: $resource"); } +$ip = $_SERVER['REMOTE_ADDR']; +if (substr($ip, 0, 7) === '::ffff:') { + $ip = substr($ip, 7); +} + + /* lookup location id(s) */ $location_ids = Location::getFromIp($ip); $location_ids = Location::getLocationRootChain($location_ids); -/* lookup lecture uuids */ -$lectures = getLecturesForLocations($location_ids); - -/* validate request -------------------------------------------- */ -/* check resources */ -if (!in_array($resource, $availableRessources)) { - Util::traceError("unknown resource: $resource"); +if ($resource === 'vmx') { + $lecture = readLectureParam(); + outputVMX($lecture); + // outputVMX does not return on success + fatalDozmodUnreachable(); } -/* check that the user requests a lecture that he is allowed to have */ -if (!in_array($lecture, $lectures)) { - Util::traceError("client is not allowed to access this lecture: $lecture"); +if ($resource === 'list') { + outputLectureXmlForLocation($location_ids); + // Won't return on success... + fatalDozmodUnreachable(); } -if ($resource === 'vmx') { - echo getVMX($lecture); -} else if ($resource === 'test') { - echo "Here's your special test data!"; -} else { - echo "I don't know how to give you that resource"; -} +Header('HTTP/1.1 400 Bad Request'); +die("I don't know how to give you that resource"); |