facebook.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. /**
  3. * Facebook service definition for Keyring. Clean implementation of OAuth2
  4. */
  5. class Keyring_Service_Facebook extends Keyring_Service_OAuth2 {
  6. const NAME = 'facebook';
  7. const LABEL = 'Facebook';
  8. function __construct() {
  9. parent::__construct();
  10. // Enable "basic" UI for entering key/secret
  11. if ( ! KEYRING__HEADLESS_MODE ) {
  12. add_action( 'keyring_facebook_manage_ui', array( $this, 'basic_ui' ) );
  13. add_filter( 'keyring_facebook_basic_ui_intro', array( $this, 'basic_ui_intro' ) );
  14. }
  15. $this->set_endpoint( 'authorize', 'https://www.facebook.com/dialog/oauth', 'GET' );
  16. $this->set_endpoint( 'access_token', 'https://graph.facebook.com/oauth/access_token', 'GET' );
  17. $this->set_endpoint( 'self', 'https://graph.facebook.com/me', 'GET' );
  18. $creds = $this->get_credentials();
  19. $this->app_id = $creds['app_id'];
  20. $this->key = $creds['key'];
  21. $this->secret = $creds['secret'];
  22. $kr_nonce = wp_create_nonce( 'keyring-verify' );
  23. $nonce = wp_create_nonce( 'keyring-verify-facebook' );
  24. $this->redirect_uri = Keyring_Util::admin_url( self::NAME, array( 'action' => 'verify', 'kr_nonce' => $kr_nonce, 'nonce' => $nonce, ) );
  25. $this->requires_token( true );
  26. add_filter( 'keyring_facebook_request_token_params', array( $this, 'filter_request_token' ) );
  27. }
  28. function basic_ui_intro() {
  29. echo '<p>' . __( "If you haven't already, you'll need to set up an app on Facebook:", 'keyring' ) . '</p>';
  30. echo '<ol>';
  31. echo '<li>' . __( "Click <strong>+ Create New App</strong> at the top-right of <a href='https://developers.facebook.com/apps'>this page</a>", 'keyring' ) . '</li>';
  32. echo '<li>' . __( "Enter a name for your app (maybe the name of your website?) and click <strong>Continue</strong> (ignore the other settings)", 'keyring' ) . '</li>';
  33. echo '<li>' . __( "Enter whatever is in the CAPTCHA and click <strong>Continue</strong>", 'keyring' ) . '</li>';
  34. echo '<li>' . sprintf( __( "Put your domain name in the <strong>App Domains</strong> box. That value is probably <code>%s</code>", 'keyring' ), $_SERVER['HTTP_HOST'] ) . '</li>';
  35. echo '<li>' . sprintf( __( "Click the <strong>Website with Facebook Login</strong> box and enter the URL to your website, which is probably <code>%s</code>", 'keyring' ), get_bloginfo( 'url' ) ) . '</li>';
  36. echo '<li>' . __( "Click <strong>Save Changes</strong>", 'keyring' ) . '</li>';
  37. echo '</ol>';
  38. echo '<p>' . __( "Once you're done configuring your app, copy and paste your <strong>App ID</strong> and <strong>App Secret</strong> (in the top section of your app's Basic details) into the appropriate fields below. Leave the App Key field blank.", 'keyring' ) . '</p>';
  39. }
  40. function _get_credentials() {
  41. if (
  42. defined( 'KEYRING__FACEBOOK_ID' )
  43. &&
  44. defined( 'KEYRING__FACEBOOK_SECRET' )
  45. ) {
  46. return array(
  47. 'app_id' => constant( 'KEYRING__FACEBOOK_ID' ),
  48. 'key' => constant( 'KEYRING__FACEBOOK_ID' ),
  49. 'secret' => constant( 'KEYRING__FACEBOOK_SECRET' ),
  50. );
  51. } else {
  52. $all = apply_filters( 'keyring_credentials', get_option( 'keyring_credentials' ) );
  53. if ( !empty( $all['facebook'] ) ) {
  54. $creds = $all['facebook'];
  55. $creds['key'] = $creds['app_id'];
  56. return $creds;
  57. }
  58. // Return null to allow fall-thru to checking generic constants + DB
  59. return null;
  60. }
  61. }
  62. function is_configured() {
  63. $credentials = $this->get_credentials();
  64. return !empty( $credentials['app_id'] ) && !empty( $credentials['secret'] );
  65. }
  66. /**
  67. * Add scope to the outbound URL, and allow developers to modify it
  68. * @param array $params Core request parameters
  69. * @return Array containing originals, plus the scope parameter
  70. */
  71. function filter_request_token( $params ) {
  72. if ( $scope = implode( ',', apply_filters( 'keyring_facebook_scope', array() ) ) )
  73. $params['scope'] = $scope;
  74. return $params;
  75. }
  76. /**
  77. * Facebook decided to make things interesting and mix OAuth1 and 2. They return
  78. * their access tokens using query string encoding, so we handle that here.
  79. */
  80. function parse_access_token( $token ) {
  81. parse_str( $token, $token );
  82. return $token;
  83. }
  84. function build_token_meta( $token ) {
  85. $this->set_token(
  86. new Keyring_Access_Token(
  87. $this->get_name(),
  88. $token['access_token'],
  89. array()
  90. )
  91. );
  92. $response = $this->request( $this->self_url, array( 'method' => $this->self_method ) );
  93. if ( Keyring_Util::is_error( $response ) ) {
  94. $meta = array();
  95. } else {
  96. $meta = array(
  97. 'username' => $response->username,
  98. 'user_id' => $response->id,
  99. 'name' => $response->name,
  100. 'picture' => "https://graph.facebook.com/{$response->id}/picture?type=large",
  101. );
  102. }
  103. return apply_filters( 'keyring_access_token_meta', $meta, 'facebook', $token, $response, $this );
  104. }
  105. function get_display( Keyring_Access_Token $token ) {
  106. return $token->get_meta( 'name' );
  107. }
  108. function test_connection() {
  109. $res = $this->request( $this->self_url, array( 'method' => $this->self_method ) );
  110. if ( !Keyring_Util::is_error( $res ) )
  111. return true;
  112. return $res;
  113. }
  114. }
  115. add_action( 'keyring_load_services', array( 'Keyring_Service_Facebook', 'init' ) );