<?php
/***************************************************************************
- * Copyright (C) 2003-2011 Polytechnique.org *
+ * Copyright (C) 2003-2014 Polytechnique.org *
* http://opensource.polytechnique.org/ *
* *
* This program is free software; you can redistribute it and/or modify *
define('ERROR_INVALID_EMAIL', 3);
define('ERROR_LOOP_EMAIL', 4);
+// Checks if an email update is required in MLs and aliases.
+// This occurs when the user don't have email permissions and her email has changed.
+function require_email_update(User $user, $new_email)
+{
+ Platal::assert(!is_null($user), 'User cannot be null.');
+
+ $is_new = !$user->checkPerms(User::PERM_MAIL) && $new_email != strtolower($user->email);
+ if ($new_email && $is_new) {
+ $already = XDB::fetchOneCell('SELECT hruid
+ FROM accounts
+ WHERE email = {?} AND uid != {?}',
+ $new_email, $user->id());
+ if ($already) {
+ Platal::page()->trigError("L'email ne peut pas être utilisé pour ce compte car il correspond déjà au compte : "
+ . $already . ". Si l'utilisateur courant et cette personne ne sont en fait qu'une "
+ . "seul et même personne, ou en cas de problème, contacter : contact@polytechnique.org");
+ return false;
+ }
+ }
+ return $is_new;
+}
+
function format_email_alias($email)
{
if ($user = User::getSilent($email)) {
return true;
}
+// Updates an email in all aliases (groups and events).
+function update_alias_user($former_email, $new_email)
+{
+ XDB::execute('UPDATE email_virtual
+ SET redirect = {?}
+ WHERE redirect = {?} AND (type = \'alias\' OR type = \'event\')',
+ $new_email, $former_email);
+}
+
function list_alias_members($local_part, $domain)
{
$emails = XDB::fetchColumn('SELECT DISTINCT(redirect)
$redirect = $domain . '_' . $local_part . '+';
foreach(array('post', 'owner', 'admin', 'bounces', 'unsubscribe') as $suffix) {
- XDB::execute('DELETE email_virtual
- WHERE redirect = {?} AND type = \'list\'',
+ XDB::execute('DELETE FROM email_virtual
+ WHERE redirect = {?} AND type = \'list\'',
$redirect . $suffix . '@' . $globals->lists->redirect_domain);
}
}
return;
}
- $user = XDB::fetchOneAssoc('SELECT r1.uid, r1.broken_level != 0 AS broken, COUNT(r2.uid) AS nb_mails,
+ $user = XDB::fetchOneAssoc('SELECT r1.uid, a.hruid, a.full_name, r1.broken_level != 0 AS broken, COUNT(r2.uid) AS nb_mails,
s.email AS alias, DATE_ADD(r1.last, INTERVAL 14 DAY) < CURDATE() as notify
FROM email_redirect_account AS r1
INNER JOIN accounts AS a ON (a.uid = r1.uid)
// function isvalid_email_redirection() {{{1
/** Checks if an email is a suitable redirection.
* @param $email the email to check
+ * @param $user the user asking for the redirection
* @return BOOL
*/
-function isvalid_email_redirection($email)
+function isvalid_email_redirection($email, User $user)
{
- return isvalid_email($email) && !preg_match("/@polytechnique\.edu$/", $email) && User::isForeignEmailAddress($email);
+ $valid = isvalid_email($email) && User::isForeignEmailAddress($email);
+ if (!$user->hasProfile() || ($user->profile()->grad_year > date('Y') - 3)) {
+ return $valid && !preg_match("/@polytechnique\.edu$/", $email);
+ } else {
+ return $valid;
+ }
}
// function ids_from_mails() {{{1
// The Bogo class represents a spam filtering level in plat/al architecture.
class Bogo
{
+ const MAIN_DEFAULT = 'default';
+ const IMAP_DEFAULT = 'let_spams';
+
public static $states = array(
0 => 'default',
1 => 'let_spams',
// Basic email properties; $sufficient indicates if the email can be used as
// an unique redirection; $redirect contains the delivery email address.
+ public $id;
public $type;
public $sufficient;
public $email;
}
$this->sufficient = ($this->type == 'smtp' || $this->type == 'googleapps');
$this->filter_level = ($this->type == 'imap') ? null : array_search($this->action, Bogo::$states);
+ if (array_key_exists($this->type , self::$storage_domains)) {
+ $this->id = $this->type;
+ } else {
+ $this->id = str_replace(array('@', '.'), array('_at_', '_dot_'), $this->email);
+ }
$this->user = &$user;
}
// Activates the email address as a redirection.
public function activate()
{
- if ($this->inactive) {
- XDB::execute('UPDATE email_redirect_account
- SET broken_level = IF(flags = \'broken\', broken_level - 1, broken_level), flags = \'active\'
- WHERE uid = {?} AND redirect = {?}',
- $this->user->id(), $this->email);
+ if (!$this->active) {
+ if (in_array($this->type, self::get_allowed_storages($this->user))) {
+ self::activate_storage($this->user, $this->type, $this->action);
+ } else {
+ XDB::execute('UPDATE email_redirect_account
+ SET broken_level = IF(flags = \'broken\', broken_level - 1, broken_level), flags = \'active\'
+ WHERE uid = {?} AND redirect = {?}',
+ $this->user->id(), $this->email);
+ }
S::logger()->log('email_on', $this->email . ($this->user->id() != S::v('uid') ? "(admin on {$this->user->login()})" : ''));
+ $this->disabled = false;
+ $this->broken = false;
$this->inactive = false;
$this->active = true;
}
public function deactivate()
{
if ($this->active) {
- XDB::execute('UPDATE email_redirect_account
- SET flags = \'inactive\'
- WHERE uid = {?} AND redirect = {?}',
- $this->user->id(), $this->email);
+ if (in_array($this->type, self::get_allowed_storages($this->user))) {
+ self::deactivate_storage($this->user, $this->type);
+ } else {
+ XDB::execute('UPDATE email_redirect_account
+ SET flags = \'inactive\'
+ WHERE uid = {?} AND redirect = {?}',
+ $this->user->id(), $this->email);
+ }
S::logger()->log('email_off', $this->email . ($this->user->id() != S::v('uid') ? "(admin on {$this->user->login()})" : "") );
$this->inactive = true;
$this->active = false;
}
// Returns the list of allowed storages for the @p user.
- static private function get_allowed_storages(User $user)
+ static public function get_allowed_storages(User $user)
{
global $globals;
$storages = array();
return $storages;
}
- static public function activate_storage(User $user, $storage)
+ static public function make_storage_redirection(User $user, $storage)
+ {
+ return $user->hruid . '@' . self::$storage_domains[$storage] . '.' . Platal::globals()->mail->domain;
+ }
+
+ static public function activate_storage(User $user, $storage, $action = null)
{
Platal::assert(in_array($storage, self::get_allowed_storages($user)), 'Unknown storage.');
- if (!self::is_active_storage($user, $storage)) {
- global $globals;
+ // We first need to retrieve the value for the antispam filter if not
+ // provided: it is either the user's redirections common value, or if
+ // they differ, our default value.
+ if (is_null($action)) {
+ $bogo = new Bogo($user);
+ $action = ($bogo->single_state ? Bogo::$states[$bogo->state] : Bogo::MAIN_DEFAULT);
+ }
- XDB::execute('INSERT INTO email_redirect_account (uid, type, redirect, flags)
- VALUES ({?}, {?}, {?}, \'active\')',
- $user->id(), $storage,
- $user->hruid . '@' . self::$storage_domains[$storage] . '.' . $globals->mail->domain);
+ if (!self::is_active_storage($user, $storage)) {
+ XDB::execute('INSERT INTO email_redirect_account (uid, type, action, redirect, flags)
+ VALUES ({?}, {?}, {?}, {?}, \'active\')',
+ $user->id(), $storage, $action, self::make_storage_redirection($user, $storage));
}
}
static public function deactivate_storage(User $user, $storage)
{
- if (in_array($storage, self::$storage_domains)) {
+ if (in_array($storage, self::get_allowed_storages($user))) {
XDB::execute('DELETE FROM email_redirect_account
WHERE uid = {?} AND type = {?}',
$user->id(), $storage);
static public function is_active_storage(User $user, $storage)
{
- if (!in_array($storage, self::$storage_domains)) {
+ if (!in_array($storage, self::get_allowed_storages($user))) {
return false;
}
$res = XDB::fetchOneCell('SELECT COUNT(*)
while ($row = $res->next()) {
$this->emails[] = new Email($user, $row);
}
+
+ if ($storages = Email::get_allowed_storages($user)) {
+ // 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($user);
+ $filter = ($bogo->single_state ? Bogo::$states[$bogo->state] : Bogo::MAIN_DEFAULT);
+
+ foreach ($storages as $storage) {
+ if (!Email::is_active_storage($user, $storage)) {
+ $this->emails[] = new Email($user, array(
+ 'redirect' => Email::make_storage_redirection($user, $storage),
+ 'rewrite' => '',
+ 'type' => $storage,
+ 'action' => $filter,
+ 'broken_date' => 0,
+ 'broken_level' => '0000-00-00',
+ 'last' => '0000-00-00',
+ 'flags' => 'inactive',
+ 'hash' => '',
+ 'allow_rewrite' => 0));
+ }
+ }
+ }
}
public function other_active($email)
if (!isvalid_email($email_stripped)) {
return ERROR_INVALID_EMAIL;
}
- if (!isvalid_email_redirection($email_stripped)) {
+ 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::$states[0]);
+ $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()})" : ""));
}
}
}
-// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker fenc=utf-8:
?>