diff --git a/include/dvb.class.php b/include/dvb.class.php new file mode 100644 index 000000000..fc9b26c1d --- /dev/null +++ b/include/dvb.class.php @@ -0,0 +1,654 @@ +, + */ +/** + * Datenverbund Services + * Anbindung für Datenverbund des Bundesrechenzetrums zur + * Abfrage und Vergabe von Matrikelnummern + */ +require_once(dirname(__FILE__).'/basis_db.class.php'); + +class dvb +{ + const DVB_URL_WEBSERVICE_OAUTH = 'https://stubei-q.portal.at/dvb/oauth/token'; + const DVB_URL_WEBSERVICE_SVNR = 'https://stubei-q.portal.at/rws/0.1/simpleStudentBySozialVersicherungsnummer.xml'; + const DVB_URL_WEBSERVICE_ERSATZKZ = 'https://stubei-q.portal.at/rws/0.1/simpleStudentByErsatzKennzeichen.xml'; + const DVB_URL_WEBSERVICE_RESERVIERUNG = 'https://stubei-q.portal.at/dvb/matrikelnummern/1.0/reservierung.xml'; + const DVB_URL_WEBSERVICE_MELDUNG = 'https://stubei-q.portal.at/dvb/matrikelnummern/1.0/meldung.xml'; + + public $authentication; + private $username; + private $password; + private $debug; + public $debug_output = ''; + + /** + * Constructor + * @param string $username Username fuer OAuth2 Login. + * @param string $password Passwort fuer OAuth2 Login. + * @param bool $debug Enables/Disables Debugging. + */ + public function __construct($username, $password, $debug = false) + { + $this->username = $username; + $this->password = $password; + $this->debug = $debug; + } + + /** + * Performs a OAuth2 Authentication and returns the OAuth Bearer Token + * @return boolean true wenn erfolgreich, false im Fehlerfall + */ + public function authenticate() + { + $this->debug('Request new OAuth Token'); + + $curl = curl_init(); + $url = self::DVB_URL_WEBSERVICE_OAUTH; + $url .= '?grant_type=client_credentials'; + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + + $headers = array( + 'Accept: application/json', + 'Content-Type: application/x-www-form-urlencoded', + 'Authorization: Basic '.base64_encode($this->username.":".$this->password), + 'User-Agent: FHComplete', + 'Connection: Keep-Alive', + 'Expect:', + 'Content-Length: 0' + ); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + + $this->debug('Sending Request to '.$url); + $json_response = curl_exec($curl); + $curl_info = curl_getinfo($curl); + curl_close($curl); + + $this->debug('Response: '.$curl_info['http_code']); + + if ($curl_info['http_code'] == '200') + { + /* Example Response: + { + "access_token": "d9c60404-1530-4b05-bb8e-0a0b0f321726", + "token_type": "bearer", + "expires_in": 41087, + "scope": "read write ROLE_bildungseinrichtung + ROLE_bildungseinrichtung_A" + } + */ + + $this->authentication = json_decode($json_response); + + // Calculate Expire Date + $ttl = new DateTime(); + $ttl->add(new DateInterval('PT'.$this->authentication->expires_in.'S')); + $this->authentication->DateTimeExpires = $ttl; + + $this->debug('Access_token:'.$this->authentication->access_token); + $this->debug('Scope:'.$this->authentication->scope); + + return true; + } + else + { + $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$json_response; + return false; + } + } + + /** + * Checks if the Token is Expired + * @return boolean true if expired, false if valid. + */ + private function tokenIsExpired() + { + if (!isset($this->authentication)) + return true; + + $dtnow = new DateTime(); + if ($this->authentication->DateTimeExpires < $dtnow) + { + return true; + } + else + return false; + } + + /** + * Get Matrikelnummer by Social Security Number + * @param string $svnr Social Security Number. + * @return Matrikelnummer or false on error. + */ + public function getMatrikelnrBySVNR($svnr) + { + if ($this->tokenIsExpired()) + { + $this->authenticate(); + } + + $this->debug('getMatirkelnrBySVNR'); + + $curl = curl_init(); + + $url = self::DVB_URL_WEBSERVICE_SVNR; + $url .= '?sozialVersicherungsNummer='.curl_escape($curl, $svnr); + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + + $headers = array( + 'Accept: application/json', + 'Authorization: Bearer '.$this->authentication->access_token, + 'User-Agent: FHComplete', + 'Connection: Keep-Alive', + 'Expect:', + 'Content-Length: 0' + ); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + + $this->debug('Sending Request to '.$url); + + $response = curl_exec($curl); + $curl_info = curl_getinfo($curl); + curl_close($curl); + + $this->debug('Response '.$curl_info['http_code']); + if ($curl_info['http_code'] == '200') + { + /* Example Response: + + + 12345678 + Max + Mustermann + M + 1999-02-19 + A + + + */ + $dom = new DOMDocument(); + $dom->loadXML($response); + $namespace = 'http://www.brz.gv.at/datenverbund-unis'; + $domnodes_matrikelnummer = $dom->getElementsByTagNameNS($namespace, 'matrikelNummer'); + foreach ($domnodes_matrikelnummer as $row) + { + // Found + return $row->textContent; + } + + $this->errormsg = ''; + return false; + } + else + { + $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$response; + return false; + } + } + + /** + * Get Matrikelnummer by Ersatzkennzeichen + * @param string $ersatzkennzeichen Ersatzkennzeichen to search for. + * @return Matrikelnummer or false + */ + public function getMatrikelnrByErsatzkennzeichen($ersatzkennzeichen) + { + if ($this->tokenIsExpired()) + { + $this->authenticate(); + } + + $this->debug('getMatrikelnrByErsatzkennzeichen'); + $curl = curl_init(); + + $url = self::DVB_URL_WEBSERVICE_ERSATZKZ; + $url .= '?ersatzKennzeichen='.curl_escape($curl, $ersatzkennzeichen); + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + + $headers = array( + 'Accept: application/json', + 'Authorization: Bearer '.$this->authentication->access_token, + 'User-Agent: FHComplete', + 'Connection: Keep-Alive', + 'Expect:', + 'Content-Length: 0' + ); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + + $this->debug('Sending Request to '.$url); + $xml_response = curl_exec($curl); + $curl_info = curl_getinfo($curl); + curl_close($curl); + $this->debug('Response: '.$curl_info['http_code']); + + if ($curl_info['http_code'] == '200') + { + /* Example Response Success + + + A + 12345678 + 2017S + ABCD201093 + Bc. + Max + Mustermann + W + 1993-06-26 + TCH + + A + 1030 + Wien + Obere Bahngasse 20/12 + + + A + 1030 + Wien + Obere Bahngasse 20/12 + + + + 12345678 + Max + Mustermann + W + 1993-06-26 + TCH + + + */ + /* 200 - No Entry found + + */ + /* 401 Error Code Token Expired + { + "error": "invalid_token", + "error_description": "Access token expired: 64a58ef3-1a70-46e9-b44f-35cc5051ae8e" + } + */ + /* 400 Bad Request + + 318e1bc5-279d-43c4-af47-5e6df2ff5279 + + + ZD00001 + Z + + Der Server konnte die Anfrage nicht vearbeiten. + Required String parameter 'ersatzKennzeichen' is not present + + + + */ + + $dom = new DOMDocument(); + $dom->loadXML($xml_response); + $namespace = 'http://www.brz.gv.at/datenverbund-unis'; + $domnodes_matrikelnummer = $dom->getElementsByTagNameNS($namespace, 'matrikelNummer'); + foreach ($domnodes_matrikelnummer as $row) + { + // Found + return $row->textContent; + } + } + else + { + $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$xml_response; + return false; + } + } + + /** + * List of already Reserved Matrikelnummern + * @param string $bildungseinrichtung Shortname of Institution. + * @param string $studienjahr Year of Reservation. + * @return array with reserved Matrikelnr. or false on failure. + */ + public function getReservations($bildungseinrichtung, $studienjahr) + { + $this->debug('getReservations'); + $uuid = $this->getUUID(); + + if ($this->tokenIsExpired()) + { + $this->authenticate(); + } + + $curl = curl_init(); + $url = self::DVB_URL_WEBSERVICE_RESERVIERUNG; + $url .= '?uuid='.curl_escape($curl, $uuid); + $url .= '&be='.curl_escape($curl, $bildungseinrichtung); + $url .= '&sj='.curl_escape($curl, $studienjahr); + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + + $headers = array( + 'Accept: application/xml', + 'Authorization: Bearer '.$this->authentication->access_token, + 'User-Agent: FHComplete', + 'Connection: Keep-Alive', + 'Expect:', + 'Content-Length: 0' + ); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + + $this->debug('Request URL:'.$url); + $response = curl_exec($curl); + $curl_info = curl_getinfo($curl); + curl_close($curl); + + $this->debug('Response: '.$curl_info['http_code']); + + /* 200 ok + + + 793d44fa-5646-42b1-b0cb-f2f121b2f14f + + + 12345678 + 23456789 + + + */ + if ($curl_info['http_code'] == '200') + { + $dom = new DOMDocument(); + $dom->loadXML($response); + $domnodes_matrikelnummer = $dom->getElementsByTagName('matrikelnummer'); + $reservations = array(); + foreach ($domnodes_matrikelnummer as $row) + { + $reservations[] = $row->textContent; + } + return $reservations; + } + else + { + $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$response; + return false; + } + } + + /** + * Request a new Matrikelnummer + * @param string $bildungseinrichtung Shortname of Institution. + * @param string $studienjahr Year of issuing. + * @param int $anzahl Number of Requested Numbers. + * @return array list of matrikelnr or false on failure. + */ + public function getKontingent($bildungseinrichtung, $studienjahr, $anzahl = 1) + { + $this->debug('getKontingent'); + $uuid = $this->getUUID(); + + if ($this->tokenIsExpired()) + { + $this->authenticate(); + } + + $data = ' + + '.$uuid.' + + '.$anzahl.' + '.$bildungseinrichtung.' + '.$studienjahr.' + + + '; + + $curl = curl_init(); + $url = self::DVB_URL_WEBSERVICE_RESERVIERUNG; + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_POSTFIELDS, $data); + + $headers = array( + 'Accept: application/xml', + 'Content-Type: application/xml', + 'Authorization: Bearer '.$this->authentication->access_token, + 'User-Agent: FHComplete', + 'Connection: Keep-Alive', + 'Expect:' + ); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + + $this->debug('Request URL:'.$url); + $this->debug('Request Data:'.$data); + $response = curl_exec($curl); + $curl_info = curl_getinfo($curl); + curl_close($curl); + + $this->debug('Response: '.$curl_info['http_code']); + + if ($curl_info['http_code'] == '200') + { + $dom = new DOMDocument(); + $dom->loadXML($response); + $domnodes_matrikelnummer = $dom->getElementsByTagName('matrikelnummer'); + $kontingent = array(); + foreach ($domnodes_matrikelnummer as $row) + { + $kontingent[] = $row->textContent; + } + return $kontingent; + } + else + { + $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$response; + return false; + } + } + + /** + * Meldet die Vergabe der Matrikelnummer + * @param string $bildungseinrichtung Kennzeichen der Bildungseinrichtung. + * @param object $person Objekt mit den Personendaten. + * @return booelan true wenn erfolgreich + */ + public function setMatrikelnummer($bildungseinrichtung, $person) + { + $this->debug('setMatrikelnummer'); + $uuid = $this->getUUID(); + + if ($this->tokenIsExpired()) + { + $this->authenticate(); + } + + $data = ' + + '.$uuid.' + + '.$bildungseinrichtung.' + '.$person->geburtsdatum.' + '.$person->geschlecht.' + '.$person->matrikelnummer.''; + if (isset($person->matura) && $person->matura != '') + $data .= ''.$person->matura.''; + else + $data .= '00000000'; + + $data .= ''.$person->nachname.''; + + if (isset($person->plz) && $person->plz != '') + $data .= ''.$person->plz.''; + + $data .= ''.$person->staat.''; + + if (isset($person->svnr) && $person->svnr != '') + $data .= ''.$person->svnr.''; + + $data .= ''.$person->vorname.''; + + if (isset($person->writeonerror) && $person->writeonerror === true) + $data .= 'J'; + + $data .= ' + + + '; + + $curl = curl_init(); + $url = self::DVB_URL_WEBSERVICE_MELDUNG; + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_POSTFIELDS, $data); + + $headers = array( + 'Accept: application/xml', + 'Content-Type: application/xml', + 'Authorization: Bearer '.$this->authentication->access_token, + 'User-Agent: FHComplete', + 'Connection: Keep-Alive', + 'Expect:' + ); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + + $this->debug('Request URL:'.$url); + $this->debug('Request Data:'.$data); + $response = curl_exec($curl); + $curl_info = curl_getinfo($curl); + curl_close($curl); + + $this->debug('Response: '.$curl_info['http_code']); + + $this->debug('Response: '.print_r($response, true)); + /* 200 Fehlermeldung + + + b76e84a9-c0bd-494c-97cb-c4ab9cd452c5 + + + ZD01471 + 90 + UNI-Kennzeichen + UNI-Kennzeichen fehlt oder ungültig (FHTEST) + BRZ + FHTEST + + + AG21333 + 65 + Datum allg.Univ.reife + kein gültiges Datum oder Format + Korrektur Datum allg. Univ.reife oder 000000 angeben, falls nicht anwendbar + leer + + + ZD10073 + 90 + Matrikelnummer + aus ungültigem Kontingent + Korrektur der Matrikelnummer + 12345678 + + + + */ + /* 200 ok + + + 8b239582-6bc5-4193-ac79-2dcf9ec96439 + + + */ + if ($curl_info['http_code'] == '200') + { + $dom = new DOMDocument(); + $dom->loadXML($response); + $domnodes_fehlerliste = $dom->getElementsByTagName('fehlerliste'); + + $fehleranzahl = $domnodes_fehlerliste[0]->getAttribute('fehleranzahl'); + if ($fehleranzahl === '0') + { + // Keine Fehler -> Meldung erfolgreich + return true; + } + else + { + $this->errormsg = 'Es gab '.$fehleranzahl.' Fehler:'; + $domnodes_fehler = $dom->getElementsByTagName('fehler'); + foreach ($domnodes_fehler as $row) + { + $datenfeld = $row->getElementsByTagName('datenfeld'); + $fehlertext = $row->getElementsByTagName('fehlertext'); + $this->errormsg .= ' Datenfeld:'.$datenfeld[0]->textContent; + $this->errormsg .= ' Fehlertext:'.$fehlertext[0]->textContent; + } + return false; + } + } + else + { + $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$response; + return false; + } + } + + /** + * Generiert eine eindeutige UUID + * @return uuid + */ + private function getUUID() + { + $data = openssl_random_pseudo_bytes(16); + $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100 + $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10 + + return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); + } + + /** + * Erstellt eine Debug Message + * @param string $msg Message to log. + * @return void + */ + private function debug($msg) + { + if ($this->debug) + $this->debug_output .= "\n
".date('Y-m-d H:i:s').': '.htmlentities($msg); + } +} diff --git a/soap/datenverbund_client.php b/soap/datenverbund_client.php new file mode 100644 index 000000000..0dc47c109 --- /dev/null +++ b/soap/datenverbund_client.php @@ -0,0 +1,245 @@ +, + */ +/** + * Testclient fuer Abfrage der REST Webservice Schnittstelle des Datenverbundes + */ +require_once('../config/vilesci.config.inc.php'); +require_once('../include/functions.inc.php'); +require_once('../include/basis_db.class.php'); +require_once('../include/benutzerberechtigung.class.php'); +require_once('../include/dvb.class.php'); + +$uid = get_uid(); +$rechte = new benutzerberechtigung(); +$rechte->getBerechtigungen($uid); +if (!$rechte->isBerechtigt('admin')) + die($rechte->errormsg); + +$db = new basis_db(); + +if (isset($_GET['action'])) + $action = $_GET['action']; +else + $action = 'getBySvnr'; + +$username = filter_input(INPUT_POST, 'username'); +$password = filter_input(INPUT_POST, 'password'); +$bildungseinrichtung = filter_input(INPUT_POST, 'bildungseinrichtung'); +$studienjahr = filter_input(INPUT_POST, 'studienjahr'); +$matrikelnr = filter_input(INPUT_POST, 'matrikelnummer'); +$nachname = filter_input(INPUT_POST, 'nachname'); +$vorname = filter_input(INPUT_POST, 'vorname'); +$geburtsdatum = filter_input(INPUT_POST, 'geburtsdatum'); +$geschlecht = filter_input(INPUT_POST, 'geschlecht'); +$postleitzahl = filter_input(INPUT_POST, 'postleitzahl'); +$staat = filter_input(INPUT_POST, 'staat'); +$matura = filter_input(INPUT_POST, 'matura'); +$svnr = filter_input(INPUT_POST, 'svnr'); +$ersatzkennzeichen = filter_input(INPUT_POST, 'ersatzkennzeichen'); + +?> + + + + Datenverbund-Client + + +

Testclient für Datenverbund-Webservice

+ +

+
+ + + + + '; + } + + printrow('username', 'Username', $username, '', 100); + printrow('password', 'Passwort', $password, '', 100); + + switch($action) + { + case 'getOAuth': + break; + + case 'getBySvnr': + printrow('svnr', 'SVNR', $svnr); + break; + + case 'getByErsatzkennzeichen': + printrow('ersatzkennzeichen', 'Ersatzkennzeichen', $ersatzkennzeichen); + break; + + case 'getReservations': + case 'getKontingent': + printrow( + 'bildungseinrichtung', + 'Bildungseinrichtung', + $bildungseinrichtung, + 'Kurzzeichen der Bildungseinrichtung' + ); + printrow('studienjahr', 'Studienjahr', $studienjahr, 'zB 2016 (für WS2016 und SS2017)', 4); + break; + + case 'setMatrikelnummer': + printrow( + 'bildungseinrichtung', + 'Bildungseinrichtung', + $bildungseinrichtung, + 'Kurzzeichen der Bildungseinrichtung' + ); + printrow('matrikelnummer', 'Matrikelnummer', $matrikelnr); + printrow('nachname', 'Nachname', $nachname, '', 255); + printrow('vorname', 'Vorname', $vorname, '', 30); + printrow('geburtsdatum', 'Geburtsdatum', $geburtsdatum, 'Format: YYYYMMDD', 10); + printrow('geschlecht', 'Geschlecht', $geschlecht, 'Format: M | W', 1); + printrow('postleitzahl', 'Postleitzahl', $postleitzahl, '', 10); + printrow('staat', 'Staat', $staat, '1-3 Stellen Codex (zb A für Österreich)', 3); + printrow('svnr', 'SVNR', $staat); + printrow('matura', 'Maturadatum', $matura, 'Format: YYYYMMDD (optional)', 10); + break; + + default: + echo "Unknown action"; + break; + } + + echo ' + + + + '; + ?> + + + + + +
'.$title.': + '.$hint.' +
Debug
+ +
+
+authenticate()) + echo '
OAuth Bearer Token: '.$dvb->authentication->access_token; + else + echo '
Failed: '.$dvb->errormsg; + break; + + case 'getBySvnr': + $matrikelnr = $dvb->getMatrikelnrBySVNR($_POST['svnr']); + if ($matrikelnr !== false) + echo '
Matrikelnummer vorhanden:'.$matrikelnr; + else + echo '
Matrikelnummer nicht vorhanden:'.$dvb->errormsg; + break; + + case 'getByErsatzkennzeichen': + $matrikelnr = $dvb->getMatrikelnrByErsatzkennzeichen($_POST['ersatzkennzeichen']); + if ($matrikelnr !== false) + echo '
Matrikelnummer vorhanden:'.$matrikelnr; + else + echo '
Matrikelnummer nicht vorhanden:'.$dvb->errormsg; + break; + + case 'getReservations': + $reservierteNummern = $dvb->getReservations($_POST['bildungseinrichtung'], $_POST['studienjahr']); + + if ($reservierteNummern !== false) + echo '
Reservierte Nummern:'.print_r($reservierteNummern, true); + else + echo '
Fehlgeschlagen:'.$dvb->errormsg; + break; + + case 'getKontingent': + $kontingent = $dvb->getKontingent($_POST['bildungseinrichtung'], $_POST['studienjahr']); + + if ($kontingent !== false) + echo '
Kontingent:'.print_r($kontingent, true); + else + echo '
Fehlgeschlagen:'.$dvb->errormsg; + break; + + case 'setMatrikelnummer': + $person = new stdClass(); + $person->matrikelnummer = $matrikelnummer; + $person->vorname = $vorname; + $person->nachname = $nachname; + $person->geburtsdatum = $geburtsdatum; + $person->geschlecht = $geschlecht; + $person->staat = $staat; + $person->plz = $postleitzahl; + $person->matura = $matura; // Optional + $person->svnr = $svnr; // Optional + + if ($dvb->setMatrikelnummer($_POST['bildungseinrichtung'], $person)) + echo '
Erfolgreich gemeldet'; + else + echo '
Fehlgeschlagen:'.$dvb->errormsg; + break; + + default: + echo "Unknown action"; + break; + } + if (isset($_POST['debug'])) + echo '
'.$dvb->debug_output.'
'; +} + +?> + + diff --git a/soap/index.html b/soap/index.html index bad3ad150..3f086ac16 100644 --- a/soap/index.html +++ b/soap/index.html @@ -8,13 +8,14 @@
  • Ort / Raum
  • Studierendendaten
  • LV-Plan
  • -
  • Personen
  • +
  • Personen
  • Sonstiges

    - \ No newline at end of file +