• FaceBook.pm

    242 243  
    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 }