function handler_remove($page, $id = null) { S::assert_xsrf_token(); $val = ValidateFilter::fromId($id, false); if ($val === false) { $page->trigError("This item doesn't exist"); return; } $val->select(ValidateSelect::validate()); if ($val->writer()->id() != S::user()->id()) { throw new Exception("Invalid crendentials"); } S::logger()->log('proposal/remove', array('type' => $val->type(), 'writer' => $val->writer()->id(), 'group' => $val->group()->id(), 'created' => $val->created()->toDb(), 'item' => $val->itemToDb())); $val->item()->sendmailcancel(S::user()); $val->clean(); pl_redirect(Env::v('url')); }
function handler_sso($page) { $this->load('sso.inc.php'); // First, perform security checks. if (!wats4u_sso_check()) { return PL_BAD_REQUEST; } global $globals; if (!S::logged()) { // Request auth. $page->assign('external_auth', true); $page->assign('ext_url', $globals->wats4u->public_url); $page->setTitle('Authentification'); $page->setDefaultSkin('group_login'); $page->assign('group', null); return PL_DO_AUTH; } if (!S::user()->checkPerms(PERMS_USER)) { // External (X.net) account return PL_FORBIDDEN; } // Update the last login information (unless the user is in SUID). $uid = S::i('uid'); if (!S::suid()) { global $platal; S::logger($uid)->log('connexion_wats4u', $platal->path . ' ' . urldecode($_GET['url'])); } // If we logged in specifically for this 'external_auth' request // and didn't want to "keep access to services", we kill the session // just before returning. // See classes/xorgsession.php:startSessionAs if (S::b('external_auth_exit')) { S::logger()->log('deconnexion', @$_SERVER['HTTP_REFERER']); Platal::session()->killAccessCookie(); Platal::session()->destroy(); } // Compute return URL $full_return = wats4u_sso_build_return_url(S::user()); if ($full_return === "") { // Something went wrong $page->kill("Erreur dans le traitement de la requête Wats4U."); } http_redirect($full_return); }
function handler_validate($page, $gid = null, $vid = null) { $page->assign('msg', ''); $gf = new GroupFilter(new PFC_Or(new GFC_Id($gid), new GFC_Name($gid))); $group = $gf->get(true); if (!$group) { throw new Exception("This Group (' . {$gid} . ') doesn't exist"); } $group->select(GroupSelect::base()); if (!S::user()->hasRights($group, Rights::admin())) { throw new Exception("You don't have the credential to validate request in this group"); } $filter = new ValidateFilter(new VFC_Group($group)); $collec = $filter->get()->select(ValidateSelect::validate()); if (Env::has('val_id')) { $el = $collec->get(Env::v('val_id')); if (!$el) { $page->assign('msg', 'La validation a déjà été effectuée.'); } else { if (Env::has('accept') || Env::has('delete')) { S::logger()->log('admin/validate', array('type' => $el->type(), 'writer' => $el->writer()->id(), 'group' => $el->group()->id(), 'created' => $el->created()->toDb(), 'valid' => Env::has('accept'), 'item' => $el->itemToDb())); } if ($el->handle_form() && (Env::has('accept') || Env::has('delete'))) { $collec->remove(Env::v('val_id')); } } } $page->assign('validation', is_null($vid) ? 0 : $vid); $page->assign('isEdition', false); $page->assign('gid', $gid); $page->assign('group', $group); $page->assign('val', $collec); $page->addCssLink('validate.css'); $page->addCssLink('surveys.css'); $page->assign('title', "Validations des requêtes"); $page->changeTpl('validate/validate.tpl'); }
/** This handler will remove the given issue. */ function handler_admin_nl_delete($page, $nid, $force = null) { $nl = $this->getNl(); if (!$nl) { return PL_NOT_FOUND; } if (!$nl->mayEdit() || !S::has_xsrf_token()) { return PL_FORBIDDEN; } if (!$nid) { $page->kill("La lettre n'a pas été spécifiée."); } $issue = $nl->getIssue($nid); if (!$issue) { $page->kill("La lettre {$nid} n'existe pas"); } if (!$issue->isEditable()) { $page->trigErrorRedirect("La lette a été envoyée ou est en cours d'envoi, elle ne peut être supprimée.", $nl->adminPrefix()); } if (!$issue->delete()) { $page->trigErrorRedirect("Une erreur est survenue lors de la suppression de la lettre.", $nl->adminPrefix()); } // Logs NL deletion. S::logger()->log('nl_issue_delete', $nid); $page->trigSuccessRedirect("La lettre a bien été supprimée.", $nl->adminPrefix()); }
public function killAccessCookie($log = true) { Cookie::kill('access'); if ($log) { S::logger()->log('cookie_off'); } }
function handler_exit($page, $level = null) { if (S::suid()) { $old = S::user()->login(); S::logger()->log('suid_stop', $old . " by " . S::suid('hruid')); Platal::session()->stopSUID(); $target = S::s('suid_startpage'); S::kill('suid_startpage'); if (!empty($target)) { http_redirect($target); } pl_redirect('admin/user/' . $old); } if ($level == 'forget' || $level == 'forgetall') { Platal::session()->killAccessCookie(); } if ($level == 'forgetuid' || $level == 'forgetall') { Platal::session()->killLoginFormCookies(); } if (S::logged()) { S::logger()->log('deconnexion', @$_SERVER['HTTP_REFERER']); Platal::session()->destroy(); } if (Get::has('redirect')) { http_redirect(rawurldecode(Get::v('redirect'))); } else { $page->changeTpl('platal/exit.tpl'); } }
public function add_email($email) { $email_stripped = strtolower(trim($email)); if (!isvalid_email($email_stripped)) { return ERROR_INVALID_EMAIL; } if (!isvalid_email_redirection($email_stripped, $this->user)) { return ERROR_LOOP_EMAIL; } // We first need to retrieve the value for the antispam filter: it is // either the user's redirections common value, or if they differ, our // default value. $bogo = new Bogo($this->user); $filter = $bogo->single_state ? Bogo::$states[$bogo->state] : Bogo::MAIN_DEFAULT; // If the email was already present for this user, we reset it to the default values, we thus use REPLACE INTO. XDB::execute('REPLACE INTO email_redirect_account (uid, redirect, flags, action) VALUES ({?}, {?}, \'active\', {?})', $this->user->id(), $email, $filter); // Replace this email by forlife email, if present in aliases and MLs. $listClient = new MMList(S::user()); $listClient->change_user_email($email, $this->user->forlifeEmail()); update_alias_user($email, $this->user->forlifeEmail()); if ($logger = S::v('log', null)) { // may be absent --> step4.php S::logger()->log('email_add', $email . ($this->user->id() != S::v('uid') ? " (admin on {$this->user->login()})" : "")); } foreach ($this->emails as $mail) { if ($mail->email == $email_stripped) { return SUCCESS; } } $this->emails[] = new Email($this->user, array('redirect' => $email, 'rewrite' => '', 'type' => 'smtp', 'action' => $filter, 'broken_date' => '0000-00-00', 'broken_level' => 0, 'last' => '0000-00-00', 'flags' => 'active', 'hash' => null, 'allow_rewrite' => 0)); // security stuff check_email($email, "Ajout d'une adresse surveillée aux redirections de " . $this->user->login()); check_redirect($this); $this->update_imap(); return SUCCESS; }
function handler_end($page, $hash = null) { global $globals; $_SESSION['subState'] = array('step' => 5); // Reject registration requests from unsafe IP addresses (and remove the // registration information from the database, to prevent IP changes). if (check_ip('unsafe')) { send_warning_mail('Une IP surveillée a tenté de finaliser son inscription.'); XDB::execute("DELETE FROM register_pending\n WHERE hash = {?} AND hash != 'INSCRIT'", $hash); return PL_FORBIDDEN; } // Retrieve the pre-registration information using the url-provided // authentication token. $res = XDB::query("SELECT r.uid, p.pid, r.forlife, r.bestalias, r.mailorg2,\n r.password, r.email, r.services, r.naissance,\n ppn.lastname_initial, ppn.firstname_initial, pe.promo_year,\n pd.promo, p.sex, p.birthdate_ref, a.type, a.email AS old_account_email\n FROM register_pending AS r\n INNER JOIN accounts AS a ON (r.uid = a.uid)\n INNER JOIN account_profiles AS ap ON (a.uid = ap.uid AND FIND_IN_SET('owner', ap.perms))\n INNER JOIN profiles AS p ON (p.pid = ap.pid)\n INNER JOIN profile_public_names AS ppn ON (ppn.pid = p.pid)\n INNER JOIN profile_display AS pd ON (p.pid = pd.pid)\n INNER JOIN profile_education AS pe ON (pe.pid = p.pid AND FIND_IN_SET('primary', pe.flags))\n WHERE hash = {?} AND hash != 'INSCRIT' AND a.state = 'pending'", $hash); if (!$hash || $res->numRows() == 0) { $page->kill("<p>Cette adresse n'existe pas, ou plus, sur le serveur.</p>\n <p>Causes probables :</p>\n <ol>\n <li>Vérifie que tu visites l'adresse du dernier\n email reçu s'il y en a eu plusieurs.</li>\n <li>Tu as peut-être mal copié l'adresse reçue par\n email, vérifie-la à la main.</li>\n <li>Tu as peut-être attendu trop longtemps pour\n confirmer. Les pré-inscriptions sont annulées\n tous les 30 jours.</li>\n <li>Tu es en fait déjà inscrit.</li>\n </ol>"); } list($uid, $pid, $forlife, $bestalias, $emailXorg2, $password, $email, $services, $birthdate, $lastname, $firstname, $yearpromo, $promo, $sex, $birthdate_ref, $type, $old_account_email) = $res->fetchOneRow(); $isX = $type == 'x'; $mail_domain = User::$sub_mail_domains[$type] . $globals->mail->domain; // Prepare the template for display. $page->changeTpl('register/end.tpl'); $page->assign('forlife', $forlife); $page->assign('firstname', $firstname); // Check if the user did enter a valid password; if not (or if none is found), // get her an information page. if (Post::has('response')) { $expected_response = sha1("{$forlife}:{$password}:" . S::v('challenge')); if (Post::v('response') != $expected_response) { $page->trigError("Mot de passe invalide."); S::logger($uid)->log('auth_fail', 'bad password (register/end)'); return; } } else { return; } // // Create the user account. // XDB::startTransaction(); XDB::execute("UPDATE accounts\n SET password = {?}, state = 'active',\n registration_date = NOW(), email = NULL\n WHERE uid = {?}", $password, $uid); XDB::execute("UPDATE profiles\n SET birthdate = {?}, last_change = NOW()\n WHERE pid = {?}", $birthdate, $pid); XDB::execute('INSERT INTO email_source_account (email, uid, type, flags, domain) SELECT {?}, {?}, \'forlife\', \'\', id FROM email_virtual_domains WHERE name = {?}', $forlife, $uid, $mail_domain); XDB::execute('INSERT INTO email_source_account (email, uid, type, flags, domain) SELECT {?}, {?}, \'alias\', \'bestalias\', id FROM email_virtual_domains WHERE name = {?}', $bestalias, $uid, $mail_domain); if ($emailXorg2) { XDB::execute('INSERT INTO email_source_account (email, uid, type, flags, domain) SELECT {?}, {?}, \'alias\', \'\', id FROM email_virtual_domains WHERE name = {?}', $emailXorg2, $uid, $mail_domain); } XDB::commit(); // Try to start a session (so the user don't have to log in); we will use // the password available in Post:: to authenticate the user. Platal::session()->start(AUTH_PASSWD); // Add the registration email address as first and only redirection. require_once 'emails.inc.php'; $user = User::getSilentWithUID($uid); $redirect = new Redirect($user); $redirect->add_email($email); fix_bestalias($user); // If the user was registered to some aliases and MLs, we must change // the subscription to her forlife email. if ($old_account_email) { $listClient = new MMList($user); $listClient->change_user_email($old_account_email, $user->forlifeEmail()); update_alias_user($old_account_email, $user->forlifeEmail()); } // Subscribe the user to the services she did request at registration time. require_once 'newsletter.inc.php'; foreach (explode(',', $services) as $service) { switch ($service) { case 'ax_letter': /* This option is deprecated by 'com_letters' */ NewsLetter::forGroup(NewsLetter::GROUP_AX)->subscribe($user); break; case 'com_letters': NewsLetter::forGroup(NewsLetter::GROUP_AX)->subscribe($user); NewsLetter::forGroup(NewsLetter::GROUP_EP)->subscribe($user); NewsLetter::forGroup(NewsLetter::GROUP_FX)->subscribe($user); break; case 'nl': NewsLetter::forGroup(NewsLetter::GROUP_XORG)->subscribe($user); break; case 'imap': Email::activate_storage($user, 'imap', Bogo::IMAP_DEFAULT); break; case 'ml_promo': if ($isX) { $r = XDB::query('SELECT id FROM groups WHERE diminutif = {?}', $yearpromo); if ($r->numRows()) { $asso_id = $r->fetchOneCell(); XDB::execute('INSERT IGNORE INTO group_members (uid, asso_id) VALUES ({?}, {?})', $uid, $asso_id); try { MailingList::subscribePromo($yearpromo, $user); } catch (Exception $e) { PlErrorReport::report($e); $page->trigError("L'inscription à la liste promo" . $yearpromo . " a échouée."); } } } break; } } // Log the registration in the user session. S::logger($uid)->log('inscription', $email); XDB::execute("UPDATE register_pending\n SET hash = 'INSCRIT'\n WHERE uid = {?}", $uid); // Congratulate our newly registered user by email. $mymail = new PlMailer('register/success.mail.tpl'); $mymail->addTo("\"{$user->fullName()}\" <{$user->forlifeEmail()}>"); if ($isX) { $mymail->setSubject('Bienvenue parmi les X sur le web !'); } else { $mymail->setSubject('Bienvenue sur Polytechnique.org !'); } $mymail->assign('forlife', $forlife); $mymail->assign('firstname', $firstname); $mymail->send(); // Index the user, to allow her to appear in searches. Profile::rebuildSearchTokens($pid); // Notify other users which were watching for her arrival. XDB::execute('INSERT INTO contacts (uid, contact) SELECT uid, {?} FROM watch_nonins WHERE ni_id = {?}', $pid, $uid); XDB::execute('DELETE FROM watch_nonins WHERE ni_id = {?}', $uid); Platal::session()->updateNbNotifs(); // Forcibly register the new user on default forums. $registeredForums = array('xorg.general', 'xorg.pa.divers', 'xorg.pa.logements'); if ($isX) { $promoForum = 'xorg.promo.' . strtolower($promo); $exists = XDB::fetchOneCell('SELECT COUNT(*) FROM forums WHERE name = {?}', $promoForum); if ($exists == 0) { // Notify the newsgroup admin of the promotion forum needs be created. $promoFull = new UserFilter(new UFC_Promo('=', UserFilter::DISPLAY, $promo)); $promoRegistered = new UserFilter(new PFC_And(new UFC_Promo('=', UserFilter::DISPLAY, $promo), new UFC_Registered(true), new PFC_Not(new UFC_Dead()))); if ($promoRegistered->getTotalCount() > 0.2 * $promoFull->getTotalCount()) { $mymail = new PlMailer('admin/forums-promo.mail.tpl'); $mymail->assign('promo', $promo); $mymail->send(); } } else { $registeredForums[] = $promoForum; } } foreach ($registeredForums as $forum) { XDB::execute("INSERT INTO forum_subs (fid, uid)\n SELECT fid, {?}\n FROM forums\n WHERE name = {?}", $uid, $val); } // Update the global registration count stats. $globals->updateNbIns(); // // Update collateral data sources, and inform watchers by email. // // Email the referrer(s) of this new user. $res = XDB::iterRow("SELECT sender, GROUP_CONCAT(email SEPARATOR ', ') AS mails, MAX(last) AS lastDate\n FROM register_marketing\n WHERE uid = {?}\n GROUP BY sender\n ORDER BY lastDate DESC", $uid); XDB::execute("UPDATE register_mstats\n SET success = NOW()\n WHERE uid = {?}", $uid); $market = array(); while (list($senderid, $maketingEmails, $lastDate) = $res->next()) { $sender = User::getWithUID($senderid); $market[] = " - par {$sender->fullName()} sur {$maketingEmails} (le plus récemment le {$lastDate})"; $mymail = new PlMailer('register/marketer.mail.tpl'); $mymail->setSubject("{$firstname} {$lastname} s'est inscrit à Polytechnique.org !"); $mymail->setTo($sender); $mymail->assign('sender', $sender); $mymail->assign('firstname', $firstname); $mymail->assign('lastname', $lastname); $mymail->assign('promo', $promo); $mymail->assign('sex', $sex); $mymail->setTxtBody(wordwrap($msg, 72)); $mymail->send(); } // Email the plat/al administrators about the registration. if ($globals->register->notif) { $mymail = new PlMailer('register/registration.mail.tpl'); $mymail->setSubject("Inscription de {$firstname} {$lastname} ({$promo})"); $mymail->assign('firstname', $firstname); $mymail->assign('lastname', $lastname); $mymail->assign('promo', $promo); $mymail->assign('sex', $sex); $mymail->assign('birthdate', $birthdate); $mymail->assign('birthdate_ref', $birthdate_ref); $mymail->assign('forlife', $forlife); $mymail->assign('email', $email); $mymail->assign('logger', S::logger()); if (count($market) > 0) { $mymail->assign('market', implode("\n", $market)); } $mymail->setTxtBody($msg); $mymail->send(); } // Remove old pending marketing requests for the new user. Marketing::clear($uid); pl_redirect('profile/edit'); }
public function saveData() { require_once 'notifs.inc.php'; $changedFields = array(); foreach ($this->settings as $field => &$setting) { if ($this->changed[$field]) { if (!is_null($setting)) { $changedFields[$field] = array(preg_replace('/(\\r\\n|\\n|\\r)/', ' - ', $setting->getText($this->orig[$field])), preg_replace('/(\\r\\n|\\n|\\r)/', ' - ', $setting->getText($this->values[$field]))); } else { $changedFields[$field] = array(preg_replace('/(\\r\\n|\\n|\\r)/', ' - ', $this->orig[$field]), preg_replace('/(\\r\\n|\\n|\\r)/', ' - ', $this->values[$field])); } if (!is_null($setting)) { $setting->save($this, $field, $this->values[$field]); } if (isset($this->watched[$field]) && $this->watched[$field]) { WatchProfileUpdate::register($this->profile, $field); } } } $this->_saveData(); // Update the last modification date XDB::execute('UPDATE profiles SET last_change = NOW() WHERE pid = {?}', $this->pid()); global $platal; S::logger()->log('profil', $platal->pl_self(2)); /** Stores all profile modifications for active users in order to: * -daily notify the user in case of third party edition, * -display the modification to the secretaries for verification in * case of an edition made by the user. */ $owner = $this->profile->owner(); $user = S::user(); if ($owner->isActive()) { foreach ($changedFields as $field => $values) { if (array_key_exists($field, Profile::$descriptions)) { XDB::execute('INSERT INTO profile_modifications (pid, uid, field, oldText, newText, type, timestamp) VALUES ({?}, {?}, {?}, {?}, {?}, {?}, NOW()) ON DUPLICATE KEY UPDATE uid = VALUES(uid), oldText = IF(VALUES(type) != type, VALUES(oldText), oldText), newText = VALUES(newText), type = VALUES(type), timestamp = NOW()', $this->pid(), $user->id(), Profile::$descriptions[$field], $values[0], $values[1], $owner->id() == $user->id() ? 'self' : 'third_party'); } } } return true; }
function handler_group_insert($page) { $group = new Group(); $group->insert(); $group->caste(Rights::admin())->addUser(S::user()); S::logger()->log("groups/insert", array('gid' => $group->id())); pl_redirect('groups/admin/' . $group->id()); }
/** Start a session as user $user */ protected function startSessionAs($user, $level) { /* Session data and required data mismatch */ if (!is_null(S::v('user')) && S::v('user')->id() != $user->id() || S::has('uid') && S::i('uid') != $user->id()) { return false; } else { if (S::has('uid')) { return true; } } /* If we want to do a SUID */ if ($level == AUTH_SUID) { S::set('auth', AUTH_MDP); } S::set('user', $user); S::set('uid', $user->id()); if (!isSmartphone()) { S::set('skin', $user->skin()); } if (!S::suid()) { if (Post::v('remember', 'false') == 'on') { $this->setAccessCookie(false); } S::logger()->saveLastSession(); } else { S::logger()->log("suid_start", S::v('hruid') . ' by ' . S::suid('hruid')); } // Set session perms from User perms S::set('perms', $user->perms()); /* Clean temp var 'cookie_uid' */ S::kill('cookie_uid'); return true; }
function handler_referent($page, $pf) { $page->changeTpl('profile/fiche_referent.tpl', SIMPLE); $pf = Profile::get($pf); if (!$pf) { return PL_NOT_FOUND; } // Referent view are logged. if (S::logged()) { S::logger()->log('view_referent', $pf->hrid()); } $page->assign_by_ref('profile', $pf); // Retrieves referents' countries. $res = XDB::query("SELECT gc.country\n FROM profile_mentor_country AS m\n LEFT JOIN geoloc_countries AS gc ON (m.country = gc.iso_3166_1_a2)\n WHERE pid = {?}", $pf->id()); $page->assign('pays', $res->fetchColumn()); }
function handler_referent($page, $action = null, $subaction = null) { global $globals; $wp = new PlWikiPage('Docs.Emploi'); $wp->buildCache(); $page->setTitle('Emploi et Carrières'); $page->addJsLink('jquery.ui.xorg.js'); // Count mentors $res = XDB::query("SELECT count(distinct pid) FROM profile_mentor_term"); $page->assign('mentors_number', $res->fetchOneCell()); // Search for mentors matching filters require_once 'ufbuilder.inc.php'; $ufb = new UFB_MentorSearch(); if (!$ufb->isEmpty()) { // Search query is logged if (S::logged() && !Env::has('page')) { S::logger()->log('search_referent', 'adv=' . var_export($_GET, true)); } require_once 'userset.inc.php'; $ufc = $ufb->getUFC(); $set = new ProfileSet($ufc); $set->addMod('mentor', 'Référents'); $set->apply('referent/search', $page, $action, $subaction); $nb_tot = $set->count(); if ($nb_tot > $globals->search->private_max) { $this->form_prepare(); $page->trigError('Recherche trop générale.'); $page->assign('plset_count', 0); } else { if ($nb_tot == 0) { $this->form_prepare(); $page->trigError('Il n\'existe personne correspondant à ces critères dans la base.'); } } } $page->changeTpl('search/referent.tpl'); }