stattbuchung_php_open/client.php

304 lines
11 KiB
PHP

<?php
/**
* Ein HTTP-Client in PHP unter Verwendung der curl-Bibliothek für den Zugriff auf die APIs
* im SDW-/BiDat-Ökosystem. Sollte im produktiven Einsatz immer SSL-gesichert verwendet werden.
*
* Autor: Benedikt Wismans
*/
define("opcLogon", 1003);
define("opcLogoff", 1002);
define("httpOK", 200);
define("httpMovedTemp", 302);
define("httpMovedTempNew", 303);
// Der Frontcontroller liegt im geschützten Bereich. Jeder Aufruf dieser URL mit egal was hinten dran verlangt
// AUthentifizierung oder eine authentifizierte Session
define("frontcontroller", "/SDW/resources/fc");
// Die Loginform liegt im public-Bereich. Aufurfe von URLs wie dem Frontcontroller werden bei nicht authtifizierten
// Session an diese URL weitergeleitet zur Authentifizierung
define("loginform", '/SDW/j_security_check');
/**
* Öffnet eine Verbindung zu einem Tomcatcontainer mit container based authentifiaction.
* Der Vorgag ist 2 stufig, als 3. Stufe wird dann noch das eigentliche Login gemacht.
*
* @param {String} $url Die URL fer Servers in der Form http(s)://fqdn:port
* @param {String} &user Der Nutzername des Accounts
* @param {String} &pass Das Kennwort des Accounts
* @param {Boolean} $debug Debug-Flag
* @returns {Object} Ein Assoc Array mit Metadtaen der geoffneten und authentifizierten Session. Muss in folgende requests reingesteckt werden.
*
*/
function login($url, $user, $pass, $debug) {
$sessionId = uniqid('', true);
$cookie='/tmp/'.$sessionId;
// stage 1: call protected ressource: Frontcontroller with Opcode Login
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_COOKIESESSION => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url.frontcontroller.'?opc='.opcLogon,
CURLOPT_USERAGENT => 'PHP Request '.$sessionId
));
// Save SdessionCookie JSESSIONID returned by server
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);
curl_exec($curl);
if (curl_errno($curl)) {
throw new Exception(curl_error($curl), curl_errno($curl));
}
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($http_code!=httpOK) {
throw new Exception('HTTP-Response STATUS<>200', $http_code);
}
curl_close($curl);
// stage 2 : send credentials using sessioncookie
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url.loginform,
CURLOPT_USERAGENT => 'PHP Request '.$sessionId,
CURLOPT_POST => 1,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
'Connection: Keep-Alive'
)
));
// Put credentail into postbody invisible in logs
curl_setopt($curl, CURLOPT_POSTFIELDS,'j_username='.urlencode($user).'&j_password='.urlencode($pass));
// Send SdessionCookie JSESSIONID
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie);
curl_exec($curl);
if (curl_errno($curl)) {
throw new Exception(curl_error($curl), curl_errno($curl));
}
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($http_code!=httpMovedTemp && $http_code!=httpMovedTempNew) {
throw new Exception('HTTP-Response STATUS<>302 || 303', $http_code);
}
curl_close($curl);
// stage 3: call protected ressource again which is now accessible due to 302:moved temporarily
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url.frontcontroller.'?opc='.opcLogon,
CURLOPT_USERAGENT => 'PHP Request '.$sessionId
));
// Send SdessionCookie JSESSIONID
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie);
// Session has changed after logon due to security issue so save new cookie
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);
$longonInfo=curl_exec($curl);
if (curl_errno($curl)) {
throw new Exception(curl_error($curl), curl_errno($curl));
}
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($http_code!=httpOK) {
throw new Exception('HTTP-Response STATUS<>200', $http_code);
}
curl_close($curl);
// convert result from JSON to assoc array and add session infos
$sessionInfo=json_decode($longonInfo, true);
$sessionInfo ['sessionId'] = $sessionId;
$sessionInfo ['cookie'] = $cookie;
$sessionInfo ['url'] = $url;
$sessionInfo ['user'] = $user;
$sessionInfo ['pass'] = "";
if ($debug) showResponse($sessionInfo);
return $sessionInfo;
}
/**
* LogOff. Abmelden vom System und dadurch kill der Session.
* Ruft nur Get mit dem richtigen Opcode auf
* @param {Object} $sessionInfo Assoc Array, wird nach dem erfolgreichen Anmelden erzeugt, siehe login
* @param {Boolean} $debug Debug-Flag für Bildschirmausgaben
* @returns {Object} Das Ergebnis des requests, ein JOSN-Objekt das als Assoc Array zurückgegeben wird
*/
function logoff($sessionInfo, $debug) {
return get($sessionInfo, opcLogoff, null, $debug);
}
/**
* Get-Methode im Rahmen der geöffneten Session.
*
* Wirft Exceptions falls der request schiefläuft. Falls die Session nicht authentifiziert ist wird
* der Aufurf vom Tomcat stillschweigend an die Login-Seite verwiesen. Das sollte also nicht passieren.
*
* @param {Object} $sessionInfo Assoc Array, wird nach dem erfolgreichen Anmelden erzeugt, siehe login
* @paeam {OPCODE} $opcode Long. Der Opcode für den request
* @param {Object} $params Assoc Array mit Parametern fpr die URL analog zum get-Aufruf
* @param {String} $data JSON-Objekt als String, die Payload für den Postbody
* @param {Boolean} $debug Debug-Flag für Bildschirmausgaben
* @returns {Object} Das Ergebnis des requests, ein JOSN-Objekt das als Assoc Array zurückgegeben wird
*/
function get($sessionInfo, $opcode, $params, $debug) {
$url=$sessionInfo ['url'].frontcontroller.'?opc='.$opcode;
if ($params) {
foreach ($params as $name => $value) {
$url .= "&".urlencode($name)."=".urlencode($value);
}
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
CURLOPT_USERAGENT => 'PHP Request '.$sessionInfo ['sessionId']
));
// Send SdessionCookie JSESSIONID
curl_setopt($curl, CURLOPT_COOKIEFILE, $sessionInfo ['cookie']);
// Session has changed et least after logon due to security issue so better save new cookie always
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);
$jsonString=curl_exec($curl);
if (curl_errno($curl)) {
throw new Exception(curl_error($curl), curl_errno($curl));
}
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($http_code!=httpOK) {
throw new Exception('HTTP-Response STATUS<>200', $http_code);
}
curl_close($curl);
if ($debug) showResponse(json_decode($jsonString, true));
return json_decode($jsonString, true);
}
/**
* Post-Methode im Rahmen der geöffneten Session.
*
* Wirft Exceptions falls der request schiefläuft. Falls die Session nicht authentifiziert ist wird
* der Aufurf vom Tomcat stillschweigend an die Login-Seite verwiesen. Das sollte also nicht passieren.
*
* @param {Object} $sessionInfo Assoc Array, wird nach dem erfolgriechen Anmelden erzeugt, siehe login
* @paeam {OPCODE} $opcode Long. Der Opcode für den request
* @param {Object} $params Assoc Array mit Parametern fpr die URL analog zum get-Aufruf
* @param {String} $data JSON-Objekt als String, die Payload für den Postbody
* @param {Boolean} $debug Debug-Flag für Bildschirmausgaben
* @returns {Object} Das Ergebnis des requests, ein JOSN-Objekt das als Assoc Array zurückgegeben wird
*/
function post($sessionInfo, $opcode, $params, $data, $debug) {
$url=$sessionInfo ['url'].frontcontroller.'?opc='.$opcode;
if ($params) {
foreach ($params as $name => $value) {
$url .= "&".urlencode($name)."=".urlencode($value);
}
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
CURLOPT_USERAGENT => 'PHP Request '.$sessionInfo ['sessionId'],
CURLOPT_POST => 1,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
'Connection: Keep-Alive'
)
));
// Send SdessionCookie JSESSIONID
curl_setopt($curl, CURLOPT_COOKIEFILE, $sessionInfo ['cookie']);
// Session has changed et least after logon due to security issue so better save new cookie always
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);
// Put credentail into postbody invisible in logs
curl_setopt($curl, CURLOPT_POSTFIELDS,'data='.urlencode($data));
// Send SdessionCookie JSESSIONID
$jsonString=curl_exec($curl);
if (curl_errno($curl)) {
throw new Exception(curl_error($curl), curl_errno($curl));
}
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($http_code!=httpOK) {
throw new Exception('HTTP-Response STATUS<>200', $http_code);
}
curl_close($curl);
if ($debug) showResponse(json_decode($jsonString, true));
return json_decode($jsonString, true);
}
/**
* Doemload-Methode im Rahmen der geöffneten Session um ein File herunterzuladen.
*
* Wirft Exceptions falls der request schiefläuft. Falls die Session nicht authentifiziert ist wird
* der Aufurf vom Tomcat stillschweigend an die Login-Seite verwiesen. Das sollte also nicht passieren.
*
* @param {Object} $sessionInfo Assoc Array, wird nach dem erfolgriechen Anmelden erzeugt, siehe login
* @paeam {OPCODE} $opcode Long. Der Opcode für den request
* @param {Object} $params Assoc Array mit Parametern fpr die URL analog zum get-Aufruf
* @param {File} $file Geöffneter und zum Schreiben bereiter Filhandle im lokalen Dateisystem
* @param {Boolean} $debug Debug-Flag für Bildschirmausgaben
* @returns {File} Den Filehandel
*/
function download($sessionInfo, $opcode, $params, $file, $debug) {
$url=$sessionInfo ['url'].frontcontroller.'?opc='.$opcode;
if ($params) {
foreach ($params as $name => $value) {
$url .= "&".urlencode($name)."=".urlencode($value);
}
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_FILE => $file,
CURLOPT_TIMEOUT => 20,
CURLOPT_URL => $url,
CURLOPT_USERAGENT => 'PHP Request '.$sessionInfo ['sessionId']
));
// Send SdessionCookie JSESSIONID
curl_setopt($curl, CURLOPT_COOKIEFILE, $sessionInfo ['cookie']);
// Session has changed et least after logon due to security issue so better save new cookie always
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);
curl_exec($curl);
if (curl_errno($curl)) {
throw new Exception(curl_error($curl), curl_errno($curl));
}
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($http_code!=httpOK) {
throw new Exception('HTTP-Response STATUS<>200', $http_code);
}
curl_close($curl);
return $file;
}
/**
* Helper-Methode für Debugzwecke
*
*/
function showResponse($response) {
foreach ($response as $name => $value) {
echo "$name = $value"."</br>";
}
}
?>