Revision 194

Date:
2012/03/15 18:25:50
Author:
ahitrov
Revision Log:
Session plugin
Files:

Legend:

 
Added
 
Removed
 
Modified
  • koi8/plugins/session/comps/contenido/session/dhandler

     
    1 % if (@call)
    2 % {
    3 <& @call &>
    4 % }
    5 <%INIT>
    6
    7 use vars qw( $keeper $request $project );
    8 $r->content_type('text/html');
    9
    10 my @path = split('/', $m->dhandler_arg());
    11 my @call = ();
    12
    13 if (length($path[0]) < 1) { $path[0] = 'index.html' };
    14 @call = (join('/',@path), %ARGS);
    15
    16 if (! $m->comp_exists($call[0]))
    17 {
    18 $m->clear_buffer();
    19 $m->abort(404);
    20 }
    21
    22 </%INIT>
  • koi8/plugins/session/comps/contenido/session/index.html

     
    1 <& "/contenido/components/header.msn", style => 'index' &>
    2
    3 <div style="text-align:center; padding:180px 20px;">
    4 % if ( $keeper->{session}->state->storage eq 'POSTGRES' ) {
    5 <form action="./index.html" method="POST"
    6 onsubmit="return confirm('�� ������������� ����������� �������� ��� ���������������� ������?\n��� �������� � ��������������� ������ ������������� �� �������!')">
    7 <input type="submit" class="input_btn" name="clear" value="������� ��� ���������������� ������">
    8
    9 </form>
    10 % }
    11 </div>
    12
    13 </body>
    14 </html>
    15 <%args>
    16
    17 $clear => undef
    18
    19 </%args>
    20 <%init>
    21
    22 if ( $clear && $keeper->{session}->state->storage eq 'POSTGRES' ) {
    23 warn "delete from sessions\n";
    24 my $req = $keeper->SQL->do('delete from sessions', {}) || $keeper->t_abort();
    25 $m->redirect ('./');
    26 }
    27
    28 </%init>
  • koi8/plugins/session/config.proto

     
    1
    2
    3 ### AUTH::FaceBook
    4 ######################################
    5 FACEBOOK_APP_ID =
    6 FACEBOOK_APP_KEY =
    7 FACEBOOK_APP_SECRET =
    8 FACEBOOK_AUTHORIZE_URL = https://graph.facebook.com/oauth/authorize
    9 FACEBOOK_ACCESS_TOKEN_URL = https://graph.facebook.com/oauth/access_token
    10 FACEBOOK_USER_INFO_URL = https://graph.facebook.com/me
    11 FACEBOOK_REDIRECT_URL =
    12 FACEBOOK_USER_POST_URL =
    13
    14 REWRITE += FACEBOOK_AUTHORIZE_URL FACEBOOK_ACCESS_TOKEN_URL FACEBOOK_USER_INFO_URL
    15
    16 ### AUTH::VKontakte
    17 ######################################
    18 VK_APP_ID =
    19 VK_APP_SECRET =
    20 VK_AUTHORIZE_URL = http://vkontakte.ru/login.php
    21 VK_ACCESS_TOKEN_URL = http://vk.com/api.php
    22 VK_USER_INFO_URL = http://vk.com/api.php
    23 VK_REDIRECT_URL =
    24 VK_USER_POST_URL =
    25
    26 REWRITE += VK_APP_ID VK_APP_SECRET
    27 REWRITE += VK_AUTHORIZE_URL VK_ACCESS_TOKEN_URL
    28
    29 CONNECTION_TIMEOUT = 3
    30
    31 PROJECT_REQUIRED += JSON-XS
    32 PROJECT_REQUIRED += Crypt-SSLeay
  • koi8/plugins/session/lib/session/Apache.pm

     
    1 package session::Apache;
    2
    3 use strict;
    4 use warnings 'all';
    5
    6 use session::State;
    7 use Contenido::Globals;
    8
    9
    10 sub child_init {
    11 # ���������� keeper ������� � keeper �������
    12 $keeper->{session} = session::Keeper->new($state->session);
    13 }
    14
    15 sub request_init {
    16 }
    17
    18 sub child_exit {
    19 }
    20
    21 1;
  • koi8/plugins/session/lib/session/AUTH/FaceBook.pm

     
    1 package session::AUTH::FaceBook;
    2
    3 use strict;
    4 use warnings;
    5 use LWP::UserAgent;
    6 use JSON::XS;
    7 use Data::Dumper;
    8 use URI;
    9 use URI::QueryParam;
    10 use Encode;
    11 use Contenido::Globals;
    12
    13 use vars qw($VERSION);
    14 $VERSION = '4.1';
    15
    16 =for rem
    17 facebook:
    18 auto_create_user: 1
    19 app_id: 122117614500563
    20 app_key: 3da06301715b0efc5c873535c56c2c33
    21 app_secret: 656bd1369486b902e9bf831a9a08132b
    22 authorize_url: https://graph.facebook.com/oauth/authorize
    23 access_token_url: https://graph.facebook.com/oauth/access_token
    24 user_info_url: https://graph.facebook.com/me
    25 user_post_url: ~
    26 store:
    27 class: "+Comments::Authentication::Store"
    28 type: facebook
    29
    30 =cut
    31
    32 our $JSON = JSON::XS->new->utf8;
    33
    34 =for rem SCHEMA
    35
    36 $m->redirect ( $fb_connect->fb_authorize_url( redirect_uri => ... ) );
    37
    38
    39 =cut
    40
    41
    42 sub new {
    43 my ($class, %config) = @_;
    44 my $self = bless {}, $class;
    45 for (qw(facebook_app_id facebook_app_key facebook_app_secret facebook_authorize_url facebook_access_token_url facebook_user_info_url)) {
    46 $self->{$_} = $config{$_} || $state->{session}->{$_} || return undef;
    47 }
    48 $self->{timeout} = $state->{session}->{connection_timeout} || 3;
    49 for (qw(facebook_user_post_url facebook_redirect_uri)) {
    50 $self->{$_} = $config{$_} || $state->{session}->{$_};
    51 }
    52 return $self;
    53 }
    54
    55 sub fb_authorize_url {
    56 my $self = shift;
    57 my (%args) = @_;
    58 my $go = URI->new( $self->{facebook_authorize_url} );
    59 warn Dumper($go);
    60 $go->query_param( client_id => $self->{facebook_app_key} );
    61 $go->query_param( scope => "publish_stream" );
    62 $args{redirect_uri} ||= $self->{facebook_redirect_uri};
    63 for ( keys %args ) {
    64 $go->query_param( $_ => $args{$_} );
    65 }
    66 $keeper->{session}->store_value( facebook_redirect_url => $self->{facebook_redirect_uri} );
    67 return $go;
    68 }
    69
    70 sub authenticate {
    71 my ( $self, %authinfo ) = @_;
    72 warn "FB.authenticate" if $DEBUG;
    73 # TODO: we need callback url
    74 #warn "user_session=".dumper( $c->user_session )." ";
    75 my $local_session = $session || $keeper->{session}->get_session;
    76 my $redirect_uri = $local_session->{facebook_redirect_url};
    77
    78 my $access_token = $local_session->{facebook_access_token};
    79 my $expires = $local_session->{facebook_expires};
    80 if ($access_token and $expires > time) {
    81 warn "Already have access_token" if $DEBUG;
    82 } else {
    83 undef $access_token;
    84 }
    85 my $code = $authinfo{'code'};
    86 unless ( $code ) {
    87 warn "Call to authenticate without code";
    88 return undef;
    89 }
    90 my $ua = LWP::UserAgent->new;
    91 $ua->timeout($self->{timeout});
    92 unless ($access_token) {
    93 my $req = URI->new( $self->{facebook_access_token_url});
    94 $req->query_param( client_id => $self->{facebook_app_id} );
    95 $req->query_param( redirect_uri => $redirect_uri );
    96 $req->query_param( client_secret=> $self->{facebook_app_secret} );
    97 $req->query_param( code => $code);
    98 warn "Get $req";
    99 my $res = $ua->get($req);
    100 unless ($res->code == 200) {
    101 warn "access_token request failed: ".$res->status_line;
    102 return undef;
    103 }
    104 my %res = eval { URI->new("?".$res->content)->query_form };
    105 warn Dumper(\%res);
    106 unless ($access_token = $res{access_token}) {
    107 warn "No access token in response: ".$res->content;
    108 return undef;
    109 }
    110 $keeper->{session}->store_value( facebook_access_token => $access_token );
    111 $local_session->{facebook_access_token} = $access_token;
    112 if( my $expires = $res{expires} ) {
    113 $local_session->{facebook_expires} = time + $expires;
    114 $keeper->{session}->store_value( facebook_expires => $local_session->{facebook_expires} );
    115 } else {
    116 #$c->user_session->{'expires'} = time + 3600*24;
    117 }
    118 warn "FB: requested access token";
    119 } else {
    120 warn "FB: have access token";
    121 }
    122
    123 my $req = URI->new( $self->{facebook_user_info_url} );
    124 $req->query_param( access_token => $access_token );
    125
    126 warn "Fetching user $req";
    127 my $res = $ua->get($req);
    128 unless ($res->code == 200) {
    129 warn "user request failed: ".$res->status_line;
    130 return undef;
    131 }
    132 my $info;
    133 unless ( $info = eval { JSON::XS->new->utf8->decode($res->content) } ) {
    134 warn "user '".$res->content."' decode failed: $@";
    135 return undef;
    136 }
    137 warn "Userhash = ".Dumper($info);
    138 #warn "facebook: user=$info->{name} / $info->{id} / $info->{gender}";
    139
    140 my @plugins = split (/[\ |\t]+/, $state->{plugins});
    141 if ( grep { $_ eq 'users' } @plugins ) {
    142 my $user = $keeper->{users}->get_profile( login => 'facebook:'.$info->{id} );
    143 unless ( ref $user ) {
    144 my $user_class = $state->{users}->profile_document_class;
    145 $user = $user_class->new( $keeper );
    146 $user->login( 'facebook:'.$info->{id} );
    147 my $name = Encode::encode('utf-8', $info->{name});
    148 Encode::from_to( $name, 'utf-8', 'koi8-r' );
    149 $user->name( $name );
    150 $user->status( 1 );
    151 $user->type( 0 );
    152 $user->login_method('facebook');
    153 $user->country( $info->{locale} );
    154 $user->email( undef );
    155
    156 my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
    157 if ( ref $prop_ava ) {
    158 my $avatar = $user->_store_image( 'https://graph.facebook.com/'.$info->{username}.'/picture?type=large', attr => 'avatar' );
    159 local $Data::Dumper::Indent = 0;
    160 $user->avatar( Data::Dumper::Dumper($avatar) );
    161 }
    162
    163 $user->store;
    164 } else {
    165 my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
    166 if ( ref $prop_ava ) {
    167 my $avatar = $user->get_image( 'avatar' );
    168 unless ( ref $avatar && exists $avatar->{filename} ) {
    169 my $avatar = $user->_store_image( 'https://graph.facebook.com/'.$info->{username}.'/picture?type=large', attr => 'avatar' );
    170 local $Data::Dumper::Indent = 0;
    171 $user->avatar( Data::Dumper::Dumper($avatar) );
    172 $user->store;
    173 }
    174 }
    175 }
    176 my %data = (
    177 id => $user->id,
    178 name => $user->name,
    179 login => $user->login,
    180 status => $user->status,
    181 type => $user->type,
    182 ltime => time,
    183 avatar => 'https://graph.facebook.com/'.$info->{username}.'/picture',
    184 );
    185 $keeper->{session}->store_value ( %data );
    186 while ( my ( $key, $value ) = each %data ) {
    187 $local_session->{$key} = $value;
    188 }
    189 }
    190 return $local_session;
    191 }
    192
    193 1;
  • koi8/plugins/session/lib/session/AUTH/VKontakte.pm

     
    1 package session::AUTH::VKontakte;
    2
    3 use strict;
    4 use warnings;
    5 use LWP::UserAgent;
    6 use JSON::XS;
    7 use Data::Dumper;
    8 use URI;
    9 use URI::QueryParam;
    10 use Encode;
    11 use Contenido::Globals;
    12
    13 use vars qw($VERSION);
    14 $VERSION = '4.1';
    15
    16 =for rem
    17 vkontakte:
    18 auto_create_user: 1
    19 app_id: 122117614500563
    20 app_secret: 656bd1369486b902e9bf831a9a08132b
    21 authorize_url: http://api.vkontakte.ru/oauth/authorize
    22 access_token_url: https://api.vkontakte.ru/oauth/access_token
    23 user_info_url: https://api.vkontakte.ru/method/getProfiles
    24 user_post_url: ~
    25 =cut
    26
    27 our $JSON = JSON::XS->new->utf8;
    28
    29 =for rem SCHEMA
    30
    31 $m->redirect ( $fb_connect->fb_authorize_url( redirect_uri => ... ) );
    32
    33
    34 =cut
    35
    36 sub new {
    37 my ($class, %config) = @_;
    38 my $self = bless {}, $class;
    39 for (qw( vk_app_id vk_app_secret vk_authorize_url vk_access_token_url vk_user_info_url)) {
    40 $self->{$_} = $config{$_} || $state->{session}->{$_} || return undef;
    41 }
    42 $self->{timeout} = $state->{session}->{connection_timeout} || 3;
    43 for (qw(vk_user_post_url vk_redirect_uri)) {
    44 $self->{$_} = $config{$_} || $state->{session}->{$_};
    45 }
    46 return $self;
    47 }
    48
    49 sub authorize_url {
    50 my $self = shift;
    51 my (%args) = @_;
    52 my $go = URI->new( $self->{vk_authorize_url} );
    53 $go->query_param( client_id => $self->{vk_app_id} );
    54 $go->query_param( scope => '' );
    55 $go->query_param( response_type => 'code' );
    56 $args{redirect_uri} ||= $self->{vk_redirect_uri};
    57 for ( keys %args ) {
    58 $go->query_param( $_ => $args{$_} );
    59 }
    60 $keeper->{session}->store_value( vk_redirect_url => $self->{vk_redirect_uri} );
    61 return $go;
    62 }
    63
    64 sub authenticate {
    65 my ( $self, %authinfo ) = @_;
    66 warn "VK.authenticate" if $DEBUG;
    67 # TODO: we need callback url
    68 #warn "user_session=".dumper( $c->user_session )." ";
    69
    70 my $local_session = $session || $keeper->{session}->get_session;
    71 my $redirect_uri = $local_session->{vk_redirect_url};
    72
    73 my $access_token = $local_session->{vk_access_token};
    74 my $vk_user_id = $local_session->{vk_user_id};
    75 my $expires = $local_session->{vk_expires};
    76 if ($access_token and $expires > time) {
    77 warn "Already have access_token" if $DEBUG;
    78 } else {
    79 undef $access_token;
    80 }
    81 my $code = $authinfo{'code'};
    82 unless ( $code ) {
    83 warn "Call to authenticate without code\n";
    84 return undef;
    85 }
    86 my $ua = LWP::UserAgent->new;
    87 $ua->timeout($self->{timeout});
    88
    89 unless ($access_token) {
    90 my $req = URI->new( $self->{vk_access_token_url});
    91 $req->query_param( client_id => $self->{vk_app_id} );
    92 $req->query_param( client_secret => $self->{vk_app_secret} );
    93 $req->query_param( code => $code );
    94 my $res = $ua->get($req);
    95 unless ($res->code == 200) {
    96 warn "VK: Access_token request failed: ".$res->status_line."\n";
    97 return undef;
    98 }
    99 my $info = $JSON->decode($res->content);
    100 unless ( ref $info eq 'HASH' && ($access_token = $info->{access_token}) ) {
    101 warn "No access token in response: ".$res->content."\n";
    102 return undef;
    103 }
    104 $keeper->{session}->store_value( vk_access_token => $access_token );
    105 $local_session->{vk_access_token} = $access_token;
    106 $keeper->{session}->store_value( vk_user_id => $info->{user_id} );
    107 $local_session->{vk_user_id} = $info->{user_id};
    108 if ( my $expires = $info->{expires_in} ) {
    109 $local_session->{vk_expires} = time + $expires;
    110 $keeper->{session}->store_value( vk_expires => $local_session->{vk_expires} );
    111 } else {
    112 #$c->user_session->{'expires'} = time + 3600*24;
    113 }
    114 warn "VK: requested access token";
    115 } else {
    116 warn "VK: have access token";
    117 }
    118
    119 my $req = URI->new( $self->{vk_user_info_url} );
    120 $req->query_param( uid => $local_session->{vk_user_id} );
    121 $req->query_param( fields => 'uid,first_name,last_name,nickname,domain,sex,bdate,city,country,timezone,photo,photo_medium,photo_big' );
    122 $req->query_param( access_token => $access_token );
    123
    124 warn "VK: Fetching user $req\n" if $DEBUG;
    125 my $res = $ua->get($req);
    126 unless ($res->code == 200) {
    127 warn "VK: user request failed: ".$res->status_line."\n";
    128 return undef;
    129 }
    130
    131 my $info;
    132 unless ( $info = eval { $JSON->decode($res->content) } ) {
    133 warn "user '".$res->content."' decode failed: $@\n";
    134 return undef;
    135 }
    136 warn Dumper($info) if $DEBUG;
    137 return undef unless exists $info->{response} && ref $info->{response} eq 'ARRAY' && @{$info->{response}};
    138 my $user_info = $info->{response}[0];
    139 foreach my $key ( qw(nickname last_name first_name) ) {
    140 $user_info->{$key} = Encode::encode('utf-8', $user_info->{$key});
    141 Encode::from_to( $user_info->{$key}, 'utf-8', 'koi8-r' );
    142 }
    143
    144 my @plugins = split (/[\ |\t]+/, $state->{plugins});
    145 my $name = $user_info->{first_name}.' '.$user_info->{last_name};
    146 if ( grep { $_ eq 'users' } @plugins ) {
    147 my $user = $keeper->{users}->get_profile( login => 'vkontakte:'.$user_info->{uid} );
    148 unless ( ref $user ) {
    149 my $user_class = $state->{users}->profile_document_class;
    150 $user = $user_class->new( $keeper );
    151 $user->login( 'vkontakte:'.$user_info->{uid} );
    152 $user->name( $user_info->{last_name}.', '.$user_info->{first_name} );
    153 $user->nickname( $user_info->{nickname} );
    154 $user->status( 1 );
    155 $user->type( 0 );
    156 $user->login_method('vkontakte');
    157 $user->country( $user_info->{country} );
    158 $user->email( undef );
    159
    160 my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
    161 if ( ref $prop_ava ) {
    162 my $avatar = $user->_store_image( $user_info->{photo_big}, attr => 'avatar' );
    163 local $Data::Dumper::Indent = 0;
    164 $user->avatar( Data::Dumper::Dumper($avatar) );
    165 }
    166
    167 $user->store;
    168 } else {
    169 my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
    170 if ( ref $prop_ava ) {
    171 my $avatar = $user->get_image( 'avatar' );
    172 unless ( ref $avatar && exists $avatar->{filename} ) {
    173 my $avatar = $user->_store_image( $user_info->{photo_big}, attr => 'avatar' );
    174 local $Data::Dumper::Indent = 0;
    175 $user->avatar( Data::Dumper::Dumper($avatar) );
    176 $user->store;
    177 }
    178 }
    179 }
    180 my %data = (
    181 id => $user->id,
    182 name => $name,
    183 login => $user->login,
    184 status => $user->status,
    185 type => $user->type,
    186 auth_by => 'vkontakte',
    187 ltime => time,
    188 );
    189 if ( $user_info->{photo} ) {
    190 $data{avatar} = $user_info->{photo};
    191 }
    192 $keeper->{session}->store_value ( %data );
    193 while ( my ( $key, $value ) = each %data ) {
    194 $local_session->{$key} = $value;
    195 }
    196
    197 } else {
    198 my %data = (
    199 id => $user_info->{uid},
    200 name => $name,
    201 nick => $user_info->{nickname} || $name,
    202 login => 'vkontakte:'.$user_info->{uid},
    203 status => 1,
    204 type => 0,
    205 auth_by => 'vkontakte',
    206 ltime => time,
    207 );
    208 if ( $user_info->{photo} ) {
    209 $data{avatar} = $user_info->{photo};
    210 }
    211 $keeper->{session}->store_value ( %data );
    212 while ( my ( $key, $value ) = each %data ) {
    213 $local_session->{$key} = $value;
    214 }
    215 }
    216 return $local_session;
    217 }
    218
    219 1;
  • koi8/plugins/session/lib/session/Init.pm

     
    1 package session::Init;
    2
    3 use strict;
    4 use warnings 'all';
    5
    6 use session::Apache;
    7 use session::Keeper;
    8 use session::AUTH::FaceBook;
    9 use session::AUTH::VKontakte;
    10
    11 # �������� ���� ����������� ������� �������
    12 # session::SQL::SomeTable
    13 # session::SomeClass
    14 Contenido::Init::load_classes(qw(
    15 ));
    16
    17 sub init {
    18 0;
    19 }
    20
    21 1;
  • koi8/plugins/session/lib/session/Keeper.pm

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

     
    1 package session::State;
    2
    3 use strict;
    4 use warnings 'all';
    5 use vars qw($AUTOLOAD);
    6
    7
    8 sub new {
    9 my ($proto) = @_;
    10 my $class = ref($proto) || $proto;
    11 my $self = {};
    12 bless $self, $class;
    13
    14 # ������� ������������ �������
    15 $self->{db_type} = 'none';
    16 $self->{storage} = '@SESSION_STORAGE@' || 'FILE'; ## ��������: FILE POSTGRES MEMCACHED
    17 $self->{session_dir} = '@SESSIONS@';
    18 $self->{session_directory} = '@SESSIONS@';
    19
    20 $self->{domain} = '@SESSION_DOMAIN@';
    21 $self->{cookie} = 'lsid';
    22 $self->{expires} = '@SESSION_EXPIRES@' || '';
    23
    24 $self->{lifetime} = '@SESSION_LIFETIME@';
    25 $self->{lifetime} *= 3600;
    26 $self->{checkout} = $self->{lifetime} - int ($self->{lifetime} / 2);
    27
    28 $self->{db_keepalive} = 0;
    29 $self->{db_host} = '';
    30 $self->{db_name} = '';
    31 $self->{db_user} = '';
    32 $self->{db_password} = '';
    33 $self->{db_port} = '';
    34
    35 $self->{data_directory} = '';
    36 $self->{images_directory} = '';
    37 $self->{binary_directory} = '';
    38 $self->{preview} = '';
    39 $self->{debug} = '';
    40 $self->{store_method} = '';
    41 $self->{cascade} = '';
    42 $self->{memcached_enable} = '';
    43
    44 $self->{facebook_app_id} = '@FACEBOOK_APP_ID@';
    45 $self->{facebook_app_key} = '@FACEBOOK_APP_KEY@';
    46 $self->{facebook_app_secret} = '@FACEBOOK_APP_SECRET@';
    47 $self->{facebook_authorize_url} = '@FACEBOOK_AUTHORIZE_URL@';
    48 $self->{facebook_access_token_url} = '@FACEBOOK_ACCESS_TOKEN_URL@';
    49 $self->{facebook_user_info_url} = '@FACEBOOK_USER_INFO_URL@';
    50 $self->{facebook_redirect_uri} = '@FACEBOOK_REDIRECT_URL@';
    51 $self->{facebook_user_post_url} = '@FACEBOOK_USER_POST_URL@';
    52
    53 $self->{vk_app_id} = '@VK_APP_ID@';
    54 $self->{vk_app_secret} = '@VK_APP_SECRET@';
    55
    56 $self->{vk_authorize_url} = '@VK_AUTHORIZE_URL@' || 'http://api.vkontakte.ru/oauth/authorize';
    57 $self->{vk_access_token_url} = '@VK_ACCESS_TOKEN_URL@' || 'https://api.vkontakte.ru/oauth/access_token';
    58 $self->{vk_user_info_url} = '@VK_USER_INFO_URL@' || 'https://api.vkontakte.ru/method/getProfiles';
    59
    60 $self->{vk_redirect_uri} = '@VK_REDIRECT_URL@';
    61 $self->{vk_user_post_url} = '@VK_USER_POST_URL@';
    62
    63 $self->{connection_timeout} = '@CONNECTION_TIMEOUT@';
    64
    65 $self->_init_();
    66 $self;
    67 }
    68
    69 sub info {
    70 my $self = shift;
    71 return unless ref $self;
    72
    73 for (sort keys %{$self->{attributes}}) {
    74 my $la = length $_;
    75 warn "\t$_".("\t" x (2-int($la/8))).": $self->{$_}\n";
    76 }
    77 }
    78
    79 sub _init_ {
    80 my $self = shift;
    81
    82 # ������� ������������ �������
    83 $self->{attributes}->{$_} = 'SCALAR' for qw(
    84 db_type
    85 session_dir
    86 session_directory
    87 domain
    88 cookie
    89 expires
    90 storage
    91 lifetime
    92 checkout
    93 db_keepalive
    94 db_host
    95 db_port
    96 db_name
    97 db_user
    98 db_password
    99 data_directory images_directory binary_directory preview debug store_method cascade memcached_enable
    100 );
    101 }
    102
    103 sub AUTOLOAD {
    104 my $self = shift;
    105 my $attribute = $AUTOLOAD;
    106
    107 $attribute =~ s/.*:://;
    108 return unless $attribute =~ /[^A-Z]/; # ��������� ������ ���� DESTROY
    109
    110 if (!exists $self->{attributes}->{$attribute}) {
    111 warn "Contenido Error (session::State): ����� ������, ��� �������� �� ���������� ��������������� ��������: ->$attribute()\n";
    112 return;
    113 }
    114
    115 $self->{$attribute} = shift @_ if $#_>=0;
    116 $self->{$attribute};
    117 }
    118
    119 1;
  • koi8/plugins/session/sql/TOAST/session.sql

     
    1 CREATE TABLE sessions (
    2 id char(32) not null primary key,
    3 dtime timestamp not null default now(),
    4 a_session text
    5 );

Небольшая справка по веткам

cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.

koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.

utf8 – актуальная ветка, заточенная под UTF-8.

Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.