Line # Revision Author
1 194 ahitrov package session::Keeper;
2
3 use strict;
4 use warnings 'all';
5 use base qw(Contenido::Keeper);
6
7 use Apache::Cookie;
8 use Apache::Session::File;
9 use Apache::Session::Postgres;
10 use Contenido::Globals;
11 use Data::Dumper;
12
13
14 sub logon {
15 my $self = shift;
16 my %opts = @_;
17
18 return if !($opts{login} || $opts{email}) && !$opts{passwd};
19
20 my $res;
21 my @plugins = split (/[\ |\t]+/, $state->{plugins});
22 if ( grep { $_ eq 'users' } @plugins ) {
23 #### ����������� ����� ������ users
24 #########################################
25 $res = $keeper->{users}->login (
26 $opts{login} ? (login => $opts{login}) : (),
27 $opts{email} ? (email => lc($opts{email})) : (),
28 passwd => $opts{passwd},
29 );
30 return unless $res;
31 } else {
32 #### ����������� ���� ��������
33
34
35
36 }
37 if ( ref $res ) {
38 my %data = (
39 id => $res->id,
40 name => $res->name,
41 email => $res->email,
42 login => $res->login,
43 status => $res->status,
44 ltime => time,
45 );
46 255 ahitrov my ($type_prop) = grep { $_->{attr} eq 'type' } $res->structure;
47 $data{type} = $res->type if $type_prop;
48 194 ahitrov $self->store_value ( %data );
49 }
50 return $self->get_session();
51 }
52
53
54 sub logoff {
55 my $self = shift;
56 281 ahitrov my (%opts) = @_;
57 243 ahitrov
58 194 ahitrov my $sid = _get_session_id ();
59 my $session = _get_session_object ( $sid );
60 return unless ref $session;
61
62 my $session_id = $session->{_session_id};
63 if (!$sid || $sid ne $session_id) {
64 warn "LOGOFF: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
65 281 ahitrov _store_session_id ($session_id, %opts)
66 194 ahitrov } else {
67 243 ahitrov if ( exists $opts{clear} ) {
68 my @clear = qw( id email login name nick type status ltime );
69 push @clear, @{ $opts{clear} } if exists $opts{clear} && ref $opts{clear} eq 'ARRAY' && @{ $opts{clear} };
70 foreach my $key ( @clear ) {
71 delete $session->{$key};
72 }
73 } else {
74 foreach my $key ( keys %$session ) {
75 next if $key eq '_session_id';
76 next if $key eq '_timestamp';
77 delete $session->{$key};
78 }
79 }
80 194 ahitrov }
81 untie %$session;
82 return 1;
83 }
84
85
86 255 ahitrov sub autologon {
87 my $self = shift;
88 my %opts = @_;
89
90 my $profile = delete $opts{profile};
91 if ( ref $profile ) {
92 my %data = (
93 id => $profile->id,
94 name => $profile->name,
95 email => $profile->email,
96 login => $profile->login,
97 status => $profile->status,
98 ltime => time,
99 );
100 my ($type_prop) = grep { $_->{attr} eq 'type' } $profile->structure;
101 $data{type} = $profile->type if $type_prop;
102 my ($ava_prop) = grep { $_->{attr} eq 'avatar' } $profile->structure;
103 if ( $ava_prop ) {
104 my $avatar = $profile->get_image('avatar');
105 $data{avatar} = $avatar->{mini}{filename} if ref $avatar && exists $avatar->{filename};
106 }
107 $self->store_value ( %data );
108 return $self->get_session();
109 }
110 return undef;
111 }
112
113
114 194 ahitrov sub get_value {
115
116 264 ahitrov my ($self, $name, %opts) = @_;
117 my $sid = delete $opts{_session_id} || _get_session_id ();
118 194 ahitrov my $session = _get_session_object ( $sid );
119 return unless ref $session;
120
121 my $session_id = $session->{_session_id};
122 my $value = $session->{$name};
123 if (!$sid || $sid ne $session_id) {
124 warn "GET_VALUE: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
125 281 ahitrov _store_session_id ($session_id, %opts);
126 194 ahitrov }
127 untie %$session;
128 return $value;
129 }
130
131
132 sub store_value {
133
134 my ($self, %opts) = @_;
135 281 ahitrov my $domain = delete $opts{domain};
136 264 ahitrov my $sid = delete $opts{_session_id} || _get_session_id ();
137 194 ahitrov my $session = _get_session_object ( $sid );
138 return unless ref $session;
139
140 foreach my $key ( keys %opts ) {
141 $session->{$key} = $opts{$key};
142 }
143
144 my $session_id = $session->{_session_id};
145 if (!$sid || $sid ne $session_id) {
146 warn "STORE_VALUE: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
147 281 ahitrov _store_session_id ($session_id, domain => $domain);
148 194 ahitrov }
149 untie %$session;
150 return 1;
151 }
152
153
154 sub delete_key {
155
156 264 ahitrov my ($self, $key, %opts) = @_;
157 194 ahitrov return unless $key;
158
159 264 ahitrov my $sid = delete $opts{_session_id} || _get_session_id ();
160 194 ahitrov my $session = _get_session_object ( $sid );
161 return unless ref $session;
162
163 my $session_id = $session->{_session_id};
164 if (!$sid || $sid ne $session_id) {
165 warn "DELETE_VALUE: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
166 281 ahitrov _store_session_id ($session_id, %opts);
167 194 ahitrov } else {
168 delete $session->{$key} if exists $session->{$key};
169 }
170 untie %$session;
171 return 1;
172 }
173
174
175 sub get_session {
176
177 my $self = shift;
178 281 ahitrov my (%opts) = @_;
179 194 ahitrov
180 my $sid = _get_session_id () || '';
181 my $session = _get_session_object ($sid);
182 return unless ref $session;
183
184 my $session_id = $session->{_session_id};
185 my %ret = %$session;
186 if (!$sid || $sid ne $session_id) {
187 warn "\nGET_SESSION: New or deprecated session. Old sid = '$sid', new sid = '$session_id'\n" if $DEBUG;
188 281 ahitrov _store_session_id ($session_id, %opts);
189 194 ahitrov }
190 untie %$session;
191
192 281 ahitrov my $session_object = session::Session->new( %ret );
193 return $session_object;
194 194 ahitrov }
195
196
197 ## ���������� �������
198 ######################################################################################
199 sub _store_session_id {
200
201 my $sid = shift;
202 281 ahitrov my (%opts) = @_;
203 194 ahitrov return unless $sid;
204 my $cookie = Apache::Cookie->new ($request->r(),
205 281 ahitrov -domain => $opts{domain} || $state->{session}->domain,
206 194 ahitrov -name => $state->{session}->cookie,
207 -expires=> $state->{session}->expires,
208 -value => $sid,
209 -path => '/',
210 );
211 $cookie->bake();
212
213 }
214
215
216 sub _get_session_id {
217
218 281 ahitrov my $keyname = shift || $state->{session}->cookie;
219
220 194 ahitrov my %cookies = Apache::Cookie->fetch;
221 warn Dumper(\%cookies) if $DEBUG;
222 281 ahitrov my $cookie = $cookies{$keyname};
223 194 ahitrov
224 # ����������� SID �� ����
225 my $sid = $cookie->value() || '' if $cookie;
226 warn "\nSession_id = $sid\n" if $DEBUG;
227
228 return $sid;
229 }
230
231
232 sub _get_session_object {
233
234 my $sid = shift;
235
236 my %session;
237 my $now = time;
238 if ( $state->{session}->storage eq 'POSTGRES' ) {
239 eval {
240 tie %session, 'Apache::Session::Postgres', $sid, {
241 Handle => $keeper->SQL,
242 };
243 };
244 253 ahitrov } elsif ( $state->{session}->storage eq 'MEMCACHED' ) {
245 eval {
246 tie %session, 'Apache::Session::Memcached', $sid, {
247 Handler => $keeper->{session}->MEMD,
248 Expiration => $state->{session}->{lifetime},
249 };
250 };
251 194 ahitrov } else {
252 eval {
253 tie %session, 'Apache::Session::File', $sid, {
254 253 ahitrov Directory => $state->{session}->session_dir,
255 194 ahitrov };
256 };
257 }
258 if ($@) {
259 warn "Session data is not accessible: $@";
260 undef $sid;
261 264 ahitrov } else {
262 $sid = $session{_session_id};
263 if ( $state->{session}->lifetime ) {
264 unless ( exists $session{_timestamp} ) {
265 $session{_timestamp} = $now;
266 } elsif ( ($now - $session{_timestamp}) > $state->{session}->lifetime ) {
267 undef $sid;
268 } elsif ( ($now - $session{_timestamp}) > $state->{session}->checkout ) {
269 $session{_timestamp} = $now;
270 }
271 194 ahitrov }
272 }
273 unless ( $sid ) {
274 if ( $state->{session}->storage eq 'POSTGRES' ) {
275 eval {
276 tie %session, 'Apache::Session::Postgres', undef, {
277 Handle => $keeper->SQL,
278 };
279 };
280 253 ahitrov } elsif ( $state->{session}->storage eq 'MEMCACHED' ) {
281 eval {
282 tie %session, 'Apache::Session::Memcached', undef, {
283 Handler => $keeper->{session}->MEMD,
284 Expiration => $state->{session}->{lifetime},
285 };
286 };
287 194 ahitrov } else {
288 eval {
289 tie %session, 'Apache::Session::File', undef, {
290 255 ahitrov Directory => $state->{session}->session_dir,
291 194 ahitrov };
292 };
293 }
294 $session{_timestamp} = $now;
295 }
296
297 return \%session;
298 }
299
300
301 sub _drop_session_object {
302
303 my (%session) = @_;
304
305 untie %session;
306
307 }
308
309 281 ahitrov sub _get_hash_from_profile {
310 my $profile = shift;
311 return unless ref $profile;
312
313 my %data = (
314 id => $profile->id,
315 name => $profile->name,
316 email => $profile->email,
317 login => $profile->login,
318 status => $profile->status,
319 ltime => time,
320 );
321 my ($type_prop) = grep { $_->{attr} eq 'type' } $profile->structure;
322 $data{type} = $profile->type if $type_prop;
323 my ($ava_prop) = grep { $_->{attr} eq 'avatar' } $profile->structure;
324 if ( $ava_prop ) {
325 my $avatar = $profile->get_image('avatar');
326 $data{avatar} = $avatar->{mini}{filename} if ref $avatar && exists $avatar->{filename};
327 }
328
329 return %data;
330 }
331
332 194 ahitrov 1;