chok / sfMelodyPlugin

Allow to communicate with many services(google, yahoo...) throw OAuth
MIT License
45 stars 21 forks source link

Example to get Gmail contacts #9

Open stylomylo opened 13 years ago

stylomylo commented 13 years ago

Hey there,

I have a fresh symfony 1.4.8 installed and installed the doctrine and melody plugins. I want to get the list of gmail contacts for a user that is logged in to my app.

My settings are: melody: google: key: xxx secret: xxx callback: @mymodule # or absolute url

  scope: contacts

  user:
    email_adress:
      call: me
      path: email
      key: true

this is in my template: echo link_to('Connect to Gmail', '@gmailConnect')

and this in the according action: public function executeConnect(sfWebRequest $request) { echo 'test'; $this->getUser()->connect('google'); }

public function executeGoogle(sfWebRequest $request) { $this->me = $this->getUser()->getMelody('google')->getMe(); }

When I click the link it redirects me to: https://www.google.com/accounts/OAuthAuthorizeToken?

and on the Google page it says: Invalid Token.

I am new to symfony and didn't completely understand the whole concept of this plugin and the necessary steps. Could please someone help my and provide an example or explain further?

Thanks a lot.

chok commented 13 years ago

Use api instead of scope with Google :

  key: xxx
  secret: xxx
  api: [contacts]
  callback: "@my_route"
  user:
    email_address:
      key: true
      call: contacts/me
      path: feed.id.$t

This is solve your problems ?

stylomylo commented 13 years ago

Thanks for the fast response, I actually tried different combination of parameters. Even now with the once you posted, same result. :(

chok commented 13 years ago

In dev, can you post the content of your log about OAuth ?

stylomylo commented 13 years ago

I am not sure how, when I click on the link on my symfony page it redirects to the google url I posted above, and there is of course no log button no more. Any instructions on that?

chok commented 13 years ago

in the dev environment by default all is logged. Just open the xxx_dev.log in the log folder of your symfony project ;-)

stylomylo commented 13 years ago

Ah thanks, there you go: Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfRoute "sf_guard_signin" (/guard/login) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfRoute "sf_guard_signout" (/guard/logout) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_filter" (/guard/users/filter.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_batch" (/guard/users/batch.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user" (/guard/users.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_new" (/guard/users/new.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_create" (/guard/users.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_edit" (/guard/users/:id/edit.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_update" (/guard/users/:id.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_delete" (/guard/users/:id.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_show" (/guard/users/:id.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_object" (/guard/users/:id/:action.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_user_collection" (/guard/users/:action/action.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_filter" (/guard/groups/filter.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_batch" (/guard/groups/batch.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group" (/guard/groups.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_new" (/guard/groups/new.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_create" (/guard/groups.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_edit" (/guard/groups/:id/edit.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_update" (/guard/groups/:id.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_delete" (/guard/groups/:id.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_show" (/guard/groups/:id.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_object" (/guard/groups/:id/:action.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_group_collection" (/guard/groups/:action/action.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_filter" (/guard/permissions/filter.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_batch" (/guard/permissions/batch.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission" (/guard/permissions.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_new" (/guard/permissions/new.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_create" (/guard/permissions.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_edit" (/guard/permissions/:id/edit.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_update" (/guard/permissions/:id.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_delete" (/guard/permissions/:id.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_show" (/guard/permissions/:id.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_object" (/guard/permissions/:id/:action.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_permission_collection" (/guard/permissions/:action/action.:sf_format) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfRoute "sf_guard_register" (/guard/register) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfRoute "sf_guard_forgot_password" (/guard/forgot_password) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Connect sfDoctrineRoute "sf_guard_forgot_password_change" (/guard/forgot_password/:unique_key) Sep 28 13:04:09 symfony [info] {sfPatternRouting} Match route "default" (/:module/:action/*) for /gmail/connect with parameters array ( 'module' => 'gmail', 'action' => 'connect',) Sep 28 13:04:09 symfony [info] {sfFilterChain} Executing filter "sfGuardRememberMeFilter" Sep 28 13:04:09 symfony [info] {sfFilterChain} Executing filter "sfRenderingFilter" Sep 28 13:04:09 symfony [info] {sfFilterChain} Executing filter "sfBasicSecurityFilter" Sep 28 13:04:09 symfony [info] {sfFilterChain} Executing filter "sfExecutionFilter" Sep 28 13:04:09 symfony [info] {gmailActions} Call "gmailActions->executeConnect()" Sep 28 13:04:09 symfony [info] {Doctrine_Connection_Mysql} exec : SET NAMES 'UTF8' - () Sep 28 13:04:09 symfony [info] {Doctrine_Connection_Statement} execute : SELECT s.id AS sid, s.first_name AS sfirst_name, s.last_name AS slast_name, s.email_address AS s__email_address, s.username AS susername, s.algorithm AS salgorithm, s.salt AS ssalt, s.password AS spassword, s.is_active AS s__is_active, s.is_super_admin AS sis_super_admin, s.last_login AS slast_login, s.created_at AS screated_at, s.updated_at AS supdated_at FROM sf_guard_user s WHERE (s.id = ?) LIMIT 1 - (3) Sep 28 13:04:09 symfony [info] {Doctrine_Connection_Statement} execute : SELECT t.id AS tid, t.name AS tname, t.token_key AS ttoken_key, t.token_secret AS ttoken_secret, t.user_id AS tuser_id, t.expire AS texpire, t.params AS tparams, t.identifier AS tidentifier, t.status AS tstatus, t.o_auth_version AS t__o_auth_version, t.created_at AS tcreated_at, t.updated_at AS tupdated_at FROM token t WHERE (t.user_id = ?) - (3) Sep 28 13:04:09 symfony [info] {Doctrine_Connection_Statement} execute : DELETE FROM token WHERE (name = ? AND user_id = ?) - (google, 3) Sep 28 13:04:09 symfony [err] {OAuth} access token failed - returns Array ( )

Sep 28 13:04:09 symfony [info] {sfFrontWebController} Redirect to "https://www.google.com/accounts/OAuthAuthorizeToken?" Sep 28 13:04:09 symfony [info] {sfWebResponse} Send status "HTTP/1.1 302 Found" Sep 28 13:04:09 symfony [info] {sfWebResponse} Send header "Location: https://www.google.com/accounts/OAuthAuthorizeToken?" Sep 28 13:04:09 symfony [info] {sfWebResponse} Send header "Content-Type: text/html; charset=utf-8" Sep 28 13:04:09 symfony [info] {sfWebDebugLogger} Configuration 1.60 ms (8) Sep 28 13:04:09 symfony [info] {sfWebDebugLogger} Factories 39.73 ms (1) Sep 28 13:04:09 symfony [info] {sfWebDebugLogger} Action "gmail/connect" 266.82 ms (1) Sep 28 13:04:09 symfony [info] {sfWebDebugLogger} Database (Doctrine) 0.01 ms (4) Sep 28 13:04:09 symfony [info] {sfWebResponse} Send content (123 o) Sep 28 13:04:09 symfony [warning] {sfWebDebugLogger} Warning at /_devroot/perforce-workspace/jobeet/lib/vendor/symfony/lib/exception/sfException.class.php on line 105 (Cannot modify header information - headers already sent by (output started at /_devroot/perforce-workspace/jobeet/lib/vendor/symfony/lib/response/sfResponse.class.php:105)) Sep 28 13:04:09 symfony [err] {sfRenderException} The template "connectSuccess.php" does not exist or is unreadable in "". Sep 28 13:04:09 symfony [warning] {sfWebDebugLogger} Warning at /_devroot/perforce-workspace/jobeet/lib/vendor/symfony/lib/exception/sfException.class.php on line 159 (Cannot modify header information - headers already sent by (output started at /_devroot/perforce-workspace/jobeet/lib/vendor/symfony/lib/response/sfResponse.class.php:105)) Sep 28 13:04:09 symfony [warning] {sfWebDebugLogger} Warning at /_devroot/perforce-workspace/jobeet/lib/vendor/symfony/lib/exception/sfException.class.php on line 159 (Cannot modify header information - headers already sent by (output started at /_devroot/perforce-workspace/jobeet/lib/vendor/symfony/lib/response/sfResponse.class.php:105)) Sep 28 13:04:09 symfony [info] {sfWebDebugLogger} Configuration 1.84 ms (9) Sep 28 13:04:09 symfony [info] {sfWebDebugLogger} Factories 39.73 ms (1) Sep 28 13:04:09 symfony [info] {sfWebDebugLogger} Action "gmail/connect" 534.22 ms (2) Sep 28 13:04:09 symfony [info] {sfWebDebugLogger} Database (Doctrine) 0.01 ms (4) Sep 28 13:04:09 symfony [info] {sfWebDebugLogger} View "Success" for "gmail/connect" 123.06 ms (1)

stylomylo commented 13 years ago

Any thoughts here?

chok commented 13 years ago

Sorry for the wait.

I have updated the sfDoctrineOAuthPlugin to have more log.

In fact, you dont receive a valid request so the redirection is not valid. (I have to work on this to manage not valid token).

You can do update sfDoctrineOAuth and put your logs here.

A little verification, php5-curl is installed on your system ?

stylomylo commented 13 years ago

I have MAMP installed, so it should come with curl. I unistalled the sfDoctrineOAuthPlugin and installed it again, but the log doesn't look different.\ Is there a better way to update a plugin?

chok commented 13 years ago

Sorry for the wait.

You have install the plugin from the comand line with symfony ?

In this case, you can upgrade your plugins. I've just released new versions.

If not, how you have installed it ?

stylomylo commented 13 years ago

Hey Chok, I found a way to get the email of my contacts now. I am using the oauth-php library. I had time pressure so I had to try different things. Thanks for your help anyways.

chok commented 13 years ago

You're welcome

JeJeJeRe commented 12 years ago

Hi, actually I have the same issue :

actions.class.php


public function executeConnect(sfWebRequest $request)
{
     $this->getUser()->connect('google');
}

app.yml


google:
  key: 10xxxxxx.apps.googleusercontent.com
  secret: mvTcbvSxxxxxxx
  callback: @connect_google_callback
  api: [contacts]

accounts.google.com/OAuthAuthorizeToken?


Invalid Token

frontend_dev.log


Oct 03 20:16:37 symfony [err] {OAuth} access token failed - google returns Array
"google" call url "https://www.google.com/accounts/OAuthAuthorizeToken" 
with params "array ('oauth_token' => NULL)"

furtheremore, the logs give me that ouptut:


1&oauth_timestamp=1317672997&oauth_version=1.0<\b>&scope=...

The oauth version is 1.0 , maybe this is the reason why it's not working ? I need to use OAuth 2.

Any idea ? Thanks !

chok commented 12 years ago

Hi

Can you give log about request token and authorize process ?

JeJeJeRe commented 12 years ago

Sure :


Oct 04 11:27:35 symfony [info] {OAuth} call https://www.google.com/accounts/OAuthGetRequestToken with params oauth_callback=http%3A%2F%2Flocalhost%2Ffrontend_dev.php%2Faccess%2Fgoogle&oauth_consumer_key=108xxxxxxxx14.apps.googleusercontent.com&oauth_nonce=a9018d1b2bd1xxxxxx5756da948&oauth_signature=Skeki%2B0jxxxxxxxPRsow%2BIkEkcCA%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1317727655&oauth_version=1.0&scope=http%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F | 
Oct 04 11:27:35 symfony [err] {OAuth} access token failed - google returns Array
(
)
chok commented 12 years ago

And the reply for request token ?

is that "acces token failed"(maybe a typo error) ?

I really have to manage error and check that deeper :-/

JeJeJeRe commented 12 years ago

There is nothing in the array :


{OAuth} access token failed - google returns Array
(
)

I was watching at the logs, I don't unserstand :

=> This Authorize part is OK


{OAuth} "facebook" call url "https://graph.facebook.com/oauth/authorize" with params "array (
  'scope' => 'email,user_about_me',
  'client_id' => '122367214xxxxx',
  'redirect_uri' => 'http://localhost/frontend_dev.php/access/facebook',
)"

=>Then, the Call seems OK, but there is an issue with the access token ...


{OAuth} call https://graph.facebook.com/oauth/access_token?
   client_id=122367xxxxxxx
   &client_secret=0309d5200f8c4426bxxxxxxxxxx
   &redirect_uri=http%3A%2F%2Flocalhost%2Ffrontend_dev.php%2Faccess%2Ffacebook
   &code=AQBO1uxws......
   with params .... (the same thing as above)
   | GET
Oct 04 13:12:38 symfony [err] {OAuth} access token failed - facebook returns Array
(
)

=>As a consequence, there are no params ..


{OAuth} call https://graph.facebook.com/me with params  | 
{OAuth} call https://graph.facebook.com/me with params  | 

=>... and some parameter are missing in the insert query :


{Doctrine_Connection_Statement} execute : INSERT INTO token (name, status, o_auth_version, user_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?) - (facebook, access, 2, 9, 2011-10-04 13:12:39, 2011-10-04 13:12:39)

I don't know what is wrong ...

I just put my app.yml again :


    facebook:
      key:  12236721xxxxxx
      secret: 0309d5200f8c4426xxxxxx
      callback: @melody_facebook
      scope:
        - email
        - user_about_me
      aliases:
        friends: me/friends
      user:
        email_address:
          call: me
          path: email
          key: true
        username:
          call: me
          path: id
          prefix: Facebook_
        first_name:
          call: me
          path: first_name
        last_name:
          call: me
          path: last_name
JeJeJeRe commented 12 years ago

I solved the issue by working with a real domain name (online), Seems like OAuth & Localhost doesn't get along.

chok commented 12 years ago

:o

ok thanks. by the way real manage of error is a big things to do do to unterstand in a second what's the problem.

Thanks.

JeJeJeRe commented 12 years ago

you're right. BTW, did you find a way to get the friends email list in Facebook API ? (https://developers.facebook.com/docs/reference/api/permissions/) Sounds like we can't ...

chok commented 12 years ago

Yes I think you can't. There is no permissions to retrieve theses informations.

I have searched a time ago and don't found solution :(

battika commented 12 years ago

Hello JeJeJeRe,

Regarding your issue with the empty array which automagically fixed itself when you moved the project to production environment. Let me take a wild guess here, your dev environment is Windows while the production one Linux. I have been experiencing the same issue for a week now, even created an issue on sfMelodyPluginDemo and finally managed to solve it: https://github.com/ElWardi/sfMelodyDemo/issues/1

The issue is related to the curl PHP library which does not have the cacerts file under Windows. More info can be found in the aforementioned thread. Hope it helps.