Line # Revision Author
1 197 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 $self->store_value ( %data );
47 }
48 return $self->get_session();
49 }
50
51
52 sub logoff {
53 my $self = shift;
54 my %opts = @_;
55
56 my $sid = _get_session_id ();
57 my $session = _get_session_object ( $sid );
58 return unless ref $session;
59
60 my $session_id = $session->{_session_id};
61 if (!$sid || $sid ne $session_id) {
62 warn "LOGOFF: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
63 _store_session_id ($session_id)
64 } else {
65 240 ahitrov if ( exists $opts{clear} ) {
66 my @clear = qw( id email login name nick type status ltime );
67 push @clear, @{ $opts{clear} } if exists $opts{clear} && ref $opts{clear} eq 'ARRAY' && @{ $opts{clear} };
68 foreach my $key ( @clear ) {
69 delete $session->{$key};
70 }
71 } else {
72 foreach my $key ( keys %$session ) {
73 next if $key eq '_session_id';
74 next if $key eq '_timestamp';
75 delete $session->{$key};
76 }
77 }
78 197 ahitrov }
79 untie %$session;
80 return 1;
81 }
82
83
84 sub get_value {
85
86 my ($self, $name) = @_;
87 my $sid = _get_session_id ();
88 my $session = _get_session_object ( $sid );
89 return unless ref $session;
90
91 my $session_id = $session->{_session_id};
92 my $value = $session->{$name};
93 if (!$sid || $sid ne $session_id) {
94 warn "GET_VALUE: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
95 _store_session_id ($session_id);
96 }
97 untie %$session;
98 return $value;
99 }
100
101
102 sub store_value {
103
104 my ($self, %opts) = @_;
105 my $sid = _get_session_id ();
106 my $session = _get_session_object ( $sid );
107 return unless ref $session;
108
109 foreach my $key ( keys %opts ) {
110 $session->{$key} = $opts{$key};
111 }
112
113 my $session_id = $session->{_session_id};
114 if (!$sid || $sid ne $session_id) {
115 warn "STORE_VALUE: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
116 _store_session_id ($session_id);
117 }
118 untie %$session;
119 return 1;
120 }
121
122
123 sub delete_key {
124
125 my ($self, $key) = @_;
126 return unless $key;
127
128 my $sid = _get_session_id ();
129 my $session = _get_session_object ( $sid );
130 return unless ref $session;
131
132 my $session_id = $session->{_session_id};
133 if (!$sid || $sid ne $session_id) {
134 warn "DELETE_VALUE: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
135 _store_session_id ($session_id);
136 } else {
137 delete $session->{$key} if exists $session->{$key};
138 }
139 untie %$session;
140 return 1;
141 }
142
143
144 sub get_session {
145
146 my $self = shift;
147
148 my $sid = _get_session_id () || '';
149 my $session = _get_session_object ($sid);
150 return unless ref $session;
151
152 my $session_id = $session->{_session_id};
153 my %ret = %$session;
154 if (!$sid || $sid ne $session_id) {
155 warn "\nGET_SESSION: New or deprecated session. Old sid = '$sid', new sid = '$session_id'\n" if $DEBUG;
156 _store_session_id ($session_id);
157 }
158 untie %$session;
159
160 return \%ret;
161 }
162
163
164 ## Внутренние функции
165 ######################################################################################
166 sub _store_session_id {
167
168 my $sid = shift;
169 return unless $sid;
170 my $cookie = Apache::Cookie->new ($request->r(),
171 -domain => $state->{session}->domain,
172 -name => $state->{session}->cookie,
173 -expires=> $state->{session}->expires,
174 -value => $sid,
175 -path => '/',
176 );
177 $cookie->bake();
178
179 }
180
181
182 sub _get_session_id {
183
184 my %cookies = Apache::Cookie->fetch;
185 warn Dumper(\%cookies) if $DEBUG;
186 my $cookie = $cookies{$state->{session}->cookie};
187
188 # Вытаскиваем SID из куки
189 my $sid = $cookie->value() || '' if $cookie;
190 warn "\nSession_id = $sid\n" if $DEBUG;
191
192 return $sid;
193 }
194
195
196 sub _get_session_object {
197
198 my $sid = shift;
199
200 my %session;
201 my $now = time;
202 if ( $state->{session}->storage eq 'POSTGRES' ) {
203 eval {
204 tie %session, 'Apache::Session::Postgres', $sid, {
205 Handle => $keeper->SQL,
206 };
207 };
208 } else {
209 eval {
210 tie %session, 'Apache::Session::File', $sid, {
211 Directory => $state->session->session_dir,
212 };
213 };
214 }
215 if ($@) {
216 warn "Session data is not accessible: $@";
217 undef $sid;
218 } elsif ( $state->{session}->lifetime ) {
219 unless ( exists $session{_timestamp} ) {
220 $session{_timestamp} = $now;
221 } elsif ( ($now - $session{_timestamp}) > $state->{session}->lifetime ) {
222 undef $sid;
223 } elsif ( ($now - $session{_timestamp}) > $state->{session}->checkout ) {
224 $session{_timestamp} = $now;
225 }
226 }
227 unless ( $sid ) {
228 if ( $state->{session}->storage eq 'POSTGRES' ) {
229 eval {
230 tie %session, 'Apache::Session::Postgres', undef, {
231 Handle => $keeper->SQL,
232 };
233 };
234 } else {
235 eval {
236 tie %session, 'Apache::Session::File', undef, {
237 Directory => $state->session->session_dir,
238 };
239 };
240 }
241 $session{_timestamp} = $now;
242 }
243
244 return \%session;
245 }
246
247
248 sub _drop_session_object {
249
250 my (%session) = @_;
251
252 untie %session;
253
254 }
255
256 1;