Commit 0fc10c8d authored by sikeda's avatar sikeda
Browse files

[dev] Separating Sympa::User class to handle global users from List package.

- List::XXX_global_user() have been obsoleted.  Functions of Sympa::User may be used, and new methods would be better to be used:
  delete_global_user()  -> $user->expire()
  get_global_user()     -> Sympa::User->new()
  get_all_global_user() -> Sympa::User::get_users()
  update_global_user()  -> $user->save()
  add_global_user()     -> $user->save()
  And $user->moveto()


git-svn-id: https://subversion.renater.fr/sympa/branches/sympa-6.2-branch@10269 05aa8bb8-cd2b-0410-b1d7-8918dfa770ce
parent d2d3a749
......@@ -459,7 +459,7 @@ sub info {
my $user;
# Part of the authorization code
$user = &List::get_global_user($sender);
$user = Sympa::User::get_global_user($sender);
my $result = $list->check_list_authz('info','md5',
{'sender' => $sender,
......@@ -586,8 +586,8 @@ sub createList {
# prepare parameters
my $param = {};
$param->{'user'}{'email'} = $sender;
if (&List::is_global_user($param->{'user'}{'email'})) {
$param->{'user'} = &List::get_global_user($sender);
if (Sympa::User::is_global_user($param->{'user'}{'email'})) {
$param->{'user'} = Sympa::User::get_global_user($sender);
}
my $parameters;
$parameters->{'creation_email'} =$sender;
......@@ -765,13 +765,13 @@ sub add {
}else {
my $u;
my $defaults = $list->get_default_user_options();
my $u2 = &List::get_global_user($email);
my $u2 = Sympa::User->new($email);
%{$u} = %{$defaults};
$u->{'email'} = $email;
$u->{'gecos'} = $gecos || $u2->{'gecos'};
$u->{'date'} = $u->{'update_date'} = time;
$u->{'password'} = $u2->{'password'} || &tools::tmp_passwd($email) ;
$u->{'lang'} = $u2->{'lang'} || $list->{'admin'}{'lang'};
$u->{'email'} = $email;
$u->{'gecos'} = $gecos || $u2->gecos;
$u->{'date'} = $u->{'update_date'} = time;
$u->{'password'} = $u2->password || tools::tmp_passwd($email) ;
$u->{'lang'} = $u2->lang || $list->{'admin'}{'lang'};
$list->add_list_member($u);
if (defined $list->{'add_outcome'}{'errors'}) {
......@@ -950,7 +950,7 @@ sub review {
my $user;
# Part of the authorization code
$user = &List::get_global_user($sender);
$user = Sympa::User::get_global_user($sender);
my $result = $list->check_list_authz('review','md5',
{'sender' => $sender,
......@@ -1161,7 +1161,7 @@ sub signoff {
$list = new List ($listname, $robot);
# Part of the authorization code
my $user = &List::get_global_user($sender);
my $user = Sympa::User::get_global_user($sender);
my $result = $list->check_list_authz('unsubscribe','md5',
{'email' => $sender,
......@@ -1350,10 +1350,11 @@ sub subscribe {
}
if ($List::use_db) {
my $u = &List::get_global_user($sender);
&List::update_global_user($sender, {'lang' => $u->{'lang'} || $list->{'admin'}{'lang'}
});
my $u = Sympa::User->new($sender);
unless ($u->lang) {
$u->lang($list->{'admin'}{'lang'});
$u->save();
}
}
## Now send the welcome file to the user
......
......@@ -191,11 +191,12 @@ sub help {
my @owner = &List::get_which ($sender, $robot,'owner');
my @editor = &List::get_which ($sender, $robot, 'editor');
$data->{'is_owner'} = 1 if ($#owner > -1);
$data->{'is_editor'} = 1 if ($#editor > -1);
$data->{'user'} = &List::get_global_user($sender);
&Language::SetLang($data->{'user'}{'lang'}) if $data->{'user'}{'lang'};
$data->{'subject'} = gettext("User guide");
$data->{'is_owner'} = 1 if @owner;
$data->{'is_editor'} = 1 if @editor;
$data->{'user'} = Sympa::User->new($sender);
&Language::SetLang($data->{'user'}->lang)
if $data->{'user'}->lang;
$data->{'subject'} = gettext("User guide");
$data->{'auto_submitted'} = 'auto-replied';
unless(&List::send_global_file("helpfile", $sender, $robot, $data)){
......@@ -844,11 +845,10 @@ sub subscribe {
}
if ($List::use_db) {
my $u = &List::get_global_user($sender);
&List::update_global_user($sender, {'lang' => $u->{'lang'} || $list->{'admin'}{'lang'},
'password' => $u->{'password'} || &tools::tmp_passwd($sender)
});
my $u = Sympa::User->new($sender);
$u->lang($list->{'admin'}{'lang'}) unless $u->lang;
$u->password(tools::tmp_passwd($sender)) unless $u->password;
$u->save;
}
## Now send the welcome file to the user
......@@ -1294,11 +1294,10 @@ sub add {
}
if ($List::use_db) {
my $u = &List::get_global_user($email);
&List::update_global_user($email, {'lang' => $u->{'lang'} || $list->{'admin'}{'lang'},
'password' => $u->{'password'} || &tools::tmp_passwd($email)
});
my $u = Sympa::User->new($email);
$u->lang($list->{'admin'}{'lang'}) unless $u->lang;
$u->password(tools::tmp_passwd($email)) unless $u->password;
$u->save;
}
## Now send the welcome file to the user if it exists and notification is supposed to be sent.
......@@ -1683,7 +1682,7 @@ sub remind {
&Log::do_log('debug2','Sending REMIND * to %d users', $count);
foreach my $email (keys %global_subscription) {
my $user = &List::get_global_user($email);
my $user = Sympa::User::get_global_user($email);
foreach my $key (keys %{$user}) {
$global_info{$email}{$key} = $user->{$key}
if ($user->{$key});
......
......@@ -33,6 +33,7 @@ use POSIX qw(strftime);
use Datasource;
use LDAPSource;
use SDM;
use Sympa::User;
use SQLSource qw(create_db);
use Upgrade;
use Sympa::LockedFile;
......@@ -3942,7 +3943,7 @@ sub send_global_file {
my $data = &tools::dup_var($context);
unless ($data->{'user'}) {
$data->{'user'} = &get_global_user($who) unless ($options->{'skip_db'});
$data->{'user'} = Sympa::User::get_global_user($who) unless ($options->{'skip_db'});
$data->{'user'}{'email'} = $who unless (defined $data->{'user'});;
}
unless ($data->{'user'}{'lang'}) {
......@@ -4044,7 +4045,7 @@ sub send_file {
## Unless multiple recipients
unless (ref ($who)) {
unless ($data->{'user'}) {
unless ($data->{'user'} = &get_global_user($who)) {
unless ($data->{'user'} = Sympa::User::get_global_user($who)) {
$data->{'user'}{'email'} = $who;
$data->{'user'}{'lang'} = $self->{'admin'}{'lang'};
}
......@@ -5778,26 +5779,9 @@ sub _append_footer_header_to_part {
return $new_body;
}
## Delete a new user to Database (in User table)
sub delete_global_user {
my @users = @_;
&Log::do_log('debug2', '');
return undef unless ($#users >= 0);
foreach my $who (@users) {
$who = &tools::clean_email($who);
## Update field
unless (&SDM::do_query("DELETE FROM user_table WHERE (email_user =%s)", &SDM::quote($who))) {
&Log::do_log('err','Unable to delete user %s', $who);
next;
}
}
return $#users + 1;
}
## Delete a user in the user_table
##sub delete_global_user
## DEPRECATED: Use User::delete_global_user() or $user->expire();
## Delete the indicate list member
## IN : - ref to array
......@@ -5948,78 +5932,12 @@ sub get_total {
}
## Returns a hash for a given user
sub get_global_user {
my $who = &tools::clean_email(shift);
&Log::do_log('debug2', '(%s)', $who);
## Additional subscriber fields
my $additional;
if ($Conf::Conf{'db_additional_user_fields'}) {
$additional = ',' . $Conf::Conf{'db_additional_user_fields'};
}
push @sth_stack, $sth;
$sth = &SDM::do_query("SELECT email_user AS email, gecos_user AS gecos, password_user AS password, cookie_delay_user AS cookie_delay, lang_user AS lang %s, attributes_user AS attributes, data_user AS data, last_login_date_user AS last_login_date, wrong_login_count_user AS wrong_login_count, last_login_host_user AS last_login_host FROM user_table WHERE email_user = %s ", $additional, &SDM::quote($who));
unless (defined $sth) {
&Log::do_log('err','Failed to prepare SQL query');
return undef;
}
my $user = $sth->fetchrow_hashref('NAME_lc');
$sth->finish();
$sth = pop @sth_stack;
if (defined $user) {
## decrypt password
if ($user->{'password'}) {
$user->{'password'} = &tools::decrypt_password($user->{'password'});
}
## Turn user_attributes into a hash
my $attributes = $user->{'attributes'};
$user->{'attributes'} = undef;
foreach my $attr (split (/__ATT_SEP__/, $attributes)) {
my ($key, $value) = split (/__PAIRS_SEP__/, $attr);
$user->{'attributes'}{$key} = $value;
}
## Turn data_user into a hash
if ($user->{'data'}) {
my %prefs = &tools::string_2_hash($user->{'data'});
$user->{'prefs'} = \%prefs;
}
}
return $user;
}
##sub get_global_user {
## DEPRECATED: Use Sympa::User::get_global_user() or Sympa::User->new().
## Returns an array of all users in User table hash for a given user
sub get_all_global_user {
&Log::do_log('debug2', '');
my @users;
my $sth;
push @sth_stack, $sth;
unless ($sth = &SDM::do_query("SELECT email_user FROM user_table")) {
&Log::do_log('err','Unable to gather all users in DB');
return undef;
}
while (my $email = ($sth->fetchrow_array)[0]) {
push @users, $email;
}
$sth->finish();
$sth = pop @sth_stack;
return @users;
}
##sub get_all_global_user {
## DEPRECATED: Use Sympa::User::get_all_global_user() or Sympa::User::get_users().
######################################################################
### suspend_subscription #
......@@ -7030,27 +6948,8 @@ sub get_total_bouncing {
}
## Is the person in user table (db only)
sub is_global_user {
my $who = &tools::clean_email(pop);
&Log::do_log('debug3', '(%s)', $who);
return undef unless ($who);
push @sth_stack, $sth;
## Query the Database
unless($sth = &SDM::do_query("SELECT count(*) FROM user_table WHERE email_user = %s", &SDM::quote($who))) {
&Log::do_log('err','Unable to check whether user %s is in the user table.');
return undef;
}
my $is_user = $sth->fetchrow();
$sth->finish();
$sth = pop @sth_stack;
return $is_user;
}
##sub is_global_user {
## DEPRECATED: Use Sympa::User::is_global_user().
## Is the indicated person a subscriber to the list?
sub is_list_member {
......@@ -7372,120 +7271,12 @@ sub update_list_admin {
## Sets new values for the given user in the Database
sub update_global_user {
my($who, $values) = @_;
&Log::do_log('debug', '(%s)', $who);
$who = &tools::clean_email($who);
## use md5 fingerprint to store password
$values->{'password'} = &Auth::password_fingerprint($values->{'password'}) if ($values->{'password'});
my ($field, $value);
my ($user, $statement, $table);
## mapping between var and field names
my %map_field = ( gecos => 'gecos_user',
password => 'password_user',
cookie_delay => 'cookie_delay_user',
lang => 'lang_user',
attributes => 'attributes_user',
email => 'email_user',
data => 'data_user',
last_login_date => 'last_login_date_user',
last_login_host => 'last_login_host_user',
wrong_login_count => 'wrong_login_count_user'
);
## Update each table
my @set_list;
while (($field, $value) = each %{$values}) {
unless ($map_field{$field}) {
&Log::do_log('error',"unkown field $field in map_field internal error");
next;
};
my $set;
if ($numeric_field{$map_field{$field}}) {
$value ||= 0; ## Can't have a null value
$set = sprintf '%s=%s', $map_field{$field}, $value;
}else {
$set = sprintf '%s=%s', $map_field{$field}, &SDM::quote($value);
}
push @set_list, $set;
}
return undef unless @set_list;
## Update field
unless ($sth = &SDM::do_query("UPDATE user_table SET %s WHERE (email_user=%s)"
, join(',', @set_list), &SDM::quote($who))) {
&Log::do_log('err','Could not update informations for user %s in user_table',$who);
return undef;
}
return 1;
}
##sub update_global_user {
## DEPRECATED: Use Sympa::User::update_global_user() or $user->save().
## Adds a user to the user_table
sub add_global_user {
my($values) = @_;
&Log::do_log('debug2', '');
my ($field, $value);
my ($user, $statement, $table);
## encrypt password
$values->{'password'} = &Auth::password_fingerprint($values->{'password'}) if ($values->{'password'});
return undef unless (my $who = &tools::clean_email($values->{'email'}));
return undef if (is_global_user($who));
## mapping between var and field names
my %map_field = ( email => 'email_user',
gecos => 'gecos_user',
custom_attribute => 'custom_attribute',
password => 'password_user',
cookie_delay => 'cookie_delay_user',
lang => 'lang_user',
attributes => 'attributes_user'
);
## Update each table
my (@insert_field, @insert_value);
while (($field, $value) = each %{$values}) {
next unless ($map_field{$field});
my $insert;
if ($numeric_field{$map_field{$field}}) {
$value ||= 0; ## Can't have a null value
$insert = $value;
}else {
$insert = sprintf "%s", &SDM::quote($value);
}
push @insert_value, $insert;
push @insert_field, $map_field{$field}
}
unless (@insert_field) {
&Log::do_log('err','The fields (%s) do not correspond to anything in the database',join (',',keys(%{$values})));
return undef;
}
## Update field
unless($sth = &SDM::do_query("INSERT INTO user_table (%s) VALUES (%s)"
, join(',', @insert_field), join(',', @insert_value))) {
&Log::do_log('err','Unable to add user %s to the DB table user_table', $values->{'email'});
return undef;
}
return 1;
}
##sub add_global_user {
## DEPRECATED: Use Sympa::User::add_global_user() or $user->save().
## Adds a list member ; no overwrite.
sub add_list_member {
......@@ -7545,15 +7336,22 @@ sub add_list_member {
unless ($new_user->{'included'}) {
## Is the email in user table?
if (! is_global_user($who)) {
## Insert in User Table
unless(&SDM::do_query("INSERT INTO user_table (email_user, gecos_user, lang_user, password_user) VALUES (%s,%s,%s,%s)",&SDM::quote($who), &SDM::quote($new_user->{'gecos'}), &SDM::quote($new_user->{'lang'}), &SDM::quote($new_user->{'password'}))){
&Log::do_log('err','Unable to add user %s to user_table.', $who);
$self->{'add_outcome'}{'errors'}{'unable_to_add_to_database'} = 1;
next;
}
}
}
unless (
Sympa::User->new(
$who,
'gecos' => $new_user->{'gecos'},
'lang' => $new_user->{'lang'},
'password' => $new_user->{'password'}
)
) {
Log::do_log('err', 'Unable to add user %s to user_table.',
$who);
$self->{'add_outcome'}{'errors'}{'unable_to_add_to_database'}
= 1;
next;
}
}
$new_user->{'subscribed'} ||= 0;
$new_user->{'included'} ||= 0;
......@@ -7632,12 +7430,18 @@ sub add_list_admin {
unless ($new_admin_user->{'included'}) {
## Is the email in user table?
if (! is_global_user($who)) {
## Insert in User Table
unless(&SDM::do_query("INSERT INTO user_table (email_user, gecos_user, lang_user, password_user) VALUES (%s,%s,%s,%s)",&SDM::quote($who), &SDM::quote($new_admin_user->{'gecos'}), &SDM::quote($new_admin_user->{'lang'}), &SDM::quote($new_admin_user->{'password'}))){
&Log::do_log('err','Unable to add admin %s to user_table', $who);
next;
}
## Insert in User Table
unless (
Sympa::User->new(
$who,
'gecos' => $new_admin_user->{'gecos'},
'lang' => $new_admin_user->{'lang'},
'password' => $new_admin_user->{'password'}
)
) {
Log::do_log('err', 'Unable to add admin %s to user_table',
$who);
next;
}
}
......@@ -12580,9 +12384,9 @@ sub get_subscription_requests {
$subscriptions{$email} = {'gecos' => $gecos,
'custom_attribute' => $xml};
unless($subscriptions{$email}{'gecos'}) {
my $user = get_global_user($email);
if ($user->{'gecos'}) {
$subscriptions{$email}{'gecos'} = $user->{'gecos'};
my $user = Sympa::User->new($email);
if ($user->gecos) {
$subscriptions{$email}{'gecos'} = $user->gecos;
}
}
......
......@@ -664,12 +664,12 @@ sub verify {
## Sender's user/subscriber attributes (if subscriber)
}elsif ($value =~ /\[user\-\>([\w\-]+)\]/i) {
$context->{'user'} ||= &List::get_global_user($context->{'sender'});
$context->{'user'} ||= Sympa::User::get_global_user($context->{'sender'});
$value =~ s/\[user\-\>([\w\-]+)\]/$context->{'user'}{$1}/;
}elsif ($value =~ /\[user_attributes\-\>([\w\-]+)\]/i) {
$context->{'user'} ||= &List::get_global_user($context->{'sender'});
$context->{'user'} ||= Sympa::User::get_global_user($context->{'sender'});
$value =~ s/\[user_attributes\-\>([\w\-]+)\]/$context->{'user'}{'attributes'}{$1}/;
}elsif (($value =~ /\[subscriber\-\>([\w\-]+)\]/i) && defined ($context->{'sender'} ne 'nobody')) {
......
# Sympa - SYsteme de Multi-Postage Automatique
#
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
# Copyright (c) 2011, 2012, 2013, 2014 GIP RENATER
#
# 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, see <http://www.gnu.org/licenses/>.
package Sympa::User;
use strict;
use warnings;
use Carp qw(carp croak);
#use Site; # this module is used in Site
## Database and SQL statement handlers
my ($sth, @sth_stack);
## mapping between var and field names
my %db_struct = Sympa::DatabaseDescription::full_db_struct();
my %map_field;
foreach my $k (keys %{$db_struct{'user_table'}->{'fields'}}) {
if ($k =~ /^(.+)_user$/) {
$map_field{$1} = $k;
}
}
## DB fields with numeric type
## We should not do quote() for these while inserting data
my %numeric_field;
foreach my $k (keys %{$db_struct{'user_table'}->{'fields'}}) {
if ($db_struct{'user_table'}->{'fields'}{$k}{'struct'} =~ /^int/) {
$numeric_field{$k} = 1;
}
}
=encoding utf-8
=head1 NAME
Sympa::User - All Users Identified by Sympa
=head1 DESCRIPTION
=head2 CONSTRUCTOR
=over 4
=item new ( EMAIL, [ KEY => VAL, ... ] )
Create new Sympa::User object.
=back
=cut
sub new {
my $pkg = shift;
my $who = tools::clean_email(shift || '');
my %values = @_;
my $self;
return undef unless $who;
# ## Canonicalize lang if possible
# $values{'lang'} =
# Language::CanonicLang($values{'lang'}) || $values{'lang'}
# if $values{'lang'};
if (!($self = get_global_user($who))) {
## unauthenticated user would not be added to database.
$values{'email'} = $who;
if (scalar grep { $_ ne 'lang' and $_ ne 'email' } keys %values) {
unless (defined add_global_user(\%values)) {
return undef;
}
}
$self = \%values;
}
bless $self => $pkg;
}
=head2 METHODS
=over 4
=item expire
Remove user information from user_table.
=back
=cut