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 }