package session::Session; use strict; use warnings 'all'; use Contenido::Globals; use session::Keeper; sub new { my ($proto, %params) = @_; my $class = ref($proto) || $proto; my $self = {}; bless $self, $class; if ( exists $params{_session_id} ) { $self->{_session_id} = delete $params{_session_id}; $self->{_timestamp} = delete $params{_timestamp}; } $self->{_domain} = delete $params{domain} || $state->{session}->domain; while ( my ($key, $val) = each %params ) { $self->{$key} = $val; } return $self; } sub session_id { my $self = shift; return $self->{_session_id}; } sub _session_id { my $self = shift; return $self->{_session_id}; } sub rehash { my ($self, $session) = @_; return $self if $self->{_session_id} eq $session->{_session_id}; warn "STORE_VALUE: New or deprecated session. Old sid = [".$self->{_session_id}."], new sid = [".$session->{_session_id}."]" if $DEBUG; session::Keeper::_store_session_id ($session->{_session_id}, domain => $self->{_domain}); foreach my $key ( keys %$self ) { next if $key eq '_domain'; delete $self->{$key}; } while ( my ($key, $val) = each %$session ) { $self->{$key} = $val; } return $self; } sub id { my $self = shift; return (exists $self->{id} && $self->{id} ? $self->{id} : undef); } sub get { my ($self, $name) = @_; return ($name && exists $self->{$name} ? $self->{$name} : undef); } sub set { my ($self, %opts) = @_; my $sid = $self->{_session_id}; my $session = session::Keeper::_get_session_object( $sid ); return unless ref $session; $self->rehash( $session ); while ( my ($key, $val) = each %opts ) { $session->{$key} = $val; $self->{$key} = $val; } untie %$session; 1; } sub delete { my ($self, @keys) = @_; my $sid = $self->{_session_id}; my $session = session::Keeper::_get_session_object( $sid ); return unless ref $session; $self->rehash( $session ); foreach my $key ( @keys ) { if ( exists $self->{$key} ) { delete $session->{$key}; delete $self->{$key}; } } untie %$session; 1; } sub logon { my $self = shift; my %opts = @_; my $profile = delete $opts{profile}; return unless ref $profile || (($opts{login} || $opts{email}) && $opts{passwd}); if ( ref $profile ) { my %data = session::Keeper::_get_hash_from_profile( $profile ); $self->set ( %data ); } else { my @plugins = split (/[\ |\t]+/, $state->{plugins}); if ( grep { $_ eq 'users' } @plugins ) { #### Авторизация через плагин users ######################################### $profile = $keeper->{users}->login ( $opts{login} ? (login => $opts{login}) : (), $opts{email} ? (email => lc($opts{email})) : (), passwd => $opts{passwd}, ); } else { #### Авторизация иным способом } if ( ref $profile ) { my %data = session::Keeper::_get_hash_from_profile( $profile ); $self->set ( %data ); } else { $self->set( login_error_code => 404 ); } } return $self; } sub logoff { my ($self, %opts) = @_; my $sid = $self->{_session_id}; my $session = session::Keeper::_get_session_object( $sid ); return unless ref $session; $self->rehash( $session ); if ( exists $opts{clear} ) { my @clear = qw( id email login name nick type status ltime avatar ); push @clear, @{ $opts{clear} } if ref $opts{clear} eq 'ARRAY' && @{ $opts{clear} }; foreach my $key ( @clear ) { delete $session->{$key}; delete $self->{$key} } } else { foreach my $key ( keys %$session ) { next if $key =~ /^_/; delete $session->{$key}; delete $self->{$key} } } untie %$session; 1; } 1;