public function commit() { if ($this->user->hasProfile()) { XDB::execute('UPDATE profiles SET alias_pub = {?} WHERE pid = {?}', $this->public, $this->user->profile()->id()); } if ($this->old) { $success = XDB::execute('UPDATE email_source_account SET email = {?} WHERE uid = {?} AND type = \'alias_aux\'', $this->alias, $this->user->id()); } else { $success = XDB::execute('INSERT INTO email_source_account (email, uid, domain, type, flags) SELECT {?}, {?}, id, \'alias_aux\', \'\' FROM email_virtual_domains WHERE name = {?}', $this->alias, $this->user->id(), Platal::globals()->mail->alias_dom); } if ($success) { // Update the local User object, to pick up the new bestalias. require_once 'emails.inc.php'; fix_bestalias($this->user); $this->user = User::getSilentWithUID($this->user->id()); } return $success; }
public function getGeocodedAddress(Address $address, $defaultLanguage = null, $forceLanguage = false) { $this->prepareAddress($address); $textAddress = $this->getTextToGeocode($address->text); if (is_null($defaultLanguage)) { $defaultLanguage = Platal::globals()->geocoder->gmaps_language; } // Try to geocode the full address. $address->geocoding_calls = 1; if ($geocodedData = $this->getPlacemarkForAddress($textAddress, $defaultLanguage)) { $this->getUpdatedAddress($address, $geocodedData, null, $forceLanguage); return; } // If the full geocoding failed, try to geocode only the final part of the address. // We start by geocoding everything but the first line, and continue until we get // a result. To respect the limit of GMaps calls, we ignore the first few lines // if there are too many address lines. $addressLines = explode("\n", $textAddress); $linesCount = count($addressLines); for ($i = max(1, $linesCount - self::MAX_GMAPS_RPC_CALLS + 1); $i < $linesCount; ++$i) { $extraLines = implode("\n", array_slice($addressLines, 0, $i)); $toGeocode = implode("\n", array_slice($addressLines, $i)); ++$address->geocoding_calls; if ($geocodedData = $this->getPlacemarkForAddress($toGeocode, $defaultLanguage)) { $this->getUpdatedAddress($address, $geocodedData, $extraLines, $forceLanguage); return; } } }
function handler_index($page) { if (Platal::globals()->merge->state == 'pending') { $page->changeTpl('fusionax/index.tpl'); } elseif (Platal::globals()->merge->state == 'done') { $issueList = array('name' => 'noms', 'job' => 'emplois', 'address' => 'adresses', 'promo' => 'promotions', 'deathdate' => 'dates de décès', 'phone' => 'téléphones', 'education' => 'formations'); $issues = XDB::rawFetchOneAssoc("SELECT COUNT(*) AS total,\n SUM(FIND_IN_SET('name', issues)) DIV 1 AS name,\n SUM(FIND_IN_SET('job', issues)) DIV 2 AS job,\n SUM(FIND_IN_SET('address', issues)) DIV 3 AS address,\n SUM(FIND_IN_SET('promo', issues)) DIV 4 AS promo,\n SUM(FIND_IN_SET('deathdate', issues)) DIV 5 AS deathdate,\n SUM(FIND_IN_SET('phone', issues)) DIV 6 AS phone,\n SUM(FIND_IN_SET('education', issues)) DIV 7 AS education\n FROM profile_merge_issues\n WHERE issues IS NOT NULL OR issues != ''"); $page->changeTpl('fusionax/issues.tpl'); $page->assign('issues', $issues); $page->assign('issueList', $issueList); } }
function send_robot_homonym(PlUser $user, $email) { $cc = "validation+homonyme@" . Platal::globals()->mail->domain; $from = "\"Support Polytechnique.org\" <{$cc}>"; $body = Post::has('mailbody') ? Post::t('mailbody') : get_robot_mail_text($user, $email); $user = User::getSilentWithUID($user->id()); $mymail = new PlMailer(); $mymail->setFrom($from); $mymail->setSubject("Mise en place du robot {$email}@" . $user->mainEmailDomain()); $mymail->addCc($cc); $mymail->setTxtBody($body); $mymail->sendTo($user); }
private static function init($type) { if (Platal::globals()->cacheEnabled() && S::has('__DE_' . $type)) { self::$enumerations[$type] = S::v('__DE_' . $type); } else { $cls = "DE_" . ucfirst($type); $obj = new $cls(); self::$enumerations[$type] = $obj; if (Platal::globals()->cacheEnabled() && $obj->capabilities & DirEnumeration::SAVE_IN_SESSION) { S::set('__DE_' . $type, $obj); } } }
private static function ListMergeIssues(Profile $profile) { if (Platal::globals()->merge->state != 'done') { return null; } $flags = XDB::fetchOneCell('SELECT issues FROM profile_merge_issues WHERE pid = {?}', $profile->id()); if (!$flags) { return null; } return new PlFlagSet($flags); }
public function __construct(PlUser $owner) { $notifs = Watch::getEvents($owner); $infos = array(); foreach ($notifs as $n) { foreach ($n['users'] as $user) { $op = $n['operation']; $date = $op->getDate($user); @($datetext = new Date($date)); @($datetext = $datetext->format('%e %B %Y')); $profile = $user->profile(); $infos[] = array('operation' => $op, 'title' => '[' . $op->getTitle(1) . '] - ' . $user->fullName() . ' le ' . $datetext, 'author' => $user->fullName(), 'publication' => $op->publicationDate($user), 'date' => strtotime($date), 'id' => $op->flag . '-' . $user->id() . '-' . strtotime($date), 'data' => $op->getData($user), 'hruid' => $user->login(), 'dead' => $user->deathdate, 'profile' => $user->profile()->hrid(), 'link' => Platal::globals()->baseurl . '/profile/' . $profile->hrid(), 'user' => $user, 'contact' => $owner->isContact($profile)); } } $this->it = PlIteratorUtils::fromArray($infos); }
public static function makeHomonymHrmid($alias) { return 'h.' . $alias . '.' . Platal::globals()->mail->domain; }
function handler_url($page, $alias) { http_redirect(Platal::globals()->core->base_url_shortener . $alias); }
function handler_add_accounts($page, $action = null, $promo = null) { require_once 'name.func.inc.php'; $page->changeTpl('admin/add_accounts.tpl'); if (Env::has('add_type') && Env::has('people')) { static $titles = array('male' => 'M', 'female' => 'MLLE'); $lines = explode("\n", Env::t('people')); $separator = Env::t('separator'); $promotion = Env::i('promotion'); if (Env::t('add_type') == 'promo') { $eduSchools = DirEnum::getOptions(DirEnum::EDUSCHOOLS); $eduSchools = array_flip($eduSchools); $eduDegrees = DirEnum::getOptions(DirEnum::EDUDEGREES); $eduDegrees = array_flip($eduDegrees); switch (Env::t('edu_type')) { case 'X': $degreeid = $eduDegrees[Profile::DEGREE_X]; $entry_year = $promotion; $grad_year = $promotion + 3; $promo = 'X' . $promotion; $hrpromo = $promotion; $type = 'x'; break; case 'M': $degreeid = $eduDegrees[Profile::DEGREE_M]; $grad_year = $promotion; $entry_year = $promotion - 2; $promo = 'M' . $promotion; $hrpromo = $promo; $type = 'master'; break; case 'D': $degreeid = $eduDegrees[Profile::DEGREE_D]; $grad_year = $promotion; $entry_year = $promotion - 3; $promo = 'D (en cours)'; $hrpromo = 'D' . $promotion; $type = 'phd'; break; default: $page->killError("La formation n'est pas reconnue : " . Env::t('edu_type') . '.'); } $best_domain = XDB::fetchOneCell('SELECT id FROM email_virtual_domains WHERE name = {?}', User::$sub_mail_domains[$type] . Platal::globals()->mail->domain); XDB::startTransaction(); foreach ($lines as $line) { if ($infos = self::formatNewUser($page, $line, $separator, $hrpromo, 6)) { $sex = self::formatSex($page, $infos[3], $line); $lastname = capitalize_name($infos[0]); $firstname = capitalize_name($infos[1]); if (!is_null($sex)) { $fullName = build_full_name($firstname, $lastname); $directoryName = build_directory_name($firstname, $lastname); $sortName = build_sort_name($firstname, $lastname); $birthDate = self::formatBirthDate($infos[2]); if ($type == 'x') { if ($promotion < 1996 && preg_match('/^[0-9]{8}$/', $infos[4])) { /* Allow using Xorg ID for old promotions, to allow fixing typos in names */ $xorgId = $infos[4]; $year = intval(substr($xorgId, 0, 4)); if ($year != $promotion) { $page->trigError("La ligne {$line} n'a pas été ajoutée car le matricule Xorg n'a pas la date correspondant à la promotion."); continue; } } else { $xorgId = Profile::getXorgId($infos[4]); } } elseif (isset($infos[4])) { $xorgId = trim($infos[4]); } else { $xorgId = 0; } if (is_null($xorgId)) { $page->trigError("La ligne {$line} n'a pas été ajoutée car le matricule École est mal renseigné."); continue; } XDB::execute('INSERT INTO profiles (hrpid, xorg_id, ax_id, birthdate_ref, sex, title) VALUES ({?}, {?}, {?}, {?}, {?}, {?})', $infos['hrid'], $xorgId, isset($infos[5]) ? $infos[5] : null, $birthDate, $sex, $titles[$sex]); $pid = XDB::insertId(); XDB::execute('INSERT INTO profile_public_names (pid, lastname_initial, lastname_main, firstname_initial, firstname_main) VALUES ({?}, {?}, {?}, {?}, {?})', $pid, $lastname, $lastname, $firstname, $firstname); XDB::execute('INSERT INTO profile_display (pid, yourself, public_name, private_name, directory_name, short_name, sort_name, promo) VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})', $pid, $firstname, $fullName, $fullName, $directoryName, $fullName, $sortName, $promo); XDB::execute('INSERT INTO profile_education (id, pid, eduid, degreeid, entry_year, grad_year, promo_year, flags) VALUES (100, {?}, {?}, {?}, {?}, {?}, {?}, \'primary\')', $pid, $eduSchools[Profile::EDU_X], $degreeid, $entry_year, $grad_year, $promotion); XDB::execute('INSERT INTO accounts (hruid, type, is_admin, state, full_name, directory_name, sort_name, display_name, lastname, firstname, sex, best_domain) VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})', $infos['hrid'], $type, 0, 'pending', $fullName, $directoryName, $sortName, $firstname, $lastname, $firstname, $sex, $best_domain); $uid = XDB::insertId(); XDB::execute('INSERT INTO account_profiles (uid, pid, perms) VALUES ({?}, {?}, {?})', $uid, $pid, 'owner'); Profile::rebuildSearchTokens($pid, false); } } } XDB::commit(); } else { if (Env::t('add_type') == 'account') { $type = Env::t('type'); $newAccounts = array(); foreach ($lines as $line) { if ($infos = self::formatNewUser($page, $line, $separator, $type, 4)) { $sex = self::formatSex($page, $infos[3], $line); if (!is_null($sex)) { $lastname = capitalize_name($infos[0]); $firstname = capitalize_name($infos[1]); $fullName = build_full_name($firstname, $lastname); $directoryName = build_directory_name($firstname, $lastname); $sortName = build_sort_name($firstname, $lastname); XDB::execute('INSERT INTO accounts (hruid, type, is_admin, state, email, full_name, directory_name, sort_name, display_name, lastname, firstname, sex) VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})', $infos['hrid'], $type, 0, 'pending', $infos[2], $fullName, $directoryName, $sortName, $firstname, $lastname, $firstname, $sex); $newAccounts[$infos['hrid']] = $fullName; } } } if (!empty($newAccounts)) { $page->assign('newAccounts', $newAccounts); } } else { if (Env::t('add_type') == 'ax_id') { $type = 'x'; foreach ($lines as $line) { $infos = explode($separator, $line); if (sizeof($infos) > 3 || sizeof($infos) < 2) { $page->trigError("La ligne {$line} n'a pas été ajoutée : mauvais nombre de champs."); continue; } $infos = array_map('trim', $infos); if (sizeof($infos) == 3) { // Get human readable ID with first name and last name $hrid = User::makeHrid($infos[1], $infos[0], $promotion); $user = User::getSilent($hrid); $axid = $infos[2]; } else { // The first column is the hrid, possibly without the promotion $user = User::getSilent($infos[0] . '.' . $promotion); if (is_null($user)) { $user = User::getSilent($infos[0]); } $axid = $infos[1]; } if (!$axid) { $page->trigError("La ligne {$line} n'a pas été ajoutée : matricule AX vide."); continue; } if (is_null($user)) { $page->trigError("La ligne {$line} n'a pas été ajoutée : aucun compte trouvé."); continue; } $profile = $user->profile(); if ($profile->ax_id) { $page->trigError("Le profil " . $profile->hrpid . " a déjà l'ID AX " . $profile->ax_id); continue; } XDB::execute('UPDATE profiles SET ax_id = {?} WHERE pid = {?}', $axid, $profile->id()); } } } } $errors = $page->nb_errs(); if ($errors == 0) { $page->trigSuccess("L'opération a été effectuée avec succès."); } else { $page->trigSuccess('L\'opération a été effectuée avec succès, sauf pour ' . ($errors == 1 ? 'l\'erreur signalée' : "les {$errors} erreurs signalées") . ' ci-dessus.'); } } else { if (Env::has('add_type')) { $res = XDB::query('SELECT type FROM account_types'); $page->assign('account_types', $res->fetchColumn()); $page->assign('add_type', Env::s('add_type')); } } }
function handler_register_ext($page, $hash = null) { http_redirect(Platal::globals()->xnet->xorg_baseurl . 'register/ext/' . $hash); }
public static function make_storage_redirection(User $user, $storage) { return $user->hruid . '@' . self::$storage_domains[$storage] . '.' . Platal::globals()->mail->domain; }
<?php /*************************************************************************** * Copyright (C) 2003-2015 Polytechnique.org * * http://opensource.polytechnique.org/ * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ***************************************************************************/ ini_set('memory_limit', '64M'); ini_set('include_path', dirname(__FILE__) . '/../core/include:' . dirname(__FILE__) . '/../include:' . dirname(__FILE__) . '/../core/classes:' . dirname(__FILE__) . '/../classes:' . '/usr/share/php'); require_once 'xorg.inc.php'; new Xorg('core'); // Do not store backtraces Platal::globals()->debug = 0; // vim:set et sw=4 sts=4 sws=4 foldmethod=marker fenc=utf-8:
private function changeLogin(PlPage $page, PlUser $user, $login, $req_broken = false, $req_marketing = false, $marketing_from = 'user') { // Search the user's uid. $xuser = User::getSilent($login); if (!$xuser) { $accounts = User::getPendingAccounts($login); if (!$accounts) { $page->trigError("L'identifiant {$login} ne correspond à aucun X."); return false; } else { if (count($accounts) > 1) { $page->trigError("L'identifiant {$login} correspond à plusieurs camarades."); return false; } } $xuser = User::getSilent($accounts[0]['uid']); } if (!$xuser) { return false; } // Market or suggest new redirection if required. $email = $user->bestEmail(); if ($req_broken) { $valid = new BrokenReq(S::user(), $xuser, $email, 'Groupe : ' . Platal::globals()->asso('nom')); $valid->submit(); } elseif ($req_marketing) { $market = Marketing::get($xuser->uid, $email); if (!$market) { $market = new Marketing($xuser->uid, $email, 'group', Platal::globals()->asso('nom'), $marketing_from, S::i('uid')); $market->add(); } } if ($user->mergeIn($xuser)) { return $xuser->login(); } return $user->login(); }
function createAliases($subState) { global $globals; $res = XDB::query("SELECT hruid, state, type\n FROM accounts\n WHERE uid = {?} AND hruid != ''", $subState->i('uid')); if ($res->numRows() == 0) { return "Tu n'as pas d'adresse à vie pré-attribuée.<br />" . "Envoie un mail à <a href=\"mailto:support@{$globals->mail->domain}\">" . "support@{$globals->mail->domain}</a> en expliquant ta situation."; } else { list($forlife, $state, $type) = $res->fetchOneRow(); } if ($state == 'active') { return "Tu es déjà inscrit, si tu ne te souviens plus de ton mot de passe d'accès au site, " . "tu peux suivre <a href=\"recovery\">la procédure de récupération de mot de passe</a>."; } else { if ($state == 'disabled') { return "Ton compte a été désactivé par les administrateurs du site suite à des abus. " . "Pour plus d'information ou pour demander la réactivation du compte, tu peux t'adresser à " . "<a href=\"mailto:support@{$globals->mail->domain}\">support@{$globals->mail->domain}</a>."; } } $emailXorg = PlUser::makeUserName($subState->t('firstname'), $subState->t('lastname')); $suffix = (User::$sub_mail_domains[$type] ? substr(User::$sub_mail_domains[$type], 0, 1) : '') . substr($subState->v('yearpromo'), -2); $emailXorg2 = $emailXorg . '.' . $suffix; // Search for homonyms: // * first case: only one homonym already registered. $res = XDB::query('SELECT uid, expire FROM email_source_account WHERE email = {?} AND type != \'alias_aux\'', $emailXorg); // * second case: at least two homonyms registerd. $result = XDB::query("SELECT hrmid\n FROM email_source_other\n WHERE type = 'homonym' AND email = {?}", $emailXorg); if ($res->numRows() || $result->numRows()) { if ($res->numRows()) { list($h_id, $expire) = $res->fetchOneRow(); if (empty($expire)) { XDB::execute('UPDATE email_source_account SET expire = ADDDATE(NOW(), INTERVAL 1 MONTH) WHERE email = {?} AND type != \'alias_aux\'', $emailXorg); $hrmid = User::makeHomonymHrmid($emailXorg); XDB::execute('INSERT IGNORE INTO homonyms_list (hrmid, uid) VALUES ({?}, {?}), ({?}, {?})', $hrmid, $h_id, $hrmid, $subState->i('uid')); $als = XDB::fetchColumn('SELECT email FROM email_source_account WHERE uid = {?} AND type != \'alias_aux\' AND expire IS NULL', $h_id); $homonym = User::getSilentWithUID($h_id); $mailer = new PlMailer('register/lostalias.mail.tpl'); $mailer->addTo($homonym); $mailer->setSubject("Perte de ton alias {$emailXorg} dans un mois !"); $mailer->assign('emailXorg', $emailXorg); $mailer->assign('als', join(', ', $als)); $mailer->SetTxtBody(wordwrap($msg, 72)); $mailer->send(); } } else { $hrmid = $result->fetchOneCell(); XDB::execute('INSERT IGNORE INTO homonyms_list (hrmid, uid) VALUES ({?}, {?})', $hrmid, $subState->i('uid')); // TODO: insert into source_other if new domain } $subState->set('forlife', $forlife); $subState->set('bestalias', $emailXorg2); $subState->set('emailXorg2', null); } else { $subState->set('forlife', $forlife); $subState->set('bestalias', $emailXorg); $subState->set('emailXorg2', $emailXorg2); } $subState->set('main_mail_domain', User::$sub_mail_domains[$type] . Platal::globals()->mail->domain); return true; }
/** * The authentication schema is based on three query parameters: * ?user=<hruid>×tamp=<timestamp>&sig=<sig> * where: * - hruid is the hruid of the querying user * - timestamp is the current UNIX timestamp, which has to be within a * given distance of the server-side UNIX timestamp * - sig is the HMAC of "<method>#<resource>#<payload>#<timestamp>" using * a known secret of the user as the key. * * At the moment, the shared secret of the user is the sha1 hash of its * password. This is temporary, though, until better support for tokens is * implemented in plat/al. * TODO(vzanotti): Switch to dedicated secrets for authentication. */ public function apiAuth($method, $resource, $payload) { // Verify that the timestamp is within acceptable bounds. $timestamp = Env::i('timestamp', 0); if (abs($timestamp - time()) > Platal::globals()->api->timestamp_tolerance) { return null; } // Retrieve the user corresponding to the forlife. Note that at the // moment, other aliases are also accepted. $user = User::getSilent(Env::s('user', '')); if (is_null($user) || !$user->isActive()) { return null; } // Determine the list of tokens associated with the user. At the moment, // this is just the sha1 of the password. $tokens = array($user->password()); // For each token, try to validate the signature. $message = implode('#', array($method, $resource, $payload, $timestamp)); $signature = Env::s('sig'); foreach ($tokens as $token) { $expected_signature = hash_hmac(Platal::globals()->api->hmac_algo, $message, $token); if ($signature == $expected_signature) { return $user; } } return null; }
require_once 'connect.db.inc.php'; require_once 'plmailer.php'; $limit = 60; $users = XDB::fetchAllAssoc('SELECT a.uid, a.hruid, r.hash, r.group_name, r.sender_name, r.email FROM register_pending_xnet AS r INNER JOIN accounts AS a ON (r.uid = a.uid) WHERE a.state = \'disabled\' ORDER BY r.date, a.uid'); $mailer = new PlMailer('xnet/account.mail.tpl'); $mailer->addCc('*****@*****.**'); $i = 0; foreach ($users as $user) { $mailer->setTo($user['email']); $mailer->assign('hash', $user['hash']); $mailer->assign('email', $user['email']); $mailer->assign('group', $user['group_name']); $mailer->assign('sender_name', $user['sender_name']); $mailer->assign('again', false); $mailer->assign('baseurl', Platal::globals()->baseurl); $mailer->send(); XDB::execute('UPDATE accounts SET state = \'pending\' WHERE uid = {?}', $user['uid']); if ($i == $limit) { $i = 0; sleep(60); } else { ++$i; } } // vim:set et sw=4 sts=4 sws=4 foldmethod=marker fenc=utf-8: