* See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * $Id: jobresult.php 2471 2009-08-17 20:09:55Z pieterb $
 **************************************************************************/
/**
 * File documentation.
 * @package Portal
 */
require_once 'include/global.php';
REST::require_method('GET', 'HEAD', 'PUT');
$user_id = Portal_User::current()->user_id();
$path_info = Portal::path_info();
$jobid = $path_info[0];
$escjobid = Portal_MySQL::escape_string($jobid);
$escuserid = Portal_MySQL::escape_string($user_id);
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
    if (strpos(@$_SERVER['CONTENT_TYPE'], 'application/x-compressed-tar') !== 0) {
        REST::fatal(REST::HTTP_UNSUPPORTED_MEDIA_TYPE);
    }
    // The job wants to put its results on the portal server
    $tmpfilename = tempnam('/tmp', 'portal_');
    $tmpfile = fopen($tmpfilename, 'w');
    while (($block = fread(REST::inputhandle(), 8192)) !== "") {
        fwrite($tmpfile, $block);
    }
    fclose(REST::inputhandle());
    fclose($tmpfile);
    if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] != filesize($tmpfilename)) {
        unlink($tmpfilename);
        REST::fatal(REST::HTTP_BAD_REQUEST, "Content-Length header doesn't match actual content length.");
 **************************************************************************/
/**
 * File documentation.
 * @package Portal
 */
require_once 'include/global.php';
if (!isset($_GET['email']) || !isset($_GET['password'])) {
    REST::fatal(REST::HTTP_BAD_REQUEST, 'Missing (one of) required parameters "email" and "password"');
}
$dn = Portal_User::csa_dn();
if (empty($dn)) {
    REST::fatal(REST::HTTP_NOT_FOUND);
}
$escemail = Portal_MySQL::escape_string($_GET['email']);
$md5password = md5($_GET['password']);
$escdn = Portal_MySQL::escape_string($dn);
Portal_MySQL::real_query(<<<EOS
DELETE FROM `User`
WHERE `user_dn` = {$escdn}
  AND `user_email` <> {$escemail};
EOS
);
Portal_MySQL::real_query(<<<EOS
UPDATE `User`
SET `user_dn` = {$escdn}
WHERE `user_email` = {$escemail}
  AND `user_password` = '{$md5password}';
EOS
);
if (!Portal_MySQL::mysql()->affected_rows) {
    Portal_User::unauthorized();
    public static function recordRequest($url, $ip = '')
    {
        $user_id = Portal_MySQL::escape_string(Portal_User::current()->user_id());
        $esc_url = Portal_MySQL::escape_string($url);
        $esc_ip = Portal_MySQL::escape_string($ip);
        Portal_MySQL::real_query(<<<EOS
INSERT INTO `Statistics` (`requested_url`, `request_origin`, `user_id`)
     VALUES ({$esc_url}, {$esc_ip}, {$user_id});
EOS
);
    }
$jobid = $path_info[0];
$escjobid = Portal_MySQL::escape_string($jobid);
$escuserid = Portal_MySQL::escape_string($user_id);
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
    if (strpos(@$_SERVER['CONTENT_TYPE'], 'text/plain') !== 0) {
        REST::fatal(REST::HTTP_UNSUPPORTED_MEDIA_TYPE);
    }
    // The job finished with an error and tries to inform us about it
    $errorstring = '';
    while (($line = fread(REST::inputhandle(), 8192)) !== '') {
        $errorstring .= $line;
    }
    if (!strlen($errorstring)) {
        REST::fatal(REST::HTTP_BAD_REQUEST, 'No error string specified');
    }
    $errorstring = Portal_MySQL::escape_string($errorstring);
    Portal_MySQL::real_query(<<<EOS
UPDATE `Token` 
   SET `token_error` = CONCAT(`token_error`, {$errorstring})
 WHERE `token_id`={$escjobid}
   AND `user_id`={$escuserid};
EOS
);
    REST::header(array('status' => REST::HTTP_NO_CONTENT));
    exit;
}
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
    if (file_exists($fullfilename = Portal::JOBRESULTS_DIR . $jobid)) {
        unlink($fullfilename);
    }
    Topos::deleteTokenFile($jobid);
 */
require_once 'include/global.php';
$referrer = empty($_GET['referrer']) ? null : REST::htmlspecialchars($_GET['referrer']);
if (isset($_GET['email']) && isset($_GET['name'])) {
    // Check the email address for syntax:
    $_GET['email'] = strtolower($_GET['email']);
    if (!preg_match('/^[\\w\\d\\-.]+@[\\w\\d\\-]+(?:\\.[\\w\\d\\-]+)*\\.\\w+$/', $_GET['email'])) {
        REST::fatal(REST::HTTP_BAD_REQUEST, '<p>"' . REST::htmlspecialchars($_GET['email']) . '" is not a well-formed e-mail address.</p>');
    }
    // Check the name:
    $_GET['name'] = preg_replace('/\\s+/', ' ', trim($_GET['name']));
    if ($_GET['name'] === '') {
        REST::fatal(REST::HTTP_BAD_REQUEST, '<p>Please provide a display name.</p>');
    }
    $escemail = Portal_MySQL::escape_string($_GET['email']);
    $escname = Portal_MySQL::escape_string($_GET['name']);
    //  $dn = ($_SERVER['SERVER_PORT'] == Portal::PORT_SSL_CSA)
    //    ? Portal_User::csa_dn() : null;
    //  $escdn = Portal_MySQL::escape_string($dn);
    $password = Portal_User::createPassword();
    $md5password = md5($password);
    Portal_MySQL::real_query(<<<EOS
INSERT INTO `User` (`user_email`, `user_name`, `user_password`)
VALUES ({$escemail}, {$escname}, '{$md5password}')
ON DUPLICATE KEY UPDATE
  `user_name` = {$escname},
  `user_password` = '{$md5password}';
EOS
);
    $csa_confirm = 'https://' . $_SERVER['SERVER_NAME'] . ':' . Portal::PORT_SSL_CSA . Portal::portalURL() . 'csaconfirm?email=' . urlencode($_GET['email']) . '&password='******'email'], 'Access to ' . $_SERVER['SERVER_NAME'], <<<EOS
 * File documentation.
 * @package Portal
 */
require_once 'include/global.php';
if (Portal::user_dn() != @$_SERVER['SSL_SERVER_S_DN']) {
    REST::fatal(REST::HTTP_UNAUTHORIZED);
}
REST::require_method('GET');
foreach (glob(Portal::PROXY_DIR . '*.pem') as $fullfilename) {
    $escfullfilename = escapeshellarg($fullfilename);
    exec("grid-proxy-info -f {$escfullfilename} -exists -valid 1:00", $output, $returnval);
    if (!$returnval) {
        continue;
    }
    // The proxy is valid for at least another hour
    $user_dn_md5 = Portal_MySQL::escape_string(basename($fullfilename, '.pem'));
    $result = Portal_MySQL::query(<<<EOS
SELECT `proxy_server`, `proxy_username`, `proxy_password` FROM `User`
 WHERE `user_dn_md5` = {$user_dn_md5};
EOS
);
    if ($row = $result->fetch_row()) {
        $escusername = escapeshellarg($row[1]);
        $escpassword = escapeshellarg($row[2]);
        $escserver = escapeshellarg($row[0]);
        exec("echo {$escpassword} | myproxy-logon -v -l {$escusername} -s {$escserver} -S -o {$escfullfilename} 2>&1", $output, $returnval);
        if ($returnval) {
            unlink($fullfilename);
            Portal_MySQL::query(<<<EOS
UPDATE `User` SET `proxy_server` = NULL, `proxy_username` = NULL, `proxy_password` = NULL
 WHERE `user_dn_md5` = {$user_dn_md5};
    global $TEMPNAM;
    exec("rm -rf {$TEMPNAM}*");
}
REST::header('text/plain; charset=UTF-8');
$TEMPNAM = tempnam('/tmp', 'portal');
register_shutdown_function('myRemoveTempFiles');
foreach (glob(Portal::PROXY_DIR . '*.pem') as $fullproxyfile) {
    #$escfilename = escapeshellarg($filename);
    $proxyfile = basename($fullproxyfile);
    if (!preg_match('/^([a-f0-9]{32})\\.pem$/', $proxyfile, $matches)) {
        Portal::debug("Strange proxy filename: {$proxyfile}");
        @unlink($fullproxyfile);
        continue;
    }
    $userdnmd5 = $matches[1];
    $escuserdnmd5 = Portal_MySQL::escape_string($userdnmd5);
    $result = Portal_MySQL::query(<<<EOS
SELECT `user_dn`, `proxy_server`, `proxy_username`, `proxy_password`
FROM `User`
WHERE `user_dn_md5` = {$escuserdnmd5};
EOS
);
    if (!($row = $result->fetch_row())) {
        Portal::debug("A proxy file {$proxyfile} was found, but there's no corresponding user in the database!");
        @unlink($fullproxyfile);
        continue;
    }
    $userdn = $row[0];
    $escproxyserver = escapeshellarg($proxyserver = $row[1]);
    $proxyusername = escapeshellarg($row[2]);
    $proxypassword = $row[3];
    /**
     * @param bool $required
     * @return Portal_User
     */
    public static function current()
    {
        if (self::$current === null) {
            switch ($_SERVER['SERVER_PORT']) {
                case Portal::PORT_PLAIN:
                    self::unauthorized();
                    break;
                    // strictly unnecessary, but syntactically nicer.
                // strictly unnecessary, but syntactically nicer.
                case Portal::PORT_SSL:
                    if (!isset($_SERVER['PHP_AUTH_USER'])) {
                        self::unauthorized();
                    }
                    $user_email = Portal_MySQL::escape_string($_SERVER['PHP_AUTH_USER']);
                    $user_password = md5($_SERVER['PHP_AUTH_PW']);
                    $result = Portal_MySQL::query(<<<EOS
SELECT `user_id`, `user_name`, `user_dn` FROM `User`
WHERE `user_email`   =  {$user_email}
  AND `user_password`= '{$user_password}';
EOS
);
                    if (!($row = $result->fetch_row())) {
                        self::unauthorized();
                    }
                    self::$current = new Portal_User((int) $row[0], $_SERVER['PHP_AUTH_USER'], $row[1], $row[2]);
                    break;
                case Portal::PORT_SSL_CSA:
                    $user_dn = self::csa_dn();
                    if (isset($_SERVER['PHP_AUTH_USER']) && (int) $_SERVER['PHP_AUTH_USER'] > 0 && preg_match('@^/O=dutchgrid/O=users/O=sara/CN=(?:Evert Lammerts|Pieter van Beek)@', $_SERVER['SSL_CLIENT_S_DN'])) {
                        $esc_user_id = (int) $_SERVER['PHP_AUTH_USER'];
                        $result = Portal_MySQL::query(<<<EOS
SELECT `user_email`, `user_name`, `user_dn` FROM `User`
WHERE `user_id` = {$esc_user_id};
EOS
);
                        if (!($row = $result->fetch_row())) {
                            REST::fatal(REST::HTTP_UNAUTHORIZED, "No such user id: {$esc_user_id}");
                        }
                        self::$current = new Portal_User($esc_user_id, $row[1], $row[0], $row[2], true);
                    } else {
                        $esc_user_dn = Portal_MySQL::escape_string($user_dn);
                        $result = Portal_MySQL::query(<<<EOS
SELECT `user_id`, `user_email`, `user_name` FROM `User`
WHERE `user_dn` =  {$esc_user_dn};
EOS
);
                        if (!($row = $result->fetch_row())) {
                            self::unauthorized();
                        }
                        self::$current = new Portal_User($row[0], $row[2], $row[1], $user_dn);
                    }
                    break;
                default:
                    REST::fatal(REST::HTTP_INTERNAL_SERVER_ERROR);
            }
        }
        return self::$current;
    }
    $userdnmd5 = md5(Portal::user_dn());
    $username = escapeshellarg(trim($_POST['username']));
    $password = escapeshellarg(trim($_POST['password']));
    $server = escapeshellarg(trim($_POST['server']));
    $filename = escapeshellarg(Portal::PROXY_DIR . $userdnmd5 . '.pem');
    exec("echo {$password} | myproxy-logon -v -l {$username} -s {$server} -S -o {$filename} 2>&1", $output, $returnval);
    $output = implode("\n", $output);
    if (preg_match('/^(?:invalid pass phrase|No credentials exist for username .*)$/m', $output)) {
        REST::fatal(REST::HTTP_UNAUTHORIZED, 'Invalid username and/or pass phrase');
    }
    if ($returnval) {
        REST::fatal(REST::HTTP_BAD_REQUEST, '<pre>' . htmlentities($output) . '</pre>');
    }
    $escserver = Portal_MySQL::escape_string($_POST['server']);
    $escusername = Portal_MySQL::escape_string($_POST['username']);
    $escpassword = Portal_MySQL::escape_string($_POST['password']);
    Portal_MySQL::real_query("UPDATE `User` SET `proxy_server` = {$escserver}, `proxy_username` = {$escusername}, `proxy_password` = {$escpassword} WHERE `user_dn_md5` = '{$userdnmd5}'");
    $best_xhtml_type = REST::best_xhtml_type();
    $type = REST::best_content_type(array($best_xhtml_type => 1.0, 'text/plain' => 1.0), $best_xhtml_type);
    $relurl = REST::urlencode(dirname($_SERVER['REDIRECT_URL'])) . '/proxy';
    REST::header(array('status' => REST::HTTP_CREATED, 'Location' => REST::urlbase() . $relurl, 'Content-Type' => "{$type}; charset=UTF-8"));
    if ($type == 'text/plain') {
        echo REST::urlbase() . $relurl;
    } else {
        echo Portal::html_start('Proxy created') . "<p><a href=\"proxy\">proxy</a></p>" . Portal::html_end();
    }
    exit;
}
REST::header(REST::best_xhtml_type() . "; charset=UTF-8");
$default_server = getenv('MYPROXY_SERVER');
echo Portal::html_start("myProxy") . <<<EOS
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * $Id: databases_versions.php 2459 2009-08-10 21:20:41Z pieterb $
 **************************************************************************/
/**
 * File documentation.
 * @package Portal
 */
require_once 'include/global.php';
REST::require_method('GET', 'HEAD');
$user_id = Portal_User::current()->user_id();
$path_info = Portal::path_info();
$dbname = Portal_MySQL::escape_string($path_info[0]);
$result = Portal_MySQL::query(<<<EOS
SELECT DISTINCT(`version`) FROM `Database`
WHERE `name` = {$dbname}
  AND ( `is_shared` > 0 OR `user_id` = {$user_id} );
EOS
);
$directory = RESTDir::factory("{$path_info['0']}: available versions");
while ($row = $result->fetch_row()) {
    $directory->line($row[0] . '/');
}
$directory->end();
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * $Id: databases_files.php 2459 2009-08-10 21:20:41Z pieterb $
 **************************************************************************/
/**
 * File documentation.
 * @package Portal
 */
require_once 'include/global.php';
$path_info = Portal::path_info();
$dbname = Portal_MySQL::escape_string($path_info[0]);
$dbversion = Portal_MySQL::escape_string($path_info[1]);
if (preg_match("/([^\\w\\-.~])/", $path_info[0] . $path_info[1])) {
    REST::fatal(REST::HTTP_FORBIDDEN, <<<EOS
Illegal characters found in database name or version.<br/>
Allowed characters are: A-Z a-z 0-9 _ - . ~
EOS
);
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $user_id = Portal_User::current()->user_id();
    if (strpos(@$_SERVER['CONTENT_TYPE'], 'multipart/form-data') === 0) {
        if (empty($_POST['type'])) {
            REST::fatal(REST::HTTP_BAD_REQUEST, "No type specified");
        }
        if (!($typeId = (int) Portal_DB::databaseTypeIDByName($_POST['type']))) {
            REST::fatal(REST::HTTP_BAD_REQUEST, "Wrong type specified");