Revision 305
- Date:
- 2013/04/22 16:42:50
- Files:
-
- /utf8/plugins/users/config.proto (Diff) (Checkout)
- /utf8/plugins/users/lib/users/Email.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/Init.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/Keeper.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/OA
- /utf8/plugins/users/lib/users/OA/Credential.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/OA/FaceBook.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/OA/Google.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/OA/Mailru.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/OA/VK.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/Phone.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/SQL/CredentialsTable.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/SQL/UserProfile.pm (Diff) (Checkout)
- /utf8/plugins/users/lib/users/State.pm.proto (Diff) (Checkout)
- /utf8/plugins/users/lib/users/UserProfile.pm (Diff) (Checkout)
Legend:
- Added
- Removed
- Modified
-
utf8/plugins/users/config.proto
18 18 PROFILE_AUTH_METHOD = RPC 19 19 REWRITE += PROFILE_AUTH_METHOD 20 20 21 21 PROFILE_USE_CREDENTIALS = <YES/NO> 22 REWRITE += PROFILE_USE_CREDENTIALS 22 23 ######################################################################## 23 24 # 24 25 # PROFILE_DOCUMENT_CLASS -
utf8/plugins/users/lib/users/Email.pm
1 package users::Email; 2 3 use base "Contenido::Document"; 4 use Contenido::Globals; 5 6 use overload ( 7 '""' => '_stringify', 8 ); 9 10 sub extra_properties 11 { 12 return ( 13 { 'attr' => 'name', 'type' => 'string', 'rusname' => 'E-mail' }, 14 { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус e-mail-адреса', 15 'cases' => [ 16 [0, 'Не активен'], 17 [1, 'Подтвержден'], 18 [2, 'Основной'], 19 [3, 'Потерян / заблокирован'], 20 ], 21 }, 22 { 'attr' => 'name_orig', 'type' => 'string', 'rusname' => 'E-mail без приведения к нижнему регистру' }, 23 # { 'attr' => 'login', 'type' => 'string', 'rusname' => 'Login' }, 24 # { 'attr' => 'passwd', 'type' => 'string', 'rusname' => 'Password' }, 25 ) 26 } 27 28 sub _stringify { 29 my $self = shift; 30 31 return $self->name; 32 } 33 34 35 sub class_name 36 { 37 return 'E-mail адрес'; 38 } 39 40 sub class_description 41 { 42 return 'E-mail адрес'; 43 } 44 45 sub search_fields 46 { 47 return ('name'); 48 } 49 50 sub class_table 51 { 52 return 'users::SQL::CredentialsTable'; 53 } 54 55 sub contenido_status_style 56 { 57 my $self = shift; 58 if ( $self->status == 2 ) { 59 return 'color:green;'; 60 } elsif ( $self->status == 3 ) { 61 return 'color:red;'; 62 } 63 } 64 65 sub pre_store 66 { 67 my $self = shift; 68 69 my $default_section = $project->s_alias->{user_emails} if ref $project->s_alias eq 'HASH' && exists $project->s_alias->{user_emails}; 70 if ( $default_section && !$self->{sections} ) { 71 $self->{sections} = $default_section; 72 } 73 74 return 1; 75 } 76 1; -
utf8/plugins/users/lib/users/Init.pm
13 13 # users::SomeClass 14 14 Contenido::Init::load_classes(qw( 15 15 users::SQL::UserProfile 16 users::SQL::CredentialsTable 16 17 17 18 users::UserProfile 19 users::Email 20 users::Phone 18 21 users::Section 22 23 users::OA::VK 24 users::OA::FaceBook 25 users::OA::Google 26 users::OA::Mailru 19 27 )); 20 28 21 29 sub init { 22 30 push @{ $state->{'available_documents'} }, 'users::UserProfile' if $state->{users}->profile_document_class eq 'users::UserProfile'; 23 31 push @{ $state->{'available_sections'} }, 'users::Section'; 32 if ( $state->{users}->use_credentials ) { 33 push @{ $state->{'available_documents'} }, 34 qw( users::Email users::Phone users::OA::VK users::OA::FaceBook users::OA::Google users::OA::Mailru ); 35 } 24 36 0; 25 37 } 26 38 -
utf8/plugins/users/lib/users/Keeper.pm
39 39 # 40 40 # login => login пользователя 41 41 # email => e-mail пользователя 42 # phone => телефон пользователя 42 43 # passwd => пароль пользователя 43 44 # ---------------------------------------------------------------------------- 44 45 sub login { 45 46 46 my $self = shift; 47 my %opts = @_; 47 my $self = shift; 48 my (%opts) = @_; 48 49 49 return if !($opts{login} || $opts{email}) && !$opts{passwd}; 50 my $passmd5 = Digest::MD5::md5_hex($opts{passwd}); 51 my $class = $self->state->profile_document_class; 52 my $res = $keeper->get_documents ( 53 class => $class, 54 $opts{login} ? (login => $opts{login}) : (), 55 $opts{email} ? (email => lc($opts{email})) : (), 56 status => [1,2,3,4,5], 57 return_mode => 'array_ref', 58 ); 59 $res = ref $res eq 'ARRAY' ? $res->[0] : undef; 60 return unless ref $res; 61 # warn "Password = ".$opts{passwd}."; Pass MD5 = $passmd5; user MD5 = ".$res->passwd."\n" if $DEBUG; 62 if ($res->passwd eq $passmd5 ) { 63 my $lastlogin = Contenido::DateTime->new ( postgres => $res->lastlogin ); 64 my $now = Contenido::DateTime->new; 65 my $then = $now->clone; 66 $then->subtract( hours => 2 ); 67 if ( DateTime->compare($then, $lastlogin) == 1 ) { 68 $res->lastlogin( $now->ymd('-').' '.$now->hms ); 69 $res->passwd(undef); 70 $res->store; 71 $res->lastlogin( $lastlogin->ymd('-').' '.$lastlogin->hms ); 50 return if !($opts{login} || $opts{email} || $opts{phone}) && !$opts{passwd}; 51 52 my $password = delete $opts{passwd}; 53 my $passmd5 = Digest::MD5::md5_hex( $password ); 54 my $class = $self->state->profile_document_class; 55 my $profile = $self->get_profile( %opts, status => [qw(1 2 3 4 5)] ); 56 return unless ref $profile; 57 58 my $result; 59 # warn "Password = ".$opts{passwd}."; Pass MD5 = $passmd5; user MD5 = ".$res->passwd."\n" if $DEBUG; 60 if ($profile->passwd eq $passmd5 ) { 61 my ($prop) = grep { $_->{attr} eq 'lastlogin' } $profile->structure; 62 if ( ref $prop ) { 63 my $now = Contenido::DateTime->new; 64 $profile->lastlogin( $now->ymd('-').' '.$now->hms ); 65 $profile->store; 72 66 } 73 return $res; 74 }else{ 75 return; 76 } 77 67 return $profile; 68 } else { 69 return undef; 70 } 78 71 } 79 72 80 73 … … 125 118 # email => по e-mail 126 119 # nickname=> по никнейму 127 120 # status => фильтр по статусу 121 # При включенных credentials: 122 # phone => по телефону 123 # vkontakte => по логину ВК 124 # facebook => по логину Facebook 125 # google => по логину Google 126 # mailru => по логину Mail.ru 128 127 # ---------------------------------------------------------------------------- 129 128 sub get_profile { 130 129 131 my $self = shift; 132 my %opts = @_; 130 my $self = shift; 131 my (%opts) = @_; 133 132 134 return if !$opts{login} && !$opts{id} && !$opts{email} && !$opts{nickname}; 135 my $class = $self->state->profile_document_class; 136 my $res = $keeper->get_documents ( 133 my $profile; 134 if ( $self->state->use_credentials && !$opts{login} && !$opts{id} ) { 135 $profile = $self->get_profile_by_credential ( %opts ); 136 } else { 137 return if !$opts{login} && !$opts{id} && !$opts{email} && !$opts{nickname}; 138 my $class = $self->state->profile_document_class; 139 ($profile) = $keeper->get_documents ( 140 class => $class, 141 %opts, 142 limit => 1, 143 ); 144 } 145 return $profile; 146 } 147 148 149 sub get_profile_by_credential { 150 151 my $self = shift; 152 my (%opts) = @_; 153 154 my $credential; 155 if ( $opts{email} && $self->_email_format($opts{email}) ) { 156 ($credential) = $keeper->get_documents ( 157 class => 'users::Email', 158 name => $self->_email_reduction( delete $opts{email} ), 159 limit => 1, 160 ); 161 } elsif ( $opts{phone} && $self->_phone_reduction($opts{phone}) ) { 162 ($credential) = $keeper->get_documents ( 163 class => 'users::Phone', 164 name => $self->_phone_reduction( delete $opts{phone} ), 165 limit => 1, 166 ); 167 } elsif ( $opts{vkontake} ) { 168 ($credential) = $keeper->get_documents ( 169 class => 'users::OA::VK', 170 ext_id => delete $opts{vkontakte}, 171 limit => 1, 172 ); 173 } elsif ( $opts{facebook} ) { 174 ($credential) = $keeper->get_documents ( 175 class => 'users::OA::FaceBook', 176 ext_id => delete $opts{facebook}, 177 limit => 1, 178 ); 179 } elsif ( $opts{mailru} ) { 180 ($credential) = $keeper->get_documents ( 181 class => 'users::OA::Mailru', 182 ext_id => delete $opts{mailru}, 183 limit => 1, 184 ); 185 } elsif ( $opts{google} ) { 186 ($credential) = $keeper->get_documents ( 187 class => 'users::OA::Google', 188 ext_id => delete $opts{google}, 189 limit => 1, 190 ); 191 } 192 return unless ref $credential; 193 194 my $class = $self->state->profile_document_class; 195 my $profile = $keeper->get_document_by_id ( $credential->uid, 137 196 class => $class, 138 197 %opts, 139 return_mode => 'array_ref', 140 198 ); 141 $res = ref $res eq 'ARRAY' && scalar @$res ? $res->[0] : undef; 142 return $res; 199 return $profile; 143 200 } 144 201 202 203 ###### Additional subs 204 ################################################### 205 sub _email_format { 206 my $self = shift; 207 my $email = shift; 208 for ( $email ) { 209 s/^\s+//; 210 s/\s+$//; 211 } 212 if ( $email =~ /^[\-\.\w\d]+\@[a-z\d\-\.]+\.[a-z\d]+$/i ) { 213 return $email; 214 } 215 return undef; 216 } 217 218 sub _email_reduction { 219 my $self = shift; 220 my $email = shift; 221 for ( $email ) { 222 s/^\s+//; 223 s/\s+$//; 224 } 225 if ( $email =~ /^[\-\.\w\d]+\@[a-z\d\-\.]+\.[a-z\d]+$/i ) { 226 return lc( $email ); 227 } 228 return undef; 229 } 230 231 sub _phone_format { 232 my $self = shift; 233 my $phone = shift; 234 if ( $phone ) { 235 for ( $phone ) { 236 s/-//g; 237 s/\[/\(/g; 238 s/\]/\)/g; 239 s/^\s+//; 240 s/\s+$//; 241 } 242 if ( $phone =~ /^\+?(\d)+[\(\ ]+(\d+)[\)\ ]+([\d+\ ])$/ ) { 243 my $cc = $1; 244 my $code = $2; 245 my $number = $3; $number =~ s/\D//g; 246 $phone = $cc.'('.$code.')'.$phone; 247 } elsif ( $phone =~ /^[\(]+(\d+)[\)\ ]+([\d+\ ])$/ ) { 248 my $cc = '7'; 249 my $code = $1; 250 my $number = $2; $number =~ s/\D//g; 251 $phone = $cc.'('.$code.')'.$phone; 252 } else { 253 $phone =~ s/\D//g; 254 } 255 return $phone; 256 } 257 } 258 259 sub _phone_reduction { 260 my $self = shift; 261 my $phone = shift; 262 if ( $phone ) { 263 $phone =~ s/\D//g; 264 return $phone || undef; 265 } 266 } 267 145 268 1; -
utf8/plugins/users/lib/users/OA/Credential.pm
1 package users::OA::Credential; 2 3 use base "Contenido::Document"; 4 use Contenido::Globals; 5 6 sub extra_properties 7 { 8 return ( 9 { 'attr' => 'name', 'type' => 'string', 'rusname' => 'Имя в системе' }, 10 { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус', 11 'cases' => [ 12 [0, 'Не активен'], 13 [1, 'Подтвержден'], 14 [3, 'Потерян / заблокирован'], 15 ], 16 }, 17 { 'attr' => 'ava_url', 'type' => 'url', 'rusname' => 'Аватар (url)' }, 18 { 'attr' => 'avatar', 'type' => 'image', 'rusname' => 'Аватар' }, 19 # { 'attr' => 'login', 'type' => 'string', 'rusname' => 'Login' }, 20 # { 'attr' => 'passwd', 'type' => 'string', 'rusname' => 'Password' }, 21 ) 22 } 23 24 sub class_name 25 { 26 return 'OpenAuth Proto'; 27 } 28 29 sub class_description 30 { 31 return 'OpenAuth Proto class'; 32 } 33 34 sub search_fields 35 { 36 return ('ext_id', 'name', 'uid'); 37 } 38 39 sub class_table 40 { 41 return 'users::SQL::CredentialsTable'; 42 } 43 44 sub contenido_status_style 45 { 46 my $self = shift; 47 if ( $self->status == 3 ) { 48 return 'color:red;'; 49 } 50 } 51 52 sub pre_store 53 { 54 my $self = shift; 55 56 my $default_section = $project->s_alias->{user_externals} if ref $project->s_alias eq 'HASH' && exists $project->s_alias->{user_externals}; 57 if ( $default_section && !$self->{sections} ) { 58 $self->{sections} = $default_section; 59 } 60 61 return 1; 62 } 63 1; -
utf8/plugins/users/lib/users/OA/FaceBook.pm
1 package users::OA::FaceBook; 2 3 use base "users::OA::Credential"; 4 use Contenido::Globals; 5 6 sub extra_properties 7 { 8 return ( 9 { 'attr' => 'name', 'type' => 'string', 'rusname' => 'Имя в системе' }, 10 { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус', 11 'cases' => [ 12 [0, 'Не активен'], 13 [1, 'Подтвержден'], 14 [3, 'Потерян / заблокирован'], 15 ], 16 }, 17 ) 18 } 19 20 sub class_name 21 { 22 return 'OpenAuth FaceBook'; 23 } 24 25 sub class_description 26 { 27 return 'OpenAuth FaceBook'; 28 } 29 30 1; -
utf8/plugins/users/lib/users/OA/Google.pm
1 package users::OA::Google; 2 3 use base "users::OA::Credential"; 4 use Contenido::Globals; 5 6 sub extra_properties 7 { 8 return ( 9 { 'attr' => 'name', 'type' => 'string', 'rusname' => 'Имя в системе' }, 10 { 'attr' => 'email', 'type' => 'string', 'rusname' => 'E-mail' }, 11 { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус', 12 'cases' => [ 13 [0, 'Не активен'], 14 [1, 'Подтвержден'], 15 [3, 'Потерян / заблокирован'], 16 ], 17 }, 18 ) 19 } 20 21 sub class_name 22 { 23 return 'OpenAuth Google'; 24 } 25 26 sub class_description 27 { 28 return 'OpenAuth Google'; 29 } 30 31 1; -
utf8/plugins/users/lib/users/OA/Mailru.pm
1 package users::OA::Mailru; 2 3 use base "users::OA::Credential"; 4 use Contenido::Globals; 5 6 sub extra_properties 7 { 8 return ( 9 { 'attr' => 'name', 'type' => 'string', 'rusname' => 'Имя в системе' }, 10 { 'attr' => 'email', 'type' => 'string', 'rusname' => 'E-mail' }, 11 { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус', 12 'cases' => [ 13 [0, 'Не активен'], 14 [1, 'Подтвержден'], 15 [3, 'Потерян / заблокирован'], 16 ], 17 }, 18 ) 19 } 20 21 sub class_name 22 { 23 return 'OpenAuth Mail.ru'; 24 } 25 26 sub class_description 27 { 28 return 'OpenAuth Mail.ru'; 29 } 30 31 1; -
utf8/plugins/users/lib/users/OA/VK.pm
1 package users::OA::VK; 2 3 use base "users::OA::Credential"; 4 use Contenido::Globals; 5 6 sub extra_properties 7 { 8 return ( 9 { 'attr' => 'name', 'type' => 'string', 'rusname' => 'Имя в системе' }, 10 { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус', 11 'cases' => [ 12 [0, 'Не активен'], 13 [1, 'Подтвержден'], 14 [3, 'Потерян / заблокирован'], 15 ], 16 }, 17 ) 18 } 19 20 sub class_name 21 { 22 return 'OpenAuth ВКонтакте'; 23 } 24 25 sub class_description 26 { 27 return 'OpenAuth ВКонтакте'; 28 } 29 30 1; -
utf8/plugins/users/lib/users/Phone.pm
1 package users::Phone; 2 3 use base "Contenido::Document"; 4 use Contenido::Globals; 5 6 sub extra_properties 7 { 8 return ( 9 { 'attr' => 'name', 'type' => 'string', 'rusname' => 'Телефон (только номер)' }, 10 { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус e-mail-адреса', 11 'cases' => [ 12 [0, 'Не активен'], 13 [1, 'Подтвержден'], 14 [2, 'Основной'], 15 [3, 'Потерян / заблокирован'], 16 ], 17 }, 18 { 'attr' => 'name_format', 'type' => 'string', 'rusname' => 'Телефон отформатированный' }, 19 { 'attr' => 'name_orig', 'type' => 'string', 'rusname' => 'Телефон (ввод пользователя)' }, 20 # { 'attr' => 'login', 'type' => 'string', 'rusname' => 'Login' }, 21 # { 'attr' => 'passwd', 'type' => 'string', 'rusname' => 'Password' }, 22 ) 23 } 24 25 sub class_name 26 { 27 return 'Телефон'; 28 } 29 30 sub class_description 31 { 32 return 'Телефон'; 33 } 34 35 sub search_fields 36 { 37 return ('name'); 38 } 39 40 sub class_table 41 { 42 return 'users::SQL::CredentialsTable'; 43 } 44 45 sub contenido_status_style 46 { 47 my $self = shift; 48 if ( $self->status == 2 ) { 49 return 'color:green;'; 50 } elsif ( $self->status == 3 ) { 51 return 'color:red;'; 52 } 53 } 54 55 sub pre_store 56 { 57 my $self = shift; 58 59 my $default_section = $project->s_alias->{user_phones} if ref $project->s_alias eq 'HASH' && exists $project->s_alias->{user_phones}; 60 if ( $default_section && !$self->{sections} ) { 61 $self->{sections} = $default_section; 62 } 63 64 return 1; 65 } 66 1; -
utf8/plugins/users/lib/users/SQL/CredentialsTable.pm
1 package users::SQL::CredentialsTable; 2 3 use strict; 4 use base 'SQL::DocumentTable'; 5 6 sub db_table 7 { 8 return 'profile_credentials'; 9 } 10 11 sub available_filters { 12 my @available_filters = qw( 13 _class_filter 14 _status_filter 15 _in_id_filter 16 _id_filter 17 _name_filter 18 _class_excludes_filter 19 _sfilter_filter 20 _datetime_filter 21 _date_equal_filter 22 _date_filter 23 _previous_days_filter 24 _s_filter 25 26 _excludes_filter 27 _link_filter 28 _uid_filter 29 _ext_id_filter 30 _main_filter 31 ); 32 return \@available_filters; 33 } 34 35 # ---------------------------------------------------------------------------- 36 # Свойства храним в массивах, потому что порядок важен! 37 # Это общие свойства - одинаковые для всех документов. 38 # 39 # attr - обязательный параметр, название атрибута; 40 # type - тип аттрибута, требуется для отображдения; 41 # rusname - русское название, опять же требуется для отображения; 42 # hidden - равен 1, когда 43 # readonly - инициализации при записи только без изменения в дальнейшем 44 # db_field - поле в таблице 45 # default - значение по умолчанию (поле всегда имеет это значение) 46 # ---------------------------------------------------------------------------- 47 sub required_properties 48 { 49 my $self = shift; 50 51 my @parent_properties = grep { $_->{attr} ne 'sections' && $_->{attr} ne 'dtime' } $self->SUPER::required_properties; 52 return ( 53 @parent_properties, 54 { 55 'attr' => 'uid', 56 'type' => 'pickup', 57 'rusname' => 'Идентификатор пользователя', 58 'lookup_opts' => { 59 'class' => 'mynotes::UserProfile', 60 'search_by' => 'name', 61 }, 62 'db_field' => 'uid', 63 'db_type' => 'integer', 64 'db_opts' => "not null default 0", 65 }, 66 { 67 'attr' => 'ext_id', 68 'type' => 'integer', 69 'rusname' => 'External ID', 70 'db_field' => 'ext_id', 71 'db_type' => 'integer', 72 'db_opts' => "not null default 0", 73 'default' => 0, 74 }, 75 { 76 'attr' => 'opaque', 77 'type' => 'status', 78 'rusname' => 'Видимость', 79 'cases' => [ 80 [0, 'не видно никому'], 81 [1, 'видно близким людям'], 82 [2, 'видно всем друзьям'], 83 [3, 'видно всем пользователям'], 84 [10, 'видно всем'], 85 ], 86 'db_field' => 'opaque', 87 'db_type' => 'integer', 88 }, 89 { 90 'attr' => 'confirm', 91 'type' => 'string', 92 'rusname' => 'Confirmation string', 93 'db_field' => 'confirm', 94 'db_type' => 'varchar(32)', 95 }, 96 { 97 'attr' => 'main', 98 'type' => 'checkbox', 99 'rusname' => 'Main credential', 100 'db_field' => 'main', 101 'db_type' => 'integer', 102 }, 103 { 104 'attr' => 'sections', 105 'type' => 'sections_list', 106 'rusname' => 'Секция', 107 'hidden' => 1, 108 'db_field' => 'sections', 109 'db_type' => 'integer', 110 }, 111 112 ); 113 } 114 115 116 sub _s_filter { 117 my ($self,%opts)=@_; 118 return undef unless ( exists $opts{s} ); 119 return &SQL::Common::_generic_int_filter('d.sections', $opts{s}); 120 } 121 122 sub _uid_filter { 123 my ($self,%opts)=@_; 124 return undef unless ( exists $opts{uid} ); 125 return &SQL::Common::_generic_int_filter('d.uid', $opts{uid}); 126 } 127 128 sub _main_filter { 129 my ($self,%opts)=@_; 130 return undef unless ( exists $opts{main} ); 131 return &SQL::Common::_generic_int_filter('d.main', $opts{main}); 132 } 133 134 sub _ext_id_filter { 135 my ($self,%opts)=@_; 136 return undef unless ( exists $opts{ext_id} ); 137 return &SQL::Common::_generic_int_filter('d.ext_id', $opts{ext_id}); 138 } 139 140 sub _name_filter { 141 my ($self,%opts)=@_; 142 return undef unless ( exists $opts{name} ); 143 if ( exists $opts{ext_id} ) { 144 return &SQL::Common::_generic_text_filter('d.name', $opts{name}); 145 } else { 146 my ($w1, $v1) = &SQL::Common::_generic_text_filter('d.name', $opts{name}); 147 my ($w2, $v2) = &SQL::Common::_generic_int_filter('d.ext_id', 0); 148 return " ($w1) AND ($w2) ", [@$v1, @$v2]; 149 } 150 } 151 152 1; -
utf8/plugins/users/lib/users/SQL/UserProfile.pm
1 1 package users::SQL::UserProfile; 2 2 3 3 use base 'SQL::DocumentTable'; 4 use Contenido::Globals; 4 5 5 6 sub db_table 6 7 { … … 152 153 'attr' => 'email', 153 154 'type' => 'string', 154 155 'rusname' => 'E-mail (primary)', 156 'hidden' => $state->{users}->use_credentials ? 1 : undef, 157 'readonly' => $state->{users}->use_credentials ? 1 : undef, 155 158 'db_field' => 'email', 156 159 'db_type' => 'text', 157 160 }, -
utf8/plugins/users/lib/users/State.pm.proto
20 20 $self->{db_password} = ''; 21 21 $self->{db_port} = ''; 22 22 $self->{profile_document_class} = '@PROFILE_DOCUMENT_CLASS@' || 'users::UserProfile'; 23 $self->{use_credentials} = uc('@PROFILE_USE_CREDENTIALS@') eq 'YES' ? 1 : 0; 23 24 24 25 $self->{data_directory} = ''; 25 26 $self->{images_directory} = ''; … … 51 52 $self->{attributes}->{$_} = 'SCALAR' for qw( 52 53 db_type 53 54 profile_document_class 55 use_credentials 54 56 db_keepalive 55 57 db_host 56 58 db_port -
utf8/plugins/users/lib/users/UserProfile.pm
4 4 use Digest::MD5; 5 5 use Contenido::Globals; 6 6 7 my %CREDENTIAL_FIELDS = ( 8 'users::Email' => 'email', 9 'users::Phone' => 'phone', 10 'users::OA::VK' => 'vkontakte', 11 'users::OA::FaceBook' => 'facebook', 12 'users::OA::Google' => 'google', 13 'users::OA::Mailru' => 'mailru', 14 ); 15 7 16 sub extra_properties 8 17 { 9 18 return ( … … 11 20 'cases' => [ 12 21 [0, 'Блокированный'], 13 22 [1, 'Активный'], 14 [2, 'Платный'], 15 [3, 'Свой/сотрудник'], 16 [4, 'VIP'], 17 23 [5, 'Временная активация'], 18 24 ], 19 25 }, … … 48 54 ) 49 55 } 50 56 57 58 sub post_init { 59 my $self = shift; 60 my $opts = shift; 61 62 $self->{passwd_prev} = $self->passwd; 63 64 return if exists $opts->{ids} || exists $opts{names} || exists $opts{light}; 65 if ( $self->id && $state->{users}->use_credentials ) { 66 my $creds = $keeper->get_documents( 67 uid => $self->id, 68 table => 'users::SQL::CredentialsTable', 69 return_mode => 'array_ref', 70 ); 71 if ( @$creds ) { 72 my %creds; 73 foreach my $cred ( @$creds ) { 74 $cred->{keeper} = undef; 75 my $main_field = $CREDENTIAL_FIELDS{$cred->class} if exists $CREDENTIAL_FIELDS{$cred->class}; 76 if ( $main_field ) { 77 my $multi_field = $main_field.'s'; 78 $self->{$multi_field} = [] unless exists $self->{$multi_field}; 79 push @{$self->{$multi_field}}, $cred; 80 $self->{$main_field} = $cred if $cred->main; 81 } 82 } 83 } 84 } 85 return; 86 } 87 88 51 89 sub name_full 52 90 { 53 91 my $self = shift; … … 112 150 } 113 151 } 114 152 153 154 sub confirm_credential { 155 my ($self, %opts) = @_; 156 my $object; 157 if ( exists $opts{confirm} && $opts{name} && $opts{class} ) { 158 ($object) = $self->keeper->get_documents( 159 class => $opts{class}, 160 uid => $self->id, 161 name => lc($opts{name}), 162 limit => 1, 163 ); 164 if ( ref $object && $object->confirm eq $opts{confirm} ) { 165 $object->status(1); 166 $object->store; 167 } 168 } elsif ( $opts{name} && $opts{class} ) { 169 ($object) = $self->keeper->get_documents( 170 class => $opts{class}, 171 uid => $self->id, 172 name => lc($opts{name}), 173 limit => 1, 174 ); 175 if ( ref $object ) { 176 $object->status(1); 177 $object->store; 178 } 179 } 180 return $object; 181 } 182 183 184 sub create_credential { 185 my ($self, %opts) = @_; 186 my $object; 187 if ( $opts{vkontakte} ) { 188 ($object) = $self->keeper->get_documents( 189 class => users::OA::VK, 190 uid => $self->id, 191 ext_id => $opts{vkontakte}, 192 limit => 1, 193 ); 194 unless ( ref $object ) { 195 $object = users::OA::VK->new ($keeper); 196 $object->name( $opts{name} ); 197 $object->status( 1 ); 198 $object->opaque( $opts{opaque} || 0 ); 199 $object->uid( $self->id ); 200 $object->ava_url( $opts{avatar} ); 201 $object->store; 202 } 203 } elsif ( $opts{facebook} ) { 204 ($object) = $self->keeper->get_documents( 205 class => users::OA::FaceBook, 206 uid => $self->id, 207 ext_id => $opts{facebook}, 208 limit => 1, 209 ); 210 unless ( ref $object ) { 211 $object = users::OA::FaceBook->new ($keeper); 212 $object->name( $opts{name} ); 213 $object->status( 1 ); 214 $object->opaque( $opts{opaque} || 0 ); 215 $object->uid( $self->id ); 216 $object->ava_url( $opts{avatar} ); 217 $object->store; 218 } 219 } elsif ( $opts{google} ) { 220 ($object) = $self->keeper->get_documents( 221 class => users::OA::Google, 222 uid => $self->id, 223 ext_id => $opts{google}, 224 limit => 1, 225 ); 226 unless ( ref $object ) { 227 $object = users::OA::Google->new ($keeper); 228 $object->name( $opts{name} ); 229 if ( $opts{email} ) { 230 $object->email( $opts{email} ); 231 $self->create_credential( email => $opts{email}, status => 1 ); 232 } 233 $object->status( 1 ); 234 $object->opaque( $opts{opaque} || 0 ); 235 $object->uid( $self->id ); 236 $object->ava_url( $opts{avatar} ); 237 $object->store; 238 } 239 } elsif ( $opts{mailru} ) { 240 ($object) = $self->keeper->get_documents( 241 class => users::OA::Mailru, 242 uid => $self->id, 243 ext_id => $opts{mailru}, 244 limit => 1, 245 ); 246 unless ( ref $object ) { 247 $object = users::OA::Mailru->new ($keeper); 248 $object->name( $opts{name} ); 249 if ( $opts{email} ) { 250 $object->email( $opts{email} ); 251 $self->create_credential( email => $opts{email}, status => 1 ); 252 } 253 $object->status( 1 ); 254 $object->opaque( $opts{opaque} || 0 ); 255 $object->uid( $self->id ); 256 $object->ava_url( $opts{avatar} ); 257 $object->store; 258 } 259 } elsif ( $opts{email} ) { 260 ($object) = $self->keeper->get_documents( 261 class => users::Email, 262 uid => $self->id, 263 name => lc($opts{email}), 264 limit => 1, 265 ); 266 unless ( ref $object ) { 267 $object = users::Email->new ($keeper); 268 $object->name( lc($opts{email}) ); 269 $object->name_orig( $opts{email} ); 270 $object->main( $opts{main} || 0 ); 271 $object->status( $opts{status} || 0 ); 272 $object->opaque( $opts{opaque} || 0 ); 273 $object->uid( $self->id ); 274 $object->confirm( Digest::MD5::md5_hex(int(rand(1000000)), $self->id, $opts{email}) ); 275 $object->store; 276 } 277 } elsif ( $opts{phone} ) { 278 ($object) = $self->keeper->get_documents( 279 class => users::Phone, 280 uid => $self->id, 281 name => $keeper->{users}->_phone_reduction( $opts{phone} ), 282 limit => 1, 283 ); 284 unless ( ref $object ) { 285 $object = users::Phone->new ($keeper); 286 $object->name( $keeper->{users}->_phone_reduction($opts{phone}) ); 287 $object->name_format( $keeper->{users}->_phone_format($opts{phone}) ); 288 $object->name_orig( $opts{phone} ); 289 $object->main( $opts{main} || 0 ); 290 $object->status( $opts{status} || 0 ); 291 $object->opaque( $opts{opaque} || 0 ); 292 $object->uid( $self->id ); 293 $object->confirm( Digest::MD5::md5_hex(int(rand(1000000)), $self->id, $opts{email}) ); 294 $object->store; 295 } 296 } 297 return $object; 298 } 299 300 115 301 sub pre_store 116 302 { 117 303 my $self = shift; … … 119 305 my $up = $self->{keeper}->get_document_by_id ( $self->id, 120 306 class => $self->class, 121 307 ); 122 if ( (ref $up && $self->passwd && $self->passwd ne $up->passwd) || (!ref $up && $self->passwd) ) { 308 my $passwd_prev = $self->{passwd_prev} || ''; 309 if ( $self->passwd && $self->passwd ne $passwd_prev ) { 123 310 warn "Pass = ".$self->passwd."\n" if $DEBUG; 124 311 my $pass = Digest::MD5::md5_hex($self->passwd); 125 312 warn "Pass_hex = $pass\n" if $DEBUG; 126 313 $self->passwd($pass); 127 } elsif ( ref $up && (!$self->passwd || $self->passwd eq $up->passwd ) ) { 128 $self->passwd($up->passwd); 314 } else { 315 $self->passwd($passwd_prev); 129 316 } 130 $self->email(lc($self->email)); 131 $self->login(lc($self->login)); 317 $self->login( lc($self->login) ); 132 318 319 if ( $state->{users}->use_credentials ) { 320 foreach my $prop ( $self->structure ) { 321 my $name = $prop->{attr}; 322 if ( ref $self->$name =~ /^users::OA::/ ) { 323 my $obj = $self->$name; 324 $self->$name( $obj->ext_id ); 325 } elsif ( ref $self->$name =~ /^users::/ ) { 326 my $obj = $self->$name; 327 $self->$name( $obj->name ); 328 } 329 } 330 } else { 331 $self->email( $keeper->{users}->_email_reduction($self->email) ); 332 } 333 133 334 my $default_section = $project->s_alias->{users} if ref $project->s_alias eq 'HASH' && exists $project->s_alias->{users}; 134 335 if ( $default_section ) { 135 336 my $sections = $self->{sections};