* Licensed under the Apache License, Version 2.0 (the "License"); you may
 * 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.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();
$result = Portal_MySQL::query(<<<EOS
SELECT DISTINCT `name` FROM `Database`
WHERE `is_shared` > 0
   OR `user_id` = {$user_id}
EOS
);
$action = REST::htmlspecialchars($_SERVER['REQUEST_URI']);
$directory = RESTDir::factory('Available databases (by name)');
while ($row = $result->fetch_row()) {
    $directory->line($row[0] . '/');
}
$directory->end();
    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();
}
$url = REST::htmlspecialchars(Portal::portalURL());
REST::fatal(REST::HTTP_OK, <<<EOS
<p>Registration complete.</p>
<p>You can now start <a href="{$url}">using the GridApps web service</a>.</p>
EOS
);
    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
);
    }
    // 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
Hi {$_GET['name']},

These are the credentials you may use for the Grid Application Portal:
    /**
     * @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;
    }
EOS
);
    exec("cd '{$sandbox}'; find -mindepth 1 -maxdepth 1 -print0 | xargs -0 tar zcf {$TEMPNAM}.tgz", $output, $return_var);
    if ($return_var) {
        $output = implode("\n", $output);
        REST::fatal(REST::HTTP_INTERNAL_SERVER_ERROR, $output);
    }
    $tokenhandle = fopen("{$TEMPNAM}.tgz", 'r');
    try {
        $token_url = Topos::putTokenFile($tokenhandle, 'application/x-compressed-tar');
    } catch (Exception $e) {
        fclose($tokenhandle);
        throw $e;
    }
    fclose($tokenhandle);
    $token_id = basename($token_url);
    Portal_MySQL::real_query(<<<EOS
INSERT INTO `Token`
       ( `token_id`,  `user_id` )
VALUES ( {$token_id}, {$user_id} );
EOS
);
    $resultURL = REST::urlbase() . Portal::portalURL() . "jobstates/{$token_id}";
    REST::created($resultURL);
}
Portal_User::current();
REST::header(array('Content-Type' => REST::best_xhtml_type()));
echo Portal::html_start("{$appname}-{$appversion}") . '<form action="' . $appversion . '" method="post" enctype="multipart/form-data">';
$portlet->doGET();
echo '</form>' . Portal::html_end();
    /**
     * Get a list of available databases, given a set of database types.
     * @param $name... string the name(s) of the database types.
     * @return string an x fragment, to be put inside a select element.
     */
    public static function availableDatabases()
    {
        $dbTypes = func_get_args();
        if (empty($dbTypes)) {
            return array();
        }
        foreach ($dbTypes as $key => $value) {
            $dbTypes[$key] = self::databaseTypeIDByName($value);
        }
        $dbTypes = implode(',', $dbTypes);
        $user_id = Portal_User::current()->user_id();
        $result = Portal_MySQL::query(<<<EOS
SELECT `d`.`name`, `d`.`version`, `d`.`type`, `u`.`user_name`, `d`.`database_id`
  FROM `Database` AS d LEFT JOIN `User` AS u USING(`user_id`)
 WHERE (`d`.`is_shared` > 0 OR `d`.`user_id` = {$user_id})
   AND `d`.`type` IN({$dbTypes});
EOS
);
        $sorter = array();
        while ($row = $result->fetch_row()) {
            $extension = self::databaseTypeExtension($row[2]);
            $sorter[$row[3]]["{$row[0]}-{$row[1]}.{$extension}"] = REST::urlencode(Portal::portalURL() . 'databases/' . $row[0] . '/' . $row[1] . '/' . $row[4] . '.' . $extension);
        }
        $user_names = array_keys($sorter);
        natsort($user_names);
        $retval = '';
        foreach ($user_names as $user_name) {
            $retval .= "\n<optgroup label=\"" . htmlentities($user_name) . "\">";
            $dbnames = array_keys($sorter[$user_name]);
            natsort($dbnames);
            foreach ($dbnames as $dbname) {
                $retval .= "\n<option value=\"" . $sorter[$user_name][$dbname] . "\">{$dbname}</option>";
            }
            $retval .= "\n</optgroup>";
        }
        return $retval;
    }