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 – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.