webAlias); private $extAlias = array(extBaseDir => extWebAlias); function base64url_decode($data) { return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); } /** * Checks if Remote Data Set has been already added */ function isRemoteViAdded($baseId, $viId) { $referXML = baseDir."/DDsys.xml"; $DDsys = new DOMDocument("1.0"); $DDsys->load($referXML); $xp = new domxpath($DDsys); $VI = $xp->query("//NAME[.='".$viId."']"); if ($VI->item(0)->nodeValue != NULL) { $base = $VI->item(0)->getAttribute("base"); if ($base != $baseId) return false; return true; } return false; } /** * Returns contents of 'Version' file from VI Location dir */ function getVersion($dataSet) { $referXML = baseDir."/DDsys.xml"; $DDsys = new DOMDocument("1.0"); $DDsys->load($referXML); $xp = new domxpath($DDsys); $VI = $xp->query("//NAME[.='".$dataSet."']"); if ($VI->item(0)->nodeValue != NULL) { $location = $VI->item(0)->parentNode->getElementsByTagName("LOCATION")->item(0)->nodeValue; } if (file_exists($location."Version")) return file_get_contents($location."Version"); return null; } /** * Returns list of datasets with TimeRestriction */ function getDatasetsWithTimeRestriction() { $result = array( ); $referXML = baseDir."/DDsys.xml"; $DDsys = new DOMDocument("1.0"); @$DDsys->load($referXML); $xp = new domxpath($DDsys); $VINodes = $xp->query("//VI"); if ($VINodes->length == 0) { return $result; } foreach ($VINodes as $VINode) { $locationNode = $VINode->getElementsByTagName("LOCATION"); $nameNode = $VINode->getElementsByTagName("NAME"); if (($locationNode->length > 0) && ($nameNode->length > 0)) { $locationNode = $locationNode->item(0); $nameNode = $nameNode->item(0); $location = $locationNode->nodeValue; $viName = $nameNode->nodeValue; if (!empty($location) && !empty($viName)) { if (file_exists($location."TimeRestriction")) { $restr = file($location."TimeRestriction", FILE_IGNORE_NEW_LINES); $result[] = array( 'vi' => $viName, 'restriction' => $restr[0], ); } } } } return $result; } /** * Returns list of datasets with TimeRestriction */ function getVIInfo($viId) { $result = array( ); $referXML = baseDir."/DDsys.xml"; $DDsys = new DOMDocument("1.0"); @$DDsys->load($referXML); $xp = new domxpath($DDsys); $VINodes = $xp->query("//NAME[.='".str_replace(":", "_",$viId)."']"); $result = array( 'success' => FALSE ); if ($VINodes->length == 0) { return $result; } $VINode = $VINodes->item(0)->parentNode; $locationNode = $VINode->getElementsByTagName("LOCATION"); $nameNode = $VINode->getElementsByTagName("NAME"); $timesNode = $VINode->getElementsByTagName("TIMES"); if (($locationNode->length > 0) && ($nameNode->length > 0) && ($timesNode->length > 0)) { $locationNode = $locationNode->item(0); $nameNode = $nameNode->item(0); $location = $locationNode->nodeValue; $viName = $nameNode->nodeValue; $timesNode = $timesNode->item(0); $timesFile = $timesNode->nodeValue; if (!empty($location) && !empty($viName)) { // Start / Stop Date $referFile = baseDir."/refer.nc"; $cmd = DDBASEBIN."/StartStop ".$referFile." ".$viId; $startStopDate = system($cmd); // Release date $releaseDate = NULL; $cmd = "/opt/tools/DDServer/bin/GetReleaseDate ".$location." ".$timesFile; $output = array(); exec($cmd, $output, $result_code); if ($result_code == 0) $releaseDate = $output[0]; // Modification date $cmd = "/opt/tools/DDServer/bin/GetModificationDate ".$location." ".$timesFile; $output = array(); exec($cmd, $output, $result_code); if ($result_code == 0) $modificationDate = $output[0]; if (!isset($releaseDate)) $releaseDate = $modificationDate; $result = array( 'success' => TRUE, 'viName' => $viName, 'releaseDate' => $releaseDate, 'modificationDate' => $modificationDate, 'startStopDate' => $startStopDate ); } } return $result; } /** * Returns restricted TimeRestriction and GlobalStop in case of time restriction */ function getTimeRestriction($dataSet) { $referXML = baseDir."/DDsys.xml"; $DDsys = new DOMDocument("1.0"); $DDsys->load($referXML); $xp = new domxpath($DDsys); $VI = $xp->query("//NAME[.='".$dataSet."']"); if ($VI->item(0)->nodeValue != NULL) { $location = $VI->item(0)->parentNode->getElementsByTagName("LOCATION")->item(0)->nodeValue; } else { return array("success" => FALSE, "days" => "NOSUCHVI", "globalstop" => NULL ); } if (file_exists($location."TimeRestriction")) { $restr = file($location."TimeRestriction", FILE_IGNORE_NEW_LINES); $infoXmlRestr = $location.$restr[1].".xml"; if (file_exists($infoXmlRestr)) { if (!$DDsys->load($infoXmlRestr)) { $currDir = getcwd(); chdir($location); $DDsys->loadXML(file_get_contents($restr[1].".xml")); // NFS connection doesn't load chdir($currDir); } $globalStop = $DDsys->getElementsByTagName("GlobalStop")->item(0)->nodeValue; } else { $globalStop = NULL; } return array("success" => TRUE, "days" => $restr[0], "globalstop" => $globalStop ); } return array("success" => FALSE, "days" => "NORESTRICTIONFILE", "globalstop" => NULL ); } /** Just returns URL addres of AMDA_Users.xml - * droits d'access */ function getUserGroups() { if (file_exists(extBaseDir."/AMDA_Users.xml")) return extWebAlias."AMDA_Users.xml"; else return NOUSERGROUPSSPECIFIED; } function checkProtectedAPI($data, $key, $check) { $data_decoded = $this->base64url_decode($data); if (empty($data_decoded)) { return array( "valid" => FALSE, ); } $data_array = json_decode($data_decoded, TRUE); if (empty($data_array) || empty($data_array["timestamp"])) { return array( "valid" => FALSE, ); } if (time() - intval($data_array["timestamp"]) > 300) { return $data_array + array("valid" => FALSE); } $keys_file = rootDir."/ddservice_clients_keys.json"; if (!file_exists($keys_file)) { return $data_array + array("valid" => FALSE); } $keys_content = file_get_contents($keys_file); if (empty($keys_content)) { return $data_array + array("valid" => FALSE); } $existing_keys = json_decode($keys_content, TRUE); if (empty($existing_keys)) { return $data_array + array("valid" => FALSE); } $private = ""; foreach ($existing_keys as $keys) { if ($keys["public"] == $key) { $private = $keys["private"]; break; } } if (empty($private)) { return $data_array + array("valid" => FALSE); } $computed_check = md5($data.$key.$private); if ($computed_check != $check) { return $data_array + array("valid" => FALSE); } return $data_array + array("valid" => TRUE); } /* * Return info about a user */ function getUserInfo($data, $key, $check) { $data_array = $this->checkProtectedAPI($data, $key, $check); if ($data_array['valid'] == FALSE) { $login = array_key_exists("login", $data_array) ? $data_array["login"] : "undefined"; return array("success" => FALSE, "login" => $login, "name" => "undefined", "first_name" => "undefined", "group" => "undefined", "email" => "undefined", "date" => "undefined", "news" => "0"); } $UsrDom = new DomDocument("1.0"); $UsrDom->load(extWebAlias."AMDA_Users_Info.xml"); $xp = new domxpath($UsrDom); $theUser = $xp->query("//user[@login='".$data_array["login"]."']"); $login = array_key_exists("login", $data_array) ? $data_array["login"] : "undefined"; return array("success" => TRUE, "login" => $login, "name" => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("name") : "undefined", "first_name" => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("first_name") : "undefined", "group" => $this->getUserMemberGroups($login), "email" => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("email") : "undefined", "date" => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("date") : "undefined", "news" => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("news") : "0"); } function createUser($data, $key, $check) { $data_array = $this->checkProtectedAPI($data, $key, $check); if ($data_array['valid'] == FALSE) { return FALSE; } if (empty($data_array['pwd']) || empty($data_array['login'])) { return FALSE; } require_once userMgrDir."/UserManagerClass.php"; putenv("PATH=./:".DDBASEBIN.":/bin:/usr/bin"); putenv("DDINFO=".extBaseDir); putenv("DDBASE=".baseDir); putenv("AMDA_USERS_INFO=AMDA_Users_Info.xml"); putenv("AMDA_GROUPS_INFO=AMDA_Users.xml"); $stderr = fopen("php://stderr","w"); $userManager = new UserManagerClass($stderr); $pwd_hash = crypt($data_array['pwd'],chr(rand(97,122)).chr(rand(97,122))); $first_name = !array_key_exists('first_name', $data_array) ? "" : $data_array['first_name']; $last_name = !array_key_exists('last_name', $data_array) ? "" : $data_array['last_name']; $email = !array_key_exists('email', $data_array) ? "" : $data_array['email']; return ($userManager->AddUser($data_array['login'], $pwd_hash, $first_name, $last_name, $email, 1, '') == 1); } function resetUserPwd($data, $key, $check) { $data_array = $this->checkProtectedAPI($data, $key, $check); if ($data_array['valid'] == FALSE) { return FALSE; } if (empty($data_array['login']) || empty($data_array['crtpwd']) || empty($data_array['newpwd'])) { return FALSE; } require_once userMgrDir."/UserManagerClass.php"; putenv("PATH=./:".DDBASEBIN.":/bin:/usr/bin"); putenv("DDINFO=".extBaseDir); putenv("DDBASE=".baseDir); putenv("AMDA_USERS_INFO=AMDA_Users_Info.xml"); putenv("AMDA_GROUPS_INFO=AMDA_Users.xml"); $stderr = fopen("php://stderr","w"); $userManager = new UserManagerClass($stderr); $crtpwd_hash = $userManager->cryptPwd($data_array['login'], $data_array['crtpwd']); $newpwd_hash = crypt($data_array['newpwd'],chr(rand(97,122)).chr(rand(97,122))); return ($userManager->ModifyUserPwd($data_array['login'], $crtpwd_hash, $newpwd_hash) == 1); } /* * Return a list of group for which a user is a member */ function getUserMemberGroups($user) { //get user $user_dom = new DomDocument("1.0"); if (!file_exists(extBaseDir."/AMDA_Users.xml")) return array(); $user_dom->load(extBaseDir."/AMDA_Users.xml"); $user_nodes = $user_dom->getElementsByTagName('user'); foreach ($user_nodes as $user_node) { if ($user_node->nodeValue == $user) return $user_node->getAttribute('group'); } return ""; } /** Return the list of available local missions for * a given user */ function getUserAvailableLocalMissions($user) { //get user groups $user_groups = explode(",",preg_replace('/\s+/', '',$this->getUserMemberGroups($user))); //get local missions $mis_dom = new DomDocument("1.0"); if (!file_exists(extBaseDir."/Missions.xml")) return array(); $mis_dom->load(extBaseDir."/Missions.xml"); $local_nodes = $mis_dom->getElementsByTagName('Local'); if ($local_nodes->length < 1) return array(); $mis_nodes = $local_nodes->item(0)->getElementsByTagName("MissionID"); $user_missions = array(); foreach ($mis_nodes as $mis_node) { if (!$mis_node->hasAttribute('group') || ($mis_node->getAttribute('group') == '')) { //public mission array_push($user_missions,$mis_node->nodeValue); } else { // private mission $mis_group = $mis_node->getAttribute('group'); if (array_search($mis_group,$user_groups) === FALSE) continue; array_push($user_missions,$mis_node->nodeValue); } } return $user_missions; } /** Return the list of available external missions for * a given user */ function getUserAvailableExternalMissions($user) { //get user groups $user_groups = explode(",",$this->getUserMemberGroups($user)); //get external missions $mis_dom = new DomDocument("1.0"); if (!file_exists(extBaseDir.extBaseXml)) return array(); $mis_dom->load(extBaseDir.extBaseXml); $external_nodes = $mis_dom->getElementsByTagName('External'); if ($external_nodes->length < 1) return array(); $mis_nodes = $external_nodes->item(0)->getElementsByTagName("CenterID"); $user_missions = array(); foreach ($mis_nodes as $mis_node) { if (!$mis_node->hasAttribute('group') || ($mis_node->getAttribute('group') == '')) { //public mission array_push($user_missions,$mis_node->nodeValue); } else { // private mission $mis_group = $mis_node->getAttribute('group'); if (array_search($mis_group,$user_groups) === FALSE) continue; array_push($user_missions,$mis_node->nodeValue); } } return $user_missions; } /** Just returns URL addres of Missions.xml - * description of AMDA local data */ function getAvailableMissions() { if (file_exists(extBaseDir."Missions.xml")) return extWebAlias."Missions.xml"; else return NOLOCALDATA; } /** Just returns URL addres of Bases.xml - * description of available external bases */ function getAvailableExternalBases() { if (file_exists(extBaseDir.extBaseXml)) return extWebAlias.extBaseXml; else return NOEXTERNALBASES; } /** Just returns URL addres of base.xml - * description of available data for particular External Base * produced by DataCenterMgr */ function getAvailableExternalData($baseID) { if (file_exists(extBaseDir.$baseID."/base.xml")) return extWebAlias.$baseID."/base.xml"; else return NOEXTERNALDATA; } /** Returns URL addres of dataSet.xml - * description of particular external DataSet * if there is no such a description * contacts External Base and gets it */ function getDataSetDescription($baseID, $remDataSetID) { if (file_exists(extBaseDir.$baseID."/".$remDataSetID.".xml")) return extWebAlias.$baseID."/".$remDataSetID.".xml"; else { } } /** * Returns date of last modif of *times.nc in DD Base */ function getLastUpdate($dataSet) { $referXML = baseDir."/DDsys.xml"; $DDsys = new DOMDocument("1.0"); $DDsys->load($referXML); $xp = new domxpath($DDsys); $VI = $xp->query("//NAME[.='".$dataSet."']"); if ($VI->item(0)->nodeValue != NULL) { $location = $VI->item(0)->parentNode->getElementsByTagName("LOCATION")->item(0)->nodeValue; $times = $VI->getElementsByTagName("TIMES")->item(0)->nodeValue; if (!file_exists($location.$times)) return null; $cmd = 'date "+%Y-%m-%dT%H:%M:%SZ" -u -r '. $location.$times; // for NFS $dateModif = exec($cmd); return $dateModif; } return null; } /** * Returns modif date of the last modified data file (*.nc.gz) for a given DataSet */ function getLastRealUpdate($dataSet) { $referXML = baseDir."/DDsys.xml"; $DDsys = new DOMDocument("1.0"); $DDsys->load($referXML); $xp = new domxpath($DDsys); $VI = $xp->query("//NAME[.='".$dataSet."']"); if ($VI->item(0)->nodeValue != NULL) { $location = $VI->item(0)->parentNode->getElementsByTagName("LOCATION")->item(0)->nodeValue; $find = 'find '.$location.' -name \'*.nc.gz\' -type f -printf \'%T@ %p\n\' | sort -n | tail -1 | cut -f2- -d" "'; $lastFile = exec($find); if (!file_exists($lastFile)) exit('NO SUCH FILE '.$lastFile); $cmd = 'date "+%Y-%m-%dT%H:%M:%SZ" -u -r '.$lastFile; // for NFS $dateModif = exec($cmd); return $dateModif; } return null; } function getGranules($dataSet) { $referXML = baseDir."/DDsys.xml"; $DDsys = new DOMDocument("1.0"); $DDsys->load($referXML); $xp = new domxpath($DDsys); $VI = $xp->query("//NAME[.='".$dataSet."']"); if ($VI->item(0)->nodeValue != NULL) { $location = $VI->item(0)->parentNode->getElementsByTagName("LOCATION")->item(0)->nodeValue; $times = $VI->item(0)->parentNode->getElementsByTagName("TIMES")->item(0)->nodeValue; $cmd = "/opt/tools/DDServer/bin/GetGranules ".$location." ".$times; exec($cmd, $output, $result_code); if ($result_code === 0) return implode("\n",$output); } return NULL; } /** * Returns String Start-Stop for local DataSet in DD Base */ function getStartStop($dataSet) { $referFile = baseDir."/refer.nc"; $cmd = DDBASEBIN."/StartStop ".$referFile." ".$dataSet; $res = system($cmd); return $res; } /** * Returns String INFO for local DataSet in DD Base */ function getInfo($dataSet, $infoID) { $referFile = baseDir."/refer.nc"; $cmd = DDBASEBIN."/GetInfo ".$referFile." ".$dataSet." ".$infoID; $res = system($cmd); return $res; } /** * Returns Desc attribute for Remote DataSet in DD Base */ function getRemoteStartStop($baseID, $dataSet) { $domName = extBaseDir.$baseID."/base.xml"; if (!file_exists($domName)) return NOEXTERNALDATA; $dom = new DomDocument("1.0"); $dom->load($domName); $vi = $dom->getElementById($dataSet); if (!$vi) return NODATASET; $res = $vi->getAttribute('desc'); return $res; } /** * Check Remote Connection */ function checkRemoteConnection($extBaseID){ switch ($extBaseID) { case "THEMIS" : return is_dir(THEMIS_DIR); case "MAPSKP" : if (fsockopen(MAPSKP_HTTP_SERVER, 80, $errno, $errstr, 30)) return true; else return false; case "CDAWEB" : if (ftp_connect(CDAWEB_FTP_SERVER)) return true; else return false; case "VEXGRAZ" : if (fsockopen(VEXGRAZ_HTTP_SERVER, 80, $errno, $errstr, 30)) return true; else return false; case "LATMOS" : if (fsockopen(LATMOS_HTTP_SERVER, 80, $errno, $errstr, 30)) return true; else return false; case "LESIA" : if (fsockopen(LESIA_HTTP_SERVER, 80, $errno, $errstr, 30)) return true; else return false; case "SINP" : if (fsockopen(SINP_HTTP_SERVER, 80, $errno, $errstr, 30)) return true; else return false; case "FMI_HYBRID" : if (fsockopen(FMI_HYBRID_HTTP_SERVER, 80, $errno, $errstr, 30)) return true; else return false; case "FMI_GUMICS" : if (fsockopen(FMI_GUMICS_HTTP_SERVER, 80, $errno, $errstr, 30)) return true; else return false; case "CCMC" : if (fsockopen(CCMC_HTTP_SERVER, 80, $errno, $errstr, 30)) return true; else return false; case "CLWeb" : if (fsockopen(CLWeb_HTTP_SERVER, 80, $errno, $errstr, 30)) return true; else return false; default: return false; } } /** * Returns Array of Data Urls for a given DataSet * in StartTime - StopTime interval */ function getDataUrl($dataSet, $StartTime, $StopTime) { $tempFile = "/tmp/".uniqid("temp"); if (file_exists($tempFile)) unlink($tempFile); $referXML = baseDir."/DDsys.xml"; $DDsys = new DOMDocument("1.0"); $DDsys->load($referXML); $xp = new domxpath($DDsys); $VI = $xp->query("//NAME[.='".$dataSet."']"); if ($VI->item(0)->nodeValue != NULL) { $location = $VI->item(0)->parentNode->getElementsByTagName("LOCATION")->item(0)->nodeValue; $times = $VI->item(0)->parentNode->getElementsByTagName("TIMES")->item(0)->nodeValue; $timesFile = $location.$times; $cmd = DDBASEBIN."/GetFileNames ".$timesFile." ".strtotime($StartTime)." ".strtotime($StopTime)." > $tempFile"; system($cmd); if (!file_exists($tempFile)) return 'ERROR'; $res = file($tempFile); if ($res[0] == OUTOFTIME) { unlink($tempFile); return $res; } $urls = explode(";",$res[0]); $url_location = strtr($location, $this->alias); if (count($urls) > 0) { unset($urls[count($urls)-1]); for ($i = 0; $i < count($urls); $i++) $urls[$i] = $url_location.$urls[$i].".gz"; } unlink($tempFile); return $urls; } return NODATASET; } } require_once(dirname(__FILE__) . '/DDserverWeb_ini.php'); ini_set("soap.wsdl_cache_enabled", "0"); // use_soap_error_handler(false); $server = new SoapServer("./dd.wsdl"); $server->setClass("DDService"); $server->handle(); ?>