blob: f75d5f8db2218c1aa3efbe7ed752940899c6bf57 [file] [log] [blame]
<?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;
}
}
?>