Line # Revision Author
1 196 ahitrov package users::Keeper;
2
3 use strict;
4 use warnings 'all';
5 use base qw(Contenido::Keeper);
6
7 use Digest::MD5;
8 use Contenido::Globals;
9 use Data::Dumper;
10
11 # ----------------------------------------------------------------------------
12 # Функции:
13 # ----------------------------------------------------------------------------
14 # check_login: Наличие пользователя в системе
15 #
16 # login => login пользователя
17 # email => email пользователя
18 # ----------------------------------------------------------------------------
19 sub check_login {
20
21 my $self = shift;
22 my %opts = @_;
23
24 return if !$opts{login} && !$opts{email};
25 my $class = $self->state->profile_document_class;
26 my $res = $keeper->get_documents (
27 class => $class,
28 $opts{login} ? (login => $opts{login}) : (),
29 $opts{email} ? (email => lc($opts{email})) : (),
30 count => 1,
31 );
32 return int($res);
33 }
34
35
36
37 # ----------------------------------------------------------------------------
38 # login: Авторизация пользователя
39 #
40 # login => login пользователя
41 # email => e-mail пользователя
42 305 ahitrov # phone => телефон пользователя
43 196 ahitrov # passwd => пароль пользователя
44 # ----------------------------------------------------------------------------
45 sub login {
46
47 305 ahitrov my $self = shift;
48 my (%opts) = @_;
49 196 ahitrov
50 305 ahitrov 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 315 ahitrov warn "Password = $password; Pass MD5 = $passmd5; user MD5 = ".$profile->passwd."\n" if $DEBUG;
60 305 ahitrov 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 315 ahitrov # $profile->store;
66 196 ahitrov }
67 315 ahitrov warn "\nLogin successful\n" if $DEBUG;
68 305 ahitrov return $profile;
69 } else {
70 315 ahitrov warn "\nLogin [UN]successful\n" if $DEBUG;
71 305 ahitrov return undef;
72 }
73 196 ahitrov }
74
75
76
77 # ----------------------------------------------------------------------------
78 # confirm: Подтверждение аутентификации
79 #
80 # login => login пользователя
81 # email => e-mail пользователя
82 # md5 => MD5 пароля пользователя
83 # ----------------------------------------------------------------------------
84 sub confirm {
85
86 my $self = shift;
87 my %opts = @_;
88
89 return if !($opts{login} || $opts{email}) && !$opts{md5};
90 my $class = $self->state->profile_document_class;
91 my $res = $keeper->get_documents (
92 class => $class,
93 $opts{login} ? (login => $opts{login}) : (),
94 $opts{email} ? (email => lc($opts{email})) : (),
95 return_mode => 'array_ref',
96 );
97 $res = ref $res eq 'ARRAY' && scalar @$res ? $res->[0] : undef;
98 return unless ref $res;
99 warn "MD5 = ".$opts{md5}."; user MD5 = ".$res->passwd."\n" if $DEBUG;
100 if ($res->passwd eq $opts{md5} ) {
101 my $now = localtime;
102 $res->lastlogin( $now );
103 $res->passwd(undef);
104 $res->status(1);
105 $res->store;
106 return $res;
107 }else{
108 return;
109 }
110
111 }
112
113
114
115 # ----------------------------------------------------------------------------
116 # get_profile: Вытащить профиль пользователя
117 #
118 # id => по ID
119 # login => по login
120 # email => по e-mail
121 # nickname=> по никнейму
122 # status => фильтр по статусу
123 305 ahitrov # При включенных credentials:
124 # phone => по телефону
125 # vkontakte => по логину ВК
126 # facebook => по логину Facebook
127 # google => по логину Google
128 # mailru => по логину Mail.ru
129 196 ahitrov # ----------------------------------------------------------------------------
130 sub get_profile {
131
132 305 ahitrov my $self = shift;
133 my (%opts) = @_;
134 196 ahitrov
135 305 ahitrov my $profile;
136 if ( $self->state->use_credentials && !$opts{login} && !$opts{id} ) {
137 $profile = $self->get_profile_by_credential ( %opts );
138 } else {
139 return if !$opts{login} && !$opts{id} && !$opts{email} && !$opts{nickname};
140 my $class = $self->state->profile_document_class;
141 ($profile) = $keeper->get_documents (
142 class => $class,
143 %opts,
144 limit => 1,
145 );
146 }
147 return $profile;
148 }
149
150
151 sub get_profile_by_credential {
152
153 my $self = shift;
154 my (%opts) = @_;
155
156 my $credential;
157 if ( $opts{email} && $self->_email_format($opts{email}) ) {
158 ($credential) = $keeper->get_documents (
159 class => 'users::Email',
160 name => $self->_email_reduction( delete $opts{email} ),
161 limit => 1,
162 );
163 } elsif ( $opts{phone} && $self->_phone_reduction($opts{phone}) ) {
164 ($credential) = $keeper->get_documents (
165 class => 'users::Phone',
166 name => $self->_phone_reduction( delete $opts{phone} ),
167 limit => 1,
168 );
169 } elsif ( $opts{vkontake} ) {
170 ($credential) = $keeper->get_documents (
171 class => 'users::OA::VK',
172 ext_id => delete $opts{vkontakte},
173 limit => 1,
174 );
175 } elsif ( $opts{facebook} ) {
176 ($credential) = $keeper->get_documents (
177 class => 'users::OA::FaceBook',
178 ext_id => delete $opts{facebook},
179 limit => 1,
180 );
181 } elsif ( $opts{mailru} ) {
182 ($credential) = $keeper->get_documents (
183 class => 'users::OA::Mailru',
184 ext_id => delete $opts{mailru},
185 limit => 1,
186 );
187 } elsif ( $opts{google} ) {
188 ($credential) = $keeper->get_documents (
189 class => 'users::OA::Google',
190 ext_id => delete $opts{google},
191 limit => 1,
192 );
193 }
194 return unless ref $credential;
195
196 my $class = $self->state->profile_document_class;
197 my $profile = $keeper->get_document_by_id ( $credential->uid,
198 196 ahitrov class => $class,
199 %opts,
200 );
201 305 ahitrov return $profile;
202 196 ahitrov }
203
204 305 ahitrov
205 ###### Additional subs
206 ###################################################
207 sub _email_format {
208 my $self = shift;
209 my $email = shift;
210 for ( $email ) {
211 s/^\s+//;
212 s/\s+$//;
213 }
214 if ( $email =~ /^[\-\.\w\d]+\@[a-z\d\-\.]+\.[a-z\d]+$/i ) {
215 return $email;
216 }
217 return undef;
218 }
219
220 sub _email_reduction {
221 my $self = shift;
222 my $email = shift;
223 for ( $email ) {
224 s/^\s+//;
225 s/\s+$//;
226 }
227 if ( $email =~ /^[\-\.\w\d]+\@[a-z\d\-\.]+\.[a-z\d]+$/i ) {
228 return lc( $email );
229 }
230 return undef;
231 }
232
233 sub _phone_format {
234 my $self = shift;
235 my $phone = shift;
236 if ( $phone ) {
237 for ( $phone ) {
238 s/-//g;
239 s/\[/\(/g;
240 s/\]/\)/g;
241 s/^\s+//;
242 s/\s+$//;
243 }
244 if ( $phone =~ /^\+?(\d)+[\(\ ]+(\d+)[\)\ ]+([\d+\ ])$/ ) {
245 my $cc = $1;
246 my $code = $2;
247 my $number = $3; $number =~ s/\D//g;
248 $phone = $cc.'('.$code.')'.$phone;
249 } elsif ( $phone =~ /^[\(]+(\d+)[\)\ ]+([\d+\ ])$/ ) {
250 my $cc = '7';
251 my $code = $1;
252 my $number = $2; $number =~ s/\D//g;
253 $phone = $cc.'('.$code.')'.$phone;
254 } else {
255 $phone =~ s/\D//g;
256 }
257 return $phone;
258 }
259 }
260
261 sub _phone_reduction {
262 my $self = shift;
263 my $phone = shift;
264 if ( $phone ) {
265 $phone =~ s/\D//g;
266 return $phone || undef;
267 }
268 }
269
270 196 ahitrov 1;