| <?php |
| /** |
| * Copyright (c) Eclipse Foundation and others. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| */ |
| |
| require_once (dirname(__FILE__) . "/debug.php"); |
| trace_file_info(__FILE__); |
| |
| /* |
| * The regular expression pattern that is used to determine whether |
| * or not a project id is valid. |
| * PRIVATE: THIS FIELD IS NOT API. |
| */ |
| $projectNameSegmentPattern = "[a-zA-Z0-9\\-]+"; |
| $projectNamePattern = "$projectNameSegmentPattern(\\.$projectNameSegmentPattern){0,2}"; |
| define('ProjectNamePattern', $projectNamePattern); |
| |
| /** |
| * Answers <code>true</code> if $id represents a valid project id; |
| * <code>false</code> otherwise. |
| * |
| * @param string $id |
| * Must not be <code>null</code> |
| * @return bool |
| */ |
| function isValidProjectId($id) { |
| global $projectNamePattern; |
| |
| return preg_match("/^$projectNamePattern$/", $id); |
| } |
| |
| /** |
| * This function normalizes the provided URL to a valid 'eclipse.org' HTTP |
| * form. |
| * Input should be a valid eclipse.org URL or a relative URL |
| * (with or without a leading slash). Note that URLs that do not correspond |
| * to an eclipse.org addresses, will result in a <code>null</code> result. |
| * |
| * Note that this is more about normalization than actual full validation; |
| * only the scheme and domain are considered. The current implementation |
| * only supports the http/https schemes; the specification of a port |
| * is not supported. This may change in the future. |
| * |
| * e.g. The following URLs are all considered valid and returned in the |
| * the form they are provided. |
| * - http://www.eclipse.org/woolsey/para.html |
| * - http://eclipse.org/woolsey/para.html |
| * - http://download.eclipse.org/woolsey/para.html |
| * - |
| * http://git.eclipse.org/c/jetty/org.eclipse.jetty.admin.git/plain/jetty-project-plan.xml |
| * |
| * e.g. The following URLs will be returned as |
| * http://eclipse.org/woolsey/para.html |
| * - woolsey/para.html |
| * - /woolsey/para.html |
| * |
| * Usage: |
| * |
| * normalizeHttpUrl('http://www.eclipse.org/woolsey/para.html'); |
| * |
| * @param string $url |
| * Must not be <code>null</code> |
| * @return string |
| */ |
| function normalizeHttpUrl($url) { |
| if (preg_match('/^https?:\/\/(\w+\.)?eclipse\.org(\/.*)?$/', $url)) |
| return $url; |
| if (preg_match('/^https?:\/\/(\w+\.)?locationtech\.org(\/.*)?$/', $url)) |
| return $url; |
| if (preg_match('/^https?:\/\/(\w+\.)?polarsys\.org(\/.*)?$/', $url)) |
| return $url; |
| |
| $relative = normalizeRelativeUrl($url, 'www'); |
| if ($relative) |
| return 'http://www.eclipse.org' . $relative; |
| |
| return null; |
| } |
| |
| /** |
| * This function normalizes the provided URL to valid file path on the |
| * eclipse.org web directory. |
| * Input should be a valid eclipse.org URL |
| * or a relative URL (with or without a leading slash). |
| * |
| * e.g. The following URLs will all normalize to |
| * /home/local/data/httpd/www.eclipse.org/html/woolsey/para.html |
| * |
| * - http://www.eclipse.org/woolsey/para.html |
| * - http://eclipse.org/woolsey/para.html |
| * - http://localhost/woolsey/para.html |
| * - woolsey/para.html |
| * - /woolsey/para.html) |
| * |
| * Note that URLs that do not correspond to eclipse.org addresses, will |
| * result in a <code>null</code> result. |
| * |
| * Usage: |
| * |
| * normalizeFilePathUrl('http://www.eclipse.org/woolsey/para.html'); |
| * |
| * @param string $url |
| * Must not be <code>null</code> |
| * @return string |
| */ |
| function normalizeFilePathUrl($url) { |
| global $_SERVER; |
| |
| $relative = normalizeRelativeUrl($url); |
| if (!$relative) |
| return null; |
| |
| return $_SERVER['DOCUMENT_ROOT'] . $relative; |
| } |
| |
| /** |
| * This function normalizes the provided URL to a relative path. |
| * Input should be a valid eclipse.org URL or a relative URL |
| * (with or without a leading slash). |
| * |
| * e.g. The following URLs will all normalize to |
| * /woolsey/para.html |
| * |
| * - http://www.eclipse.org/woolsey/para.html |
| * - http://eclipse.org/woolsey/para.html |
| * - http://localhost/woolsey/para.html |
| * - woolsey/para.html |
| * - /woolsey/para.html) |
| * |
| * Note that URLs that do not correspond to eclipse.org addresses, will |
| * result in a <code>null</code> result. |
| * |
| * Usage: |
| * |
| * normalizeRelativeUrl('http://www.eclipse.org/woolsey/para.html'); |
| * |
| * @param string $url |
| * Must not be <code>null</code> |
| * @return string |
| */ |
| function normalizeRelativeUrl($url) { |
| if (!$url) |
| return null; |
| |
| $url = trim($url); |
| |
| $pattern_word = '\w[\w-]*'; |
| $pattern_segment = "$pattern_word(\\.$pattern_word)*"; |
| $pattern_relative_part = "$pattern_segment(\\/$pattern_segment)*\\/?"; |
| $pattern_relative_url = "/^\\/?($pattern_relative_part)$/"; |
| $pattern_http_url = "/^http:\\/\\/(www\\.)?eclipse\\.org\\/($pattern_relative_part)$/"; |
| $pattern_http_local_url = "/^http:\\/\\/localhost\\/($pattern_relative_part)$/"; |
| |
| if (preg_match($pattern_relative_url, $url, $matches1)) { |
| return '/' . $matches1[1]; |
| } |
| else |
| if (preg_match($pattern_http_url, $url, $matches2)) { |
| return '/' . $matches2[2]; |
| } |
| else |
| if (preg_match($pattern_http_local_url, $url, $matches3)) { |
| return '/' . $matches3[1]; |
| } |
| else { |
| trace("The url ($url) cannot be normalized."); |
| return null; |
| } |
| } |
| |
| /** |
| * Test to see if the user is a committer, and execute |
| * the callable if they are not. |
| * |
| * This function assumes that the $App variable exists and has been |
| * assigned an instance of the App class (from app.class.php). |
| * |
| * @param callable $function |
| */ |
| function callIfNotCommitter($function) { |
| global $App; |
| if ($App->devmode) { |
| return; |
| } |
| |
| // Force no-caching before we attempt a redirect to anywhere. |
| header("Cache-Control: no-cache, no-store, must-revalidate"); |
| header("Pragma: no-cache"); |
| header("Expires: 0"); |
| |
| $Session = $App->useSession("required"); |
| $friend = $Session->getFriend(); |
| |
| // TODO There may be a better way to do this. |
| if (preg_match('/^.+@eclipse-foundation\.org$/', $friend->getEmail())) { |
| return; |
| } |
| |
| if (!$friend->getIsCommitter()) { |
| call_user_func($function); |
| } |
| } |
| |
| /** |
| * This function forces a login event if the current user is not |
| * logged in. |
| * If the logged in user is not an Eclipse Foundation |
| * employee, they are redirected to the /projects/ page. It must |
| * be called before any HTML is written to the output stream. |
| * |
| * This function assumes that the $App variable exists and has been |
| * assigned an instance of the App class (from app.class.php). |
| * |
| * @return Friend |
| */ |
| function mustBeFoundationEmployee() { |
| global $App; |
| if ($App->devmode) |
| return; |
| |
| $session = $App->useSession('required'); |
| $friend = $session->getFriend(); |
| |
| // TODO There may be a better way to do this. |
| if (!preg_match('/^.+@eclipse-foundation\.org$/', $friend->getEmail())) { |
| header("Location: /projects"); |
| exit(); |
| } |
| |
| return $friend; |
| } |
| |
| /** |
| * This function basically throws a fit if the caller is |
| * coming from anywhere outside of the EF. |
| * It determines |
| * whether or not to grant access based on the IP Address. |
| */ |
| function mustBeEclipseFoundationCaller() { |
| global $App; |
| |
| $App->preventCaching(); |
| $ip = $App->getRemoteIPAddress (); |
| $patterns = array ( |
| '198.41.30.', // 198.41.30.192/26 |
| '99.240.80.', |
| '172.25.', // 172.25.0.0/16 |
| '172.30.', // 172.30.0.0/16 |
| '127.0.0.1', |
| '::1' |
| ); |
| $match = preg_replace ( '/\./', '\.', implode ( '|', $patterns ) ); |
| if (preg_match ( "/^($match)/", $ip )) |
| return; |
| echo "{$ip} is an invalid caller\n"; |
| exit (); |
| } |
| |
| function getUrlContents($url) { |
| $ch = curl_init(); |
| curl_setopt($ch, CURLOPT_USERAGENT,"Eclipse"); |
| curl_setopt($ch, CURLOPT_URL, $url); |
| curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); |
| curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
| $page = curl_exec($ch); |
| |
| $error = curl_errno($ch); |
| if ($error) { |
| $message = curl_error($ch); |
| throw new Exception("[{$error}] {$message}"); |
| } |
| |
| curl_close($ch); |
| return $page; |
| } |
| |
| function implodeWithConjunction($values, $conjunction = 'and', $start = 0) { |
| $end = count($values) - 1; |
| if ($start > $end) { |
| return; |
| } elseif ($start == $end) { |
| return $values[$start]; |
| } elseif ($end - $start == 1) { |
| return $values[$start] . ', ' . $conjunction . ' ' . $values[$end]; |
| } else { |
| return $values[$start] . ', ' . implodeWithConjunction($values, $conjunction, $start + 1); |
| } |
| } |
| |
| function renderAsHeaderComment($string, $length = 80) { |
| $output = array (); |
| $output [] = '/' . str_repeat ( '*', $length ); |
| foreach ( explode ( "\n", $string ) as $line ) { |
| if (preg_match ( '/^SPDX\-License\-Identifier/', $line )) { |
| $output [] = ' * ' . $line; |
| } else { |
| foreach ( explode ( "\n", wordwrap ( $line, $length - 5 ) ) as $fragment ) { |
| $output [] = ' * ' . $fragment; |
| } |
| } |
| } |
| $output [] = ' ' . str_repeat ( '*', $length ) . '/'; |
| |
| return implode ( "\n", $output ); |
| } |
| |
| function compareSemanticVersion($a, $b) { |
| $va = explode('.', $a); |
| $vb = explode('.', $b); |
| |
| $max = 5; |
| while ($max-- > 0) { |
| $ca = current($va); |
| $cb = current($vb); |
| |
| // FALSE means that we've run out of terms. If we're out of terms, |
| // assume that the value is zero. This allows us to, for example, |
| // meaningfully and correctly compare '3.0' and '3.0.0'. |
| if ($ca === FALSE) $ca = 0; |
| if ($cb === FALSE) $cb = 0; |
| |
| // Compare as integers rather than strings. |
| $ca = (int) $ca; |
| $cb = (int) $cb; |
| |
| if ($ca > $cb) { |
| return 1; |
| } elseif ($cb > $ca) { |
| return -1; |
| } |
| |
| next($va); |
| next($vb); |
| } |
| |
| return 0; |
| } |
| |
| /** |
| * This function answers the id of the Eclipse project that produces the bits |
| * with the provided ClearlyDefined coordinates. |
| * |
| * @deprecated |
| */ |
| function getEclipseProjectFor($id) { |
| require_once dirname(__FILE__) . '/ProjectContentIdMapper.class.inc'; |
| |
| return ProjectContentIdMapper::getEclipseProjectFor($id); |
| } |
| |
| if (!function_exists('mb_str_pad')) { |
| function mb_str_pad($string, $length) { |
| $value = $string; |
| while (mb_strlen($value) < $length) $value .= ' '; |
| return $value; |
| } |
| } |
| ?> |