Subversion Repositories oidplus

Rev

Rev 1200 | Rev 1305 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
  6.  *
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *     http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  */
  19.  
  20. use ViaThinkSoft\OIDplus\OIDplus;
  21. use ViaThinkSoft\OIDplus\OIDplusGui;
  22. use ViaThinkSoft\OIDplus\OIDplusException;
  23. use ViaThinkSoft\OIDplus\OIDplusRA;
  24.  
  25. # More information about the OAuth2 implementation:
  26. # - https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow
  27. # - https://developers.facebook.com/tools/explorer/
  28.  
  29. require_once __DIR__ . '/../../../../includes/oidplus.inc.php';
  30.  
  31. set_exception_handler(array(OIDplusGui::class, 'html_exception_handler'));
  32.  
  33. OIDplus::init(true);
  34.  
  35. if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_ViaThinkSoft\OIDplus\OIDplusPagePublicLoginFacebook', false)) {
  36.         throw new OIDplusException(_L('This plugin was disabled by the system administrator!'));
  37. }
  38.  
  39. if (!OIDplus::baseConfig()->getValue('FACEBOOK_OAUTH2_ENABLED', false)) {
  40.         throw new OIDplusException(_L('Facebook OAuth authentication is disabled on this system.'));
  41. }
  42.  
  43. _CheckParamExists($_GET, 'code');
  44. _CheckParamExists($_GET, 'state');
  45. _CheckParamExists($_COOKIE, 'csrf_token_weak');
  46.  
  47. if ($_GET['state'] != $_COOKIE['csrf_token_weak']) {
  48.         die(_L('Missing or wrong CSRF Token'));
  49. }
  50.  
  51. // Get access token
  52.  
  53. $cont = url_post_contents(
  54.         "https://graph.facebook.com/v8.0/oauth/access_token?".
  55.                 "client_id=".urlencode(OIDplus::baseConfig()->getValue('FACEBOOK_OAUTH2_CLIENT_ID'))."&".
  56.                 "redirect_uri=".urlencode(OIDplus::webpath(__DIR__,OIDplus::PATH_ABSOLUTE_CANONICAL).'oauth.php')."&".
  57.                 "client_secret=".urlencode(OIDplus::baseConfig()->getValue('FACEBOOK_OAUTH2_CLIENT_SECRET'))."&".
  58.                 "code=".$_GET['code']
  59. );
  60.  
  61. if ($cont === false) {
  62.         throw new OIDplusException(_L('Communication with %1 server failed', 'Facebook'));
  63. }
  64.  
  65. $data = json_decode($cont,true);
  66. if (isset($data['error'])) {
  67.         echo '<h2>Error at step 2</h2>';
  68.         echo '<p>'.$data['error']['message'].'</p>';
  69.         die();
  70. }
  71. $access_token = $data['access_token'];
  72.  
  73. // Get user infos
  74.  
  75. $cont = url_post_contents(
  76.         "https://graph.facebook.com/v8.0/me?".
  77.                 "fields=id,email,name&".
  78.                 "access_token=".urlencode($access_token)
  79. );
  80.  
  81. if ($cont === false) {
  82.         throw new OIDplusException(_L('Communication with %1 server failed', 'Facebook'));
  83. }
  84.  
  85. $data = json_decode($cont,true);
  86. if (isset($data['error'])) {
  87.         throw new OIDplusException(_L('Error receiving the authentication token from %1: %2','Facebook',$data['error']['message']));
  88. }
  89. $personal_name = $data['name'];
  90. $email = !isset($data['email']) ? '' : $data['email'];
  91. if (empty($email)) {
  92.         throw new OIDplusException(_L('Your Facebook account does not have an email address.'));
  93. }
  94.  
  95. // Everything's done! Now login and/or create account
  96.  
  97. $ra = new OIDplusRA($email);
  98. if (!$ra->existing()) {
  99.         $ra->register_ra(null); // create a user account without password
  100.  
  101.         OIDplus::db()->query("update ###ra set ra_name = ?, personal_name = ? where email = ?", array($personal_name, $personal_name, $email));
  102.  
  103.         OIDplus::logger()->log("V2:[INFO]RA(%1)", "RA '%1' was created because of successful Facebook OAuth2 login", $email);
  104. }
  105.  
  106. OIDplus::authUtils()->raLoginEx($email, $remember_me=false, 'Facebook-OAuth2');
  107.  
  108. OIDplus::db()->query("UPDATE ###ra set last_login = ".OIDplus::db()->sqlDate()." where email = ?", array($email));
  109.  
  110. // Go back to OIDplus
  111.  
  112. OIDplus::invoke_shutdown();
  113.  
  114. header('Location:'.OIDplus::webpath(null,OIDplus::PATH_ABSOLUTE_CANONICAL));
  115.