| <?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-php8-classes/system/ldapconnection.class.php"; | |
| require_once "/home/data/httpd/eclipse-php8-classes/system/dbconnection_rw.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)"; | |
| $dbc = new DBConnectionRW(); | |
| $dbh = $dbc->connect(); | |
| mysqli_query($dbh, $sql); | |
| $return = mysqli_insert_id($dbh); | |
| $this->setFriendID($return); | |
| $dbc->disconnect(); | |
| } | |
| 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 = mysqli_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 = mysqli_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 = mysqli_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; | |
| } | |
| } |