summaryrefslogtreecommitdiffstats
path: root/modules-available/dozmod/api.inc.php
diff options
context:
space:
mode:
authorSimon Rettberg2016-07-06 11:54:37 +0200
committerSimon Rettberg2016-07-06 11:54:37 +0200
commit94417b9f935f02c8710e8a2d28e2d832dbac79fc (patch)
treebe0bbdb80884676219864b2bfb3e985ea24373b9 /modules-available/dozmod/api.inc.php
parent[exams] Handle global room 0 when checking if exam mode is active (diff)
downloadslx-admin-94417b9f935f02c8710e8a2d28e2d832dbac79fc.tar.gz
slx-admin-94417b9f935f02c8710e8a2d28e2d832dbac79fc.tar.xz
slx-admin-94417b9f935f02c8710e8a2d28e2d832dbac79fc.zip
[dozmod] api: Add error checks, implement lecture list resource type
Diffstat (limited to 'modules-available/dozmod/api.inc.php')
-rw-r--r--modules-available/dozmod/api.inc.php170
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");