blob: ecb1137e7ae27c2d768ad04229732e5d05632876 [file] [log] [blame]
<?php
/**
* Copyright (c) 2006, 2023 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/
*
* Contributors:
* Denis Roy (Eclipse Foundation)- initial API and implementation
* Christopher Guindon (Eclipse Foundation) - Refactoring to avoid Friend() seriazilation in database
*
* SPDX-License-Identifier: EPL-2.0
*/
require_once realpath(dirname(__FILE__) . "/../../system/app.class.php");
require_once "/home/data/httpd/eclipse-php-classes/system/ldapconnection.class.php";
/**
* Friend class.
*
* @deprecated
* The Friends of Eclipse program has been deprecated.
*/
class Friend {
/**
* An instance of the App class from eclipse.org-common/system/App.
*
* @var App
*/
private $App = NULL;
/**
* Expiration date of the benefit.
*
* Calculated based on the current date/time in SQL:
* DATE_ADD(NOW(), INTERVAL 1 YEAR)
*
* @var DateTime|null
* Expiration date of the benefit, or null if not set.
*/
private $benefit_expires = NULL;
/**
* Bugzilla ID associated with the Friend.
*
* @var int
*/
private $bugzilla_id = 0;
/**
* Date the friend first sponsored.
*
* Calculated based on the current date/time in SQL: NOW()
*
* @var DateTime|null
* Date of first sponsorship, or null if not set.
*/
private $date_joined = NULL;
/**
* LDAP's Distinguished Name (dn) for the user.
*
* @var string
*/
private $dn = "";
/**
* User's email address.
*
* @var string
*/
private $email = "";
/**
* Unique ID for the friend from the friends database table.
*
* @var int
*/
private $friend_id = 0;
/**
* User's first name.
*
* @var string
*/
private $first_name = "";
/**
* Flag to indicate if the user's donation is anonymous.
*
* 1 for anonymous, 0 otherwise.
*
* @var int
*/
private $is_anonymous = 0;
/**
* Flag to indicate if the user's donation exceeds $35.
*
* @var int
* Set to 1 if the donation includes benefits, 0 otherwise.
*/
private $is_benefit = 0;
/**
* User's last name.
*
* @var string
*/
private $last_name = "";
/**
* LDAPConnection instance
*
* @var LDAPConnection
*/
private $Ldap = NULL;
/**
* The LDAP username for the user.
*
* @var string
*/
private $uid = NULL;
/**
* Constructor.
*/
public function __construct() {
$this->App = new App();
$this->Ldap = new LDAPConnection();
}
/**
* Retrieves the benefit expiration date.
*
* @return DateTime|null
* The expiration date of the benefit, or null if not set.
*/
public function getBenefitExpires() {
return $this->benefit_expires;
}
/**
* Sets the benefit expiration date.
*
* @param DateTime $_benefit_expires
* The expiration date to set.
*/
public function setBenefitExpires($_benefit_expires) {
$this->benefit_expires = $_benefit_expires;
}
/**
* Retrieves the Bugzilla ID for the Friend.
*
* @return int
* The Bugzilla ID.
*/
public function getBugzillaID() {
return $this->bugzilla_id;
}
/**
* Sets the Bugzilla ID for the Friend.
*
* @param int $_bugzilla_id
* The Bugzilla ID to set. Must be a digit.
*/
public function setBugzillaID($_bugzilla_id) {
if (ctype_digit($_bugzilla_id)) {
$this->bugzilla_id = $_bugzilla_id;
}
}
/**
* Retrieves the date the friend first sponsored.
*
* @return DateTime|null
* The date of first sponsorship, or null if not set.
*/
public function getDateJoined() {
return $this->date_joined;
}
/**
* Sets the date of the friend's first sponsorship.
*
* @param DateTime $_date_joined
* The date of first sponsorship to set.
*/
public function setDateJoined($_date_joined) {
$this->date_joined = $_date_joined;
}
/**
* Retrieves the LDAP's Distinguished Name (dn) for the user.
*
* @return string
* The LDAP distinguished name.
*/
public function getDn() {
$uid = $this->getLDAPUID();
if (empty($this->dn) && !empty($uid)) {
$dn = $this->Ldap->getDNFromUid($this->getLDAPUID());
$this->setDn($dn);
}
return $this->dn;
}
/**
* Sets the LDAP's Distinguished Name (dn) for the friend.
*
* @param string $_dn
* The LDAP distinguished name to set.
*/
public function setDn($_dn) {
$this->dn = $_dn;
}
/**
* Retrieves the user's email address.
*
* @return string
* The email address.
*/
public function getEmail() {
return $this->email;
}
/**
* Sets the user's email address.
*
* @param string $_email
* The email address to set.
*/
public function setEmail($_email) {
$this->email = $_email;
}
/**
* Retrieves the unique Friend ID from the friends database table.
*
* @return int
* The Friend ID.
*/
public function getFriendID() {
return $this->friend_id;
}
/**
* Sets the unique Friend ID from the friends database table.
*
* @param int $_friend_id
* The Friend ID to set.
*/
public function setFriendID($_friend_id) {
$this->friend_id = $_friend_id;
}
/**
* Retrieves the user's first name.
*
* @return string
* The first name.
*/
public function getFirstName() {
return $this->first_name;
}
/**
* Sets the user's first name.
*
* Strips out '<' and '>' characters.
*
* @param string $_first_name
* The first name to set.
*/
public function setFirstName($_first_name) {
$this->first_name = preg_replace('/[<>]/', '', $_first_name);
}
/**
* Retrieves the flag indicating if the user's donation is anonymous.
*
* @return bool
* True if the donation is anonymous, false otherwise.
*/
public function getIsAnonymous() {
return $this->is_anonymous;
}
/**
* Sets the flag indicating if the user's donation is anonymous.
*
* @param int $_is_anonymous
* Default is 1. The flag value to set.
*/
public function setIsAnonymous($_is_anonymous = 1) {
$this->is_anonymous = $_is_anonymous;
}
/**
* Retrieves the flag indicating if the user's donation exceeds $35.
*
* @return bool
* True if the donation includes benefits, false otherwise.
*/
public function getIsBenefit() {
return $this->is_benefit;
}
/**
* Sets the flag indicating if the user's donation exceeds $35.
*
* @param bool $_is_benefit
* The flag value to set.
*/
public function setIsBenefit($_is_benefit) {
$this->is_benefit = $_is_benefit;
}
/**
* Retrieves the user's last name.
*
* @return string
* The last name.
*/
public function getLastName() {
return $this->last_name;
}
/**
* Sets the user's last name.
*
* Strips out '<' and '>' characters.
*
* @param string $_last_name
* The last name to set.
*/
public function setLastName($_last_name) {
$this->last_name = preg_replace('/[<>]/', '', $_last_name);
}
/**
* Get LDAP username for the user.
*
* @return string|false
* The extracted UID or false if extraction failed.
*
* @deprecated
* Use getUID() instead.
*/
public function getLDAPUID() {
return $this->getUID();
}
/**
* Sets the LDAP username for the user.
*
* @param string $_uid
* The LDAP username to set.
*
* @deprecated
* Use setUID() instead.
*/
public function setLDAPUID($_uid) {
$this->setUID($_uid);
}
/**
* Retrieve the LDAP UID.
*
* @return string|false
* The extracted UID or false if extraction failed.
*/
public function getUID() {
if (empty($this->uid)) {
return FALSE;
}
return $this->uid;
}
/**
* Sets the LDAP username for the user.
*
* @param string $_uid
* The LDAP username to set.
*/
public function setUID($_uid) {
$this->uid = $_uid;
}
/**
* Determines if the user is a committer.
*
* The user's committer status is inferred from the presence of 'ou=people,'
* in the LDAP Distinguished Name (dn).
*
* @return bool
* Returns true if the user is a committer, false otherwise.
*/
public function getIsCommitter() {
$dn = $this->getDn();
if (!empty($dn) && preg_match('/ou=people,/i', $dn)) {
return TRUE;
}
return FALSE;
}
/**
* Inserts a new friend entry or updates an existing one in the 'friends' table.
*
* - If 'date_joined' is not set, it defaults to current date/time.
* - Checks if a friend with 'friend_id' exists:
* - If yes, updates the friend's details.
* - If no, inserts a new entry in the database.
* - Input data is sanitized to prevent SQL injection.
* - After insert, 'friend_id' is retrieved and set to the object.
*
* @return int
* Returns the 'friend_id' of the inserted/updated entry.
*/
public function insertUpdateFriend() {
$return = 0;
$date_joined = $this->date_joined === NULL ? "NOW()" : $this->App->quoteAndSanitize($this->date_joined);
$bugzilla_id = $this->App->quoteAndSanitize($this->getBugzillaID());
$first_name = $this->App->quoteAndSanitize($this->getFirstName());
$last_name = $this->App->quoteAndSanitize($this->getLastName());
$is_anonymous = $this->App->quoteAndSanitize($this->getIsAnonymous());
$is_benefit = $this->App->quoteAndSanitize($this->getIsBenefit());
$uid = $this->App->quoteAndSanitize($this->getLDAPUID());
$friend_id_sanitized = $this->App->sqlSanitize($this->getFriendID());
if ($this->selectFriendID("friend_id", $friend_id_sanitized)) {
// Update.
$sql = "UPDATE friends SET
bugzilla_id = $bugzilla_id,
first_name = $first_name,
last_name = $last_name,
date_joined = $date_joined,
is_anonymous = $is_anonymous,
is_benefit = $is_benefit,
uid = $uid
WHERE
friend_id = $friend_id_sanitized";
$this->App->eclipse_sql($sql);
$return = $this->friend_id;
}
else {
// Insert.
$sql = "INSERT INTO friends (
bugzilla_id,
first_name,
last_name,
date_joined,
is_anonymous,
is_benefit,
uid)
VALUES (
$bugzilla_id,
$first_name,
$last_name,
$date_joined,
$is_anonymous,
$is_benefit,
$uid)";
$this->App->eclipse_sql($sql);
$return = mysql_insert_id();
$this->setFriendID($return);
}
return $return;
}
/**
* Fetches and sets details of a friend based on a 'friend_id' from the table.
*
* - Executes an SQL query to retrieve friend information and the latest
* contribution's expiry date from 'friends_contributions'.
* - If a friend entry is found, details are set to the object's properties.
* - All input data are sanitized to prevent SQL injection.
*
* @param string $_friend_id
* The ID of the friend to fetch.
*
* @return bool
* TRUE if friend entry was fetched and set, FALSE otherwise.
*/
public function selectFriend($_friend_id) {
if (empty($_friend_id)) {
return FALSE;
}
$_friend_id = $this->App->quoteAndSanitize($_friend_id);
$sql = "SELECT /* USE MASTER */ f.friend_id, f.bugzilla_id, f.first_name,
f.last_name, f.date_joined, f.is_anonymous, f.is_benefit, f.uid,
fc_temp.date_expired
FROM friends as f
LEFT JOIN (
SELECT friend_id, MAX(date_expired) AS date_expired
FROM friends_contributions GROUP BY friend_id) fc_temp
ON fc_temp.friend_id = f.friend_id
WHERE f.friend_id = $_friend_id";
$result = $this->App->eclipse_sql($sql);
if ($myrow = mysql_fetch_array($result)) {
$this->setFriendID($myrow["friend_id"]);
$this->setBugzillaID($myrow["bugzilla_id"]);
$this->setFirstName($myrow["first_name"]);
$this->setLastName($myrow["last_name"]);
$this->setDateJoined($myrow["date_joined"]);
$this->setIsAnonymous($myrow["is_anonymous"]);
$this->setIsBenefit($myrow["is_benefit"]);
$this->setUID($myrow["uid"]);
$this->setBenefitExpires($myrow["date_expired"]);
return TRUE;
}
return FALSE;
}
/**
* Fetches 'friend_id' from the 'friends' table based on a field and value.
*
* - Allows a dynamic query to search for 'friend_id' using any specified field
* in the 'friends' table.
* - Input data is sanitized to prevent SQL injection.
*
* @param string $_fieldname
* Database field name to search.
* @param string $_searchfor
* Value to search for in the field.
*
* @return int
* Returns 'friend_id' if found, 0 otherwise.
*/
public function selectFriendID($_fieldname, $_searchfor) {
$friend_id = 0;
// Ensure the field and value are provided.
if (empty($_fieldname) || empty($_searchfor)) {
return $friend_id;
}
// Sanitize fieldname separately as we don't want it quoted.
$_fieldname = $this->App->sqlSanitize($_fieldname, NULL);
$_searchfor = $this->App->quoteAndSanitize($_searchfor);
$sql = "SELECT friend_id FROM friends WHERE $_fieldname = $_searchfor";
$result = $this->App->eclipse_sql($sql);
if ($result) {
$myrow = mysql_fetch_array($result);
if (isset($myrow['friend_id'])) {
$friend_id = $myrow['friend_id'];
}
}
return $friend_id;
}
/**
* Retrieves the Bugzilla user ID associated with an email address.
*
* - Queries the 'profiles' table in the Bugzilla database for the 'userid'.
* - Can specify the use of the master database replica for up-to-date data.
* - Input parameters are sanitized to prevent SQL injection.
*
* @param string $_email
* Email address to fetch the Bugzilla user ID.
* @param bool $use_primary
* If TRUE, query uses the master database.
*
* @return int
* Returns the Bugzilla user ID for the email; 0 otherwise.
*/
public function getBugzillaIDFromEmail($_email, $use_primary = FALSE) {
$bugzilla_id = 0;
// Ensure a valid email is provided.
if (empty($_email)) {
return $bugzilla_id;
}
$_email = $this->App->quoteAndSanitize($_email);
// Construct SQL query.
$primary_query = $use_primary ? "/* USE MASTER */" : "";
$sql = "SELECT {$primary_query} userid FROM profiles WHERE login_name = $_email";
$result = $this->App->bugzilla_sql($sql);
if ($result) {
$myrow = mysql_fetch_array($result);
if (isset($myrow['userid'])) {
$bugzilla_id = $myrow['userid'];
}
}
return $bugzilla_id;
}
/**
* Updates the profile using data fetched from LDAP.
*
* @return void
*/
public function updateFriendFromLdap() {
if ($entry = $this->Ldap->getAllAttributesFromUid($this->getLDAPUID())) {
// Map LDAP attributes to corresponding methods.
$attributes_to_methods = array(
'mail' => 'setEmail',
'uid' => 'setUID',
'givenname' => 'setFirstName',
'sn' => 'setLastName'
);
// Set attributes using corresponding methods.
foreach ($attributes_to_methods as $attribute => $method) {
if (isset($entry[$attribute][0])) {
$this->$method($entry[$attribute][0]);
}
}
}
}
/**
* Checks if the user belongs to a specified LDAP group.
*
* - Rather than invoking directly, use wrapper functions for group verification.
* Example: Use checkUserIsFoundationStaff() instead of checkUserInGroup().
*
* @param string $group
* The group name to check against.
*
* @return bool
* TRUE if user is in the group; FALSE otherwise.
*/
private function checkUserInGroup($group = '') {
$group = filter_var($group, FILTER_SANITIZE_STRING);
$ldap_uid = $this->getLDAPUID();
if (empty($ldap_uid)) {
return FALSE;
}
if ($this->Ldap->checkUserInGroup($ldap_uid, $group)) {
return TRUE;
}
return FALSE;
}
/**
* Determines if the Friend instance represents a Foundation Staff member.
*
* @return bool
* TRUE if user is Foundation Staff; FALSE otherwise.
*/
public function checkUserIsFoundationStaff() {
return $this->checkUserInGroup('www-auth');
}
/**
* Determines if the Friend instance represents a Webmaster.
*
* @return bool
* TRUE if user is a Webmaster; FALSE otherwise.
*/
public function checkUserIsWebmaster() {
return $this->checkUserInGroup('admins');
}
/**
* Retrieves a list of Friends who donated over $100.
*
* @param int $offset
* Starting index for results.
* @param int $num
* Number of results to return.
* @param bool $get_anonymous
* If TRUE, includes anonymous friends.
*
* @return array
* An array of Friend objects (now empty as it's deprecated).
*
* @deprecated
* This method is deprecated and not reliable for future development.
*/
public function getBestFriends($offset = 0, $num = 100, $get_anonymous = TRUE) {
trigger_error("Deprecated function called.", E_USER_NOTICE);
return array();
}
/**
* Authenticates a user based on Bugzilla credentials.
*
* @param string $email
* User's email address.
* @param string $password
* User's password.
*
* @return bool TRUE if authenticated; FALSE otherwise.
*
* @since 2007-11-20
* @deprecated Use LDAP() for authentication
*/
public function authenticate($email, $password) {
trigger_error("Deprecated function called.", E_USER_NOTICE);
return FALSE;
}
}