Revision 240

Date:
2012/09/06 17:21:54
Author:
ahitrov
Revision Log:
Facebook config optimization
VKontakte addon
Files:

Legend:

 
Added
 
Removed
 
Modified
  • utf8/plugins/session/comps/www/oauth/facebook.html

     
    1 1 <script type="text/javascript">
    2 2 <!--
    3 opener.AuthOnEnd();
    3 opener.location.reload(true);
    4 4 close();
    5 5 //-->
    6 6 </script>
    7
    8 <pre><% Dumper($fb_connect) %></pre>
    7 %#<pre><% Dumper($fb_connect) %></pre>
    9 8 %#<a href="<% $auth_url->as_string %>"><% $auth_url->as_string %></a>
    10 <pre><% Dumper($session) %></pre>
    11
    9 %#<pre><% Dumper($session) %></pre>
    12 10 <%doc>
    13 11
    14 12 Manual redirect:
    15 13
    16 14 use session::AUTH::FaceBook;
    17 my $site = $state->development ? 'www22.zvuki.ru' : 'www.zvuki.ru';
    15 my $site = $state->development ? 'www' : 'www';
    18 16 my $fb_connect = session::AUTH::FaceBook->new(
    19 17 facebook_redirect_uri => 'http://'.$site.'/oauth/facebook.html',
    20 18 );
     
    33 31 if ( $code ) {
    34 32 my $local_session = $fb_connect->authenticate( code => $code, state => $state );
    35 33 if ( ref $local_session && exists $local_session->{id} ) {
    36 my $profile = $keeper->{users}->get_profile( id => $local_session->{id} );
    34 my $profile = $keeper->{users}->get_profile( id => $local_session->{id} ) if exists $keeper->{users};
    37 35 if ( ref $profile ) {
    38 36 unless ( exists $local_session->{avatar} ) {
    39 37 my $avatar = $profile->get_image('avatar');
  • utf8/plugins/session/comps/www/oauth/logoff.html

     
    1 <%args>
    2
    3 $back => 'referer'
    4
    5 </%args>
    6 <%init>
    7
    8 my $referer = $back eq 'referer' ? $r->header_in("Referer") : $back;
    9 $keeper->{session}->logoff;
    10 $m->redirect($referer);
    11
    12 </%init>
  • utf8/plugins/session/comps/www/oauth/vkontakte.html

     
    1 <script type="text/javascript">
    2 <!--
    3 opener.location.reload(true);
    4 close();
    5 //-->
    6 </script>
    7 <%doc>
    8 <pre><% Dumper($user_info) %></pre>
    9 </%doc>
    10 <%doc>
    11
    12 use LWP::UserAgent;
    13 use JSON::XS;
    14 use URI;
    15 use Encode;
    16 use URI;
    17 use URI::QueryParam;
    18 my $JSON = JSON::XS->new->utf8;
    19
    20 Manual redirect:
    21 use session::AUTH::FaceBook;
    22 my $site = $state->development ? 'www' : 'www';
    23 my $vk_connect = session::AUTH::VKontakte->new(
    24 vk_redirect_uri => 'http://'.$site.'/auth/vkontakte.html',
    25 );
    26
    27
    28 </%doc>
    29 <%once>
    30
    31 my $site = $state->development ? 'www22.zvuki.ru' : 'www.zvuki.ru';
    32
    33 </%once>
    34 <%args>
    35
    36 $code => undef
    37
    38 </%args>
    39 <%init>
    40
    41 my $res;
    42 my $info;
    43
    44 my $vk_connect = session::AUTH::VKontakte->new;
    45 my $auth_url = $vk_connect->authorize_url;
    46 if ( $code ) {
    47 my $local_session = $vk_connect->authenticate( code => $code );
    48 if ( ref $local_session && exists $local_session->{id} ) {
    49 my $profile = $keeper->{users}->get_profile( id => $local_session->{id} ) if exists $keeper->{users};
    50 if ( ref $profile ) {
    51 unless ( exists $local_session->{avatar} ) {
    52 my $avatar = $profile->get_image('avatar');
    53 $session->{avatar} = ref $avatar && exists $avatar->{filename} ? $avatar->{mini}{'54x54'}{filename} : undef;
    54 $keeper->{session}->store_value (
    55 name => $profile->name_full,
    56 last_name => $profile->name_family,
    57 first_name => $profile->name_part,
    58 avatar => $session->{avatar},
    59 );
    60 } else {
    61 $keeper->{session}->store_value (
    62 name => $profile->name_full,
    63 last_name => $profile->name_family,
    64 first_name => $profile->name_part,
    65 );
    66 }
    67 }
    68 }
    69 } elsif ( $auth_url ) {
    70 $m->redirect($auth_url->as_string);
    71 } else {
    72 &abort404 unless $DEBUG;
    73 }
    74
    75 </%init>
  • utf8/plugins/session/config.proto

     
    51 51 ######################################
    52 52 FACEBOOK_APP_ID =
    53 53 FACEBOOK_APP_SECRET =
    54 FACEBOOK_AUTHOTIZE_URL = https://www.facebook.com/dialog/oauth
    55 FACEBOOK_ACCESS_TOKEN_URL = https://graph.facebook.com/oauth/access_token
    56 FACEBOOK_USER_INFO_URL = https://graph.facebook.com/me
    57 54 FACEBOOK_REDIRECT_URL =
    58 55 FACEBOOK_USER_POST_URL =
    59 56
    60 REWRITE += FACEBOOK_APP_ID FACEBOOK_APP_SECRET FACEBOOK_REDIRECT_URL
    61 REWRITE += FACEBOOK_AUTHOTIZE_URL FACEBOOK_ACCESS_TOKEN_URL FACEBOOK_USER_INFO_URL
    57 REWRITE += FACEBOOK_APP_ID FACEBOOK_APP_SECRET FACEBOOK_REDIRECT_URL FACEBOOK_USER_POST_URL
    62 58
    59
    60 ### AUTH::VKontakte
    61 ######################################
    62 VK_APP_ID =
    63 VK_APP_SECRET =
    64 VK_REDIRECT_URL =
    65 VK_USER_POST_URL =
    66
    67 REWRITE += VK_APP_ID VK_APP_SECRET VK_REDIRECT_URL VK_USER_POST_URL
    68
    69
    63 70 CONNECTION_TIMEOUT = 3
    64 71
    65 72 PROJECT_REQUIRED += Crypt-SSLeay
  • utf8/plugins/session/lib/session/AUTH/FaceBook.pm

     
    42 42 sub new {
    43 43 my ($class, %config) = @_;
    44 44 my $self = bless {}, $class;
    45 for (qw(facebook_app_id facebook_app_secret facebook_authorize_url facebook_access_token_url facebook_user_info_url)) {
    45
    46 $self->{facebook_authorize_url} = 'https://www.facebook.com/dialog/oauth';
    47 $self->{facebook_access_token_url} = 'https://graph.facebook.com/oauth/access_token';
    48 $self->{facebook_user_info_url} = 'https://graph.facebook.com/me';
    49
    50 for (qw(facebook_app_id facebook_app_secret)) {
    46 51 $self->{$_} = $config{$_} || $state->{session}{$_} || return undef;
    47 52 }
    48 53 $self->{timeout} = $state->{session}{connection_timeout} || 3;
  • utf8/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
    40 $self->{vk_authorize_url} = 'http://oauth.vk.com/authorize';
    41 $self->{vk_access_token_url} = 'https://oauth.vk.com/access_token';
    42 $self->{vk_user_info_url} = 'https://api.vk.com/method/getProfiles';
    43
    44 for (qw( vk_app_id vk_app_secret )) {
    45 $self->{$_} = $config{$_} || $state->{session}->{$_} || return undef;
    46 }
    47 $self->{timeout} = $state->{session}->{connection_timeout} || 3;
    48 for (qw(vk_user_post_url vk_redirect_uri)) {
    49 $self->{$_} = $config{$_} || $state->{session}->{$_};
    50 }
    51 return $self;
    52 }
    53
    54 sub authorize_url {
    55 my $self = shift;
    56 my (%args) = @_;
    57 my $go = URI->new( $self->{vk_authorize_url} );
    58 $go->query_param( client_id => $self->{vk_app_id} );
    59 $go->query_param( scope => '' );
    60 $go->query_param( response_type => 'code' );
    61 $args{redirect_uri} ||= $self->{vk_redirect_uri};
    62 for ( keys %args ) {
    63 $go->query_param( $_ => $args{$_} );
    64 }
    65 $keeper->{session}->store_value( vk_redirect_url => $self->{vk_redirect_uri} );
    66 return $go;
    67 }
    68
    69 sub authenticate {
    70 my ( $self, %authinfo ) = @_;
    71 warn "VK.authenticate" if $DEBUG;
    72
    73 my $local_session = $session || $keeper->{session}->get_session;
    74 my $redirect_uri = $self->{vk_redirect_uri};
    75
    76 my $access_token = $local_session->{vk_access_token};
    77 my $vk_user_id = $local_session->{vk_user_id};
    78 my $expires = $local_session->{vk_expires};
    79 if ($access_token and $expires > time) {
    80 warn "Already have access_token" if $DEBUG;
    81 } else {
    82 undef $access_token;
    83 }
    84 my $code = $authinfo{'code'};
    85 unless ( $code ) {
    86 warn "Call to authenticate without code\n";
    87 return undef;
    88 }
    89 my $ua = LWP::UserAgent->new;
    90 $ua->timeout($self->{timeout});
    91
    92 unless ($access_token) {
    93 my $req = URI->new( $self->{vk_access_token_url});
    94 $req->query_param( client_id => $self->{vk_app_id} );
    95 $req->query_param( client_secret => $self->{vk_app_secret} );
    96 $req->query_param( code => $code );
    97 $req->query_param( redirect_uri => $redirect_uri );
    98 warn "Token request: [$req]\n";
    99 my $res = $ua->get($req);
    100 unless ($res->code == 200) {
    101 warn "VK: Access_token request failed: ".$res->status_line."\n";
    102 return undef;
    103 }
    104 my $info = $JSON->decode($res->content);
    105 unless ( ref $info eq 'HASH' && ($access_token = $info->{access_token}) ) {
    106 warn "No access token in response: ".$res->content."\n";
    107 return undef;
    108 }
    109 $keeper->{session}->store_value( vk_access_token => $access_token );
    110 $local_session->{vk_access_token} = $access_token;
    111 $keeper->{session}->store_value( vk_user_id => $info->{user_id} );
    112 $local_session->{vk_user_id} = $info->{user_id};
    113 if ( my $expires = $info->{expires_in} ) {
    114 $local_session->{vk_expires} = time + $expires;
    115 $keeper->{session}->store_value( vk_expires => $local_session->{vk_expires} );
    116 } else {
    117 #$c->user_session->{'expires'} = time + 3600*24;
    118 }
    119 warn "VK: requested access token";
    120 } else {
    121 warn "VK: have access token";
    122 }
    123
    124 my $req = URI->new( $self->{vk_user_info_url} );
    125 $req->query_param( uid => $local_session->{vk_user_id} );
    126 $req->query_param( fields => 'uid,first_name,last_name,nickname,domain,sex,bdate,city,country,timezone,photo,photo_medium,photo_big' );
    127 $req->query_param( access_token => $access_token );
    128
    129 warn "VK: Fetching user $req\n" if $DEBUG;
    130 my $res = $ua->get($req);
    131 unless ($res->code == 200) {
    132 warn "VK: user request failed: ".$res->status_line."\n";
    133 return undef;
    134 }
    135
    136 my $info;
    137 unless ( $info = eval { $JSON->decode($res->content) } ) {
    138 warn "user '".$res->content."' decode failed: $@\n";
    139 return undef;
    140 }
    141 warn Dumper($info) if $DEBUG;
    142 return undef unless exists $info->{response} && ref $info->{response} eq 'ARRAY' && @{$info->{response}};
    143 my $user_info = $info->{response}[0];
    144 foreach my $key ( qw(nickname last_name first_name) ) {
    145 $user_info->{$key} = Encode::encode('utf-8', $user_info->{$key});
    146 }
    147
    148 my @plugins = split (/[\ |\t]+/, $state->{plugins});
    149 my $name = $user_info->{first_name}.' '.$user_info->{last_name};
    150 if ( grep { $_ eq 'users' } @plugins ) {
    151 my $user = $keeper->{users}->get_profile( login => 'vkontakte:'.$user_info->{uid} );
    152 unless ( ref $user ) {
    153 my $user_class = $state->{users}->profile_document_class;
    154 $user = $user_class->new( $keeper );
    155 $user->login( 'vkontakte:'.$user_info->{uid} );
    156 $user->name( $user_info->{last_name}.', '.$user_info->{first_name} );
    157 $user->nickname( $user_info->{nickname} );
    158 $user->status( 1 );
    159 $user->type( 0 );
    160 $user->login_method('vkontakte');
    161 $user->country( $user_info->{country} );
    162 $user->email( undef );
    163
    164 my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
    165 if ( ref $prop_ava ) {
    166 my $avatar = $user->_store_image( $user_info->{photo_big}, attr => 'avatar' );
    167 local $Data::Dumper::Indent = 0;
    168 $user->avatar( Data::Dumper::Dumper($avatar) );
    169 }
    170
    171 $user->store;
    172 } else {
    173 my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
    174 if ( ref $prop_ava ) {
    175 my $avatar = $user->get_image( 'avatar' );
    176 unless ( ref $avatar && exists $avatar->{filename} ) {
    177 my $avatar = $user->_store_image( $user_info->{photo_big}, attr => 'avatar' );
    178 local $Data::Dumper::Indent = 0;
    179 $user->avatar( Data::Dumper::Dumper($avatar) );
    180 $user->store;
    181 }
    182 }
    183 }
    184 my %data = (
    185 id => $user->id,
    186 name => $name,
    187 login => $user->login,
    188 status => $user->status,
    189 type => $user->type,
    190 auth_by => 'vkontakte',
    191 ltime => time,
    192 );
    193 if ( $user_info->{photo} ) {
    194 $data{avatar} = $user_info->{photo};
    195 }
    196 $keeper->{session}->store_value ( %data );
    197 while ( my ( $key, $value ) = each %data ) {
    198 $local_session->{$key} = $value;
    199 }
    200
    201 } else {
    202 my %data = (
    203 id => $user_info->{uid},
    204 name => $name,
    205 nick => $user_info->{nickname} || $name,
    206 login => 'vkontakte:'.$user_info->{uid},
    207 status => 1,
    208 type => 0,
    209 auth_by => 'vkontakte',
    210 ltime => time,
    211 );
    212 if ( $user_info->{photo} ) {
    213 $data{avatar} = $user_info->{photo};
    214 }
    215 $keeper->{session}->store_value ( %data );
    216 while ( my ( $key, $value ) = each %data ) {
    217 $local_session->{$key} = $value;
    218 }
    219 }
    220 return $local_session;
    221 }
    222
    223 1;
  • utf8/plugins/session/lib/session/Init.pm

     
    6 6 use session::Apache;
    7 7 use session::Keeper;
    8 8 use session::AUTH::FaceBook;
    9 use session::AUTH::VKontakte;
    9 10
    10 11 # загрузка всех необходимых плагину классов
    11 12 # session::SQL::SomeTable
  • utf8/plugins/session/lib/session/Keeper.pm

     
    62 62 warn "LOGOFF: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
    63 63 _store_session_id ($session_id)
    64 64 } else {
    65 my @clear = qw( id email login name nick type status ltime );
    66 push @clear, @{ $opts{clear} } if exists $opts{clear} && ref $opts{clear} eq 'ARRAY' && @{ $opts{clear} };
    67 foreach my $key ( @clear ) {
    68 delete $session->{$key};
    69 }
    65 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 }
    70 78 }
    71 79 untie %$session;
    72 80 return 1;
  • utf8/plugins/session/lib/session/State.pm.proto

     
    42 42 $self->{memcached_enable} = '';
    43 43
    44 44 $self->{facebook_app_id} = '@FACEBOOK_APP_ID@';
    45 $self->{facebook_app_key} = '@FACEBOOK_APP_KEY@';
    46 45 $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 46 $self->{facebook_redirect_uri} = '@FACEBOOK_REDIRECT_URL@';
    51 47 $self->{facebook_user_post_url} = '@FACEBOOK_USER_POST_URL@';
    52 48
    49 $self->{vk_app_id} = '@VK_APP_ID@';
    50 $self->{vk_app_secret} = '@VK_APP_SECRET@';
    51 $self->{vk_redirect_uri} = '@VK_REDIRECT_URL@';
    52 $self->{vk_user_post_url} = '@VK_USER_POST_URL@';
    53
    53 54 $self->_init_();
    54 55 $self;
    55 56 }

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

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

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

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

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