Revision 242
Date:
2012/09/13 17:48:36
Author:
ahitrov
Revision Log:
AUTH::Mailru
Files:
Legend:
Added
Removed
Modified
utf8/plugins/session/comps/www/oauth/facebook.html
4
4
close();
5
5
//-->
6
6
</script>
7
%#<pre><% Dumper($fb_connect) %></pre>
8
%#<a href="<% $auth_url->as_string %>"><% $auth_url->as_string %></a>
9
%#<pre><% Dumper($session) %></pre>
10
7
<%doc>
11
8
12
9
Manual redirect:
…
…
27
24
<%init>
28
25
29
26
my $fb_connect = session::AUTH::FaceBook->new();
30
my $auth_url = $fb_connect->fb_authorize_url( state => $state );
27
my $auth_url = $fb_connect->authorize_url( state => $state );
31
28
if ( $code ) {
32
29
my $local_session = $fb_connect->authenticate( code => $code, state => $state );
33
30
if ( ref $local_session && exists $local_session->{id} ) {
utf8/plugins/session/comps/www/oauth/mailru.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::Mailru;
22
my $site = $state->development ? 'www' : 'www';
23
my $mail_connect = session::AUTH::Mailru->new(
24
mail_redirect_uri => 'http://'.$site.'/auth/mailru.html',
25
);
26
27
28
</%doc>
29
<%once>
30
31
my $site = $state->development ? '' : '';
32
use session::AUTH::Mailru;
33
34
</%once>
35
<%args>
36
37
$code => undef
38
39
</%args>
40
<%init>
41
42
my $res;
43
my $info;
44
45
my $mail_connect = session::AUTH::Mailru->new;
46
my $auth_url = $mail_connect->authorize_url;
47
if ( $code ) {
48
my $local_session = $mail_connect->authenticate( code => $code );
49
if ( ref $local_session && exists $local_session->{id} ) {
50
my $profile = $keeper->{users}->get_profile( id => $local_session->{id} ) if exists $keeper->{users};
51
if ( ref $profile ) {
52
unless ( exists $local_session->{avatar} ) {
53
my $avatar = $profile->get_image('avatar');
54
$session->{avatar} = ref $avatar && exists $avatar->{filename} ? $avatar->{mini}{'54x54'}{filename} : undef;
55
$keeper->{session}->store_value (
56
name => $profile->name_full,
57
last_name => $profile->name_family,
58
first_name => $profile->name_part,
59
avatar => $session->{avatar},
60
);
61
} else {
62
$keeper->{session}->store_value (
63
name => $profile->name_full,
64
last_name => $profile->name_family,
65
first_name => $profile->name_part,
66
);
67
}
68
}
69
}
70
} elsif ( $auth_url ) {
71
$m->redirect($auth_url->as_string);
72
} else {
73
&abort404 unless $DEBUG;
74
}
75
76
</%init>
utf8/plugins/session/comps/www/oauth/vkontakte.html
18
18
my $JSON = JSON::XS->new->utf8;
19
19
20
20
Manual redirect:
21
use session::AUTH::FaceBook;
21
use session::AUTH::VKontakte;
22
22
my $site = $state->development ? 'www' : 'www';
23
23
my $vk_connect = session::AUTH::VKontakte->new(
24
24
vk_redirect_uri => 'http://'.$site.'/auth/vkontakte.html',
…
…
28
28
</%doc>
29
29
<%once>
30
30
31
my $site = $state->development ? 'www22.zvuki.ru' : 'www.zvuki.ru';
31
my $site = $state->development ? '' : '';
32
32
33
33
</%once>
34
34
<%args>
utf8/plugins/session/config.proto
67
67
REWRITE += VK_APP_ID VK_APP_SECRET VK_REDIRECT_URL VK_USER_POST_URL
68
68
69
69
70
### AUTH::Mailru
71
######################################
72
MAILRU_APP_ID =
73
MAILRU_APP_SECRET =
74
MAILRU_REDIRECT_URL =
75
MAILRU_USER_POST_URL =
76
77
REWRITE += MAILRU_APP_ID MAILRU_APP_SECRET MAILRU_REDIRECT_URL MAILRU_USER_POST_URL
78
79
70
80
CONNECTION_TIMEOUT = 3
71
81
72
82
PROJECT_REQUIRED += Crypt-SSLeay
utf8/plugins/session/lib/session/AUTH/FaceBook.pm
33
33
34
34
=for rem SCHEMA
35
35
36
$m->redirect ( $fb_connect->fb_authorize_url( redirect_uri => ... ) );
36
$m->redirect ( $fb_connect->authorize_url( facebook_redirect_uri => ... )->as_string );
37
37
38
38
39
39
=cut
…
…
57
57
return $self;
58
58
}
59
59
60
sub fb_authorize_url {
60
sub authorize_url {
61
61
my $self = shift;
62
62
my (%args) = @_;
63
63
my $go = URI->new( $self->{facebook_authorize_url} );
…
…
190
190
while ( my ( $key, $value ) = each %data ) {
191
191
$local_session->{$key} = $value;
192
192
}
193
} else {
194
my %data = (
195
id => $info->{id},
196
name => $name,
197
login => 'facebook:'.$info->{id},
198
status => 1,
199
type => 0,
200
auth_by => 'facebook',
201
ltime => time,
202
avatar => 'https://graph.facebook.com/'.$info->{username}.'/picture?type=large',
203
);
204
$keeper->{session}->store_value ( %data );
205
while ( my ( $key, $value ) = each %data ) {
206
$local_session->{$key} = $value;
207
}
193
208
}
194
209
return $local_session;
195
210
}
utf8/plugins/session/lib/session/AUTH/Mailru.pm
1
package session::AUTH::Mailru;
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 Digest::MD5 qw/ md5_hex /;
12
use Contenido::Globals;
13
14
use vars qw($VERSION);
15
$VERSION = '4.1';
16
17
=for rem
18
facebook:
19
auto_create_user: 1
20
app_id: 15 decimal digits
21
app_secret: 32 hex digits
22
authorize_url: https://connect.mail.ru/oauth/authorize
23
access_token_url: https://connect.mail.ru/oauth/token
24
user_info_url: https://graph.facebook.com/me
25
user_post_url: ~
26
state: is passed back to your app as a parameter of the redirect_uri when the user completed the authentication
27
store:
28
class: "+Comments::Authentication::Store"
29
type: facebook
30
31
=cut
32
33
our $JSON = JSON::XS->new->utf8;
34
35
=for rem SCHEMA
36
37
$m->redirect ( $fb_connect->authorize_url( redirect_uri => ... ) );
38
39
40
=cut
41
42
43
sub new {
44
my ($class, %config) = @_;
45
my $self = bless {}, $class;
46
47
$self->{mailru_authorize_url} = 'https://connect.mail.ru/oauth/authorize';
48
$self->{mailru_access_token_url} = 'https://connect.mail.ru/oauth/token';
49
$self->{mailru_user_info_url} = 'http://www.appsmail.ru/platform/api';
50
51
for (qw(mailru_app_id mailru_app_secret)) {
52
$self->{$_} = $config{$_} || $state->{session}{$_} || return undef;
53
}
54
$self->{timeout} = $state->{session}{connection_timeout} || 3;
55
for (qw(mailru_user_post_url mailru_redirect_uri)) {
56
$self->{$_} = $config{$_} || $state->{session}{$_};
57
}
58
return $self;
59
}
60
61
sub authorize_url {
62
my $self = shift;
63
my (%args) = @_;
64
my $go = URI->new( $self->{mailru_authorize_url} );
65
$go->query_param( client_id => $self->{mailru_app_id} );
66
$go->query_param( response_type => "code" );
67
$args{redirect_uri} ||= $self->{mailru_redirect_uri};
68
for ( keys %args ) {
69
$go->query_param( $_ => $args{$_} );
70
}
71
warn Dumper($go) if $DEBUG;
72
return $go;
73
}
74
75
sub authenticate {
76
my ( $self, %authinfo ) = @_;
77
warn "Mailru.authenticate" if $DEBUG;
78
79
my $local_session = $session || $keeper->{session}->get_session;
80
my $redirect_uri = $self->{mailru_redirect_uri};
81
82
my $access_token = $local_session->{mailru_access_token} || $local_session->{mailru_refresh_token};
83
my $expires = $local_session->{mailru_expires};
84
if ($access_token and $expires > time) {
85
warn "Already have access_token" if $DEBUG;
86
} else {
87
undef $access_token;
88
}
89
my $code = $authinfo{'code'};
90
unless ( $code ) {
91
warn "Call to authenticate without code";
92
return undef;
93
}
94
my $ua = LWP::UserAgent->new;
95
$ua->timeout($self->{timeout});
96
unless ($access_token) {
97
my $req = URI->new( $self->{mailru_access_token_url});
98
$req->query_param( client_id => $self->{mailru_app_id} );
99
$req->query_param( grant_type => 'authorization_code' );
100
$req->query_param( redirect_uri => $redirect_uri );
101
$req->query_param( client_secret=> $self->{mailru_app_secret} );
102
$req->query_param( code => $code);
103
warn "Post $req" if $DEBUG;
104
my $res = $ua->post($req);
105
unless ($res->code == 200) {
106
warn "access_token request failed: ".$res->status_line;
107
return undef;
108
}
109
my $info = $JSON->decode($res->content);
110
unless ( ref $info eq 'HASH' && ($access_token = $info->{access_token}) ) {
111
warn "No access token in response: ".$res->content."\n";
112
return undef;
113
}
114
$keeper->{session}->store_value(
115
mailru_access_token => $access_token,
116
mailru_refresh_token => $info->{refresh_token},
117
mailru_id => $info->{x_mailru_vid},
118
);
119
$local_session->{mailru_access_token} = $access_token;
120
$local_session->{mailru_refresh_token} = $info->{refresh_token};
121
$local_session->{mailru_id} = $info->{x_mailru_vid};
122
if( my $expires = $info->{expires_in} ) {
123
$local_session->{mailru_expires} = time + $expires;
124
$keeper->{session}->store_value( mailru_expires => $local_session->{mailru_expires} );
125
} else {
126
#$c->user_session->{'expires'} = time + 3600*24;
127
}
128
warn "Mailru: requested access token" if $DEBUG;
129
} else {
130
warn "Mailru: have access token" if $DEBUG;
131
}
132
133
my $req = URI->new( $self->{mailru_user_info_url} );
134
my %params = (
135
session_key => $access_token,
136
app_id => $self->{mailru_app_id},
137
method => 'users.getInfo',
138
uids => $local_session->{mailru_id},
139
secure => 1,
140
);
141
while ( my ($param, $value) = each %params ) {
142
$req->query_param( $param => $value );
143
}
144
warn "SIG String: [".join ( '', map { $_.'='.$params{$_} } sort keys %params) . $self->{mailru_app_secret}."]\n";
145
my $sig = md5_hex( join ( '', map { $_.'='.$params{$_} } sort keys %params) . $self->{mailru_app_secret} );
146
$req->query_param( sig => $sig );
147
148
warn "Fetching user $req" if $DEBUG;
149
my $res = $ua->get($req);
150
unless ($res->code == 200) {
151
warn "user request failed: ".$res->status_line;
152
return undef;
153
}
154
my $info;
155
unless ( $info = eval { $JSON->decode($res->content) } ) {
156
warn "user '".$res->content."' decode failed: $@";
157
return undef;
158
}
159
if ( ref $info eq 'ARRAY' && @$info ) {
160
$info = $info->[0];
161
} else {
162
warn "Mailru: non-natural user info responce ".Dumper($info)."\n";
163
return undef;
164
}
165
foreach my $key ( qw(nick last_name first_name) ) {
166
$info->{$key} = Encode::encode('utf-8', $info->{$key});
167
}
168
warn "Userhash = ".Dumper($info) if $DEBUG;
169
#warn "facebook: user=$info->{name} / $info->{id} / $info->{gender}";
170
171
$keeper->{session}->delete_key( 'mailru_redirect_url' );
172
delete $local_session->{mailru_redirect_url};
173
174
my @plugins = split (/[\ |\t]+/, $state->{plugins});
175
my $name = $info->{first_name}.' '.$info->{last_name};
176
if ( grep { $_ eq 'users' } @plugins ) {
177
my $user = $keeper->{users}->get_profile( email => $info->{email} ) if $info->{email};
178
$user ||= $keeper->{users}->get_profile( login => 'mailru:'.$info->{uid} );
179
unless ( ref $user ) {
180
my $user_class = $state->{users}->profile_document_class;
181
$user = $user_class->new( $keeper );
182
$user->login( $info->{email} || 'mailru:'.$info->{uid} );
183
$user->name( $name );
184
$user->nickname( $info->{nick} );
185
$user->status( 1 );
186
$user->type( 0 );
187
$user->login_method('mailru');
188
if ( $info->{location} ) {
189
$user->country( Encode::encode('utf-8', $info->{location}{country}{name}) );
190
}
191
if ( $info->{birthday} && $info->{birthday} =~ /(\d{2})\.(\d{2})\.(\d{4})/ ) {
192
$user->dtime( "$3-$2-$1" );
193
}
194
$user->email( $info->{email} || undef );
195
196
my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
197
if ( ref $prop_ava && $info->{pic_big} ) {
198
my $avatar = $user->_store_image( $info->{pic_big}, attr => 'avatar' );
199
$user->avatar( $user->_serialize($avatar) );
200
}
201
202
$user->store;
203
} else {
204
my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
205
if ( ref $prop_ava ) {
206
my $avatar = $user->get_image( 'avatar' );
207
if ( $info->{pic_big} && !(ref $avatar && exists $avatar->{filename}) ) {
208
my $avatar = $user->_store_image( $info->{pic_big}, attr => 'avatar' );
209
$user->avatar( $user->_serialize($avatar) );
210
$user->store;
211
}
212
}
213
}
214
my %data = (
215
id => $user->id,
216
name => $user->name,
217
nick => $user->nickname,
218
login => $user->login,
219
email => $user->email,
220
status => $user->status,
221
type => $user->type,
222
ltime => time,
223
avatar => $info->{pic},
224
);
225
$keeper->{session}->store_value ( %data );
226
while ( my ( $key, $value ) = each %data ) {
227
$local_session->{$key} = $value;
228
}
229
} else {
230
my %data = (
231
id => $info->{uid},
232
name => $name,
233
nick => $info->{nick} || $name,
234
email => $info->{email},
235
login => $info->{email} || 'mailru:'.$info->{uid},
236
status => 1,
237
type => 0,
238
auth_by => 'mailru',
239
ltime => time,
240
);
241
if ( $user->{pic} ) {
242
$data{avatar} = $info->{pic};
243
}
244
$keeper->{session}->store_value ( %data );
245
while ( my ( $key, $value ) = each %data ) {
246
$local_session->{$key} = $value;
247
}
248
}
249
return $local_session;
250
}
251
252
1;
utf8/plugins/session/lib/session/AUTH/VKontakte.pm
16
16
=for rem
17
17
vkontakte:
18
18
auto_create_user: 1
19
app_id: 122117614500563
20
app_secret: 656bd1369486b902e9bf831a9a08132b
19
app_id: decimal digits
20
app_secret: 32 hex digits
21
21
authorize_url: http://api.vkontakte.ru/oauth/authorize
22
22
access_token_url: https://api.vkontakte.ru/oauth/access_token
23
23
user_info_url: https://api.vkontakte.ru/method/getProfiles
…
…
28
28
29
29
=for rem SCHEMA
30
30
31
$m->redirect ( $fb_connect->fb_authorize_url( redirect_uri => ... ) );
31
$m->redirect ( $vk_connect->authorize_url( vk_redirect_uri => ... )->as_string );
32
32
33
33
34
34
=cut
…
…
95
95
$req->query_param( client_secret => $self->{vk_app_secret} );
96
96
$req->query_param( code => $code );
97
97
$req->query_param( redirect_uri => $redirect_uri );
98
warn "Token request: [$req]\n";
98
warn "Token request: [$req]\n" if $DEBUG;
99
99
my $res = $ua->get($req);
100
100
unless ($res->code == 200) {
101
101
warn "VK: Access_token request failed: ".$res->status_line."\n";
utf8/plugins/session/lib/session/Init.pm
7
7
use session::Keeper;
8
8
use session::AUTH::FaceBook;
9
9
use session::AUTH::VKontakte;
10
use session::AUTH::Mailru;
10
11
11
12
# загрузка всех необходимых плагину классов
12
13
# session::SQL::SomeTable
utf8/plugins/session/lib/session/State.pm.proto
51
51
$self->{vk_redirect_uri} = '@VK_REDIRECT_URL@';
52
52
$self->{vk_user_post_url} = '@VK_USER_POST_URL@';
53
53
54
$self->{mailru_app_id} = '@MAILRU_APP_ID@';
55
$self->{mailru_app_secret} = '@MAILRU_APP_SECRET@';
56
$self->{mailru_redirect_uri} = '@MAILRU_REDIRECT_URL@';
57
$self->{mailru_user_post_url} = '@MAILRU_USER_POST_URL@';
58
54
59
$self->_init_();
55
60
$self;
56
61
}
Небольшая справка по веткам
cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8 – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.