Revision 243
Date:
2012/09/13 18:29:46
Author:
ahitrov
Revision Log:
oAuth: Facebook, Vkontakte, Mail.ru
Files:
Legend:
Added
Removed
Modified
koi8/plugins/session/comps/www/oauth/facebook.html
1
<script type="text/javascript">
2
<!--
3
opener.location.reload(true);
4
close();
5
//-->
6
</script>
7
<%doc>
8
9
Manual redirect:
10
11
use session::AUTH::FaceBook;
12
my $site = $state->development ? 'www' : 'www';
13
my $fb_connect = session::AUTH::FaceBook->new(
14
facebook_redirect_uri => 'http://'.$site.'/oauth/facebook.html',
15
);
16
17
</%doc>
18
<%args>
19
20
$code => undef
21
$state => undef
22
23
</%args>
24
<%init>
25
26
my $fb_connect = session::AUTH::FaceBook->new();
27
my $auth_url = $fb_connect->authorize_url( state => $state );
28
if ( $code ) {
29
my $local_session = $fb_connect->authenticate( code => $code, state => $state );
30
if ( ref $local_session && exists $local_session->{id} ) {
31
my $profile = $keeper->{users}->get_profile( id => $local_session->{id} ) if exists $keeper->{users};
32
if ( ref $profile ) {
33
unless ( exists $local_session->{avatar} ) {
34
my $avatar = $profile->get_image('avatar');
35
$session->{avatar} = ref $avatar && exists $avatar->{filename} ? $avatar->{mini}{'54x54'}{filename} : undef;
36
$keeper->{session}->store_value (
37
name => $profile->name_full,
38
last_name => $profile->name_family,
39
first_name => $profile->name_part,
40
avatar => $session->{avatar},
41
);
42
} else {
43
$keeper->{session}->store_value (
44
name => $profile->name_full,
45
last_name => $profile->name_family,
46
first_name => $profile->name_part,
47
);
48
}
49
}
50
}
51
} elsif ( $auth_url ) {
52
$m->redirect($auth_url->as_string);
53
} else {
54
&abort404 unless $DEBUG;
55
}
56
57
</%init>
koi8/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>
koi8/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>
koi8/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::VKontakte;
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 ? '' : '';
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>
koi8/plugins/session/config.proto
1
#############################################################################
2
#
3
# ��������� ������� ������� ���������� ������� �������� � config.mk �������
4
# � �������� � ������������ � ������������ �������
5
#
6
#############################################################################
1
7
8
PLUGINS += session
9
PROJECT_REQUIRED += Apache-Session
10
PROJECT_REQUIRED += JSON-XS
11
PROJECT_REQUIRED += P-WebFetcher
2
12
13
### �������������� ��������, default = lsid
14
SESSION_COOKIE_NAME = lsid
15
REWRITE += SESSION_COOKIE_NAME
16
17
ifeq (${DEVELOPMENT}, YES)
18
19
SESSION_DOMAIN =
20
SESSION_STORAGE = POSTGRES
21
SESSION_LIFETIME = 24
22
SESSION_EXPIRES = +10d
23
24
else
25
26
SESSION_DOMAIN =
27
SESSION_STORAGE = POSTGRES
28
SESSION_LIFETIME = 24
29
SESSION_EXPIRES = +10d
30
31
endif
32
33
REWRITE += SESSION_STORAGE SESSION_DOMAIN SESSION_LIFETIME SESSION_EXPIRES
34
35
########################################################################
36
#
37
# SESSION_DOMAIN
38
# �����, �� ������� �������� ������. ����� �� ���������
39
# SESSION_STORAGE
40
# ��������� ��� �������� ������. ��������: POSTGRES � FILE
41
# SESSION_LIFETIME
42
# ����� ����� ������ �� �����������. �������� � �����, ������������
43
# ��� ��������� � crontab ������� ������� �� services
44
# SESSION_EXPIRES
45
# ����� ����� ���� ������. �������� � ������� Apache
46
#
47
########################################################################
48
49
3
50
### AUTH::FaceBook
4
51
######################################
5
52
FACEBOOK_APP_ID =
6
FACEBOOK_APP_KEY =
7
53
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
54
FACEBOOK_REDIRECT_URL =
12
55
FACEBOOK_USER_POST_URL =
13
56
14
REWRITE += FACEBOOK_AUTHORIZE_URL FACEBOOK_ACCESS_TOKEN_URL FACEBOOK_USER_INFO_URL
57
REWRITE += FACEBOOK_APP_ID FACEBOOK_APP_SECRET FACEBOOK_REDIRECT_URL FACEBOOK_USER_POST_URL
15
58
59
16
60
### AUTH::VKontakte
17
61
######################################
18
62
VK_APP_ID =
19
63
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
64
VK_REDIRECT_URL =
24
65
VK_USER_POST_URL =
25
66
26
REWRITE += VK_APP_ID VK_APP_SECRET
27
REWRITE += VK_AUTHORIZE_URL VK_ACCESS_TOKEN_URL
67
REWRITE += VK_APP_ID VK_APP_SECRET VK_REDIRECT_URL VK_USER_POST_URL
28
68
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
29
80
CONNECTION_TIMEOUT = 3
30
81
82
PROJECT_REQUIRED += Crypt-SSLeay
31
83
PROJECT_REQUIRED += JSON-XS
32
PROJECT_REQUIRED += Crypt-SSLeay
koi8/plugins/session/lib/session/AUTH/FaceBook.pm
16
16
=for rem
17
17
facebook:
18
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
19
app_id: 15 decimal digits
20
app_secret: 32 hex digits
21
authorize_url: https://www.facebook.com/dialog/oauth
23
22
access_token_url: https://graph.facebook.com/oauth/access_token
24
23
user_info_url: https://graph.facebook.com/me
25
24
user_post_url: ~
25
state: is passed back to your app as a parameter of the redirect_uri when the user completed the authentication
26
26
store:
27
27
class: "+Comments::Authentication::Store"
28
28
type: facebook
…
…
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
…
…
42
42
sub new {
43
43
my ($class, %config) = @_;
44
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;
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)) {
51
$self->{$_} = $config{$_} || $state->{session}{$_} || return undef;
47
52
}
48
$self->{timeout} = $state->{session}->{connection_timeout} || 3;
53
$self->{timeout} = $state->{session}{connection_timeout} || 3;
49
54
for (qw(facebook_user_post_url facebook_redirect_uri)) {
50
$self->{$_} = $config{$_} || $state->{session}->{$_};
55
$self->{$_} = $config{$_} || $state->{session}{$_};
51
56
}
52
57
return $self;
53
58
}
54
59
55
sub fb_authorize_url {
60
sub authorize_url {
56
61
my $self = shift;
57
62
my (%args) = @_;
58
63
my $go = URI->new( $self->{facebook_authorize_url} );
59
warn Dumper($go);
60
$go->query_param( client_id => $self->{facebook_app_key} );
64
$go->query_param( client_id => $self->{facebook_app_id} );
65
$go->query_param( state => $args{state} ) if $args{state};
61
66
$go->query_param( scope => "publish_stream" );
62
67
$args{redirect_uri} ||= $self->{facebook_redirect_uri};
63
68
for ( keys %args ) {
64
69
$go->query_param( $_ => $args{$_} );
65
70
}
66
$keeper->{session}->store_value( facebook_redirect_url => $self->{facebook_redirect_uri} );
71
warn Dumper($go) if $DEBUG;
67
72
return $go;
68
73
}
69
74
…
…
71
76
my ( $self, %authinfo ) = @_;
72
77
warn "FB.authenticate" if $DEBUG;
73
78
# TODO: we need callback url
74
#warn "user_session=".dumper( $c->user_session )." ";
75
79
my $local_session = $session || $keeper->{session}->get_session;
76
my $redirect_uri = $local_session->{facebook_redirect_url};
80
my $redirect_uri = $self->{facebook_redirect_uri};
77
81
78
82
my $access_token = $local_session->{facebook_access_token};
79
83
my $expires = $local_session->{facebook_expires};
…
…
95
99
$req->query_param( redirect_uri => $redirect_uri );
96
100
$req->query_param( client_secret=> $self->{facebook_app_secret} );
97
101
$req->query_param( code => $code);
98
warn "Get $req";
102
warn "Get $req" if $DEBUG;
99
103
my $res = $ua->get($req);
100
104
unless ($res->code == 200) {
101
105
warn "access_token request failed: ".$res->status_line;
102
106
return undef;
103
107
}
104
108
my %res = eval { URI->new("?".$res->content)->query_form };
105
warn Dumper(\%res);
109
warn Dumper(\%res) if $DEBUG;
106
110
unless ($access_token = $res{access_token}) {
107
111
warn "No access token in response: ".$res->content;
108
112
return undef;
…
…
115
119
} else {
116
120
#$c->user_session->{'expires'} = time + 3600*24;
117
121
}
118
warn "FB: requested access token";
122
warn "FB: requested access token" if $DEBUG;
119
123
} else {
120
warn "FB: have access token";
124
warn "FB: have access token" if $DEBUG;
121
125
}
122
126
123
127
my $req = URI->new( $self->{facebook_user_info_url} );
124
128
$req->query_param( access_token => $access_token );
125
129
126
warn "Fetching user $req";
130
warn "Fetching user $req" if $DEBUG;
127
131
my $res = $ua->get($req);
128
132
unless ($res->code == 200) {
129
133
warn "user request failed: ".$res->status_line;
…
…
134
138
warn "user '".$res->content."' decode failed: $@";
135
139
return undef;
136
140
}
137
warn "Userhash = ".Dumper($info);
141
warn "Userhash = ".Dumper($info) if $DEBUG;
138
142
#warn "facebook: user=$info->{name} / $info->{id} / $info->{gender}";
139
143
144
$keeper->{session}->delete_key( 'facebook_redirect_url' );
145
delete $local_session->{facebook_redirect_url};
146
140
147
my @plugins = split (/[\ |\t]+/, $state->{plugins});
148
my $name = Encode::encode('utf-8', $info->{name});
149
Encode::from_to( $name, 'utf-8', 'koi8-r' );
141
150
if ( grep { $_ eq 'users' } @plugins ) {
142
151
my $user = $keeper->{users}->get_profile( login => 'facebook:'.$info->{id} );
143
152
unless ( ref $user ) {
144
153
my $user_class = $state->{users}->profile_document_class;
145
154
$user = $user_class->new( $keeper );
146
155
$user->login( 'facebook:'.$info->{id} );
147
my $name = Encode::encode('utf-8', $info->{name});
148
Encode::from_to( $name, 'utf-8', 'koi8-r' );
149
156
$user->name( $name );
150
157
$user->status( 1 );
151
158
$user->type( 0 );
…
…
186
193
while ( my ( $key, $value ) = each %data ) {
187
194
$local_session->{$key} = $value;
188
195
}
196
} else {
197
my %data = (
198
id => $info->{id},
199
name => $name,
200
login => 'facebook:'.$info->{id},
201
status => 1,
202
type => 0,
203
auth_by => 'facebook',
204
ltime => time,
205
avatar => 'https://graph.facebook.com/'.$info->{username}.'/picture?type=large',
206
);
207
$keeper->{session}->store_value ( %data );
208
while ( my ( $key, $value ) = each %data ) {
209
$local_session->{$key} = $value;
210
}
189
211
}
190
212
return $local_session;
191
213
}
koi8/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( mailru_redirect_uri => ... )->as_string );
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
Encode::from_to( $info->{$key}, 'utf-8', 'koi8-r' );
168
}
169
warn "Userhash = ".Dumper($info) if $DEBUG;
170
#warn "facebook: user=$info->{name} / $info->{id} / $info->{gender}";
171
172
$keeper->{session}->delete_key( 'mailru_redirect_url' );
173
delete $local_session->{mailru_redirect_url};
174
175
my @plugins = split (/[\ |\t]+/, $state->{plugins});
176
my $name = $info->{first_name}.' '.$info->{last_name};
177
if ( grep { $_ eq 'users' } @plugins ) {
178
my $user = $keeper->{users}->get_profile( email => $info->{email} ) if $info->{email};
179
$user ||= $keeper->{users}->get_profile( login => 'mailru:'.$info->{uid} );
180
unless ( ref $user ) {
181
my $user_class = $state->{users}->profile_document_class;
182
$user = $user_class->new( $keeper );
183
$user->login( $info->{email} || 'mailru:'.$info->{uid} );
184
$user->name( $name );
185
$user->nickname( $info->{nick} );
186
$user->status( 1 );
187
$user->type( 0 );
188
$user->login_method('mailru');
189
if ( $info->{location} ) {
190
my $country = Encode::encode('utf-8', $info->{location}{country}{name});
191
Encode::from_to( $country, 'utf-8', 'koi8-r' );
192
$user->country( $country );
193
}
194
if ( $info->{birthday} && $info->{birthday} =~ /(\d{2})\.(\d{2})\.(\d{4})/ ) {
195
$user->dtime( "$3-$2-$1" );
196
}
197
$user->email( $info->{email} || undef );
198
199
my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
200
if ( ref $prop_ava && $info->{pic_big} ) {
201
my $avatar = $user->_store_image( $info->{pic_big}, attr => 'avatar' );
202
$user->avatar( $user->_serialize($avatar) );
203
}
204
205
$user->store;
206
} else {
207
my ($prop_ava) = grep { $_->{attr} eq 'avatar' && $_->{type} eq 'image' } $user->structure;
208
if ( ref $prop_ava ) {
209
my $avatar = $user->get_image( 'avatar' );
210
if ( $info->{pic_big} && !(ref $avatar && exists $avatar->{filename}) ) {
211
my $avatar = $user->_store_image( $info->{pic_big}, attr => 'avatar' );
212
$user->avatar( $user->_serialize($avatar) );
213
$user->store;
214
}
215
}
216
}
217
my %data = (
218
id => $user->id,
219
name => $user->name,
220
nick => $user->nickname,
221
login => $user->login,
222
email => $user->email,
223
status => $user->status,
224
type => $user->type,
225
ltime => time,
226
avatar => $info->{pic},
227
);
228
$keeper->{session}->store_value ( %data );
229
while ( my ( $key, $value ) = each %data ) {
230
$local_session->{$key} = $value;
231
}
232
} else {
233
my %data = (
234
id => $info->{uid},
235
name => $name,
236
nick => $info->{nick} || $name,
237
email => $info->{email},
238
login => $info->{email} || 'mailru:'.$info->{uid},
239
status => 1,
240
type => 0,
241
auth_by => 'mailru',
242
ltime => time,
243
);
244
if ( $user->{pic} ) {
245
$data{avatar} = $info->{pic};
246
}
247
$keeper->{session}->store_value ( %data );
248
while ( my ( $key, $value ) = each %data ) {
249
$local_session->{$key} = $value;
250
}
251
}
252
return $local_session;
253
}
254
255
1;
koi8/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
…
…
36
36
sub new {
37
37
my ($class, %config) = @_;
38
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)) {
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 )) {
40
45
$self->{$_} = $config{$_} || $state->{session}->{$_} || return undef;
41
46
}
42
47
$self->{timeout} = $state->{session}->{connection_timeout} || 3;
…
…
64
69
sub authenticate {
65
70
my ( $self, %authinfo ) = @_;
66
71
warn "VK.authenticate" if $DEBUG;
67
# TODO: we need callback url
68
#warn "user_session=".dumper( $c->user_session )." ";
69
72
70
73
my $local_session = $session || $keeper->{session}->get_session;
71
my $redirect_uri = $local_session->{vk_redirect_url};
74
my $redirect_uri = $self->{vk_redirect_uri};
72
75
73
76
my $access_token = $local_session->{vk_access_token};
74
77
my $vk_user_id = $local_session->{vk_user_id};
…
…
91
94
$req->query_param( client_id => $self->{vk_app_id} );
92
95
$req->query_param( client_secret => $self->{vk_app_secret} );
93
96
$req->query_param( code => $code );
97
$req->query_param( redirect_uri => $redirect_uri );
98
warn "Token request: [$req]\n" if $DEBUG;
94
99
my $res = $ua->get($req);
95
100
unless ($res->code == 200) {
96
101
warn "VK: Access_token request failed: ".$res->status_line."\n";
koi8/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
koi8/plugins/session/lib/session/Keeper.pm
51
51
52
52
sub logoff {
53
53
my $self = shift;
54
my %opts = @_;
55
54
56
my $sid = _get_session_id ();
55
57
my $session = _get_session_object ( $sid );
56
58
return unless ref $session;
…
…
60
62
warn "LOGOFF: New or deprecated session. Old sid = '$sid', new sid = '$session_id'" if $DEBUG;
61
63
_store_session_id ($session_id)
62
64
} 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
}
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
}
68
78
}
69
79
untie %$session;
70
80
return 1;
koi8/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
53
49
$self->{vk_app_id} = '@VK_APP_ID@';
54
50
$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
51
$self->{vk_redirect_uri} = '@VK_REDIRECT_URL@';
61
52
$self->{vk_user_post_url} = '@VK_USER_POST_URL@';
62
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
63
59
$self->{connection_timeout} = '@CONNECTION_TIMEOUT@';
64
60
65
61
$self->_init_();
Небольшая справка по веткам
cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8 – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.