5.3 버전 내용 적용
@ -3,6 +3,7 @@
|
||||
/* COMMON */
|
||||
body,#smart_editor2,#smart_editor2 p,#smart_editor2 h1,#smart_editor2 h2,#smart_editor2 h3,#smart_editor2 h4,#smart_editor2 h5,#smart_editor2 h6,#smart_editor2 ul,#smart_editor2 ol,#smart_editor2 li,#smart_editor2 dl,#smart_editor2 dt,#smart_editor2 dd,#smart_editor2 table,#smart_editor2 th,#smart_editor2 td,#smart_editor2 form,#smart_editor2 fieldset,#smart_editor2 legend,#smart_editor2 input,#smart_editor2 textarea,#smart_editor2 button,#smart_editor2 select{margin:0;padding:0}
|
||||
#smart_editor2,#smart_editor2 h1,#smart_editor2 h2,#smart_editor2 h3,#smart_editor2 h4,#smart_editor2 h5,#smart_editor2 h6,#smart_editor2 input,#smart_editor2 textarea,#smart_editor2 select,#smart_editor2 table,#smart_editor2 button{font-family:'돋움',Dotum,Helvetica,sans-serif;font-size:12px;color:#666}
|
||||
#smart_editor2{background:#fff}
|
||||
#smart_editor2 span,#smart_editor2 em{font-size:12px}
|
||||
#smart_editor2 em,#smart_editor2 address{font-style:normal}
|
||||
#smart_editor2 img,#smart_editor2 fieldset{border:0}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
|
||||
|
||||
add_stylesheet('<link type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/base/jquery-ui.css" rel="stylesheet" />', 0);
|
||||
add_stylesheet('<link type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/base/jquery-ui.css" rel="stylesheet" />', 0);
|
||||
add_stylesheet('<link type="text/css" href="'.G5_PLUGIN_URL.'/jquery-ui/style.css">', 0);
|
||||
?>
|
||||
|
||||
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.min.js"></script>
|
||||
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
|
||||
<script>
|
||||
jQuery(function($){
|
||||
$.datepicker.regional["ko"] = {
|
||||
|
||||
@ -248,9 +248,9 @@ function captcha_html($class="captcha")
|
||||
if (is_mobile()) $html .= '<audio id="captcha_audio" controls></audio>';
|
||||
//$html .= "\n".'<img src="#" alt="" id="captcha_img">';
|
||||
$html .= "\n".'<img src="'.G5_CAPTCHA_URL.'/img/dot.gif" alt="" id="captcha_img">';
|
||||
$html .= '<input type="text" name="captcha_key" id="captcha_key" required class="captcha_box required" size="6" maxlength="6">';
|
||||
if (!is_mobile()) $html .= "\n".'<button type="button" id="captcha_mp3"><span></span>숫자음성듣기</button>';
|
||||
$html .= "\n".'<button type="button" id="captcha_reload"><span></span>새로고침</button>';
|
||||
$html .= '<input type="text" name="captcha_key" id="captcha_key" required class="captcha_box required" size="6" maxlength="6">';
|
||||
$html .= "\n".'<span id="captcha_info">자동등록방지 숫자를 순서대로 입력하세요.</span>';
|
||||
$html .= "\n".'</fieldset>';
|
||||
return $html;
|
||||
|
||||
3
plugin/recaptcha/_common.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include_once('../../common.php');
|
||||
?>
|
||||
4
plugin/recaptcha/captcha.lib.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
require_once(dirname(__FILE__).'/recaptcha.class.php');
|
||||
require_once(dirname(__FILE__).'/recaptcha.user.lib.php');
|
||||
?>
|
||||
147
plugin/recaptcha/recaptcha.class.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* @copyright Copyright (c) 2015, Google Inc.
|
||||
* @link http://www.google.com/recaptcha
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'ReCaptchaResponse_v' ) ){
|
||||
class ReCaptchaResponse_v
|
||||
{
|
||||
public $success;
|
||||
public $errorCodes;
|
||||
}
|
||||
}
|
||||
|
||||
class ReCaptcha_GNU
|
||||
{
|
||||
/**
|
||||
* Version of this client library.
|
||||
* @const string
|
||||
*/
|
||||
const VERSION = 'php_1.1.2';
|
||||
|
||||
private static $_signupUrl = 'https://www.google.com/recaptcha/admin';
|
||||
private static $_siteVerifyUrl = 'https://www.google.com/recaptcha/api/siteverify';
|
||||
|
||||
/**
|
||||
* Shared secret for the site.
|
||||
* @var string
|
||||
*/
|
||||
private $secret;
|
||||
|
||||
/**
|
||||
* Create a configured instance to use the reCAPTCHA service.
|
||||
*
|
||||
* @param string $secret shared secret between site and reCAPTCHA server.
|
||||
* @param RequestMethod $requestMethod method used to send the request. Defaults to POST.
|
||||
* @throws \RuntimeException if $secret is invalid
|
||||
*/
|
||||
public function __construct($secret)
|
||||
{
|
||||
if (empty($secret)) {
|
||||
throw new Exception('No secret provided');
|
||||
}
|
||||
|
||||
if (!is_string($secret)) {
|
||||
throw new Exception('The provided secret must be a string');
|
||||
}
|
||||
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
public function get_content($url, $data=array()) {
|
||||
|
||||
$curlsession = curl_init();
|
||||
curl_setopt ($curlsession, CURLOPT_URL, $url);
|
||||
curl_setopt ($curlsession, CURLOPT_POST, 1);
|
||||
curl_setopt ($curlsession, CURLOPT_POSTFIELDS, http_build_query($data, '', '&'));
|
||||
curl_setopt ($curlsession, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
|
||||
curl_setopt ($curlsession, CURLINFO_HEADER_OUT, false);
|
||||
curl_setopt ($curlsession, CURLOPT_HEADER, false);
|
||||
curl_setopt ($curlsession, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt ($curlsession, CURLOPT_SSL_VERIFYPEER, 1);
|
||||
curl_setopt ($curlsession, CURLOPT_TIMEOUT, 3);
|
||||
|
||||
$response = curl_exec($curlsession);
|
||||
$cinfo = curl_getinfo($curlsession);
|
||||
curl_close($curlsession);
|
||||
|
||||
if ($cinfo['http_code'] != 200){
|
||||
return '';
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits an HTTP GET to a reCAPTCHA server.
|
||||
*
|
||||
* @param string $path url path to recaptcha server.
|
||||
* @param array $data array of parameters to be sent.
|
||||
*
|
||||
* @return array response
|
||||
*/
|
||||
private function submit($url, $data)
|
||||
{
|
||||
$response = $this->get_content($url, $data);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the reCAPTCHA siteverify API to verify whether the user passes
|
||||
* CAPTCHA test.
|
||||
*
|
||||
* @param string $remoteIp IP address of end user.
|
||||
* @param string $response response string from recaptcha verification.
|
||||
*
|
||||
* @return ReCaptchaResponse_v
|
||||
*/
|
||||
public function verify($response, $remoteIp = null)
|
||||
{
|
||||
// Discard empty solution submissions
|
||||
if ($response == null || strlen($response) == 0) {
|
||||
$recaptchaResponse = new ReCaptchaResponse_v();
|
||||
$recaptchaResponse->success = false;
|
||||
$recaptchaResponse->errorCodes = 'missing-input';
|
||||
return $recaptchaResponse;
|
||||
}
|
||||
$getResponse = $this->submit(
|
||||
self::$_siteVerifyUrl,
|
||||
array (
|
||||
'secret' => $this->secret,
|
||||
'remoteip' => $remoteIp,
|
||||
'version' => self::VERSION,
|
||||
'response' => $response
|
||||
)
|
||||
);
|
||||
$answers = $getResponse ? json_decode($getResponse, true) : array();
|
||||
$recaptchaResponse = new ReCaptchaResponse_v();
|
||||
if (isset($answers['success']) && $answers['success'] == true) {
|
||||
$recaptchaResponse->success = true;
|
||||
} else {
|
||||
$recaptchaResponse->success = false;
|
||||
$recaptchaResponse->errorCodes = isset($answers['error-codes']) ? $answers['error-codes'] : 'http_error';
|
||||
}
|
||||
return $recaptchaResponse;
|
||||
}
|
||||
}
|
||||
?>
|
||||
9
plugin/recaptcha/recaptcha.js
Normal file
@ -0,0 +1,9 @@
|
||||
function chk_captcha()
|
||||
{
|
||||
if ( ! jQuery('#g-recaptcha-response').val()) {
|
||||
alert("자동등록방지를 반드시 체크해 주세요.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
51
plugin/recaptcha/recaptcha.user.lib.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
|
||||
|
||||
// 캡챠 HTML 코드 출력
|
||||
function captcha_html($class="captcha")
|
||||
{
|
||||
|
||||
global $config;
|
||||
|
||||
/*
|
||||
#hl=ko 표시는 언어지정가능
|
||||
*/
|
||||
$html = '<fieldset id="captcha" class="captcha recaptcha">';
|
||||
$html .= '<script src="https://www.google.com/recaptcha/api.js?hl=ko"></script>';
|
||||
$html .= '<script src="'.G5_CAPTCHA_URL.'/recaptcha.js"></script>';
|
||||
$html .= '<div class="g-recaptcha" data-sitekey="'.$config['cf_recaptcha_site_key'].'"></div>';
|
||||
$html .= '</fieldset>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
// 캡챠 사용시 자바스크립트에서 입력된 캡챠를 검사함
|
||||
function chk_captcha_js()
|
||||
{
|
||||
return "if (!chk_captcha()) return false;\n";
|
||||
}
|
||||
|
||||
function chk_captcha(){
|
||||
|
||||
global $config;
|
||||
|
||||
$resp = null;
|
||||
|
||||
if ( isset($_POST["g-recaptcha-response"]) && !empty($_POST["g-recaptcha-response"]) ) {
|
||||
|
||||
$reCaptcha = new ReCaptcha_GNU( $config['cf_recaptcha_secret_key'] );
|
||||
|
||||
$resp = $reCaptcha->verify($_POST["g-recaptcha-response"], $_SERVER["REMOTE_ADDR"]);
|
||||
}
|
||||
|
||||
if( ! $resp ){
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($resp != null && $resp->success) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
?>
|
||||
3
plugin/recaptcha_inv/_common.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include_once('../../common.php');
|
||||
?>
|
||||
4
plugin/recaptcha_inv/captcha.lib.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
require_once(dirname(__FILE__).'/recaptcha.class.php');
|
||||
require_once(dirname(__FILE__).'/recaptcha.user.lib.php');
|
||||
?>
|
||||
147
plugin/recaptcha_inv/recaptcha.class.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* @copyright Copyright (c) 2015, Google Inc.
|
||||
* @link http://www.google.com/recaptcha
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'ReCaptchaResponse_v' ) ){
|
||||
class ReCaptchaResponse_v
|
||||
{
|
||||
public $success;
|
||||
public $errorCodes;
|
||||
}
|
||||
}
|
||||
|
||||
class ReCaptcha_GNU
|
||||
{
|
||||
/**
|
||||
* Version of this client library.
|
||||
* @const string
|
||||
*/
|
||||
const VERSION = 'php_1.1.2';
|
||||
|
||||
private static $_signupUrl = 'https://www.google.com/recaptcha/admin';
|
||||
private static $_siteVerifyUrl = 'https://www.google.com/recaptcha/api/siteverify';
|
||||
|
||||
/**
|
||||
* Shared secret for the site.
|
||||
* @var string
|
||||
*/
|
||||
private $secret;
|
||||
|
||||
/**
|
||||
* Create a configured instance to use the reCAPTCHA service.
|
||||
*
|
||||
* @param string $secret shared secret between site and reCAPTCHA server.
|
||||
* @param RequestMethod $requestMethod method used to send the request. Defaults to POST.
|
||||
* @throws \RuntimeException if $secret is invalid
|
||||
*/
|
||||
public function __construct($secret)
|
||||
{
|
||||
if (empty($secret)) {
|
||||
throw new Exception('No secret provided');
|
||||
}
|
||||
|
||||
if (!is_string($secret)) {
|
||||
throw new Exception('The provided secret must be a string');
|
||||
}
|
||||
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
public function get_content($url, $data=array()) {
|
||||
|
||||
$curlsession = curl_init();
|
||||
curl_setopt ($curlsession, CURLOPT_URL, $url);
|
||||
curl_setopt ($curlsession, CURLOPT_POST, 1);
|
||||
curl_setopt ($curlsession, CURLOPT_POSTFIELDS, http_build_query($data, '', '&'));
|
||||
curl_setopt ($curlsession, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
|
||||
curl_setopt ($curlsession, CURLINFO_HEADER_OUT, false);
|
||||
curl_setopt ($curlsession, CURLOPT_HEADER, false);
|
||||
curl_setopt ($curlsession, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt ($curlsession, CURLOPT_SSL_VERIFYPEER, 1);
|
||||
curl_setopt ($curlsession, CURLOPT_TIMEOUT, 3);
|
||||
|
||||
$response = curl_exec($curlsession);
|
||||
$cinfo = curl_getinfo($curlsession);
|
||||
curl_close($curlsession);
|
||||
|
||||
if ($cinfo['http_code'] != 200){
|
||||
return '';
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits an HTTP GET to a reCAPTCHA server.
|
||||
*
|
||||
* @param string $path url path to recaptcha server.
|
||||
* @param array $data array of parameters to be sent.
|
||||
*
|
||||
* @return array response
|
||||
*/
|
||||
private function submit($url, $data)
|
||||
{
|
||||
$response = $this->get_content($url, $data);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the reCAPTCHA siteverify API to verify whether the user passes
|
||||
* CAPTCHA test.
|
||||
*
|
||||
* @param string $remoteIp IP address of end user.
|
||||
* @param string $response response string from recaptcha verification.
|
||||
*
|
||||
* @return ReCaptchaResponse_v
|
||||
*/
|
||||
public function verify($response, $remoteIp = null)
|
||||
{
|
||||
// Discard empty solution submissions
|
||||
if ($response == null || strlen($response) == 0) {
|
||||
$recaptchaResponse = new ReCaptchaResponse_v();
|
||||
$recaptchaResponse->success = false;
|
||||
$recaptchaResponse->errorCodes = 'missing-input';
|
||||
return $recaptchaResponse;
|
||||
}
|
||||
$getResponse = $this->submit(
|
||||
self::$_siteVerifyUrl,
|
||||
array (
|
||||
'secret' => $this->secret,
|
||||
'remoteip' => $remoteIp,
|
||||
'version' => self::VERSION,
|
||||
'response' => $response
|
||||
)
|
||||
);
|
||||
$answers = $getResponse ? json_decode($getResponse, true) : array();
|
||||
$recaptchaResponse = new ReCaptchaResponse_v();
|
||||
if (isset($answers['success']) && $answers['success'] == true) {
|
||||
$recaptchaResponse->success = true;
|
||||
} else {
|
||||
$recaptchaResponse->success = false;
|
||||
$recaptchaResponse->errorCodes = isset($answers['error-codes']) ? $answers['error-codes'] : 'http_error';
|
||||
}
|
||||
return $recaptchaResponse;
|
||||
}
|
||||
}
|
||||
?>
|
||||
20
plugin/recaptcha_inv/recaptcha.js
Normal file
@ -0,0 +1,20 @@
|
||||
function chk_captcha()
|
||||
{
|
||||
if ( ! jQuery('#g-recaptcha-response').val()) {
|
||||
grecaptcha.execute();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function recaptcha_validate(token) {
|
||||
var $form = jQuery("#g-recaptcha-response").closest("form"),
|
||||
form_id = $form.attr("id");
|
||||
|
||||
|
||||
if( $form.length ){
|
||||
$form.submit();
|
||||
}
|
||||
|
||||
}
|
||||
52
plugin/recaptcha_inv/recaptcha.user.lib.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
|
||||
|
||||
// 캡챠 HTML 코드 출력
|
||||
function captcha_html($class="captcha")
|
||||
{
|
||||
|
||||
global $config;
|
||||
|
||||
/*
|
||||
#hl=ko 표시는 언어지정가능
|
||||
*/
|
||||
$html = '<fieldset id="captcha" class="captcha invisible_recaptcha">';
|
||||
$html .= '<script src="https://www.google.com/recaptcha/api.js?hl=ko"></script>';
|
||||
$html .= '<script src="'.G5_CAPTCHA_URL.'/recaptcha.js"></script>';
|
||||
$html .= '<div id="recaptcha" class="g-recaptcha" data-sitekey="' . $config['cf_recaptcha_site_key'] . '" data-callback="recaptcha_validate" data-badge="inline" data-size="invisible"></div>';
|
||||
$html .= '<script>jQuery("#recaptcha").hide().parent(".invisible_recaptcha").hide().closest(".is_captcha_use").hide();</script>';
|
||||
$html .= '</fieldset>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
// 캡챠 사용시 자바스크립트에서 입력된 캡챠를 검사함
|
||||
function chk_captcha_js()
|
||||
{
|
||||
return "if (!chk_captcha()) return false;\n";
|
||||
}
|
||||
|
||||
function chk_captcha(){
|
||||
|
||||
global $config;
|
||||
|
||||
$resp = null;
|
||||
|
||||
if ( isset($_POST["g-recaptcha-response"]) && !empty($_POST["g-recaptcha-response"]) ) {
|
||||
|
||||
$reCaptcha = new ReCaptcha_GNU( $config['cf_recaptcha_secret_key'] );
|
||||
|
||||
$resp = $reCaptcha->verify($_POST["g-recaptcha-response"], $_SERVER["REMOTE_ADDR"]);
|
||||
}
|
||||
|
||||
if( ! $resp ){
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($resp != null && $resp->success) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
?>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 3.3 KiB |
@ -30,12 +30,15 @@ $gplus_url = $sns_send.'&sns=gplus';
|
||||
Kakao.init("<?php echo $config['cf_kakao_js_apikey']; ?>");
|
||||
</script>
|
||||
<?php } ?>
|
||||
<div class="bo_v_snswr">
|
||||
<button type="button" class="btn btn_b03 btn_share"><i class="fa fa-share-alt" aria-hidden="true"></i> SNS공유</button>
|
||||
|
||||
<ul id="bo_v_sns">
|
||||
<li><a href="<?php echo $facebook_url; ?>" target="_blank"><img src="<?php echo G5_SNS_URL; ?>/icon/facebook.png" alt="페이스북으로 보내기"></a></li>
|
||||
<li><a href="<?php echo $twitter_url; ?>" target="_blank"><img src="<?php echo G5_SNS_URL; ?>/icon/twitter.png" alt="트위터로 보내기"></a></li>
|
||||
<li><a href="<?php echo $gplus_url; ?>" target="_blank"><img src="<?php echo G5_SNS_URL; ?>/icon/gplus.png" alt="구글플러스로 보내기"></a></li>
|
||||
<li><a href="<?php echo $twitter_url; ?>" target="_blank" class="sns_t"><img src="<?php echo G5_SNS_URL; ?>/icon/twitter.png" alt="트위터로 보내기" width="20"></a></li>
|
||||
<li><a href="<?php echo $facebook_url; ?>" target="_blank" class="sns_f"><img src="<?php echo G5_SNS_URL; ?>/icon/facebook.png" alt="페이스북으로 보내기" width="20"></a></li>
|
||||
<li><a href="<?php echo $gplus_url; ?>" target="_blank" class="sns_g"><img src="<?php echo G5_SNS_URL; ?>/icon/gplus.png" alt="구글플러스로 보내기" width="20"></a></li>
|
||||
<?php if(G5_IS_MOBILE && $config['cf_kakao_js_apikey']) { ?>
|
||||
<li><a href="javascript:kakaolink_send('<?php echo $sns_msg; ?>', '<?php echo urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); ?>');"><img src="<?php echo G5_SNS_URL; ?>/icon/kakaotalk.png" alt="카카오톡으로 보내기"></a></li>
|
||||
<li><a href="javascript:kakaolink_send('<?php echo $sns_msg; ?>', '<?php echo urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); ?>');" class="sns_k" ><img src="<?php echo G5_SNS_URL; ?>/icon/kakaotalk.png" alt="카카오톡으로 보내기" width="20"></a></li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
include_once('./_common.php');
|
||||
|
||||
if (!$board['bo_use_sns']) die('');
|
||||
if (!$board['bo_use_sns']) return;
|
||||
?>
|
||||
|
||||
<ul id="bo_vc_sns">
|
||||
@ -30,17 +30,16 @@ if ($config['cf_facebook_appid']) {
|
||||
}
|
||||
}
|
||||
|
||||
echo '<li>';
|
||||
echo '<li class="sns_li_f '.($facebook_user?'':'sns_li_off').'">';
|
||||
if ($facebook_user) {
|
||||
echo '<img src="'.G5_SNS_URL.'/icon/facebook.png" id="facebook_icon">';
|
||||
echo '<label for="" class="sound_only">페이스북 동시 등록</label>';
|
||||
echo '<input type="checkbox" name="facebook_checked" id="facebook_checked" '.(get_cookie('ck_facebook_checked')?'checked':'').' value="1">';
|
||||
} else {
|
||||
$facebook_url = $facebook->getLoginUrl(array("redirect_uri"=>G5_SNS_URL."/facebook/callback.php", "scope"=>"publish_stream,read_stream,offline_access", "display"=>"popup"));
|
||||
|
||||
echo '<a href="'.$facebook_url.'" id="facebook_url" onclick="return false;"><img src="'.G5_SNS_URL.'/icon/facebook'.($facebook_user?'':'_off').'.png" id="facebook_icon"></a>';
|
||||
echo '<label for="" class="sound_only">페이스북 동시 등록</label>';
|
||||
echo '<input type="checkbox" name="facebook_checked" id="facebook_checked" disabled value="1">';
|
||||
echo '<a href="'.$facebook_url.'" id="facebook_url" onclick="return false;"><img src="'.G5_SNS_URL.'/icon/facebook.png" id="facebook_icon" width="20"></a>';
|
||||
echo '<label for="" class="sound_only">페이스북 동시 등록</label>';
|
||||
echo '<script>$(function(){ $(document).on("click", "#facebook_url", function(){ window.open(this.href, "facebook_url", "width=600,height=250"); }); });</script>';
|
||||
}
|
||||
echo '</li>';
|
||||
@ -90,15 +89,15 @@ if ($config['cf_twitter_key']) {
|
||||
}
|
||||
}
|
||||
|
||||
echo '<li>';
|
||||
echo '<li class="sns_li_t '.($twitter_user?'':'sns_li_off').'">';
|
||||
if ($twitter_user) {
|
||||
echo '<img src="'.G5_SNS_URL.'/icon/twitter.png" id="twitter_icon">';
|
||||
echo '<label for="" class="sound_only">트위터 동시 등록</label>';
|
||||
echo '<input type="checkbox" name="twitter_checked" id="twitter_checked" '.(get_cookie('ck_twitter_checked')?'checked':'').' value="1">';
|
||||
} else {
|
||||
echo '<a href="'.$twitter_url.'" id="twitter_url" onclick="return false;"><img src="'.G5_SNS_URL.'/icon/twitter'.($twitter_user?'':'_off').'.png" id="twitter_icon"></a>';
|
||||
echo '<label for="" class="sound_only">트위터 동시 등록</label>';
|
||||
echo '<input type="checkbox" name="twitter_checked" id="twitter_checked" disabled value="1">';
|
||||
echo '<a href="'.$twitter_url.'" id="twitter_url" onclick="return false;" "><img src="'.G5_SNS_URL.'/icon/twitter.png" id="twitter_icon" width="20"></a>';
|
||||
echo '<script>$(function(){ $(document).on("click", "#twitter_url", function(){ window.open(this.href, "twitter_url", "width=600,height=250"); }); });</script>';
|
||||
}
|
||||
echo '</li>';
|
||||
|
||||
414
plugin/social/Hybrid/Auth.php
Normal file
@ -0,0 +1,414 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Auth class
|
||||
*
|
||||
* Hybrid_Auth class provide a simple way to authenticate users via OpenID and OAuth.
|
||||
*
|
||||
* Generally, Hybrid_Auth is the only class you should instanciate and use throughout your application.
|
||||
*/
|
||||
class Hybrid_Auth {
|
||||
|
||||
public static $version = "2.9.6";
|
||||
|
||||
/**
|
||||
* Configuration array
|
||||
* @var array
|
||||
*/
|
||||
public static $config = array();
|
||||
|
||||
/**
|
||||
* Auth cache
|
||||
* @var Hybrid_Storage
|
||||
*/
|
||||
public static $store = null;
|
||||
|
||||
/**
|
||||
* Error pool
|
||||
* @var Hybrid_Error
|
||||
*/
|
||||
public static $error = null;
|
||||
|
||||
/**
|
||||
* Logger
|
||||
* @var Hybrid_Logger
|
||||
*/
|
||||
public static $logger = null;
|
||||
|
||||
/**
|
||||
* Try to start a new session of none then initialize Hybrid_Auth
|
||||
*
|
||||
* Hybrid_Auth constructor will require either a valid config array or
|
||||
* a path for a configuration file as parameter. To know more please
|
||||
* refer to the Configuration section:
|
||||
* http://hybridauth.sourceforge.net/userguide/Configuration.html
|
||||
*
|
||||
* @param array $config Configuration array or path to a configratuion file
|
||||
*/
|
||||
function __construct($config) {
|
||||
Hybrid_Auth::initialize($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to initialize Hybrid_Auth with given $config hash or file
|
||||
*
|
||||
* @param array $config Configuration array or path to a configratuion file
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function initialize($config) {
|
||||
if (!is_array($config) && !file_exists($config)) {
|
||||
throw new Exception("Hybriauth config does not exist on the given path.", 1);
|
||||
}
|
||||
|
||||
if (!is_array($config)) {
|
||||
$config = include $config;
|
||||
}
|
||||
|
||||
// build some need'd paths
|
||||
$config["path_base"] = realpath(dirname(__FILE__)) . "/";
|
||||
$config["path_libraries"] = $config["path_base"] . "thirdparty/";
|
||||
$config["path_resources"] = $config["path_base"] . "resources/";
|
||||
$config["path_providers"] = $config["path_base"] . "Providers/";
|
||||
|
||||
// reset debug mode
|
||||
if (!isset($config["debug_mode"])) {
|
||||
$config["debug_mode"] = false;
|
||||
$config["debug_file"] = null;
|
||||
}
|
||||
|
||||
# load hybridauth required files, a autoload is on the way...
|
||||
require_once $config["path_base"] . "Error.php";
|
||||
require_once $config["path_base"] . "Exception.php";
|
||||
require_once $config["path_base"] . "Logger.php";
|
||||
|
||||
require_once $config["path_base"] . "Provider_Adapter.php";
|
||||
|
||||
require_once $config["path_base"] . "Provider_Model.php";
|
||||
require_once $config["path_base"] . "Provider_Model_OpenID.php";
|
||||
require_once $config["path_base"] . "Provider_Model_OAuth1.php";
|
||||
require_once $config["path_base"] . "Provider_Model_OAuth2.php";
|
||||
|
||||
require_once $config["path_base"] . "User.php";
|
||||
require_once $config["path_base"] . "User_Profile.php";
|
||||
require_once $config["path_base"] . "User_Contact.php";
|
||||
require_once $config["path_base"] . "User_Activity.php";
|
||||
|
||||
if (!class_exists("Hybrid_Storage", false)) {
|
||||
require_once $config["path_base"] . "Storage.php";
|
||||
}
|
||||
|
||||
// hash given config
|
||||
Hybrid_Auth::$config = $config;
|
||||
|
||||
// instance of log mng
|
||||
Hybrid_Auth::$logger = new Hybrid_Logger();
|
||||
|
||||
// instance of errors mng
|
||||
Hybrid_Auth::$error = new Hybrid_Error();
|
||||
|
||||
// start session storage mng
|
||||
Hybrid_Auth::$store = new Hybrid_Storage();
|
||||
|
||||
Hybrid_Logger::info("Enter Hybrid_Auth::initialize()");
|
||||
Hybrid_Logger::info("Hybrid_Auth::initialize(). PHP version: " . PHP_VERSION);
|
||||
Hybrid_Logger::info("Hybrid_Auth::initialize(). Hybrid_Auth version: " . Hybrid_Auth::$version);
|
||||
Hybrid_Logger::info("Hybrid_Auth::initialize(). Hybrid_Auth called from: " . Hybrid_Auth::getCurrentUrl());
|
||||
|
||||
// PHP Curl extension [http://www.php.net/manual/en/intro.curl.php]
|
||||
if (!function_exists('curl_init')) {
|
||||
Hybrid_Logger::error('Hybridauth Library needs the CURL PHP extension.');
|
||||
throw new Exception('Hybridauth Library needs the CURL PHP extension.');
|
||||
}
|
||||
|
||||
// PHP JSON extension [http://php.net/manual/en/book.json.php]
|
||||
if (!function_exists('json_decode')) {
|
||||
Hybrid_Logger::error('Hybridauth Library needs the JSON PHP extension.');
|
||||
throw new Exception('Hybridauth Library needs the JSON PHP extension.');
|
||||
}
|
||||
|
||||
// session.name
|
||||
if (session_name() != "PHPSESSID") {
|
||||
Hybrid_Logger::info('PHP session.name diff from default PHPSESSID. http://php.net/manual/en/session.configuration.php#ini.session.name.');
|
||||
}
|
||||
|
||||
// safe_mode is on
|
||||
if (ini_get('safe_mode')) {
|
||||
Hybrid_Logger::info('PHP safe_mode is on. http://php.net/safe-mode.');
|
||||
}
|
||||
|
||||
// open basedir is on
|
||||
if (ini_get('open_basedir')) {
|
||||
Hybrid_Logger::info('PHP open_basedir is on. http://php.net/open-basedir.');
|
||||
}
|
||||
|
||||
Hybrid_Logger::debug("Hybrid_Auth initialize. dump used config: ", serialize($config));
|
||||
Hybrid_Logger::debug("Hybrid_Auth initialize. dump current session: ", Hybrid_Auth::storage()->getSessionData());
|
||||
Hybrid_Logger::info("Hybrid_Auth initialize: check if any error is stored on the endpoint...");
|
||||
|
||||
if (Hybrid_Error::hasError()) {
|
||||
$m = Hybrid_Error::getErrorMessage();
|
||||
$c = Hybrid_Error::getErrorCode();
|
||||
$p = Hybrid_Error::getErrorPrevious();
|
||||
|
||||
Hybrid_Logger::error("Hybrid_Auth initialize: A stored Error found, Throw an new Exception and delete it from the store: Error#$c, '$m'");
|
||||
|
||||
Hybrid_Error::clearError();
|
||||
|
||||
// try to provide the previous if any
|
||||
// Exception::getPrevious (PHP 5 >= 5.3.0) http://php.net/manual/en/exception.getprevious.php
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '>=') && ($p instanceof Exception)) {
|
||||
throw new Exception($m, $c, $p);
|
||||
} else {
|
||||
throw new Exception($m, $c);
|
||||
}
|
||||
}
|
||||
|
||||
Hybrid_Logger::info("Hybrid_Auth initialize: no error found. initialization succeed.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Hybrid storage system accessor
|
||||
*
|
||||
* Users sessions are stored using HybridAuth storage system ( HybridAuth 2.0 handle PHP Session only) and can be accessed directly by
|
||||
* Hybrid_Auth::storage()->get($key) to retrieves the data for the given key, or calling
|
||||
* Hybrid_Auth::storage()->set($key, $value) to store the key => $value set.
|
||||
*
|
||||
* @return Hybrid_Storage
|
||||
*/
|
||||
public static function storage() {
|
||||
return Hybrid_Auth::$store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hybridauth session data
|
||||
* @return string|null
|
||||
*/
|
||||
function getSessionData() {
|
||||
return Hybrid_Auth::storage()->getSessionData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore hybridauth session data
|
||||
*
|
||||
* @param string $sessiondata Serialized session data
|
||||
* @retun void
|
||||
*/
|
||||
function restoreSessionData($sessiondata = null) {
|
||||
Hybrid_Auth::storage()->restoreSessionData($sessiondata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to authenticate the user with a given provider.
|
||||
*
|
||||
* If the user is already connected we just return and instance of provider adapter,
|
||||
* ELSE, try to authenticate and authorize the user with the provider.
|
||||
*
|
||||
* $params is generally an array with required info in order for this provider and HybridAuth to work,
|
||||
* like :
|
||||
* hauth_return_to: URL to call back after authentication is done
|
||||
* openid_identifier: The OpenID identity provider identifier
|
||||
* google_service: can be "Users" for Google user accounts service or "Apps" for Google hosted Apps
|
||||
*
|
||||
* @param string $providerId ID of the provider
|
||||
* @param array $params Params
|
||||
* @return
|
||||
*/
|
||||
public static function authenticate($providerId, $params = null) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Auth::authenticate( $providerId )");
|
||||
|
||||
if (!Hybrid_Auth::storage()->get("hauth_session.$providerId.is_logged_in")) {
|
||||
// if user not connected to $providerId then try setup a new adapter and start the login process for this provider
|
||||
Hybrid_Logger::info("Hybrid_Auth::authenticate( $providerId ), User not connected to the provider. Try to authenticate..");
|
||||
$provider_adapter = Hybrid_Auth::setup($providerId, $params);
|
||||
$provider_adapter->login();
|
||||
} else {
|
||||
// else, then return the adapter instance for the given provider
|
||||
Hybrid_Logger::info("Hybrid_Auth::authenticate( $providerId ), User is already connected to this provider. Return the adapter instance.");
|
||||
return Hybrid_Auth::getAdapter($providerId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the adapter instance for an authenticated provider
|
||||
*
|
||||
* @param string $providerId ID of the provider
|
||||
* @return Hybrid_Provider_Adapter
|
||||
*/
|
||||
public static function getAdapter($providerId = null) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Auth::getAdapter( $providerId )");
|
||||
return Hybrid_Auth::setup($providerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup an adapter for a given provider
|
||||
*
|
||||
* @param string $providerId ID of the provider
|
||||
* @param array $params Adapter params
|
||||
* @return Hybrid_Provider_Adapter
|
||||
*/
|
||||
public static function setup($providerId, $params = null) {
|
||||
Hybrid_Logger::debug("Enter Hybrid_Auth::setup( $providerId )", $params);
|
||||
|
||||
if (!$params) {
|
||||
$params = Hybrid_Auth::storage()->get("hauth_session.$providerId.id_provider_params");
|
||||
|
||||
Hybrid_Logger::debug("Hybrid_Auth::setup( $providerId ), no params given. Trying to get the stored for this provider.", $params);
|
||||
}
|
||||
|
||||
if (!$params) {
|
||||
$params = array();
|
||||
Hybrid_Logger::info("Hybrid_Auth::setup( $providerId ), no stored params found for this provider. Initialize a new one for new session");
|
||||
}
|
||||
|
||||
if (is_array($params) && !isset($params["hauth_return_to"])) {
|
||||
$params["hauth_return_to"] = Hybrid_Auth::getCurrentUrl();
|
||||
Hybrid_Logger::debug("Hybrid_Auth::setup( $providerId ). HybridAuth Callback URL set to: ", $params["hauth_return_to"]);
|
||||
}
|
||||
|
||||
# instantiate a new IDProvider Adapter
|
||||
$provider = new Hybrid_Provider_Adapter();
|
||||
$provider->factory($providerId, $params);
|
||||
return $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user is connected to a given provider
|
||||
*
|
||||
* @param string $providerId ID of the provider
|
||||
* @return bool
|
||||
*/
|
||||
public static function isConnectedWith($providerId) {
|
||||
return (bool) Hybrid_Auth::storage()->get("hauth_session.{$providerId}.is_logged_in");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array listing all authenticated providers
|
||||
* @return array
|
||||
*/
|
||||
public static function getConnectedProviders() {
|
||||
$idps = array();
|
||||
|
||||
foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) {
|
||||
if (Hybrid_Auth::isConnectedWith($idpid)) {
|
||||
$idps[] = $idpid;
|
||||
}
|
||||
}
|
||||
|
||||
return $idps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array listing all enabled providers as well as a flag if you are connected
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'Facebook' => array(
|
||||
* 'connected' => true
|
||||
* )
|
||||
* )
|
||||
* </code>
|
||||
* @return array
|
||||
*/
|
||||
public static function getProviders() {
|
||||
$idps = array();
|
||||
|
||||
foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) {
|
||||
if ($params['enabled']) {
|
||||
$idps[$idpid] = array('connected' => false);
|
||||
|
||||
if (Hybrid_Auth::isConnectedWith($idpid)) {
|
||||
$idps[$idpid]['connected'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $idps;
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic function to logout all connected provider at once
|
||||
* @return void
|
||||
*/
|
||||
public static function logoutAllProviders() {
|
||||
$idps = Hybrid_Auth::getConnectedProviders();
|
||||
|
||||
foreach ($idps as $idp) {
|
||||
$adapter = Hybrid_Auth::getAdapter($idp);
|
||||
$adapter->logout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function, redirect to a given URL with php header or using javascript location.href
|
||||
*
|
||||
* @param string $url URL to redirect to
|
||||
* @param string $mode PHP|JS
|
||||
*/
|
||||
public static function redirect($url, $mode = "PHP") {
|
||||
if(!$mode){
|
||||
$mode = 'PHP';
|
||||
}
|
||||
Hybrid_Logger::info("Enter Hybrid_Auth::redirect( $url, $mode )");
|
||||
|
||||
// Ensure session is saved before sending response, see https://github.com/symfony/symfony/pull/12341
|
||||
if ((PHP_VERSION_ID >= 50400 && PHP_SESSION_ACTIVE === session_status()) || (PHP_VERSION_ID < 50400 && isset($_SESSION) && session_id())) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
if ($mode == "PHP") {
|
||||
header("Location: $url");
|
||||
} elseif ($mode == "JS") {
|
||||
echo '<html>';
|
||||
echo '<head>';
|
||||
echo '<script type="text/javascript">';
|
||||
echo 'function redirect(){ window.top.location.href="' . $url . '"; }';
|
||||
echo '</script>';
|
||||
echo '</head>';
|
||||
echo '<body onload="redirect()">';
|
||||
echo 'Redirecting, please wait...';
|
||||
echo '</body>';
|
||||
echo '</html>';
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function, return the current url
|
||||
*
|
||||
* @param bool $request_uri true to get $_SERVER['REQUEST_URI'], false for $_SERVER['PHP_SELF']
|
||||
* @return string
|
||||
*/
|
||||
public static function getCurrentUrl($request_uri = true) {
|
||||
if (php_sapi_name() == 'cli') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$protocol = 'http://';
|
||||
|
||||
if ((isset($_SERVER['HTTPS']) && ( $_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1 ))
|
||||
|| (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))
|
||||
{
|
||||
$protocol = 'https://';
|
||||
}
|
||||
|
||||
$url = $protocol . $_SERVER['HTTP_HOST'];
|
||||
|
||||
if ($request_uri) {
|
||||
$url .= $_SERVER['REQUEST_URI'];
|
||||
} else {
|
||||
$url .= $_SERVER['PHP_SELF'];
|
||||
}
|
||||
|
||||
// return current url
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
222
plugin/social/Hybrid/Endpoint.php
Normal file
@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Endpoint class
|
||||
*
|
||||
* Provides a simple way to handle the OpenID and OAuth endpoint
|
||||
*/
|
||||
class Hybrid_Endpoint {
|
||||
|
||||
protected $request = null;
|
||||
protected $initDone = false;
|
||||
|
||||
/**
|
||||
* Process the current request
|
||||
*
|
||||
* @param array $request The current request parameters. Leave as null to default to use $_REQUEST.
|
||||
*/
|
||||
public function __construct($request = null) {
|
||||
if (is_null($request)) {
|
||||
// Fix a strange behavior when some provider call back ha endpoint
|
||||
// with /index.php?hauth.done={provider}?{args}...
|
||||
// >here we need to parse $_SERVER[QUERY_STRING]
|
||||
$request = $_REQUEST;
|
||||
if (isset($_SERVER["QUERY_STRING"]) && strrpos($_SERVER["QUERY_STRING"], '?')) {
|
||||
$_SERVER["QUERY_STRING"] = str_replace("?", "&", $_SERVER["QUERY_STRING"]);
|
||||
parse_str($_SERVER["QUERY_STRING"], $request);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup request variable
|
||||
$this->request = $request;
|
||||
|
||||
// If openid_policy requested, we return our policy document
|
||||
if (isset($this->request["get"]) && $this->request["get"] == "openid_policy") {
|
||||
$this->processOpenidPolicy();
|
||||
}
|
||||
|
||||
// If openid_xrds requested, we return our XRDS document
|
||||
if (isset($this->request["get"]) && $this->request["get"] == "openid_xrds") {
|
||||
$this->processOpenidXRDS();
|
||||
}
|
||||
|
||||
// If we get a hauth.start
|
||||
if (isset($this->request["hauth_start"]) && $this->request["hauth_start"]) {
|
||||
$this->processAuthStart();
|
||||
}
|
||||
// Else if hauth.done
|
||||
elseif (isset($this->request["hauth_done"]) && $this->request["hauth_done"]) {
|
||||
$this->processAuthDone();
|
||||
}
|
||||
// Else we advertise our XRDS document, something supposed to be done from the Realm URL page
|
||||
else {
|
||||
$this->processOpenidRealm();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the current request
|
||||
*
|
||||
* @param array $request The current request parameters. Leave as null to default to use $_REQUEST.
|
||||
* @return Hybrid_Endpoint
|
||||
*/
|
||||
public static function process($request = null) {
|
||||
// Trick for PHP 5.2, because it doesn't support late static binding
|
||||
$class = function_exists('get_called_class') ? get_called_class() : __CLASS__;
|
||||
new $class($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process OpenID policy request
|
||||
* @return void
|
||||
*/
|
||||
protected function processOpenidPolicy() {
|
||||
$output = file_get_contents(dirname(__FILE__) . "/resources/openid_policy.html");
|
||||
print $output;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process OpenID XRDS request
|
||||
* @return void
|
||||
*/
|
||||
protected function processOpenidXRDS() {
|
||||
header("Content-Type: application/xrds+xml");
|
||||
|
||||
$output = str_replace("{RETURN_TO_URL}", str_replace(
|
||||
array("<", ">", "\"", "'", "&"), array("<", ">", """, "'", "&"), Hybrid_Auth::getCurrentUrl(false)
|
||||
), file_get_contents(dirname(__FILE__) . "/resources/openid_xrds.xml"));
|
||||
print $output;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process OpenID realm request
|
||||
* @return void
|
||||
*/
|
||||
protected function processOpenidRealm() {
|
||||
$output = str_replace("{X_XRDS_LOCATION}", htmlentities(Hybrid_Auth::getCurrentUrl(false), ENT_QUOTES, 'UTF-8')
|
||||
. "?get=openid_xrds&v="
|
||||
. Hybrid_Auth::$version, file_get_contents(dirname(__FILE__) . "/resources/openid_realm.html"));
|
||||
print $output;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define: endpoint step 3
|
||||
* @return void
|
||||
* @throws Hybrid_Exception
|
||||
*/
|
||||
protected function processAuthStart() {
|
||||
$this->authInit();
|
||||
|
||||
$provider_id = trim(strip_tags($this->request["hauth_start"]));
|
||||
|
||||
// check if page accessed directly
|
||||
if (!Hybrid_Auth::storage()->get("hauth_session.$provider_id.hauth_endpoint")) {
|
||||
Hybrid_Logger::error("Endpoint: hauth_endpoint parameter is not defined on hauth_start, halt login process!");
|
||||
|
||||
throw new Hybrid_Exception("You cannot access this page directly.");
|
||||
}
|
||||
|
||||
// define:hybrid.endpoint.php step 2.
|
||||
$hauth = Hybrid_Auth::setup($provider_id);
|
||||
|
||||
// if REQUESTed hauth_idprovider is wrong, session not created, etc.
|
||||
if (!$hauth) {
|
||||
Hybrid_Logger::error("Endpoint: Invalid parameter on hauth_start!");
|
||||
throw new Hybrid_Exception("Invalid parameter! Please return to the login page and try again.");
|
||||
}
|
||||
|
||||
try {
|
||||
Hybrid_Logger::info("Endpoint: call adapter [{$provider_id}] loginBegin()");
|
||||
|
||||
$hauth->adapter->loginBegin();
|
||||
} catch (Exception $e) {
|
||||
Hybrid_Logger::error("Exception:" . $e->getMessage(), $e);
|
||||
Hybrid_Error::setError($e->getMessage(), $e->getCode(), $e->getTraceAsString(), $e->getPrevious());
|
||||
|
||||
$hauth->returnToCallbackUrl();
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define: endpoint step 3.1 and 3.2
|
||||
* @return void
|
||||
* @throws Hybrid_Exception
|
||||
*/
|
||||
protected function processAuthDone() {
|
||||
$this->authInit();
|
||||
|
||||
$provider_id = trim(strip_tags($this->request["hauth_done"]));
|
||||
|
||||
$hauth = Hybrid_Auth::setup($provider_id);
|
||||
|
||||
if (!$hauth) {
|
||||
Hybrid_Logger::error("Endpoint: Invalid parameter on hauth_done!");
|
||||
|
||||
$hauth->adapter->setUserUnconnected();
|
||||
|
||||
throw new Hybrid_Exception("Invalid parameter! Please return to the login page and try again.");
|
||||
}
|
||||
|
||||
try {
|
||||
Hybrid_Logger::info("Endpoint: call adapter [{$provider_id}] loginFinish() ");
|
||||
$hauth->adapter->loginFinish();
|
||||
} catch (Exception $e) {
|
||||
Hybrid_Logger::error("Exception:" . $e->getMessage(), $e);
|
||||
Hybrid_Error::setError($e->getMessage(), $e->getCode(), $e->getTraceAsString(), $e->getPrevious());
|
||||
|
||||
$hauth->adapter->setUserUnconnected();
|
||||
}
|
||||
|
||||
Hybrid_Logger::info("Endpoint: job done. return to callback url.");
|
||||
|
||||
$hauth->returnToCallbackUrl();
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes authentication
|
||||
* @throws Hybrid_Exception
|
||||
*/
|
||||
protected function authInit() {
|
||||
if (!$this->initDone) {
|
||||
$this->initDone = true;
|
||||
|
||||
// Init Hybrid_Auth
|
||||
try {
|
||||
if (!class_exists("Hybrid_Storage", false)) {
|
||||
require_once realpath(dirname(__FILE__)) . "/Storage.php";
|
||||
}
|
||||
if (!class_exists("Hybrid_Exception", false)) {
|
||||
require_once realpath(dirname(__FILE__)) . "/Exception.php";
|
||||
}
|
||||
if (!class_exists("Hybrid_Logger", false)) {
|
||||
require_once realpath(dirname(__FILE__)) . "/Logger.php";
|
||||
}
|
||||
|
||||
$storage = new Hybrid_Storage();
|
||||
|
||||
// Check if Hybrid_Auth session already exist
|
||||
if (!$storage->config("CONFIG")) {
|
||||
throw new Hybrid_Exception("You cannot access this page directly.");
|
||||
}
|
||||
|
||||
Hybrid_Auth::initialize($storage->config("CONFIG"));
|
||||
} catch (Exception $e) {
|
||||
Hybrid_Logger::error("Endpoint: Error while trying to init Hybrid_Auth: " . $e->getMessage());
|
||||
throw new Hybrid_Exception( "Endpoint: Error while trying to init Hybrid_Auth: " . $e->getMessage(), $e->getCode(), $e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
88
plugin/social/Hybrid/Error.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Errors manager
|
||||
*
|
||||
* HybridAuth errors are stored in Hybrid::storage() and not displayed directly to the end user
|
||||
*/
|
||||
class Hybrid_Error {
|
||||
|
||||
/**
|
||||
* Store error in session
|
||||
*
|
||||
* @param string $message Error message
|
||||
* @param int $code Error code
|
||||
* @param string $trace Back trace
|
||||
* @param string $previous Previous exception
|
||||
*/
|
||||
public static function setError($message, $code = null, $trace = null, $previous = null) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Error::setError( $message )");
|
||||
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.status", 1);
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.message", $message);
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.code", $code);
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.trace", $trace);
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.previous", $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the last error
|
||||
* @return void
|
||||
*/
|
||||
public static function clearError() {
|
||||
Hybrid_Logger::info("Enter Hybrid_Error::clearError()");
|
||||
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.status");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.message");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.code");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.trace");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.previous");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if there is a an error.
|
||||
* @return boolean true if there is an error.
|
||||
*/
|
||||
public static function hasError() {
|
||||
return (bool) Hybrid_Auth::storage()->get("hauth_session.error.status");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return error message
|
||||
* @return string
|
||||
*/
|
||||
public static function getErrorMessage() {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.error.message");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return error code
|
||||
* @return int
|
||||
*/
|
||||
public static function getErrorCode() {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.error.code");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string detailed error backtrace as string
|
||||
* @return string
|
||||
*/
|
||||
public static function getErrorTrace() {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.error.trace");
|
||||
}
|
||||
|
||||
/**
|
||||
* Detailed error backtrace as string
|
||||
* @return string
|
||||
*/
|
||||
public static function getErrorPrevious() {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.error.previous");
|
||||
}
|
||||
|
||||
}
|
||||
17
plugin/social/Hybrid/Exception.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception implementation
|
||||
*
|
||||
* The base Exception is extended to allow applications to handle exceptions from hybrid auth
|
||||
* separately from general exceptions.
|
||||
*/
|
||||
class Hybrid_Exception extends Exception {
|
||||
|
||||
}
|
||||
102
plugin/social/Hybrid/Logger.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Debugging and Logging manager
|
||||
*/
|
||||
class Hybrid_Logger {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct() {
|
||||
// if debug mode is set to true, then check for the writable log file
|
||||
if (Hybrid_Auth::$config["debug_mode"]) {
|
||||
if (!isset(Hybrid_Auth::$config["debug_file"])) {
|
||||
throw new Exception("'debug_mode' is set to 'true' but no log file path 'debug_file' is set.", 1);
|
||||
} elseif (!file_exists(Hybrid_Auth::$config["debug_file"]) && !is_writable(Hybrid_Auth::$config["debug_file"])) {
|
||||
if (!touch(Hybrid_Auth::$config["debug_file"])) {
|
||||
throw new Exception("'debug_mode' is set to 'true', but the file " . Hybrid_Auth::$config['debug_file'] . " in 'debug_file' can not be created.", 1);
|
||||
}
|
||||
} elseif (!is_writable(Hybrid_Auth::$config["debug_file"])) {
|
||||
throw new Exception("'debug_mode' is set to 'true', but the given log file path 'debug_file' is not a writable file.", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a debug message with an object dump
|
||||
*
|
||||
* @param string $message Debug message
|
||||
* @param stdClass $object Object being debugged
|
||||
* @return void
|
||||
*/
|
||||
public static function debug($message, $object = null) {
|
||||
if (Hybrid_Auth::$config["debug_mode"] === true) {
|
||||
$dt = new DateTime('now', new DateTimeZone( 'UTC' ));
|
||||
file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array(
|
||||
"DEBUG",
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
$dt->format(DATE_ATOM),
|
||||
$message,
|
||||
print_r($object, true) . PHP_EOL,
|
||||
)), FILE_APPEND
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an info message
|
||||
*
|
||||
* @param string $message Info message
|
||||
* @return void
|
||||
*/
|
||||
public static function info($message) {
|
||||
if (in_array(Hybrid_Auth::$config["debug_mode"], array(true, 'info'), true)) {
|
||||
$dt = new DateTime('now', new DateTimeZone( 'UTC' ));
|
||||
file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array(
|
||||
"INFO",
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
$dt->format(DATE_ATOM),
|
||||
$message . PHP_EOL,
|
||||
)), FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an error message with an object dump
|
||||
*
|
||||
* @param string $message Error message
|
||||
* @param stdClass $object Object being debugged
|
||||
* @return void
|
||||
*/
|
||||
public static function error($message, $object = null) {
|
||||
if (isset(Hybrid_Auth::$config["debug_mode"]) && in_array(Hybrid_Auth::$config["debug_mode"], array(true, 'info', 'error'), true)) {
|
||||
$dt = new DateTime('now', new DateTimeZone( 'UTC' ));
|
||||
file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array(
|
||||
'ERROR',
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
$dt->format(DATE_ATOM),
|
||||
$message,
|
||||
print_r($object, true) . PHP_EOL
|
||||
)), FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the data in the way suitable to be output in log files for debug purposes
|
||||
*
|
||||
* @param mixed $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function dumpData($data) {
|
||||
return var_export($data, true);
|
||||
}
|
||||
|
||||
}
|
||||
340
plugin/social/Hybrid/Provider_Adapter.php
Normal file
@ -0,0 +1,340 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Provider_Adapter is the basic class which Hybrid_Auth will use
|
||||
* to connect users to a given provider.
|
||||
*
|
||||
* Basically Hybrid_Provider_Adapter will create a bridge from your php
|
||||
* application to the provider api.
|
||||
*
|
||||
* Hybrid_Auth will automatically load Hybrid_Provider_Adapter and create
|
||||
* an instance of it for each authenticated provider.
|
||||
*/
|
||||
class Hybrid_Provider_Adapter {
|
||||
|
||||
/**
|
||||
* Provider ID (or unique name)
|
||||
* @var mixed
|
||||
*/
|
||||
public $id = null;
|
||||
|
||||
/**
|
||||
* Provider adapter specific config
|
||||
* @var array
|
||||
*/
|
||||
public $config = null;
|
||||
|
||||
/**
|
||||
* Provider adapter extra parameters
|
||||
* @var array
|
||||
*/
|
||||
public $params = array();
|
||||
|
||||
/**
|
||||
* Provider adapter wrapper path
|
||||
* @var string
|
||||
*/
|
||||
public $wrapper = null;
|
||||
|
||||
/**
|
||||
* Provider adapter instance
|
||||
* @var Hybrid_Provider_Model
|
||||
*/
|
||||
public $adapter = null;
|
||||
|
||||
/**
|
||||
* Create a new adapter switch IDp name or ID
|
||||
*
|
||||
* @param string $id The id or name of the IDp
|
||||
* @param array $params (optional) required parameters by the adapter
|
||||
* @return Hybrid_Provider_Adapter
|
||||
* @throws Exception
|
||||
*/
|
||||
function factory($id, $params = array()) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Provider_Adapter::factory( $id )");
|
||||
|
||||
# init the adapter config and params
|
||||
$this->id = $id;
|
||||
$this->params = $params;
|
||||
$this->id = $this->getProviderCiId($this->id);
|
||||
$this->config = $this->getConfigById($this->id);
|
||||
|
||||
# check the IDp id
|
||||
if (!$this->id) {
|
||||
throw new Exception("No provider ID specified.", 2);
|
||||
}
|
||||
|
||||
# check the IDp config
|
||||
if (!$this->config) {
|
||||
throw new Exception("Unknown Provider ID, check your configuration file.", 3);
|
||||
}
|
||||
|
||||
# check the IDp adapter is enabled
|
||||
if (!$this->config["enabled"]) {
|
||||
throw new Exception("The provider '{$this->id}' is not enabled.", 3);
|
||||
}
|
||||
|
||||
# include the adapter wrapper
|
||||
if (isset($this->config["wrapper"]) && is_array($this->config["wrapper"])) {
|
||||
if (isset($this->config["wrapper"]["path"])) {
|
||||
require_once $this->config["wrapper"]["path"];
|
||||
}
|
||||
|
||||
if (!class_exists($this->config["wrapper"]["class"])) {
|
||||
throw new Exception("Unable to load the adapter class.", 3);
|
||||
}
|
||||
|
||||
$this->wrapper = $this->config["wrapper"]["class"];
|
||||
} else {
|
||||
require_once Hybrid_Auth::$config["path_providers"] . $this->id . ".php";
|
||||
|
||||
$this->wrapper = "Hybrid_Providers_" . $this->id;
|
||||
}
|
||||
|
||||
# create the adapter instance, and pass the current params and config
|
||||
$this->adapter = new $this->wrapper($this->id, $this->config, $this->params);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hybrid_Provider_Adapter::login(), prepare the user session and the authentication request
|
||||
* for index.php
|
||||
* @return void
|
||||
* @throw Exception
|
||||
*/
|
||||
function login() {
|
||||
Hybrid_Logger::info("Enter Hybrid_Provider_Adapter::login( {$this->id} ) ");
|
||||
|
||||
if (!$this->adapter) {
|
||||
throw new Exception("Hybrid_Provider_Adapter::login() should not directly used.");
|
||||
}
|
||||
|
||||
// clear all unneeded params
|
||||
foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) {
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$idpid}.hauth_return_to");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$idpid}.hauth_endpoint");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$idpid}.id_provider_params");
|
||||
}
|
||||
|
||||
// make a fresh start
|
||||
$this->logout();
|
||||
|
||||
# get hybridauth base url
|
||||
if (empty(Hybrid_Auth::$config["base_url"])) {
|
||||
// the base url wasn't provide, so we must use the current
|
||||
// url (which makes sense actually)
|
||||
$url = empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off' ? 'http' : 'https';
|
||||
$url .= '://' . $_SERVER['HTTP_HOST'];
|
||||
$url .= $_SERVER['REQUEST_URI'];
|
||||
$HYBRID_AUTH_URL_BASE = $url;
|
||||
} else {
|
||||
$HYBRID_AUTH_URL_BASE = Hybrid_Auth::$config["base_url"];
|
||||
}
|
||||
|
||||
// make sure params is array
|
||||
if (!is_array($this->params)) {
|
||||
$this->params = array();
|
||||
}
|
||||
|
||||
# we make use of session_id() as storage hash to identify the current user
|
||||
# using session_regenerate_id() will be a problem, but ..
|
||||
$this->params["hauth_token"] = session_id();
|
||||
|
||||
# set request timestamp
|
||||
$this->params["hauth_time"] = time();
|
||||
|
||||
# for default HybridAuth endpoint url hauth_login_start_url
|
||||
# auth.start required the IDp ID
|
||||
# auth.time optional login request timestamp
|
||||
if (!isset($this->params["login_start"]) ) {
|
||||
$this->params["login_start"] = $HYBRID_AUTH_URL_BASE . ( strpos($HYBRID_AUTH_URL_BASE, '?') ? '&' : '?' ) . "hauth.start={$this->id}&hauth.time={$this->params["hauth_time"]}";
|
||||
}
|
||||
|
||||
# for default HybridAuth endpoint url hauth_login_done_url
|
||||
# auth.done required the IDp ID
|
||||
if (!isset($this->params["login_done"]) ) {
|
||||
$this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos($HYBRID_AUTH_URL_BASE, '?') ? '&' : '?' ) . "hauth.done={$this->id}";
|
||||
}
|
||||
|
||||
# workaround to solve windows live authentication since microsoft disallowed redirect urls to contain any parameters
|
||||
# http://mywebsite.com/path_to_hybridauth/?hauth.done=Live will not work
|
||||
if ($this->id=="Live") {
|
||||
$this->params["login_done"] = $HYBRID_AUTH_URL_BASE."live.php";
|
||||
}
|
||||
|
||||
# Workaround to fix broken callback urls for the Facebook OAuth client
|
||||
if ($this->adapter->useSafeUrls) {
|
||||
$this->params['login_done'] = str_replace('hauth.done', 'hauth_done', $this->params['login_done']);
|
||||
}
|
||||
|
||||
if (isset($this->params["hauth_return_to"])) {
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->id}.hauth_return_to", $this->params["hauth_return_to"]);
|
||||
}
|
||||
if (isset($this->params["login_done"])) {
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->id}.hauth_endpoint", $this->params["login_done"]);
|
||||
}
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->id}.id_provider_params", $this->params);
|
||||
|
||||
// store config to be used by the end point
|
||||
Hybrid_Auth::storage()->config("CONFIG", Hybrid_Auth::$config);
|
||||
|
||||
// move on
|
||||
Hybrid_Logger::debug("Hybrid_Provider_Adapter::login( {$this->id} ), redirect the user to login_start URL.");
|
||||
|
||||
// redirect
|
||||
if (empty($this->params["redirect_mode"])) {
|
||||
Hybrid_Auth::redirect($this->params["login_start"]);
|
||||
} else {
|
||||
Hybrid_Auth::redirect($this->params["login_start"],$this->params["redirect_mode"]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let hybridauth forget all about the user for the current provider
|
||||
* @return bool
|
||||
*/
|
||||
function logout() {
|
||||
$this->adapter->logout();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return true if the user is connected to the current provider
|
||||
* @return bool
|
||||
*/
|
||||
public function isUserConnected() {
|
||||
return $this->adapter->isUserConnected();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Call adapter methods defined in the adapter model:
|
||||
* getUserProfile()
|
||||
* getUserContacts()
|
||||
* getUserActivity()
|
||||
* setUserStatus()
|
||||
*
|
||||
* @param string $name Method name
|
||||
* @param array $arguments Call arguments
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __call($name, $arguments) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Provider_Adapter::$name(), Provider: {$this->id}");
|
||||
|
||||
if (!$this->isUserConnected()) {
|
||||
throw new Exception("User not connected to the provider {$this->id}.", 7);
|
||||
}
|
||||
|
||||
if (!method_exists($this->adapter, $name)) {
|
||||
throw new Exception("Call to undefined function Hybrid_Providers_{$this->id}::$name().");
|
||||
}
|
||||
|
||||
return call_user_func_array(array($this->adapter, $name), $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user is connected, then return the access_token and access_token_secret
|
||||
* if the provider api use oauth
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'access_token' => '',
|
||||
* 'access_token_secret' => '',
|
||||
* 'refresh_token' => '',
|
||||
* 'expires_in' => '',
|
||||
* 'expires_at' => '',
|
||||
* )
|
||||
* </code>
|
||||
* @return array
|
||||
*/
|
||||
public function getAccessToken() {
|
||||
if (!$this->adapter->isUserConnected()) {
|
||||
Hybrid_Logger::error("User not connected to the provider.");
|
||||
throw new Exception("User not connected to the provider.", 7);
|
||||
}
|
||||
|
||||
return array(
|
||||
"access_token" => $this->adapter->token("access_token"), // OAuth access token
|
||||
"access_token_secret" => $this->adapter->token("access_token_secret"), // OAuth access token secret
|
||||
"refresh_token" => $this->adapter->token("refresh_token"), // OAuth refresh token
|
||||
"expires_in" => $this->adapter->token("expires_in"), // OPTIONAL. The duration in seconds of the access token lifetime
|
||||
"expires_at" => $this->adapter->token("expires_at"), // OPTIONAL. Timestamp when the access_token expire. if not provided by the social api, then it should be calculated: expires_at = now + expires_in
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Naive getter of the current connected IDp API client
|
||||
* @return stdClass
|
||||
* @throws Exception
|
||||
*/
|
||||
function api() {
|
||||
if (!$this->adapter->isUserConnected()) {
|
||||
Hybrid_Logger::error("User not connected to the provider.");
|
||||
|
||||
throw new Exception("User not connected to the provider.", 7);
|
||||
}
|
||||
return $this->adapter->api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the user to hauth_return_to (the callback url)
|
||||
* @return void
|
||||
*/
|
||||
function returnToCallbackUrl() {
|
||||
// get the stored callback url
|
||||
$callback_url = Hybrid_Auth::storage()->get("hauth_session.{$this->id}.hauth_return_to");
|
||||
|
||||
// if the user presses the back button in the browser and we already deleted the hauth_return_to from
|
||||
// the session in the previous request, we will redirect to '/' instead of displaying a blank page.
|
||||
if (!$callback_url) {
|
||||
$callback_url = '/';
|
||||
}
|
||||
|
||||
// remove some unneeded stored data
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$this->id}.hauth_return_to");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$this->id}.hauth_endpoint");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$this->id}.id_provider_params");
|
||||
|
||||
// back to home
|
||||
Hybrid_Auth::redirect($callback_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the provider config by id
|
||||
*
|
||||
* @param string $id Config key
|
||||
* @return mixed
|
||||
*/
|
||||
function getConfigById($id) {
|
||||
if (isset(Hybrid_Auth::$config["providers"][$id])) {
|
||||
return Hybrid_Auth::$config["providers"][$id];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the provider config by id; case insensitive
|
||||
*
|
||||
* @param string $id Provider id
|
||||
* @return mixed
|
||||
*/
|
||||
function getProviderCiId($id) {
|
||||
foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) {
|
||||
if (strtolower($idpid) == strtolower($id)) {
|
||||
return $idpid;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
247
plugin/social/Hybrid/Provider_Model.php
Normal file
@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Provider_Model provide a common interface for supported IDps on HybridAuth.
|
||||
*
|
||||
* Basically, each provider adapter has to define at least 4 methods:
|
||||
* Hybrid_Providers_{provider_name}::initialize()
|
||||
* Hybrid_Providers_{provider_name}::loginBegin()
|
||||
* Hybrid_Providers_{provider_name}::loginFinish()
|
||||
* Hybrid_Providers_{provider_name}::getUserProfile()
|
||||
*
|
||||
* HybridAuth also come with three others models
|
||||
* Class Hybrid_Provider_Model_OpenID for providers that uses the OpenID 1 and 2 protocol.
|
||||
* Class Hybrid_Provider_Model_OAuth1 for providers that uses the OAuth 1 protocol.
|
||||
* Class Hybrid_Provider_Model_OAuth2 for providers that uses the OAuth 2 protocol.
|
||||
*/
|
||||
abstract class Hybrid_Provider_Model {
|
||||
|
||||
/**
|
||||
* IDp ID (or unique name)
|
||||
* @var mixed
|
||||
*/
|
||||
public $providerId = null;
|
||||
|
||||
/**
|
||||
* Specific provider adapter config
|
||||
* @var array
|
||||
*/
|
||||
public $config = null;
|
||||
|
||||
/**
|
||||
* Provider extra parameters
|
||||
* @var array
|
||||
*/
|
||||
public $params = null;
|
||||
|
||||
/**
|
||||
* Endpoint URL for that provider
|
||||
* @var string
|
||||
*/
|
||||
public $endpoint = null;
|
||||
|
||||
/**
|
||||
* Hybrid_User obj, represents the current loggedin user
|
||||
* @var Hybrid_User
|
||||
*/
|
||||
public $user = null;
|
||||
|
||||
/**
|
||||
* The provider api client (optional)
|
||||
* @var stdClass
|
||||
*/
|
||||
public $api = null;
|
||||
|
||||
/**
|
||||
* Model should use "gzip,deflate" for CURLOPT_ENCODING
|
||||
* @var stdClass
|
||||
*/
|
||||
public $compressed = false;
|
||||
|
||||
/** @var bool $useSafeUrls Enable this to replace '.' with '_' characters in the callback urls */
|
||||
public $useSafeUrls = false;
|
||||
|
||||
/**
|
||||
* Common providers adapter constructor
|
||||
*
|
||||
* @param mixed $providerId Provider ID
|
||||
* @param array $config Provider adapter config
|
||||
* @param array $params Provider extra params
|
||||
*/
|
||||
function __construct($providerId, $config, $params = null) {
|
||||
# init the IDp adapter parameters, get them from the cache if possible
|
||||
if (!$params) {
|
||||
$this->params = Hybrid_Auth::storage()->get("hauth_session.$providerId.id_provider_params");
|
||||
} else {
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
// idp id
|
||||
$this->providerId = $providerId;
|
||||
|
||||
// set HybridAuth endpoint for this provider
|
||||
$this->endpoint = Hybrid_Auth::storage()->get("hauth_session.$providerId.hauth_endpoint");
|
||||
|
||||
// idp config
|
||||
$this->config = $config;
|
||||
|
||||
// new user instance
|
||||
$this->user = new Hybrid_User();
|
||||
$this->user->providerId = $providerId;
|
||||
|
||||
// initialize the current provider adapter
|
||||
$this->initialize();
|
||||
|
||||
Hybrid_Logger::debug("Hybrid_Provider_Model::__construct( $providerId ) initialized. dump current adapter instance: ", serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* IDp wrappers initializer
|
||||
*
|
||||
* The main job of wrappers initializer is to performs (depend on the IDp api client it self):
|
||||
* - include some libs needed by this provider,
|
||||
* - check IDp key and secret,
|
||||
* - set some needed parameters (stored in $this->params) by this IDp api client
|
||||
* - create and setup an instance of the IDp api client on $this->api
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract protected function initialize();
|
||||
|
||||
/**
|
||||
* Begin login
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract public function loginBegin();
|
||||
|
||||
/**
|
||||
* Finish login
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract public function loginFinish();
|
||||
|
||||
/**
|
||||
* Generic logout, just erase current provider adapter stored data to let Hybrid_Auth all forget about it
|
||||
* @return bool
|
||||
*/
|
||||
function logout() {
|
||||
Hybrid_Logger::info("Enter [{$this->providerId}]::logout()");
|
||||
$this->clearTokens();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab the user profile from the IDp api client
|
||||
* @return Hybrid_User_Profile
|
||||
* @throws Exception
|
||||
*/
|
||||
function getUserProfile() {
|
||||
Hybrid_Logger::error("HybridAuth do not provide users contacts list for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the current logged in user contacts list from the IDp api client
|
||||
* @return Hybrid_User_Contact[]
|
||||
* @throws Exception
|
||||
*/
|
||||
function getUserContacts() {
|
||||
Hybrid_Logger::error("HybridAuth do not provide users contacts list for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user activity stream
|
||||
* @return Hybrid_User_Activity[]
|
||||
* @throws Exception
|
||||
*/
|
||||
function getUserActivity($stream) {
|
||||
Hybrid_Logger::error("HybridAuth do not provide user's activity stream for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user status
|
||||
* @return mixed Provider response
|
||||
* @throws Exception
|
||||
*/
|
||||
function setUserStatus($status) {
|
||||
Hybrid_Logger::error("HybridAuth do not provide user's activity stream for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user status
|
||||
* @return mixed Provider response
|
||||
* @throws Exception
|
||||
*/
|
||||
function getUserStatus($statusid) {
|
||||
Hybrid_Logger::error("HybridAuth do not provide user's status for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the user is connected to the current provider
|
||||
* @return bool
|
||||
*/
|
||||
public function isUserConnected() {
|
||||
return (bool) Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.is_logged_in");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user to connected
|
||||
* @return void
|
||||
*/
|
||||
public function setUserConnected() {
|
||||
Hybrid_Logger::info("Enter [{$this->providerId}]::setUserConnected()");
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.is_logged_in", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user to unconnected
|
||||
* @return void
|
||||
*/
|
||||
public function setUserUnconnected() {
|
||||
Hybrid_Logger::info("Enter [{$this->providerId}]::setUserUnconnected()");
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.is_logged_in", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set a token
|
||||
* @return string
|
||||
*/
|
||||
public function token($token, $value = null) {
|
||||
if ($value === null) {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.token.$token");
|
||||
} else {
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.token.$token", $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a stored token
|
||||
* @return void
|
||||
*/
|
||||
public function deleteToken($token) {
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$this->providerId}.token.$token");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all existent tokens for this provider
|
||||
* @return void
|
||||
*/
|
||||
public function clearTokens() {
|
||||
Hybrid_Auth::storage()->deleteMatch("hauth_session.{$this->providerId}.");
|
||||
}
|
||||
|
||||
}
|
||||
174
plugin/social/Hybrid/Provider_Model_OAuth1.php
Normal file
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* To implement an OAuth 1 based service provider, Hybrid_Provider_Model_OAuth1
|
||||
* can be used to save the hassle of the authentication flow.
|
||||
*
|
||||
* Each class that inherit from Hybrid_Provider_Model_OAuth1 have to implement
|
||||
* at least 2 methods:
|
||||
* Hybrid_Providers_{provider_name}::initialize() to setup the provider api end-points urls
|
||||
* Hybrid_Providers_{provider_name}::getUserProfile() to grab the user profile
|
||||
*
|
||||
* Hybrid_Provider_Model_OAuth1 use OAuth1Client v0.1 which can be found on
|
||||
* Hybrid/thirdparty/OAuth/OAuth1Client.php
|
||||
*/
|
||||
class Hybrid_Provider_Model_OAuth1 extends Hybrid_Provider_Model {
|
||||
|
||||
/**
|
||||
* Provider API client
|
||||
* @var OAuth1Client
|
||||
*/
|
||||
public $api = null;
|
||||
|
||||
/**
|
||||
* Request_tokens as received from provider
|
||||
* @var stdClas
|
||||
*/
|
||||
public $request_tokens_raw = null;
|
||||
|
||||
/**
|
||||
* Access_tokens as received from provider
|
||||
* @var stdClass
|
||||
*/
|
||||
public $access_tokens_raw = null;
|
||||
|
||||
/**
|
||||
* Try to get the error message from provider api
|
||||
*
|
||||
* @param int $code Error code
|
||||
* @return string
|
||||
*/
|
||||
function errorMessageByStatus($code = null) {
|
||||
$http_status_codes = array(
|
||||
200 => "OK: Success!",
|
||||
304 => "Not Modified: There was no new data to return.",
|
||||
400 => "Bad Request: The request was invalid.",
|
||||
401 => "Unauthorized.",
|
||||
403 => "Forbidden: The request is understood, but it has been refused.",
|
||||
404 => "Not Found: The URI requested is invalid or the resource requested does not exists.",
|
||||
406 => "Not Acceptable.",
|
||||
500 => "Internal Server Error: Something is broken.",
|
||||
502 => "Bad Gateway.",
|
||||
503 => "Service Unavailable."
|
||||
);
|
||||
|
||||
if (!$code && $this->api) {
|
||||
$code = $this->api->http_code;
|
||||
}
|
||||
|
||||
if (isset($http_status_codes[$code])) {
|
||||
return $code . " " . $http_status_codes[$code];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
// 1 - check application credentials
|
||||
if (!$this->config["keys"]["key"] || !$this->config["keys"]["secret"]) {
|
||||
throw new Exception("Your application key and secret are required in order to connect to {$this->providerId}.", 4);
|
||||
}
|
||||
|
||||
// 2 - include OAuth lib and client
|
||||
if (! class_exists('OAuthConsumer') ) {
|
||||
require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth.php";
|
||||
}
|
||||
require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth1Client.php";
|
||||
|
||||
// 3.1 - setup access_token if any stored
|
||||
if ($this->token("access_token")) {
|
||||
$this->api = new OAuth1Client(
|
||||
$this->config["keys"]["key"], $this->config["keys"]["secret"], $this->token("access_token"), $this->token("access_token_secret")
|
||||
);
|
||||
}
|
||||
|
||||
// 3.2 - setup request_token if any stored, in order to exchange with an access token
|
||||
elseif ($this->token("request_token")) {
|
||||
$this->api = new OAuth1Client(
|
||||
$this->config["keys"]["key"], $this->config["keys"]["secret"], $this->token("request_token"), $this->token("request_token_secret")
|
||||
);
|
||||
}
|
||||
|
||||
// 3.3 - instanciate OAuth client with client credentials
|
||||
else {
|
||||
$this->api = new OAuth1Client($this->config["keys"]["key"], $this->config["keys"]["secret"]);
|
||||
}
|
||||
|
||||
// Set curl proxy if exist
|
||||
if (isset(Hybrid_Auth::$config["proxy"])) {
|
||||
$this->api->curl_proxy = Hybrid_Auth::$config["proxy"];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
$tokens = $this->api->requestToken($this->endpoint);
|
||||
|
||||
// request tokens as received from provider
|
||||
$this->request_tokens_raw = $tokens;
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5);
|
||||
}
|
||||
|
||||
if (!isset($tokens["oauth_token"])) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid oauth token.", 5);
|
||||
}
|
||||
|
||||
$this->token("request_token", $tokens["oauth_token"]);
|
||||
$this->token("request_token_secret", $tokens["oauth_token_secret"]);
|
||||
|
||||
# redirect the user to the provider authentication url
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($tokens));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
$oauth_token = (array_key_exists('oauth_token', $_REQUEST)) ? $_REQUEST['oauth_token'] : "";
|
||||
$oauth_verifier = (array_key_exists('oauth_verifier', $_REQUEST)) ? $_REQUEST['oauth_verifier'] : "";
|
||||
|
||||
if (!$oauth_token || !$oauth_verifier) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid oauth verifier.", 5);
|
||||
}
|
||||
|
||||
// request an access token
|
||||
$tokens = $this->api->accessToken($oauth_verifier);
|
||||
|
||||
// access tokens as received from provider
|
||||
$this->access_tokens_raw = $tokens;
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5);
|
||||
}
|
||||
|
||||
// we should have an access_token, or else, something has gone wrong
|
||||
if (!isset($tokens["oauth_token"])) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5);
|
||||
}
|
||||
|
||||
// we no more need to store request tokens
|
||||
$this->deleteToken("request_token");
|
||||
$this->deleteToken("request_token_secret");
|
||||
|
||||
// store access_token for later user
|
||||
$this->token("access_token", $tokens['oauth_token']);
|
||||
$this->token("access_token_secret", $tokens['oauth_token_secret']);
|
||||
|
||||
// set user as logged in to the current provider
|
||||
$this->setUserConnected();
|
||||
}
|
||||
|
||||
}
|
||||
184
plugin/social/Hybrid/Provider_Model_OAuth2.php
Normal file
@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* To implement an OAuth 2 based service provider, Hybrid_Provider_Model_OAuth2
|
||||
* can be used to save the hassle of the authentication flow.
|
||||
*
|
||||
* Each class that inherit from Hybrid_Provider_Model_OAuth2 have to implement
|
||||
* at least 2 methods:
|
||||
* Hybrid_Providers_{provider_name}::initialize() to setup the provider api end-points urls
|
||||
* Hybrid_Providers_{provider_name}::getUserProfile() to grab the user profile
|
||||
*
|
||||
* Hybrid_Provider_Model_OAuth2 use OAuth2Client v0.1 which can be found on
|
||||
* Hybrid/thirdparty/OAuth/OAuth2Client.php
|
||||
*/
|
||||
class Hybrid_Provider_Model_OAuth2 extends Hybrid_Provider_Model {
|
||||
|
||||
/**
|
||||
* Default permissions
|
||||
* @var string
|
||||
*/
|
||||
public $scope = "";
|
||||
|
||||
/**
|
||||
* Provider API wrapper
|
||||
* @var OAuth2Client
|
||||
*/
|
||||
public $api = null;
|
||||
|
||||
/**
|
||||
* Try to get the error message from provider api
|
||||
*
|
||||
* @param int $code Error code
|
||||
* @return string
|
||||
*/
|
||||
function errorMessageByStatus($code = null) {
|
||||
$http_status_codes = array(
|
||||
200 => "OK: Success!",
|
||||
304 => "Not Modified: There was no new data to return.",
|
||||
400 => "Bad Request: The request was invalid.",
|
||||
401 => "Unauthorized.",
|
||||
403 => "Forbidden: The request is understood, but it has been refused.",
|
||||
404 => "Not Found: The URI requested is invalid or the resource requested does not exists.",
|
||||
406 => "Not Acceptable.",
|
||||
500 => "Internal Server Error: Something is broken.",
|
||||
502 => "Bad Gateway.",
|
||||
503 => "Service Unavailable."
|
||||
);
|
||||
|
||||
if (!$code && $this->api) {
|
||||
$code = $this->api->http_code;
|
||||
}
|
||||
|
||||
if (isset($http_status_codes[$code])) {
|
||||
return $code . " " . $http_status_codes[$code];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter initializer
|
||||
*/
|
||||
function initialize() {
|
||||
if (!$this->config["keys"]["id"] || !$this->config["keys"]["secret"]) {
|
||||
throw new Exception("Your application id and secret are required in order to connect to {$this->providerId}.", 4);
|
||||
}
|
||||
|
||||
// override requested scope
|
||||
if (isset($this->config["scope"]) && !empty($this->config["scope"])) {
|
||||
$this->scope = $this->config["scope"];
|
||||
}
|
||||
|
||||
// include OAuth2 client
|
||||
require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth2Client.php";
|
||||
|
||||
// create a new OAuth2 client instance
|
||||
$this->api = new OAuth2Client($this->config["keys"]["id"], $this->config["keys"]["secret"], $this->endpoint, $this->compressed);
|
||||
|
||||
// If we have an access token, set it
|
||||
if ($this->token("access_token")) {
|
||||
$this->api->access_token = $this->token("access_token");
|
||||
$this->api->refresh_token = $this->token("refresh_token");
|
||||
$this->api->access_token_expires_in = $this->token("expires_in");
|
||||
$this->api->access_token_expires_at = $this->token("expires_at");
|
||||
}
|
||||
|
||||
// Set curl proxy if exist
|
||||
if (isset(Hybrid_Auth::$config["proxy"])) {
|
||||
$this->api->curl_proxy = Hybrid_Auth::$config["proxy"];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
// redirect the user to the provider authentication url
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl(array("scope" => $this->scope)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
$error = (array_key_exists('error', $_REQUEST)) ? $_REQUEST['error'] : "";
|
||||
|
||||
// check for errors
|
||||
if ($error) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error: $error", 5);
|
||||
}
|
||||
|
||||
// try to authenticate user
|
||||
$code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : "";
|
||||
|
||||
try {
|
||||
$this->api->authenticate($code);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an error: " . $e->getMessage(), 6);
|
||||
}
|
||||
|
||||
// check if authenticated
|
||||
if (!$this->api->access_token) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5);
|
||||
}
|
||||
|
||||
// store tokens
|
||||
$this->token("access_token", $this->api->access_token);
|
||||
$this->token("refresh_token", $this->api->refresh_token);
|
||||
$this->token("expires_in", $this->api->access_token_expires_in);
|
||||
$this->token("expires_at", $this->api->access_token_expires_at);
|
||||
|
||||
// set user connected locally
|
||||
$this->setUserConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function refreshToken() {
|
||||
// have an access token?
|
||||
if ($this->api->access_token) {
|
||||
|
||||
// have to refresh?
|
||||
if ($this->api->refresh_token && $this->api->access_token_expires_at) {
|
||||
|
||||
// expired?
|
||||
if ($this->api->access_token_expires_at <= time()) {
|
||||
$response = $this->api->refreshToken(array("refresh_token" => $this->api->refresh_token));
|
||||
|
||||
if (!isset($response->access_token) || !$response->access_token) {
|
||||
// set the user as disconnected at this point and throw an exception
|
||||
$this->setUserUnconnected();
|
||||
|
||||
throw new Exception("The Authorization Service has return an invalid response while requesting a new access token. " . (string) $response->error);
|
||||
}
|
||||
|
||||
// set new access_token
|
||||
$this->api->access_token = $response->access_token;
|
||||
|
||||
if (isset($response->refresh_token))
|
||||
$this->api->refresh_token = $response->refresh_token;
|
||||
|
||||
if (isset($response->expires_in)) {
|
||||
$this->api->access_token_expires_in = $response->expires_in;
|
||||
|
||||
// even given by some idp, we should calculate this
|
||||
$this->api->access_token_expires_at = time() + $response->expires_in;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// re store tokens
|
||||
$this->token("access_token", $this->api->access_token);
|
||||
$this->token("refresh_token", $this->api->refresh_token);
|
||||
$this->token("expires_in", $this->api->access_token_expires_in);
|
||||
$this->token("expires_at", $this->api->access_token_expires_at);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
170
plugin/social/Hybrid/Provider_Model_OpenID.php
Normal file
@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* To implement an OpenID based service provider, Hybrid_Provider_Model_OpenID
|
||||
* can be used to save the hassle of the authentication flow.
|
||||
*
|
||||
* Each class that inherit from Hybrid_Provider_Model_OAuth2 have only to define
|
||||
* the provider identifier : <code>public $openidIdentifier = ""; </code>
|
||||
*
|
||||
* Hybrid_Provider_Model_OpenID use LightOpenID lib which can be found on
|
||||
* Hybrid/thirdparty/OpenID/LightOpenID.php
|
||||
*/
|
||||
class Hybrid_Provider_Model_OpenID extends Hybrid_Provider_Model {
|
||||
|
||||
/**
|
||||
* Provider API client
|
||||
* @var LightOpenID
|
||||
*/
|
||||
public $api = null;
|
||||
|
||||
/**
|
||||
* Openid provider identifier
|
||||
* @var string
|
||||
*/
|
||||
public $openidIdentifier = "";
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
if (isset($this->params["openid_identifier"])) {
|
||||
$this->openidIdentifier = $this->params["openid_identifier"];
|
||||
}
|
||||
|
||||
// include LightOpenID lib
|
||||
require_once Hybrid_Auth::$config["path_libraries"] . "OpenID/LightOpenID.php";
|
||||
|
||||
// An error was occurring when proxy wasn't set. Not sure where proxy was meant to be set/initialized.
|
||||
Hybrid_Auth::$config['proxy'] = isset(Hybrid_Auth::$config['proxy']) ? Hybrid_Auth::$config['proxy'] : '';
|
||||
|
||||
$hostPort = parse_url(Hybrid_Auth::$config["base_url"], PHP_URL_PORT);
|
||||
$hostUrl = parse_url(Hybrid_Auth::$config["base_url"], PHP_URL_HOST);
|
||||
|
||||
// Check for port on url
|
||||
if ($hostPort) {
|
||||
$hostUrl .= ':' . $hostPort;
|
||||
}
|
||||
|
||||
$this->api = new LightOpenID($hostUrl, Hybrid_Auth::$config["proxy"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
if (empty($this->openidIdentifier)) {
|
||||
throw new Exception("OpenID adapter require the identity provider identifier 'openid_identifier' as an extra parameter.", 4);
|
||||
}
|
||||
|
||||
$this->api->identity = $this->openidIdentifier;
|
||||
$this->api->returnUrl = $this->endpoint;
|
||||
$this->api->required = array(
|
||||
'namePerson/first',
|
||||
'namePerson/last',
|
||||
'namePerson/friendly',
|
||||
'namePerson',
|
||||
'contact/email',
|
||||
'birthDate',
|
||||
'birthDate/birthDay',
|
||||
'birthDate/birthMonth',
|
||||
'birthDate/birthYear',
|
||||
'person/gender',
|
||||
'pref/language',
|
||||
'contact/postalCode/home',
|
||||
'contact/city/home',
|
||||
'contact/country/home',
|
||||
'media/image/default',
|
||||
);
|
||||
|
||||
# redirect the user to the provider authentication url
|
||||
Hybrid_Auth::redirect($this->api->authUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
# if user don't grant access of their data to your site, halt with an Exception
|
||||
if ($this->api->mode == 'cancel') {
|
||||
throw new Exception("Authentication failed! User has canceled authentication!", 5);
|
||||
}
|
||||
|
||||
# if something goes wrong
|
||||
if (!$this->api->validate()) {
|
||||
throw new Exception("Authentication failed. Invalid request received!", 5);
|
||||
}
|
||||
|
||||
# fetch received user data
|
||||
$response = $this->api->getAttributes();
|
||||
|
||||
# store the user profile
|
||||
$this->user->profile->identifier = $this->api->identity;
|
||||
|
||||
$this->user->profile->firstName = (array_key_exists("namePerson/first", $response)) ? $response["namePerson/first"] : "";
|
||||
$this->user->profile->lastName = (array_key_exists("namePerson/last", $response)) ? $response["namePerson/last"] : "";
|
||||
$this->user->profile->displayName = (array_key_exists("namePerson", $response)) ? $response["namePerson"] : "";
|
||||
$this->user->profile->email = (array_key_exists("contact/email", $response)) ? $response["contact/email"] : "";
|
||||
$this->user->profile->language = (array_key_exists("pref/language", $response)) ? $response["pref/language"] : "";
|
||||
$this->user->profile->country = (array_key_exists("contact/country/home", $response)) ? $response["contact/country/home"] : "";
|
||||
$this->user->profile->zip = (array_key_exists("contact/postalCode/home", $response)) ? $response["contact/postalCode/home"] : "";
|
||||
$this->user->profile->gender = (array_key_exists("person/gender", $response)) ? $response["person/gender"] : "";
|
||||
$this->user->profile->photoURL = (array_key_exists("media/image/default", $response)) ? $response["media/image/default"] : "";
|
||||
|
||||
$this->user->profile->birthDay = (array_key_exists("birthDate/birthDay", $response)) ? $response["birthDate/birthDay"] : "";
|
||||
$this->user->profile->birthMonth = (array_key_exists("birthDate/birthMonth", $response)) ? $response["birthDate/birthMonth"] : "";
|
||||
$this->user->profile->birthYear = (array_key_exists("birthDate/birthDate", $response)) ? $response["birthDate/birthDate"] : "";
|
||||
|
||||
if (isset($response['namePerson/friendly']) && !empty($response['namePerson/friendly']) && !$this->user->profile->displayName) {
|
||||
$this->user->profile->displayName = $response["namePerson/friendly"];
|
||||
}
|
||||
|
||||
if (isset($response['birthDate']) && !empty($response['birthDate']) && !$this->user->profile->birthDay) {
|
||||
list( $birthday_year, $birthday_month, $birthday_day ) = $response['birthDate'];
|
||||
|
||||
$this->user->profile->birthDay = (int) $birthday_day;
|
||||
$this->user->profile->birthMonth = (int) $birthday_month;
|
||||
$this->user->profile->birthYear = (int) $birthday_year;
|
||||
}
|
||||
|
||||
if (!$this->user->profile->displayName) {
|
||||
$this->user->profile->displayName = trim($this->user->profile->firstName . " " . $this->user->profile->lastName);
|
||||
}
|
||||
|
||||
if ($this->user->profile->gender == "f") {
|
||||
$this->user->profile->gender = "female";
|
||||
}
|
||||
|
||||
if ($this->user->profile->gender == "m") {
|
||||
$this->user->profile->gender = "male";
|
||||
}
|
||||
|
||||
// set user as logged in
|
||||
$this->setUserConnected();
|
||||
|
||||
// with openid providers we get the user profile only once, so store it
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.user", $this->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
// try to get the user profile from stored data
|
||||
$this->user = Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.user");
|
||||
|
||||
// if not found
|
||||
if (!is_object($this->user)) {
|
||||
throw new Exception("User profile request failed! User is not connected to {$this->providerId} or his session has expired.", 6);
|
||||
}
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
}
|
||||
335
plugin/social/Hybrid/Providers/Facebook.php
Normal file
@ -0,0 +1,335 @@
|
||||
<?php
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
/**
|
||||
* Hybrid_Providers_Facebook provider adapter based on OAuth2 protocol
|
||||
*
|
||||
* Hybrid_Providers_Facebook use the Facebook PHP SDK created by Facebook
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_Facebook.html
|
||||
*/
|
||||
class Hybrid_Providers_Facebook extends Hybrid_Provider_Model_OAuth2 {
|
||||
/**
|
||||
* default permissions, and a lot of them. You can change them from the configuration by setting the scope to what you want/need
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $scope = "email, user_about_me, user_birthday, user_hometown, user_location, user_website, publish_actions, read_custom_friendlists";
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
|
||||
parent::initialize();
|
||||
|
||||
// Provider API end-points
|
||||
$this->api->api_base_url = 'https://graph.facebook.com/';
|
||||
$this->api->authorize_url = 'https://www.facebook.com/dialog/oauth';
|
||||
$this->api->token_url = 'https://graph.facebook.com/v2.3/oauth/access_token';
|
||||
$this->api->token_debug = 'https://graph.facebook.com/debug_token';
|
||||
|
||||
if (!$this->config["keys"]["id"] || !$this->config["keys"]["secret"]) {
|
||||
throw new Exception("Your application id and secret are required in order to connect to {$this->providerId}.", 4);
|
||||
}
|
||||
|
||||
// redirect uri mismatches when authenticating with Facebook.
|
||||
if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) {
|
||||
$this->api->redirect_uri = $this->config['redirect_uri'];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
|
||||
$token = md5(uniqid(mt_rand(), true));
|
||||
Hybrid_Auth::storage()->set('fb_auth_nonce', $token);
|
||||
|
||||
$parameters = array(
|
||||
"response_type" => "code",
|
||||
"client_id" => $this->api->client_id,
|
||||
"redirect_uri" => $this->api->redirect_uri,
|
||||
"state" => $token,
|
||||
"scope" => $this->scope,
|
||||
);
|
||||
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($parameters));
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
|
||||
// in case we get error_reason=user_denied&error=access_denied
|
||||
if (isset($_REQUEST['error']) && $_REQUEST['error'] == "access_denied") {
|
||||
throw new Exception("Authentication failed! The user denied your request.", 5);
|
||||
}
|
||||
|
||||
// try to authenicate user
|
||||
$code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : "";
|
||||
try{
|
||||
$response = $this->api->authenticate( $code );
|
||||
}
|
||||
catch( Exception $e ){
|
||||
throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 );
|
||||
}
|
||||
|
||||
// check if authenticated
|
||||
if ( ! $this->api->authenticated() ){
|
||||
throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 );
|
||||
}
|
||||
// store tokens
|
||||
$this->token("access_token", $this->api->access_token);
|
||||
$this->token("refresh_token", $this->api->refresh_token);
|
||||
$this->token("expires_in", $this->api->access_token_expires_in);
|
||||
$this->token("expires_at", $this->api->access_token_expires_at);
|
||||
// set user connected locally
|
||||
$this->setUserConnected();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function logout() {
|
||||
parent::logout();
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
// request user profile from fb api
|
||||
try {
|
||||
$fields = array(
|
||||
'id', 'name', 'first_name', 'last_name', 'link', 'website',
|
||||
'gender', 'locale', 'about', 'email', 'hometown', 'location',
|
||||
'birthday'
|
||||
);
|
||||
$data = $this->api->api('/me?fields=' . implode(',', $fields).'&access_token='.$this->token('access_token'));
|
||||
} catch (Exception $e) {
|
||||
$this->logout();
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an error: {$e->getMessage()}", 6, $e);
|
||||
}
|
||||
|
||||
if( is_object($data) ){
|
||||
$data = json_decode(json_encode($data), true);
|
||||
}
|
||||
|
||||
// if the provider identifier is not received, we assume the auth has failed
|
||||
if (!isset($data["id"])) {
|
||||
$this->logout();
|
||||
throw new Exception("User profile request failed! {$this->providerId} api returned an invalid response: " . Hybrid_Logger::dumpData( $data ), 6);
|
||||
}
|
||||
# store the user profile.
|
||||
$this->user->profile->identifier = (array_key_exists('id', $data)) ? $data['id'] : "";
|
||||
$this->user->profile->username = (array_key_exists('username', $data)) ? $data['username'] : "";
|
||||
$this->user->profile->displayName = (array_key_exists('name', $data)) ? $data['name'] : "";
|
||||
$this->user->profile->firstName = (array_key_exists('first_name', $data)) ? $data['first_name'] : "";
|
||||
$this->user->profile->lastName = (array_key_exists('last_name', $data)) ? $data['last_name'] : "";
|
||||
$this->user->profile->photoURL = "https://graph.facebook.com/" . $this->user->profile->identifier . "/picture?width=150&height=150";
|
||||
$this->user->profile->coverInfoURL = "https://graph.facebook.com/" . $this->user->profile->identifier . "?fields=cover&access_token=" . $this->token('access_token');
|
||||
$this->user->profile->profileURL = (array_key_exists('link', $data)) ? $data['link'] : "";
|
||||
$this->user->profile->webSiteURL = (array_key_exists('website', $data)) ? $data['website'] : "";
|
||||
$this->user->profile->gender = (array_key_exists('gender', $data)) ? $data['gender'] : "";
|
||||
$this->user->profile->language = (array_key_exists('locale', $data)) ? $data['locale'] : "";
|
||||
$this->user->profile->description = (array_key_exists('about', $data)) ? $data['about'] : "";
|
||||
$this->user->profile->email = (array_key_exists('email', $data)) ? $data['email'] : "";
|
||||
$this->user->profile->emailVerified = (array_key_exists('email', $data)) ? $data['email'] : "";
|
||||
$this->user->profile->region = (array_key_exists("location", $data) && array_key_exists("name", $data['location'])) ? $data['location']["name"] : "";
|
||||
if (!empty($this->user->profile->region)) {
|
||||
$regionArr = explode(',', $this->user->profile->region);
|
||||
if (count($regionArr) > 1) {
|
||||
$this->user->profile->city = trim($regionArr[0]);
|
||||
$this->user->profile->country = trim($regionArr[1]);
|
||||
}
|
||||
}
|
||||
if (array_key_exists('birthday', $data)) {
|
||||
list($birthday_month, $birthday_day, $birthday_year) = explode("/", $data['birthday']);
|
||||
$this->user->profile->birthDay = (int) $birthday_day;
|
||||
$this->user->profile->birthMonth = (int) $birthday_month;
|
||||
$this->user->profile->birthYear = (int) $birthday_year;
|
||||
}
|
||||
|
||||
$this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId );
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
/**
|
||||
* Attempt to retrieve the url to the cover image given the coverInfoURL
|
||||
*
|
||||
* @param string $coverInfoURL coverInfoURL variable
|
||||
* @return string url to the cover image OR blank string
|
||||
*/
|
||||
function getCoverURL($coverInfoURL) {
|
||||
try {
|
||||
$headers = get_headers($coverInfoURL);
|
||||
if (substr($headers[0], 9, 3) != "404") {
|
||||
$coverOBJ = json_decode(file_get_contents($coverInfoURL));
|
||||
if (array_key_exists('cover', $coverOBJ)) {
|
||||
return $coverOBJ->cover->source;
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserContacts() {
|
||||
$apiCall = '?fields=link,name';
|
||||
$returnedContacts = array();
|
||||
$pagedList = false;
|
||||
do {
|
||||
try {
|
||||
$response = $this->api->api('/me/friends' . $apiCall);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("User contacts request failed! {$this->providerId} returned an error {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
// Prepare the next call if paging links have been returned
|
||||
if (array_key_exists('paging', $response) && array_key_exists('next', $response['paging'])) {
|
||||
$pagedList = true;
|
||||
$next_page = explode('friends', $response['paging']['next']);
|
||||
$apiCall = $next_page[1];
|
||||
} else {
|
||||
$pagedList = false;
|
||||
}
|
||||
// Add the new page contacts
|
||||
$returnedContacts = array_merge($returnedContacts, $response['data']);
|
||||
} while ($pagedList == true);
|
||||
$contacts = array();
|
||||
foreach ($returnedContacts as $item) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
$uc->identifier = (array_key_exists("id", $item)) ? $item["id"] : "";
|
||||
$uc->displayName = (array_key_exists("name", $item)) ? $item["name"] : "";
|
||||
$uc->profileURL = (array_key_exists("link", $item)) ? $item["link"] : "https://www.facebook.com/profile.php?id=" . $uc->identifier;
|
||||
$uc->photoURL = "https://graph.facebook.com/" . $uc->identifier . "/picture?width=150&height=150";
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
return $contacts;
|
||||
}
|
||||
/**
|
||||
* Update user status
|
||||
*
|
||||
* @param mixed $status An array describing the status, or string
|
||||
* @param string $pageid (optional) User page id
|
||||
* @return array
|
||||
* @throw Exception
|
||||
*/
|
||||
function setUserStatus($status, $pageid = null) {
|
||||
if (!is_array($status)) {
|
||||
$status = array('message' => $status);
|
||||
}
|
||||
if (is_null($pageid)) {
|
||||
$pageid = 'me';
|
||||
// if post on page, get access_token page
|
||||
} else {
|
||||
$access_token = null;
|
||||
foreach ($this->getUserPages(true) as $p) {
|
||||
if (isset($p['id']) && intval($p['id']) == intval($pageid)) {
|
||||
$access_token = $p['access_token'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_null($access_token)) {
|
||||
throw new Exception("Update user page failed, page not found or not writable!");
|
||||
}
|
||||
$status['access_token'] = $access_token;
|
||||
}
|
||||
try {
|
||||
$response = $this->api->api('/' . $pageid . '/feed', 'post', $status);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("Update user status failed! {$this->providerId} returned an error {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
/**
|
||||
* {@inheridoc}
|
||||
*/
|
||||
function getUserStatus($postid) {
|
||||
try {
|
||||
$postinfo = $this->api->api("/" . $postid);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("Cannot retrieve user status! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
return $postinfo;
|
||||
}
|
||||
/**
|
||||
* {@inheridoc}
|
||||
*/
|
||||
function getUserPages($writableonly = false) {
|
||||
if (( isset($this->config['scope']) && strpos($this->config['scope'], 'manage_pages') === false ) || (!isset($this->config['scope']) && strpos($this->scope, 'manage_pages') === false ))
|
||||
throw new Exception("User status requires manage_page permission!");
|
||||
try {
|
||||
$pages = $this->api->api("/me/accounts", 'get');
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("Cannot retrieve user pages! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
if (!isset($pages['data'])) {
|
||||
return array();
|
||||
}
|
||||
if (!$writableonly) {
|
||||
return $pages['data'];
|
||||
}
|
||||
$wrpages = array();
|
||||
foreach ($pages['data'] as $p) {
|
||||
if (isset($p['perms']) && in_array('CREATE_CONTENT', $p['perms'])) {
|
||||
$wrpages[] = $p;
|
||||
}
|
||||
}
|
||||
return $wrpages;
|
||||
}
|
||||
/**
|
||||
* load the user latest activity
|
||||
* - timeline : all the stream
|
||||
* - me : the user activity only
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserActivity($stream) {
|
||||
try {
|
||||
if ($stream == "me") {
|
||||
$response = $this->api->api('/me/feed');
|
||||
} else {
|
||||
$response = $this->api->api('/me/home');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("User activity stream request failed! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
if (!$response || !count($response['data'])) {
|
||||
return array();
|
||||
}
|
||||
$activities = array();
|
||||
foreach ($response['data'] as $item) {
|
||||
if ($stream == "me" && $item["from"]["id"] != $this->api->getUser()) {
|
||||
continue;
|
||||
}
|
||||
$ua = new Hybrid_User_Activity();
|
||||
$ua->id = (array_key_exists("id", $item)) ? $item["id"] : "";
|
||||
$ua->date = (array_key_exists("created_time", $item)) ? strtotime($item["created_time"]) : "";
|
||||
if ($item["type"] == "video") {
|
||||
$ua->text = (array_key_exists("link", $item)) ? $item["link"] : "";
|
||||
}
|
||||
if ($item["type"] == "link") {
|
||||
$ua->text = (array_key_exists("link", $item)) ? $item["link"] : "";
|
||||
}
|
||||
if (empty($ua->text) && isset($item["story"])) {
|
||||
$ua->text = (array_key_exists("link", $item)) ? $item["link"] : "";
|
||||
}
|
||||
if (empty($ua->text) && isset($item["message"])) {
|
||||
$ua->text = (array_key_exists("message", $item)) ? $item["message"] : "";
|
||||
}
|
||||
if (!empty($ua->text)) {
|
||||
$ua->user->identifier = (array_key_exists("id", $item["from"])) ? $item["from"]["id"] : "";
|
||||
$ua->user->displayName = (array_key_exists("name", $item["from"])) ? $item["from"]["name"] : "";
|
||||
$ua->user->profileURL = "https://www.facebook.com/profile.php?id=" . $ua->user->identifier;
|
||||
$ua->user->photoURL = "https://graph.facebook.com/" . $ua->user->identifier . "/picture?type=square";
|
||||
$activities[] = $ua;
|
||||
}
|
||||
}
|
||||
return $activities;
|
||||
}
|
||||
}
|
||||
308
plugin/social/Hybrid/Providers/Google.php
Normal file
@ -0,0 +1,308 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Google provider adapter based on OAuth2 protocol
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_Google.html
|
||||
*/
|
||||
class Hybrid_Providers_Google extends Hybrid_Provider_Model_OAuth2 {
|
||||
|
||||
/**
|
||||
* > more infos on google APIs: http://developer.google.com (official site)
|
||||
* or here: http://discovery-check.appspot.com/ (unofficial but up to date)
|
||||
* default permissions
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $scope = "https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.profile.emails.read https://www.google.com/m8/feeds/";
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
// Provider api end-points
|
||||
$this->api->authorize_url = "https://accounts.google.com/o/oauth2/auth";
|
||||
$this->api->token_url = "https://accounts.google.com/o/oauth2/token";
|
||||
$this->api->token_info_url = "https://www.googleapis.com/oauth2/v2/tokeninfo";
|
||||
|
||||
// Google POST methods require an access_token in the header
|
||||
$this->api->curl_header = array("Authorization: OAuth " . $this->api->access_token);
|
||||
|
||||
// Override the redirect uri when it's set in the config parameters. This way we prevent
|
||||
// redirect uri mismatches when authenticating with Google.
|
||||
if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) {
|
||||
$this->api->redirect_uri = $this->config['redirect_uri'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
$parameters = array("scope" => $this->scope, "access_type" => "offline");
|
||||
$optionals = array("scope", "access_type", "redirect_uri", "approval_prompt", "hd", "state");
|
||||
|
||||
foreach ($optionals as $parameter) {
|
||||
if (isset($this->config[$parameter]) && !empty($this->config[$parameter])) {
|
||||
$parameters[$parameter] = $this->config[$parameter];
|
||||
}
|
||||
if (isset($this->config["scope"]) && !empty($this->config["scope"])) {
|
||||
$this->scope = $this->config["scope"];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->config['force']) && $this->config['force'] === true) {
|
||||
$parameters['approval_prompt'] = 'force';
|
||||
}
|
||||
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
// refresh tokens if needed
|
||||
$this->refreshToken();
|
||||
|
||||
// ask google api for user infos
|
||||
if (strpos($this->scope, '/auth/plus.profile.emails.read') !== false) {
|
||||
$verified = $this->api->api("https://www.googleapis.com/plus/v1/people/me");
|
||||
|
||||
if (!isset($verified->id) || isset($verified->error))
|
||||
$verified = new stdClass();
|
||||
} else {
|
||||
$verified = $this->api->api("https://www.googleapis.com/plus/v1/people/me/openIdConnect");
|
||||
|
||||
if (!isset($verified->sub) || isset($verified->error))
|
||||
$verified = new stdClass();
|
||||
}
|
||||
|
||||
$response = $this->api->api("https://www.googleapis.com/plus/v1/people/me");
|
||||
if (!isset($response->id) || isset($response->error)) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an invalid response:" . Hybrid_Logger::dumpData( $response ), 6);
|
||||
}
|
||||
|
||||
$this->user->profile->identifier = (property_exists($verified, 'id')) ? $verified->id : ((property_exists($response, 'id')) ? $response->id : "");
|
||||
$this->user->profile->firstName = (property_exists($response, 'name')) ? $response->name->givenName : "";
|
||||
$this->user->profile->lastName = (property_exists($response, 'name')) ? $response->name->familyName : "";
|
||||
$this->user->profile->displayName = (property_exists($response, 'displayName')) ? $response->displayName : "";
|
||||
$this->user->profile->photoURL = (property_exists($response, 'image')) ? ((property_exists($response->image, 'url')) ? substr($response->image->url, 0, -2) . "200" : '') : '';
|
||||
$this->user->profile->profileURL = (property_exists($response, 'url')) ? $response->url : "";
|
||||
$this->user->profile->description = (property_exists($response, 'aboutMe')) ? $response->aboutMe : "";
|
||||
$this->user->profile->gender = (property_exists($response, 'gender')) ? $response->gender : "";
|
||||
$this->user->profile->language = (property_exists($response, 'locale')) ? $response->locale : ((property_exists($verified, 'locale')) ? $verified->locale : "");
|
||||
$this->user->profile->email = (property_exists($response, 'email')) ? $response->email : ((property_exists($verified, 'email')) ? $verified->email : "");
|
||||
$this->user->profile->emailVerified = (property_exists($verified, 'email')) ? $verified->email : "";
|
||||
if (property_exists($response, 'emails')) {
|
||||
if (count($response->emails) == 1) {
|
||||
$this->user->profile->email = $response->emails[0]->value;
|
||||
} else {
|
||||
foreach ($response->emails as $email) {
|
||||
if ($email->type == 'account') {
|
||||
$this->user->profile->email = $email->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (property_exists($verified, 'emails')) {
|
||||
if (count($verified->emails) == 1) {
|
||||
$this->user->profile->emailVerified = $verified->emails[0]->value;
|
||||
} else {
|
||||
foreach ($verified->emails as $email) {
|
||||
if ($email->type == 'account') {
|
||||
$this->user->profile->emailVerified = $email->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->user->profile->phone = (property_exists($response, 'phone')) ? $response->phone : "";
|
||||
$this->user->profile->country = (property_exists($response, 'country')) ? $response->country : "";
|
||||
$this->user->profile->region = (property_exists($response, 'region')) ? $response->region : "";
|
||||
$this->user->profile->zip = (property_exists($response, 'zip')) ? $response->zip : "";
|
||||
if (property_exists($response, 'placesLived')) {
|
||||
$this->user->profile->city = "";
|
||||
$this->user->profile->address = "";
|
||||
foreach ($response->placesLived as $c) {
|
||||
if (property_exists($c, 'primary')) {
|
||||
if ($c->primary == true) {
|
||||
$this->user->profile->address = $c->value;
|
||||
$this->user->profile->city = $c->value;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (property_exists($c, 'value')) {
|
||||
$this->user->profile->address = $c->value;
|
||||
$this->user->profile->city = $c->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// google API returns multiple urls, but a "website" only if it is verified
|
||||
// see http://support.google.com/plus/answer/1713826?hl=en
|
||||
if (property_exists($response, 'urls')) {
|
||||
foreach ($response->urls as $u) {
|
||||
if (property_exists($u, 'primary') && $u->primary == true)
|
||||
$this->user->profile->webSiteURL = $u->value;
|
||||
}
|
||||
} else {
|
||||
$this->user->profile->webSiteURL = '';
|
||||
}
|
||||
// google API returns age ranges min and/or max as of https://developers.google.com/+/web/api/rest/latest/people#resource
|
||||
if (property_exists($response, 'ageRange')) {
|
||||
if (property_exists($response->ageRange, 'min') && property_exists($response->ageRange, 'max')) {
|
||||
$this->user->profile->age = $response->ageRange->min . ' - ' . $response->ageRange->max;
|
||||
} else {
|
||||
if (property_exists($response->ageRange, 'min')) {
|
||||
$this->user->profile->age = '>= ' . $response->ageRange->min;
|
||||
} else {
|
||||
if (property_exists($response->ageRange, 'max')) {
|
||||
$this->user->profile->age = '<= ' . $response->ageRange->max;
|
||||
} else {
|
||||
$this->user->profile->age = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->user->profile->age = '';
|
||||
}
|
||||
// google API returns birthdays only if a user set 'show in my account'
|
||||
if (property_exists($response, 'birthday')) {
|
||||
list($birthday_year, $birthday_month, $birthday_day) = explode('-', $response->birthday);
|
||||
|
||||
$this->user->profile->birthDay = (int) $birthday_day;
|
||||
$this->user->profile->birthMonth = (int) $birthday_month;
|
||||
$this->user->profile->birthYear = (int) $birthday_year;
|
||||
} else {
|
||||
$this->user->profile->birthDay = 0;
|
||||
$this->user->profile->birthMonth = 0;
|
||||
$this->user->profile->birthYear = 0;
|
||||
}
|
||||
|
||||
$this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId );
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserContacts() {
|
||||
// refresh tokens if needed
|
||||
$this->refreshToken();
|
||||
|
||||
$contacts = array();
|
||||
if (!isset($this->config['contacts_param'])) {
|
||||
$this->config['contacts_param'] = array("max-results" => 500);
|
||||
}
|
||||
|
||||
// Google Gmail and Android contacts
|
||||
if (strpos($this->scope, '/m8/feeds/') !== false) {
|
||||
|
||||
$response = $this->api->api("https://www.google.com/m8/feeds/contacts/default/full?"
|
||||
. http_build_query(array_merge(array('alt' => 'json'), $this->config['contacts_param'])));
|
||||
|
||||
if (!$response) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if (isset($response->feed->entry)) {
|
||||
foreach ($response->feed->entry as $idx => $entry) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
$uc->email = isset($entry->{'gd$email'}[0]->address) ? (string) $entry->{'gd$email'}[0]->address : '';
|
||||
$uc->displayName = isset($entry->title->{'$t'}) ? (string) $entry->title->{'$t'} : '';
|
||||
$uc->identifier = ($uc->email != '') ? $uc->email : '';
|
||||
$uc->description = '';
|
||||
if (property_exists($entry, 'link')) {
|
||||
/**
|
||||
* sign links with access_token
|
||||
*/
|
||||
if (is_array($entry->link)) {
|
||||
foreach ($entry->link as $l) {
|
||||
if (property_exists($l, 'gd$etag') && $l->type == "image/*") {
|
||||
$uc->photoURL = $this->addUrlParam($l->href, array('access_token' => $this->api->access_token));
|
||||
} else if ($l->type == "self") {
|
||||
$uc->profileURL = $this->addUrlParam($l->href, array('access_token' => $this->api->access_token));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$uc->profileURL = '';
|
||||
}
|
||||
if (property_exists($response, 'website')) {
|
||||
if (is_array($response->website)) {
|
||||
foreach ($response->website as $w) {
|
||||
if ($w->primary == true)
|
||||
$uc->webSiteURL = $w->value;
|
||||
}
|
||||
} else {
|
||||
$uc->webSiteURL = $response->website->value;
|
||||
}
|
||||
} else {
|
||||
$uc->webSiteURL = '';
|
||||
}
|
||||
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Google social contacts
|
||||
if (strpos($this->scope, '/auth/plus.login') !== false) {
|
||||
|
||||
$response = $this->api->api("https://www.googleapis.com/plus/v1/people/me/people/visible?"
|
||||
. http_build_query($this->config['contacts_param']));
|
||||
|
||||
if (!$response) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ($response->items as $idx => $item) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
$uc->email = (property_exists($item, 'email')) ? $item->email : '';
|
||||
$uc->displayName = (property_exists($item, 'displayName')) ? $item->displayName : '';
|
||||
$uc->identifier = (property_exists($item, 'id')) ? $item->id : '';
|
||||
|
||||
$uc->description = (property_exists($item, 'objectType')) ? $item->objectType : '';
|
||||
$uc->photoURL = (property_exists($item, 'image')) ? ((property_exists($item->image, 'url')) ? $item->image->url : '') : '';
|
||||
$uc->profileURL = (property_exists($item, 'url')) ? $item->url : '';
|
||||
$uc->webSiteURL = '';
|
||||
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add query parameters to the $url
|
||||
*
|
||||
* @param string $url URL
|
||||
* @param array $params Parameters to add
|
||||
* @return string
|
||||
*/
|
||||
function addUrlParam($url, array $params){
|
||||
$query = parse_url($url, PHP_URL_QUERY);
|
||||
|
||||
// Returns the URL string with new parameters
|
||||
if ($query) {
|
||||
$url .= '&' . http_build_query($params);
|
||||
} else {
|
||||
$url .= '?' . http_build_query($params);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
177
plugin/social/Hybrid/Providers/Kakao.php
Normal file
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Team TamedBitches.
|
||||
* Written by Chuck JS. Oh <jinseokoh@hotmail.com>
|
||||
* http://facebook.com/chuckoh
|
||||
*
|
||||
* Date: 11 10, 2014
|
||||
* Time: 01:51 AM
|
||||
*
|
||||
* This program is free software. It comes without any warranty, to
|
||||
* the extent permitted by applicable law. You can redistribute it
|
||||
* and/or modify it under the terms of the Do What The Fuck You Want
|
||||
* To Public License, Version 2, as published by Sam Hocevar. See
|
||||
* http://www.wtfpl.net/txt/copying/ for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
//https://github.com/jinseokoh/additional-providers
|
||||
class Hybrid_Providers_Kakao extends Hybrid_Provider_Model_OAuth2
|
||||
{
|
||||
/**
|
||||
* initialization
|
||||
*/
|
||||
function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
// Provider API end-points
|
||||
$this->api->api_base_url = "https://kapi.kakao.com/v1/";
|
||||
$this->api->authorize_url = "https://kauth.kakao.com/oauth/authorize";
|
||||
$this->api->token_url = "https://kauth.kakao.com/oauth/token";
|
||||
|
||||
// redirect uri mismatches when authenticating with Kakao.
|
||||
if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) {
|
||||
$this->api->redirect_uri = $this->config['redirect_uri'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* finish login step
|
||||
*/
|
||||
function loginFinish()
|
||||
{
|
||||
$error = (array_key_exists('error', $_REQUEST)) ? $_REQUEST['error'] : "";
|
||||
// check for errors
|
||||
if ( $error ){
|
||||
throw new Exception( "Authentication failed! {$this->providerId} returned an error: $error", 5 );
|
||||
}
|
||||
// try to authenicate user
|
||||
$code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : "";
|
||||
try{
|
||||
$this->authenticate( $code );
|
||||
}
|
||||
catch( Exception $e ){
|
||||
throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 );
|
||||
}
|
||||
// check if authenticated
|
||||
if ( ! $this->api->access_token ){
|
||||
throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 );
|
||||
}
|
||||
// store tokens
|
||||
$this->token("access_token", $this->api->access_token);
|
||||
$this->token("refresh_token", $this->api->refresh_token);
|
||||
$this->token("expires_in", $this->api->access_token_expires_in);
|
||||
$this->token("expires_at", $this->api->access_token_expires_at);
|
||||
// set user connected locally
|
||||
$this->setUserConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* load the user profile
|
||||
*/
|
||||
function getUserProfile()
|
||||
{
|
||||
$params = array('property_keys'=>'kaccount_email');
|
||||
|
||||
$this->api->decode_json = false;
|
||||
$this->api->curl_header = array( 'Authorization: Bearer ' . $this->api->access_token );
|
||||
|
||||
$data = $this->api->api("user/me", "POST", $params);
|
||||
|
||||
if ( ! isset( $data->id ) ) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an invalid response.", 6);
|
||||
}
|
||||
# store the user profile.
|
||||
$this->user->profile->identifier = @ $data->id;
|
||||
$this->user->profile->displayName = @ $data->properties->nickname;
|
||||
$this->user->profile->photoURL = @ $data->properties->thumbnail_image;
|
||||
$email = @ $data->kaccount_email;
|
||||
|
||||
if( $email ){
|
||||
$this->user->profile->email = $email;
|
||||
}
|
||||
|
||||
$this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId );
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
private function authenticate($code)
|
||||
{
|
||||
$params = array(
|
||||
"grant_type" => "authorization_code",
|
||||
"client_id" => $this->api->client_id,
|
||||
"redirect_uri" => $this->api->redirect_uri,
|
||||
"code" => $code
|
||||
);
|
||||
|
||||
if( $this->api->client_secret && ($this->api->client_secret !== $this->api->client_id) ){
|
||||
$params['client_secret'] = $this->api->client_secret;
|
||||
}
|
||||
|
||||
$response = $this->request($this->api->token_url, $params, $this->api->curl_authenticate_method);
|
||||
$response = $this->parseRequestResult($response);
|
||||
if ( ! $response || ! isset($response->access_token) ) {
|
||||
throw new Exception("The Authorization Service has return: " . $response->error);
|
||||
}
|
||||
if ( isset($response->access_token) ) $this->api->access_token = $response->access_token;
|
||||
if ( isset($response->refresh_token) ) $this->api->refresh_token = $response->refresh_token;
|
||||
if ( isset($response->expires_in) ) $this->api->access_token_expires_in = $response->expires_in;
|
||||
|
||||
// calculate when the access token expire
|
||||
if ( isset($response->expires_in) ) {
|
||||
$this->api->access_token_expires_at = time() + $response->expires_in;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function request($url, $params=false, $type="GET")
|
||||
{
|
||||
if(Class_exists('Hybrid_Logger')){
|
||||
Hybrid_Logger::info("Enter OAuth2Client::request( $url )");
|
||||
Hybrid_Logger::debug("OAuth2Client::request(). dump request params: ", serialize( $params ));
|
||||
}
|
||||
$this->http_info = array();
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL , $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT , $this->api->curl_time_out);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT , $this->api->curl_useragent);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->api->curl_connect_time_out);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->api->curl_ssl_verifypeer);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER , $this->api->curl_header);
|
||||
|
||||
if ( $this->api->curl_proxy ) {
|
||||
curl_setopt( $ch, CURLOPT_PROXY, $this->curl_proxy);
|
||||
}
|
||||
if ( $type == "POST" ) {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
if ($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($params) );
|
||||
}
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if(Class_exists('Hybrid_Logger')){
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request info: ", serialize(curl_getinfo($ch)) );
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request result: ", serialize($response ));
|
||||
}
|
||||
$this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$this->http_info = array_merge($this->http_info, curl_getinfo($ch));
|
||||
curl_close ($ch);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function parseRequestResult($result)
|
||||
{
|
||||
if ( json_decode($result) ) return json_decode($result);
|
||||
parse_str( $result, $ouput );
|
||||
$result = new StdClass();
|
||||
foreach( $ouput as $k => $v )
|
||||
$result->$k = $v;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
234
plugin/social/Hybrid/Providers/Naver.php
Normal file
@ -0,0 +1,234 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Team TamedBitches.
|
||||
* Written by Chuck JS. Oh <jinseokoh@hotmail.com>
|
||||
* http://facebook.com/chuckoh
|
||||
*
|
||||
* Date: 11 11, 2014
|
||||
* Time: 11:38 AM
|
||||
*
|
||||
* This program is free software. It comes without any warranty, to
|
||||
* the extent permitted by applicable law. You can redistribute it
|
||||
* and/or modify it under the terms of the Do What The Fuck You Want
|
||||
* To Public License, Version 2, as published by Sam Hocevar. See
|
||||
* http://www.wtfpl.net/txt/copying/ for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
//https://github.com/jinseokoh/additional-providers
|
||||
class Hybrid_Providers_Naver extends Hybrid_Provider_Model_OAuth2
|
||||
{
|
||||
/**
|
||||
* initialization
|
||||
*/
|
||||
function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
// Provider API end-points
|
||||
$this->api->api_base_url = "https://apis.naver.com/nidlogin/";
|
||||
$this->api->authorize_url = "https://nid.naver.com/oauth2.0/authorize";
|
||||
$this->api->token_url = "https://nid.naver.com/oauth2.0/token";
|
||||
|
||||
// redirect uri mismatches when authenticating with Naver.
|
||||
if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) {
|
||||
$this->api->redirect_uri = $this->config['redirect_uri'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* begin login step
|
||||
*/
|
||||
function loginBegin()
|
||||
{
|
||||
$token = $this->generate_state_token();
|
||||
Hybrid_Auth::storage()->set("naver_state_token", $token);
|
||||
|
||||
$parameters = array(
|
||||
"response_type" => "code",
|
||||
"client_id" => $this->api->client_id,
|
||||
"redirect_uri" => $this->api->redirect_uri,
|
||||
"state" => $token,
|
||||
);
|
||||
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
* finish login step
|
||||
*/
|
||||
function loginFinish()
|
||||
{
|
||||
$error = (array_key_exists('error', $_REQUEST)) ? $_REQUEST['error'] : "";
|
||||
// check for errors
|
||||
if ( $error ){
|
||||
throw new Exception( "Authentication failed! {$this->providerId} returned an error: $error", 5 );
|
||||
}
|
||||
// try to authenicate user
|
||||
$code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : "";
|
||||
try{
|
||||
$this->authenticate( $code );
|
||||
}
|
||||
catch( Exception $e ){
|
||||
throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 );
|
||||
}
|
||||
// check if authenticated
|
||||
if ( ! $this->api->access_token ){
|
||||
throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 );
|
||||
}
|
||||
// store tokens
|
||||
$this->token("access_token", $this->api->access_token);
|
||||
$this->token("refresh_token", $this->api->refresh_token);
|
||||
$this->token("expires_in", $this->api->access_token_expires_in);
|
||||
$this->token("expires_at", $this->api->access_token_expires_at);
|
||||
// set user connected locally
|
||||
$this->setUserConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* set propper headers
|
||||
*/
|
||||
function profile($url) {
|
||||
$this->api->decode_json = false;
|
||||
$this->api->curl_header = array( 'Authorization: Bearer ' . $this->api->access_token );
|
||||
$response = $this->api->get($url, array(), false);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* load the user profile
|
||||
*/
|
||||
//https://developers.naver.com/docs/login/profile/
|
||||
function getUserProfile()
|
||||
{
|
||||
$response = $this->profile("nid/getUserProfile.xml");
|
||||
|
||||
$xml = @ new SimpleXMLElement($response);
|
||||
$data = array();
|
||||
if ( $xml->result[0]->resultcode == '00' ) {
|
||||
foreach ($xml->response->children() as $response => $k) {
|
||||
$data[(string)$response] = (string) $k;
|
||||
}
|
||||
} else {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an invalid response.", 6);
|
||||
}
|
||||
|
||||
# store the user profile.
|
||||
//$this->user->profile->identifier = (array_key_exists('enc_id',$data))?$data['enc_id']:"";
|
||||
$this->user->profile->identifier = (array_key_exists('id',$data))?$data['id']:"";
|
||||
$this->user->profile->age = (array_key_exists('age',$data))?$data['age']:"";
|
||||
$this->user->profile->displayName = '';
|
||||
/*
|
||||
if( array_key_exists('email',$data) ){
|
||||
$tmp = explode("@", $data['email']);
|
||||
$this->user->profile->displayName = $tmp[0];
|
||||
}
|
||||
*/
|
||||
$this->user->profile->displayName = (array_key_exists('nickname',$data))?$data['nickname']:"";
|
||||
$this->user->profile->birthDay = '';
|
||||
$this->user->profile->birthMonth = '';
|
||||
if( array_key_exists('birthday',$data) ){
|
||||
$tmp = explode("-",$data['birthday']);
|
||||
if( isset($tmp[0]) ){
|
||||
$this->user->profile->birthDay = $tmp[0];
|
||||
}
|
||||
if( isset($tmp[1]) ){
|
||||
$this->user->profile->birthMonth = $tmp[1];
|
||||
}
|
||||
}
|
||||
$this->user->profile->email = (array_key_exists('email',$data))?$data['email']:"";
|
||||
$this->user->profile->emailVerified = (array_key_exists('email',$data))?$data['email']:"";
|
||||
$this->user->profile->gender = (array_key_exists('gender',$data))?(($data['gender'] == "M")?"male":"female"):"";
|
||||
$this->user->profile->photoURL = (array_key_exists('profile_image',$data))?$data['profile_image']:"";
|
||||
|
||||
$this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId );
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
private function authenticate($code)
|
||||
{
|
||||
$token = Hybrid_Auth::storage()->get("naver_state_token");
|
||||
$params = array(
|
||||
"grant_type" => "authorization_code",
|
||||
"client_id" => $this->api->client_id,
|
||||
"client_secret" => $this->api->client_secret,
|
||||
// "redirect_uri" => $this->api->redirect_uri,
|
||||
"code" => $code,
|
||||
"state" => $token
|
||||
);
|
||||
Hybrid_Auth::storage()->set("naver_state_token", null);
|
||||
|
||||
$response = $this->request($this->api->token_url, $params, $this->api->curl_authenticate_method);
|
||||
$response = $this->parseRequestResult($response);
|
||||
if ( ! $response || ! isset($response->access_token) ) {
|
||||
throw new Exception("The Authorization Service has return: " . $response->error);
|
||||
}
|
||||
if ( isset($response->access_token) ) $this->api->access_token = $response->access_token;
|
||||
if ( isset($response->refresh_token) ) $this->api->refresh_token = $response->refresh_token;
|
||||
if ( isset($response->expires_in) ) $this->api->access_token_expires_in = $response->expires_in;
|
||||
|
||||
// calculate when the access token expire
|
||||
if ( isset($response->expires_in) ) {
|
||||
$this->api->access_token_expires_at = time() + $response->expires_in;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function request($url, $params=false, $type="GET")
|
||||
{
|
||||
if(Class_exists('Hybrid_Logger')){
|
||||
Hybrid_Logger::info("Enter OAuth2Client::request( $url )");
|
||||
Hybrid_Logger::debug("OAuth2Client::request(). dump request params: ", serialize( $params ));
|
||||
}
|
||||
$this->http_info = array();
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL , $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT , $this->api->curl_time_out);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT , $this->api->curl_useragent);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->api->curl_connect_time_out);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->api->curl_ssl_verifypeer);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER , $this->api->curl_header);
|
||||
|
||||
if ( $this->api->curl_proxy ) {
|
||||
curl_setopt( $ch, CURLOPT_PROXY, $this->curl_proxy);
|
||||
}
|
||||
if ( $type == "POST" ) {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
if ($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($params) );
|
||||
}
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if(Class_exists('Hybrid_Logger')){
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request info: ", serialize(curl_getinfo($ch)) );
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request result: ", serialize($response ));
|
||||
}
|
||||
$this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$this->http_info = array_merge($this->http_info, curl_getinfo($ch));
|
||||
curl_close ($ch);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function parseRequestResult($result)
|
||||
{
|
||||
if ( json_decode($result) ) return json_decode($result);
|
||||
parse_str( $result, $ouput );
|
||||
$result = new StdClass();
|
||||
foreach( $ouput as $k => $v )
|
||||
$result->$k = $v;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function generate_state_token() {
|
||||
$mt = microtime();
|
||||
$rand = mt_rand();
|
||||
|
||||
return md5($mt . $rand);
|
||||
}
|
||||
}
|
||||
212
plugin/social/Hybrid/Providers/Payco.php
Normal file
@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
/**
|
||||
* Hybrid_Providers_Payco provider adapter based on OAuth2 protocol
|
||||
* Copyright (c) 2017 SIR - thisgun
|
||||
* http://sir.kr
|
||||
*
|
||||
*
|
||||
*/
|
||||
class Hybrid_Providers_Payco extends Hybrid_Provider_Model_OAuth2 {
|
||||
|
||||
private $idNo;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
|
||||
parent::initialize();
|
||||
|
||||
// Provider API end-points
|
||||
$this->api->api_base_url = 'https://id.payco.com/oauth2.0/';
|
||||
$this->api->authorize_url = 'https://id.payco.com/oauth2.0/authorize';
|
||||
$this->api->token_url = 'https://id.payco.com/oauth2.0/token';
|
||||
$this->api->token_info = 'https://apis3.krp.toastoven.net/payco/friends/getIdNoByFriendsToken.json';
|
||||
$this->api->profile_url = 'https://apis3.krp.toastoven.net/payco/friends/getMemberProfileByFriendsToken.json';
|
||||
|
||||
if (!$this->config["keys"]["id"] || !$this->config["keys"]["secret"]) {
|
||||
throw new Exception("Your application id and secret are required in order to connect to {$this->providerId}.", 4);
|
||||
}
|
||||
|
||||
// redirect uri mismatches when authenticating with Payco.
|
||||
if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) {
|
||||
$this->api->redirect_uri = $this->config['redirect_uri'];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
|
||||
$token = md5(uniqid(mt_rand(), true));
|
||||
Hybrid_Auth::storage()->set('payco_auth_token', $token);
|
||||
|
||||
$parameters = array(
|
||||
"response_type" => "code",
|
||||
"client_id" => $this->api->client_id,
|
||||
"redirect_uri" => $this->api->redirect_uri,
|
||||
"state" => $token,
|
||||
"userLocale" => "ko_KR",
|
||||
"serviceProviderCode" => "FRIENDS",
|
||||
);
|
||||
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($parameters));
|
||||
|
||||
exit;
|
||||
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
|
||||
// in case we get error_reason=user_denied&error=access_denied
|
||||
if (isset($_REQUEST['error']) && $_REQUEST['error'] == "access_denied") {
|
||||
throw new Exception("Authentication failed! The user denied your request.", 5);
|
||||
}
|
||||
|
||||
// try to authenicate user
|
||||
$code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : "";
|
||||
try{
|
||||
$response = $this->api->authenticate( $code );
|
||||
}
|
||||
catch( Exception $e ){
|
||||
throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 );
|
||||
}
|
||||
|
||||
// check if authenticated
|
||||
if ( ! $this->api->authenticated() ){
|
||||
throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 );
|
||||
}
|
||||
// store tokens
|
||||
$this->token("access_token", $this->api->access_token);
|
||||
$this->token("refresh_token", $this->api->refresh_token);
|
||||
$this->token("expires_in", $this->api->access_token_expires_in);
|
||||
$this->token("expires_at", $this->api->access_token_expires_at);
|
||||
|
||||
$this->setUserConnected();
|
||||
|
||||
}
|
||||
|
||||
function check_valid_access_token(){
|
||||
|
||||
$params = array(
|
||||
'body' => array(
|
||||
'client_id'=>$this->api->client_id,
|
||||
'access_token'=>$this->api->access_token,
|
||||
),
|
||||
);
|
||||
|
||||
$this->api->curl_header = array(
|
||||
|
||||
'Content-Type:application/json',
|
||||
'client_id: '.$this->api->client_id,
|
||||
'access_token: '.$this->api->access_token,
|
||||
|
||||
);
|
||||
|
||||
$response = $this->api->api( $this->api->token_info, 'POST', $params );
|
||||
|
||||
if( is_object($response) && !empty($response->idNo) && $response->header->successful ){
|
||||
$this->idNo = $response->idNo;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function logout() {
|
||||
parent::logout();
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
/**
|
||||
* set propper headers
|
||||
*/
|
||||
function getUserProfile() {
|
||||
|
||||
$data = null;
|
||||
|
||||
// request user profile
|
||||
try {
|
||||
|
||||
if( $this->check_valid_access_token() ){
|
||||
$params = array(
|
||||
'body' => array(
|
||||
'client_id'=>$this->api->client_id,
|
||||
'access_token'=>$this->api->access_token,
|
||||
'MemberProfile'=>'idNo,id,name',
|
||||
'idNo'=>$this->idNo,
|
||||
),
|
||||
);
|
||||
|
||||
$this->api->curl_header = array(
|
||||
'Content-Type:application/json',
|
||||
'client_id: '.$this->api->client_id,
|
||||
'access_token: '.$this->api->access_token,
|
||||
'Authorization: Bearer ' . $this->api->access_token,
|
||||
);
|
||||
|
||||
$response = $this->api->api( $this->api->profile_url, 'POST', $params );
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an error: {$e->getMessage()}", 6, $e);
|
||||
}
|
||||
|
||||
if( ! is_object($response) || property_exists($response, 'error_code') ){
|
||||
$this->logout();
|
||||
|
||||
throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 );
|
||||
}
|
||||
|
||||
if( is_object($response) ){
|
||||
$result = json_decode(json_encode($response), true);
|
||||
$data = $result['memberProfile'];
|
||||
}
|
||||
|
||||
// if the provider identifier is not received, we assume the auth has failed
|
||||
if (!isset($data["id"])) {
|
||||
$this->logout();
|
||||
throw new Exception("User profile request failed! {$this->providerId} api returned an invalid response: " . Hybrid_Logger::dumpData( $data ), 6);
|
||||
}
|
||||
|
||||
# store the user profile.
|
||||
$this->user->profile->identifier = (array_key_exists('idNo', $data)) ? $data['idNo'] : "";
|
||||
$this->user->profile->username = (array_key_exists('name', $data)) ? $data['name'] : "";
|
||||
$this->user->profile->displayName = (array_key_exists('name', $data)) ? $data['name'] : "";
|
||||
$this->user->profile->age = (array_key_exists('ageGroup', $data)) ? $data['ageGroup'] : "";
|
||||
|
||||
include_once(G5_LIB_PATH.'/register.lib.php');
|
||||
|
||||
$payco_no = substr(base_convert($this->user->profile->identifier, 16, 36), 0, 16);
|
||||
$email = (array_key_exists('id', $data)) ? $data['id'] : "";
|
||||
|
||||
$this->user->profile->gender = (array_key_exists('sexCode', $data)) ? $data['sexCode'] : "";
|
||||
|
||||
$this->user->profile->email = ! valid_mb_email($email) ? $email : "";
|
||||
$this->user->profile->emailVerified = ! valid_mb_email($email) ? $email : "";
|
||||
|
||||
|
||||
if (array_key_exists('birthdayMMdd', $data)) {
|
||||
$this->user->profile->birthMonth = substr($data['birthdayMMdd'], 0, 2);
|
||||
$this->user->profile->birthDay = substr($data['birthdayMMdd'], 2, 4);
|
||||
}
|
||||
|
||||
$this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId );
|
||||
|
||||
return $this->user->profile;
|
||||
} //end function getUserProfile
|
||||
|
||||
}
|
||||
266
plugin/social/Hybrid/Providers/Twitter.php
Normal file
@ -0,0 +1,266 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Twitter provider adapter based on OAuth1 protocol
|
||||
*/
|
||||
class Hybrid_Providers_Twitter extends Hybrid_Provider_Model_OAuth1 {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
// Provider api end-points
|
||||
$this->api->api_base_url = "https://api.twitter.com/1.1/";
|
||||
$this->api->authorize_url = "https://api.twitter.com/oauth/authenticate";
|
||||
$this->api->request_token_url = "https://api.twitter.com/oauth/request_token";
|
||||
$this->api->access_token_url = "https://api.twitter.com/oauth/access_token";
|
||||
|
||||
if (isset($this->config['api_version']) && $this->config['api_version']) {
|
||||
$this->api->api_base_url = "https://api.twitter.com/{$this->config['api_version']}/";
|
||||
}
|
||||
|
||||
if (isset($this->config['authorize']) && $this->config['authorize']) {
|
||||
$this->api->authorize_url = "https://api.twitter.com/oauth/authorize";
|
||||
}
|
||||
|
||||
$this->api->curl_auth_header = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
// Initiate the Reverse Auth flow; cf. https://dev.twitter.com/docs/ios/using-reverse-auth
|
||||
if (isset($_REQUEST['reverse_auth']) && ($_REQUEST['reverse_auth'] == 'yes')) {
|
||||
$stage1 = $this->api->signedRequest($this->api->request_token_url, 'POST', array('x_auth_mode' => 'reverse_auth'));
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5);
|
||||
}
|
||||
$responseObj = array('x_reverse_auth_parameters' => $stage1, 'x_reverse_auth_target' => $this->config["keys"]["key"]);
|
||||
$response = json_encode($responseObj);
|
||||
header("Content-Type: application/json", true, 200);
|
||||
echo $response;
|
||||
die();
|
||||
}
|
||||
$tokens = $this->api->requestToken($this->endpoint);
|
||||
|
||||
// request tokens as received from provider
|
||||
$this->request_tokens_raw = $tokens;
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5);
|
||||
}
|
||||
|
||||
if (!isset($tokens["oauth_token"])) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid oauth token.", 5);
|
||||
}
|
||||
|
||||
$this->token("request_token", $tokens["oauth_token"]);
|
||||
$this->token("request_token_secret", $tokens["oauth_token_secret"]);
|
||||
|
||||
// redirect the user to the provider authentication url with force_login
|
||||
if (( isset($this->config['force_login']) && $this->config['force_login'] ) || ( isset($this->config['force']) && $this->config['force'] === true )) {
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($tokens, array('force_login' => true)));
|
||||
}
|
||||
|
||||
// else, redirect the user to the provider authentication url
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($tokens));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
// in case we are completing a Reverse Auth flow; cf. https://dev.twitter.com/docs/ios/using-reverse-auth
|
||||
if (isset($_REQUEST['oauth_token_secret'])) {
|
||||
$tokens = $_REQUEST;
|
||||
$this->access_tokens_raw = $tokens;
|
||||
|
||||
// we should have an access_token unless something has gone wrong
|
||||
if (!isset($tokens["oauth_token"])) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5);
|
||||
}
|
||||
|
||||
// Get rid of tokens we don't need
|
||||
$this->deleteToken("request_token");
|
||||
$this->deleteToken("request_token_secret");
|
||||
|
||||
// Store access_token and secret for later use
|
||||
$this->token("access_token", $tokens['oauth_token']);
|
||||
$this->token("access_token_secret", $tokens['oauth_token_secret']);
|
||||
|
||||
// set user as logged in to the current provider
|
||||
$this->setUserConnected();
|
||||
return;
|
||||
}
|
||||
parent::loginFinish();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
$includeEmail = isset($this->config['includeEmail']) ? (bool) $this->config['includeEmail'] : false;
|
||||
$response = $this->api->get('account/verify_credentials.json'. ($includeEmail ? '?include_email=true' : ''));
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 6);
|
||||
}
|
||||
|
||||
if (!is_object($response) || !isset($response->id)) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} api returned an invalid response: " . Hybrid_Logger::dumpData( $response ), 6);
|
||||
}
|
||||
|
||||
# store the user profile.
|
||||
$this->user->profile->identifier = (property_exists($response, 'id')) ? $response->id : "";
|
||||
$this->user->profile->displayName = (property_exists($response, 'screen_name')) ? $response->screen_name : "";
|
||||
$this->user->profile->description = (property_exists($response, 'description')) ? $response->description : "";
|
||||
$this->user->profile->firstName = (property_exists($response, 'name')) ? $response->name : "";
|
||||
$this->user->profile->photoURL = (property_exists($response, 'profile_image_url')) ? (str_replace('_normal', '', $response->profile_image_url)) : "";
|
||||
$this->user->profile->profileURL = (property_exists($response, 'screen_name')) ? ("http://twitter.com/" . $response->screen_name) : "";
|
||||
$this->user->profile->webSiteURL = (property_exists($response, 'url')) ? $response->url : "";
|
||||
$this->user->profile->region = (property_exists($response, 'location')) ? $response->location : "";
|
||||
if($includeEmail) $this->user->profile->email = (property_exists($response, 'email')) ? $response->email : "";
|
||||
if($includeEmail) $this->user->profile->emailVerified = (property_exists($response, 'email')) ? $response->email : "";
|
||||
|
||||
$this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId );
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserContacts() {
|
||||
$parameters = array('cursor' => '-1');
|
||||
$response = $this->api->get('friends/ids.json', $parameters);
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("User contacts request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
if (!$response || !count($response->ids)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// 75 id per time should be okey
|
||||
$contactsids = array_chunk($response->ids, 75);
|
||||
|
||||
$contacts = array();
|
||||
|
||||
foreach ($contactsids as $chunk) {
|
||||
$parameters = array('user_id' => implode(",", $chunk));
|
||||
$response = $this->api->get('users/lookup.json', $parameters);
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("User contacts request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
if ($response && count($response)) {
|
||||
foreach ($response as $item) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
|
||||
$uc->identifier = (property_exists($item, 'id')) ? $item->id : "";
|
||||
$uc->displayName = (property_exists($item, 'name')) ? $item->name : "";
|
||||
$uc->profileURL = (property_exists($item, 'screen_name')) ? ("http://twitter.com/" . $item->screen_name) : "";
|
||||
$uc->photoURL = (property_exists($item, 'profile_image_url')) ? $item->profile_image_url : "";
|
||||
$uc->description = (property_exists($item, 'description')) ? $item->description : "";
|
||||
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function setUserStatus($status) {
|
||||
|
||||
if (is_array($status) && isset($status['message']) && isset($status['picture'])) {
|
||||
$response = $this->api->post('statuses/update_with_media.json', array('status' => $status['message'], 'media[]' => file_get_contents($status['picture'])), null, null, true);
|
||||
} else {
|
||||
$response = $this->api->post('statuses/update.json', array('status' => $status));
|
||||
}
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Update user status failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserStatus($tweetid) {
|
||||
$info = $this->api->get('statuses/show.json?id=' . $tweetid . '&include_entities=true');
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200 || !isset($info->id)) {
|
||||
throw new Exception("Cannot retrieve user status! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* load the user latest activity
|
||||
* - timeline : all the stream
|
||||
* - me : the user activity only
|
||||
*
|
||||
* by default return the timeline
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserActivity($stream) {
|
||||
if ($stream == "me") {
|
||||
$response = $this->api->get('statuses/user_timeline.json');
|
||||
} else {
|
||||
$response = $this->api->get('statuses/home_timeline.json');
|
||||
}
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("User activity stream request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
if (!$response) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$activities = array();
|
||||
|
||||
foreach ($response as $item) {
|
||||
$ua = new Hybrid_User_Activity();
|
||||
|
||||
$ua->id = (property_exists($item, 'id')) ? $item->id : "";
|
||||
$ua->date = (property_exists($item, 'created_at')) ? strtotime($item->created_at) : "";
|
||||
$ua->text = (property_exists($item, 'text')) ? $item->text : "";
|
||||
|
||||
$ua->user->identifier = (property_exists($item->user, 'id')) ? $item->user->id : "";
|
||||
$ua->user->displayName = (property_exists($item->user, 'name')) ? $item->user->name : "";
|
||||
$ua->user->profileURL = (property_exists($item->user, 'screen_name')) ? ("http://twitter.com/" . $item->user->screen_name) : "";
|
||||
$ua->user->photoURL = (property_exists($item->user, 'profile_image_url')) ? $item->user->profile_image_url : "";
|
||||
|
||||
$activities[] = $ua;
|
||||
}
|
||||
|
||||
return $activities;
|
||||
}
|
||||
|
||||
}
|
||||
141
plugin/social/Hybrid/Storage.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
require_once realpath(dirname(__FILE__)) . "/StorageInterface.php";
|
||||
|
||||
/**
|
||||
* HybridAuth storage manager
|
||||
*/
|
||||
class Hybrid_Storage implements Hybrid_Storage_Interface {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct() {
|
||||
if (!session_id()) {
|
||||
if (!session_start()) {
|
||||
throw new Exception("Hybridauth requires the use of 'session_start()' at the start of your script, which appears to be disabled.", 1);
|
||||
}
|
||||
}
|
||||
|
||||
$this->config("php_session_id", session_id());
|
||||
$this->config("version", Hybrid_Auth::$version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a value in the config storage, or returns config if value is null
|
||||
*
|
||||
* @param string $key Config name
|
||||
* @param string $value Config value
|
||||
* @return array|null
|
||||
*/
|
||||
public function config($key, $value = null) {
|
||||
$key = strtolower($key);
|
||||
|
||||
if ($value) {
|
||||
$_SESSION["HA::CONFIG"][$key] = serialize($value);
|
||||
} elseif (isset($_SESSION["HA::CONFIG"][$key])) {
|
||||
return unserialize($_SESSION["HA::CONFIG"][$key]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value from session storage
|
||||
*
|
||||
* @param string $key Key
|
||||
* @return string|null
|
||||
*/
|
||||
public function get($key) {
|
||||
$key = strtolower($key);
|
||||
|
||||
if (isset($_SESSION["HA::STORE"], $_SESSION["HA::STORE"][$key])) {
|
||||
return unserialize($_SESSION["HA::STORE"][$key]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a key value pair to the session storage
|
||||
*
|
||||
* @param string $key Key
|
||||
* @param string $value Value
|
||||
* @return void
|
||||
*/
|
||||
public function set($key, $value) {
|
||||
$key = strtolower($key);
|
||||
$_SESSION["HA::STORE"][$key] = serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear session storage
|
||||
* @return void
|
||||
*/
|
||||
function clear() {
|
||||
$_SESSION["HA::STORE"] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a specific key from session storage
|
||||
*
|
||||
* @param string $key Key
|
||||
* @return void
|
||||
*/
|
||||
function delete($key) {
|
||||
$key = strtolower($key);
|
||||
|
||||
if (isset($_SESSION["HA::STORE"], $_SESSION["HA::STORE"][$key])) {
|
||||
$f = $_SESSION['HA::STORE'];
|
||||
unset($f[$key]);
|
||||
$_SESSION["HA::STORE"] = $f;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all keys recursively from session storage
|
||||
*
|
||||
* @param string $key Key
|
||||
* @retun void
|
||||
*/
|
||||
function deleteMatch($key) {
|
||||
$key = strtolower($key);
|
||||
|
||||
if (isset($_SESSION["HA::STORE"]) && count($_SESSION["HA::STORE"])) {
|
||||
$f = $_SESSION['HA::STORE'];
|
||||
foreach ($f as $k => $v) {
|
||||
if (strstr($k, $key)) {
|
||||
unset($f[$k]);
|
||||
}
|
||||
}
|
||||
$_SESSION["HA::STORE"] = $f;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns session storage as a serialized string
|
||||
* @return string|null
|
||||
*/
|
||||
function getSessionData() {
|
||||
if (isset($_SESSION["HA::STORE"])) {
|
||||
return serialize($_SESSION["HA::STORE"]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the session from serialized session data
|
||||
*
|
||||
* @param string $sessiondata Serialized session data
|
||||
* @return void
|
||||
*/
|
||||
function restoreSessionData($sessiondata = null) {
|
||||
$_SESSION["HA::STORE"] = unserialize($sessiondata);
|
||||
}
|
||||
|
||||
}
|
||||
29
plugin/social/Hybrid/StorageInterface.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* HybridAuth storage manager interface
|
||||
*/
|
||||
interface Hybrid_Storage_Interface {
|
||||
|
||||
public function config($key, $value = null);
|
||||
|
||||
public function get($key);
|
||||
|
||||
public function set($key, $value);
|
||||
|
||||
function clear();
|
||||
|
||||
function delete($key);
|
||||
|
||||
function deleteMatch($key);
|
||||
|
||||
function getSessionData();
|
||||
|
||||
function restoreSessionData($sessiondata = null);
|
||||
}
|
||||
40
plugin/social/Hybrid/User.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Hybrid_User class represents the current logged in user
|
||||
*/
|
||||
class Hybrid_User {
|
||||
|
||||
/**
|
||||
* The ID (name) of the connected provider
|
||||
* @var mixed
|
||||
*/
|
||||
public $providerId = null;
|
||||
|
||||
/**
|
||||
* Timestamp connection to the provider
|
||||
* @var int
|
||||
*/
|
||||
public $timestamp = null;
|
||||
|
||||
/**
|
||||
* User profile, contains the list of fields available in the normalized user profile structure used by HybridAuth
|
||||
* @var Hybrid_User_Profile
|
||||
*/
|
||||
public $profile = null;
|
||||
|
||||
/**
|
||||
* Initialize the user object
|
||||
*/
|
||||
function __construct() {
|
||||
$this->timestamp = time();
|
||||
$this->profile = new Hybrid_User_Profile();
|
||||
}
|
||||
|
||||
}
|
||||
55
plugin/social/Hybrid/User_Activity.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_User_Activity
|
||||
*
|
||||
* used to provider the connected user activity stream on a standardized structure across supported social apis.
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/Profile_Data_User_Activity.html
|
||||
*/
|
||||
class Hybrid_User_Activity {
|
||||
|
||||
/**
|
||||
* Activity id on the provider side, usually given as integer
|
||||
* @var mixed
|
||||
*/
|
||||
public $id = null;
|
||||
|
||||
/**
|
||||
* Activity date of creation
|
||||
* @var int
|
||||
*/
|
||||
public $date = null;
|
||||
|
||||
/**
|
||||
* Activity content as a string
|
||||
* @var string
|
||||
*/
|
||||
public $text = null;
|
||||
|
||||
/**
|
||||
* User who created the activity
|
||||
* @var stdClass
|
||||
*/
|
||||
public $user = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->user = new stdClass();
|
||||
|
||||
// typically, we should have a few information about the user who created the event from social apis
|
||||
$this->user->identifier = null;
|
||||
$this->user->displayName = null;
|
||||
$this->user->profileURL = null;
|
||||
$this->user->photoURL = null;
|
||||
}
|
||||
|
||||
}
|
||||
60
plugin/social/Hybrid/User_Contact.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_User_Contact
|
||||
*
|
||||
* used to provider the connected user contacts list on a standardized structure across supported social apis.
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/Profile_Data_User_Contacts.html
|
||||
*/
|
||||
class Hybrid_User_Contact {
|
||||
|
||||
/**
|
||||
* The Unique contact user ID
|
||||
* @var mixed
|
||||
*/
|
||||
public $identifier = null;
|
||||
|
||||
/**
|
||||
* User website, blog, web page
|
||||
* @var string
|
||||
*/
|
||||
public $webSiteURL = null;
|
||||
|
||||
/**
|
||||
* URL link to profile page on the IDp web site
|
||||
* @var string
|
||||
*/
|
||||
public $profileURL = null;
|
||||
|
||||
/**
|
||||
* URL link to user photo or avatar
|
||||
* @var string
|
||||
*/
|
||||
public $photoURL = null;
|
||||
|
||||
/**
|
||||
* User displayName provided by the IDp or a concatenation of first and last name
|
||||
* @var string
|
||||
*/
|
||||
public $displayName = null;
|
||||
|
||||
/**
|
||||
* A short about_me
|
||||
* @var string
|
||||
*/
|
||||
public $description = null;
|
||||
|
||||
/**
|
||||
* User email. Not all of IDp grant access to the user email
|
||||
* @var string
|
||||
*/
|
||||
public $email = null;
|
||||
|
||||
}
|
||||
163
plugin/social/Hybrid/User_Profile.php
Normal file
@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_User_Profile object represents the current logged in user profile.
|
||||
* The list of fields available in the normalized user profile structure used by HybridAuth.
|
||||
*
|
||||
* The Hybrid_User_Profile object is populated with as much information about the user as
|
||||
* HybridAuth was able to pull from the given API or authentication provider.
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/Profile_Data_User_Profile.html
|
||||
*/
|
||||
class Hybrid_User_Profile {
|
||||
|
||||
/**
|
||||
* The Unique user's ID on the connected provider
|
||||
* @var mixed
|
||||
*/
|
||||
public $identifier = null;
|
||||
|
||||
/**
|
||||
* User website, blog, web page
|
||||
* @var string
|
||||
*/
|
||||
public $webSiteURL = null;
|
||||
|
||||
/**
|
||||
* URL link to profile page on the IDp web site
|
||||
* @var string
|
||||
*/
|
||||
public $profileURL = null;
|
||||
|
||||
/**
|
||||
* URL link to user photo or avatar
|
||||
* @var string
|
||||
*/
|
||||
public $photoURL = null;
|
||||
|
||||
/**
|
||||
* User displayName provided by the IDp or a concatenation of first and last name.
|
||||
* @var string
|
||||
*/
|
||||
public $displayName = null;
|
||||
|
||||
/**
|
||||
* A short about_me
|
||||
* @var string
|
||||
*/
|
||||
public $description = null;
|
||||
|
||||
/**
|
||||
* User's first name
|
||||
* @var string
|
||||
*/
|
||||
public $firstName = null;
|
||||
|
||||
/**
|
||||
* User's last name
|
||||
* @var string
|
||||
*/
|
||||
public $lastName = null;
|
||||
|
||||
/**
|
||||
* Male or female
|
||||
* @var string
|
||||
*/
|
||||
public $gender = null;
|
||||
|
||||
/**
|
||||
* Language
|
||||
* @var string
|
||||
*/
|
||||
public $language = null;
|
||||
|
||||
/**
|
||||
* User age, we don't calculate it. we return it as is if the IDp provide it.
|
||||
* @var int
|
||||
*/
|
||||
public $age = null;
|
||||
|
||||
/**
|
||||
* User birth Day
|
||||
* @var int
|
||||
*/
|
||||
public $birthDay = null;
|
||||
|
||||
/**
|
||||
* User birth Month
|
||||
* @var int
|
||||
*/
|
||||
public $birthMonth = null;
|
||||
|
||||
/**
|
||||
* User birth Year
|
||||
* @var int
|
||||
*/
|
||||
public $birthYear = null;
|
||||
|
||||
/**
|
||||
* User email. Note: not all of IDp grant access to the user email
|
||||
* @var string
|
||||
*/
|
||||
public $email = null;
|
||||
|
||||
/**
|
||||
* Verified user email. Note: not all of IDp grant access to verified user email
|
||||
* @var string
|
||||
*/
|
||||
public $emailVerified = null;
|
||||
|
||||
/**
|
||||
* Phone number
|
||||
* @var string
|
||||
*/
|
||||
public $phone = null;
|
||||
|
||||
/**
|
||||
* Complete user address
|
||||
* @var string
|
||||
*/
|
||||
public $address = null;
|
||||
|
||||
/**
|
||||
* User country
|
||||
* @var string
|
||||
*/
|
||||
public $country = null;
|
||||
|
||||
/**
|
||||
* Region
|
||||
* @var string
|
||||
*/
|
||||
public $region = null;
|
||||
|
||||
/**
|
||||
* City
|
||||
* @var string
|
||||
*/
|
||||
public $city = null;
|
||||
|
||||
/**
|
||||
* Postal code
|
||||
* @var string
|
||||
*/
|
||||
public $zip = null;
|
||||
|
||||
/**
|
||||
* Job title
|
||||
* @var string
|
||||
*/
|
||||
public $job_title = null;
|
||||
|
||||
/**
|
||||
* Organization name
|
||||
* @var string
|
||||
*/
|
||||
public $organization_name = null;
|
||||
}
|
||||
10
plugin/social/Hybrid/index.html
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
10
plugin/social/Hybrid/resources/index.html
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
10
plugin/social/Hybrid/resources/openid_policy.html
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenID Policy</title>
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
Set here your OpenID Policy,
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
13
plugin/social/Hybrid/resources/openid_realm.html
Normal file
@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HybridAuth Endpoint</title>
|
||||
<meta name="robots" content="NOINDEX, NOFOLLOW">
|
||||
<meta http-equiv="X-XRDS-Location" content="{X_XRDS_LOCATION}" />
|
||||
</head>
|
||||
<body>
|
||||
<h3 style="margin-bottom: 2px;">HybridAuth</h3>
|
||||
Open Source Social Sign On PHP Library.
|
||||
<br />
|
||||
<a href="http://hybridauth.sourceforge.net/" style="color:green;text-decoration:none;">hybridauth.sourceforge.net/</a>
|
||||
</body>
|
||||
</html>
|
||||
12
plugin/social/Hybrid/resources/openid_xrds.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xrds:XRDS
|
||||
xmlns:xrds="xri://$xrds"
|
||||
xmlns:openid="http://openid.net/xmlns/1.0"
|
||||
xmlns="xri://$xrd*($v*2.0)">
|
||||
<XRD>
|
||||
<Service priority="1">
|
||||
<Type>http://specs.openid.net/auth/2.0/return_to</Type>
|
||||
<URI>{RETURN_TO_URL}</URI>
|
||||
</Service>
|
||||
</XRD>
|
||||
</xrds:XRDS>
|
||||
901
plugin/social/Hybrid/thirdparty/OAuth/OAuth.php
vendored
Normal file
@ -0,0 +1,901 @@
|
||||
<?php
|
||||
// http://oauth.googlecode.com/svn/code/php/OAuth.php
|
||||
// rev 1276, July 4, 2014
|
||||
|
||||
// vim: foldmethod=marker
|
||||
|
||||
/* Generic exception class
|
||||
*/
|
||||
if (!class_exists('OAuthException', false)) {
|
||||
class OAuthException extends Exception {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthConsumer {
|
||||
public $key;
|
||||
public $secret;
|
||||
|
||||
function __construct($key, $secret, $callback_url=null) {
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
$this->callback_url = $callback_url;
|
||||
}
|
||||
|
||||
function __toString() {
|
||||
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthToken {
|
||||
// access tokens and request tokens
|
||||
public $key;
|
||||
public $secret;
|
||||
|
||||
/**
|
||||
* key = the token
|
||||
* secret = the token secret
|
||||
*/
|
||||
function __construct($key, $secret) {
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* generates the basic string serialization of a token that a server
|
||||
* would respond to request_token and access_token calls with
|
||||
*/
|
||||
function to_string() {
|
||||
return "oauth_token=" .
|
||||
OAuthUtil::urlencode_rfc3986($this->key) .
|
||||
"&oauth_token_secret=" .
|
||||
OAuthUtil::urlencode_rfc3986($this->secret);
|
||||
}
|
||||
|
||||
function __toString() {
|
||||
return $this->to_string();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class for implementing a Signature Method
|
||||
* See section 9 ("Signing Requests") in the spec
|
||||
*/
|
||||
abstract class OAuthSignatureMethod {
|
||||
/**
|
||||
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
|
||||
* @return string
|
||||
*/
|
||||
abstract public function get_name();
|
||||
|
||||
/**
|
||||
* Build up the signature
|
||||
* NOTE: The output of this function MUST NOT be urlencoded.
|
||||
* the encoding is handled in OAuthRequest when the final
|
||||
* request is serialized
|
||||
* @param OAuthRequest $request
|
||||
* @param OAuthConsumer $consumer
|
||||
* @param OAuthToken $token
|
||||
* @return string
|
||||
*/
|
||||
abstract public function build_signature($request, $consumer, $token);
|
||||
|
||||
/**
|
||||
* Verifies that a given signature is correct
|
||||
* @param OAuthRequest $request
|
||||
* @param OAuthConsumer $consumer
|
||||
* @param OAuthToken $token
|
||||
* @param string $signature
|
||||
* @return bool
|
||||
*/
|
||||
public function check_signature($request, $consumer, $token, $signature) {
|
||||
$built = $this->build_signature($request, $consumer, $token);
|
||||
|
||||
// Check for zero length, although unlikely here
|
||||
if (strlen($built) == 0 || strlen($signature) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($built) != strlen($signature)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid a timing leak with a (hopefully) time insensitive compare
|
||||
$result = 0;
|
||||
for ($i = 0; $i < strlen($signature); $i++) {
|
||||
$result |= ord($built{$i}) ^ ord($signature{$i});
|
||||
}
|
||||
|
||||
return $result == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
|
||||
* where the Signature Base String is the text and the key is the concatenated values (each first
|
||||
* encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
|
||||
* character (ASCII code 38) even if empty.
|
||||
* - Chapter 9.2 ("HMAC-SHA1")
|
||||
*/
|
||||
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
|
||||
function get_name() {
|
||||
return "HMAC-SHA1";
|
||||
}
|
||||
|
||||
public function build_signature($request, $consumer, $token) {
|
||||
$base_string = $request->get_signature_base_string();
|
||||
$request->base_string = $base_string;
|
||||
|
||||
$key_parts = array(
|
||||
$consumer->secret,
|
||||
($token) ? $token->secret : ""
|
||||
);
|
||||
|
||||
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
|
||||
$key = implode('&', $key_parts);
|
||||
|
||||
return base64_encode(hash_hmac('sha1', $base_string, $key, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The PLAINTEXT method does not provide any security protection and SHOULD only be used
|
||||
* over a secure channel such as HTTPS. It does not use the Signature Base String.
|
||||
* - Chapter 9.4 ("PLAINTEXT")
|
||||
*/
|
||||
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
|
||||
public function get_name() {
|
||||
return "PLAINTEXT";
|
||||
}
|
||||
|
||||
/**
|
||||
* oauth_signature is set to the concatenated encoded values of the Consumer Secret and
|
||||
* Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
|
||||
* empty. The result MUST be encoded again.
|
||||
* - Chapter 9.4.1 ("Generating Signatures")
|
||||
*
|
||||
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as
|
||||
* OAuthRequest handles this!
|
||||
*/
|
||||
public function build_signature($request, $consumer, $token) {
|
||||
$key_parts = array(
|
||||
$consumer->secret,
|
||||
($token) ? $token->secret : ""
|
||||
);
|
||||
|
||||
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
|
||||
$key = implode('&', $key_parts);
|
||||
$request->base_string = $key;
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
|
||||
* [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
|
||||
* EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
|
||||
* verified way to the Service Provider, in a manner which is beyond the scope of this
|
||||
* specification.
|
||||
* - Chapter 9.3 ("RSA-SHA1")
|
||||
*/
|
||||
abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
|
||||
public function get_name() {
|
||||
return "RSA-SHA1";
|
||||
}
|
||||
|
||||
// Up to the SP to implement this lookup of keys. Possible ideas are:
|
||||
// (1) do a lookup in a table of trusted certs keyed off of consumer
|
||||
// (2) fetch via http using a url provided by the requester
|
||||
// (3) some sort of specific discovery code based on request
|
||||
//
|
||||
// Either way should return a string representation of the certificate
|
||||
protected abstract function fetch_public_cert(&$request);
|
||||
|
||||
// Up to the SP to implement this lookup of keys. Possible ideas are:
|
||||
// (1) do a lookup in a table of trusted certs keyed off of consumer
|
||||
//
|
||||
// Either way should return a string representation of the certificate
|
||||
protected abstract function fetch_private_cert(&$request);
|
||||
|
||||
public function build_signature($request, $consumer, $token) {
|
||||
$base_string = $request->get_signature_base_string();
|
||||
$request->base_string = $base_string;
|
||||
|
||||
// Fetch the private key cert based on the request
|
||||
$cert = $this->fetch_private_cert($request);
|
||||
|
||||
// Pull the private key ID from the certificate
|
||||
$privatekeyid = openssl_get_privatekey($cert);
|
||||
|
||||
// Sign using the key
|
||||
$ok = openssl_sign($base_string, $signature, $privatekeyid);
|
||||
|
||||
// Release the key resource
|
||||
openssl_free_key($privatekeyid);
|
||||
|
||||
return base64_encode($signature);
|
||||
}
|
||||
|
||||
public function check_signature($request, $consumer, $token, $signature) {
|
||||
$decoded_sig = base64_decode($signature);
|
||||
|
||||
$base_string = $request->get_signature_base_string();
|
||||
|
||||
// Fetch the public key cert based on the request
|
||||
$cert = $this->fetch_public_cert($request);
|
||||
|
||||
// Pull the public key ID from the certificate
|
||||
$publickeyid = openssl_get_publickey($cert);
|
||||
|
||||
// Check the computed signature against the one passed in the query
|
||||
$ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
|
||||
|
||||
// Release the key resource
|
||||
openssl_free_key($publickeyid);
|
||||
|
||||
return $ok == 1;
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthRequest {
|
||||
protected $parameters;
|
||||
protected $http_method;
|
||||
protected $http_url;
|
||||
// for debug purposes
|
||||
public $base_string;
|
||||
public static $version = '1.0';
|
||||
public static $POST_INPUT = 'php://input';
|
||||
|
||||
function __construct($http_method, $http_url, $parameters=null) {
|
||||
$parameters = ($parameters) ? $parameters : array();
|
||||
$parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
|
||||
$this->parameters = $parameters;
|
||||
$this->http_method = $http_method;
|
||||
$this->http_url = $http_url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* attempt to build up a request from what was passed to the server
|
||||
*/
|
||||
public static function from_request($http_method=null, $http_url=null, $parameters=null) {
|
||||
$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
|
||||
? 'http'
|
||||
: 'https';
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
|
||||
$scheme = $_SERVER['HTTP_X_FORWARDED_PROTO'];
|
||||
}
|
||||
$http_url = ($http_url) ? $http_url : $scheme .
|
||||
'://' . $_SERVER['SERVER_NAME'] .
|
||||
':' .
|
||||
$_SERVER['SERVER_PORT'] .
|
||||
$_SERVER['REQUEST_URI'];
|
||||
$http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
// We weren't handed any parameters, so let's find the ones relevant to
|
||||
// this request.
|
||||
// If you run XML-RPC or similar you should use this to provide your own
|
||||
// parsed parameter-list
|
||||
if (!$parameters) {
|
||||
// Find request headers
|
||||
$request_headers = OAuthUtil::get_headers();
|
||||
|
||||
// Parse the query-string to find GET parameters
|
||||
$parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
|
||||
|
||||
// It's a POST request of the proper content-type, so parse POST
|
||||
// parameters and add those overriding any duplicates from GET
|
||||
if ($http_method == "POST"
|
||||
&& isset($request_headers['Content-Type'])
|
||||
&& strstr($request_headers['Content-Type'],
|
||||
'application/x-www-form-urlencoded')
|
||||
) {
|
||||
$post_data = OAuthUtil::parse_parameters(
|
||||
file_get_contents(self::$POST_INPUT)
|
||||
);
|
||||
$parameters = array_merge($parameters, $post_data);
|
||||
}
|
||||
|
||||
// We have a Authorization-header with OAuth data. Parse the header
|
||||
// and add those overriding any duplicates from GET or POST
|
||||
if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') {
|
||||
$header_parameters = OAuthUtil::split_header(
|
||||
$request_headers['Authorization']
|
||||
);
|
||||
$parameters = array_merge($parameters, $header_parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new OAuthRequest($http_method, $http_url, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* pretty much a helper function to set up the request
|
||||
*/
|
||||
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=null) {
|
||||
$parameters = ($parameters) ? $parameters : array();
|
||||
$defaults = array("oauth_version" => OAuthRequest::$version,
|
||||
"oauth_nonce" => OAuthRequest::generate_nonce(),
|
||||
"oauth_timestamp" => OAuthRequest::generate_timestamp(),
|
||||
"oauth_consumer_key" => $consumer->key);
|
||||
if ($token)
|
||||
$defaults['oauth_token'] = $token->key;
|
||||
|
||||
$parameters = array_merge($defaults, $parameters);
|
||||
|
||||
return new OAuthRequest($http_method, $http_url, $parameters);
|
||||
}
|
||||
|
||||
public function set_parameter($name, $value, $allow_duplicates = true) {
|
||||
if ($allow_duplicates && isset($this->parameters[$name])) {
|
||||
// We have already added parameter(s) with this name, so add to the list
|
||||
if (is_scalar($this->parameters[$name])) {
|
||||
// This is the first duplicate, so transform scalar (string)
|
||||
// into an array so we can add the duplicates
|
||||
$this->parameters[$name] = array($this->parameters[$name]);
|
||||
}
|
||||
|
||||
$this->parameters[$name][] = $value;
|
||||
} else {
|
||||
$this->parameters[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_parameter($name) {
|
||||
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
|
||||
}
|
||||
|
||||
public function get_parameters() {
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
public function unset_parameter($name) {
|
||||
unset($this->parameters[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The request parameters, sorted and concatenated into a normalized string.
|
||||
* @return string
|
||||
*/
|
||||
public function get_signable_parameters() {
|
||||
// Grab all parameters
|
||||
$params = $this->parameters;
|
||||
|
||||
// Remove oauth_signature if present
|
||||
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
|
||||
if (isset($params['oauth_signature'])) {
|
||||
unset($params['oauth_signature']);
|
||||
}
|
||||
|
||||
return OAuthUtil::build_http_query($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base string of this request
|
||||
*
|
||||
* The base string defined as the method, the url
|
||||
* and the parameters (normalized), each urlencoded
|
||||
* and the concated with &.
|
||||
*/
|
||||
public function get_signature_base_string() {
|
||||
$parts = array(
|
||||
$this->get_normalized_http_method(),
|
||||
$this->get_normalized_http_url(),
|
||||
$this->get_signable_parameters()
|
||||
);
|
||||
|
||||
$parts = OAuthUtil::urlencode_rfc3986($parts);
|
||||
|
||||
return implode('&', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* just uppercases the http method
|
||||
*/
|
||||
public function get_normalized_http_method() {
|
||||
return strtoupper($this->http_method);
|
||||
}
|
||||
|
||||
/**
|
||||
* parses the url and rebuilds it to be
|
||||
* scheme://host/path
|
||||
*/
|
||||
public function get_normalized_http_url() {
|
||||
$parts = parse_url($this->http_url);
|
||||
|
||||
$scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
|
||||
$port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80');
|
||||
$host = (isset($parts['host'])) ? strtolower($parts['host']) : '';
|
||||
$path = (isset($parts['path'])) ? $parts['path'] : '';
|
||||
|
||||
if (($scheme == 'https' && $port != '443')
|
||||
|| ($scheme == 'http' && $port != '80')) {
|
||||
$host = "$host:$port";
|
||||
}
|
||||
return "$scheme://$host$path";
|
||||
}
|
||||
|
||||
/**
|
||||
* builds a url usable for a GET request
|
||||
*/
|
||||
public function to_url() {
|
||||
$post_data = $this->to_postdata();
|
||||
$out = $this->get_normalized_http_url();
|
||||
if ($post_data) {
|
||||
$out .= '?'.$post_data;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* builds the data one would send in a POST request
|
||||
*/
|
||||
public function to_postdata() {
|
||||
return OAuthUtil::build_http_query($this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* builds the Authorization: header
|
||||
*/
|
||||
public function to_header($realm=null) {
|
||||
$first = true;
|
||||
if($realm) {
|
||||
$out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
|
||||
$first = false;
|
||||
} else
|
||||
$out = 'Authorization: OAuth';
|
||||
|
||||
$total = array();
|
||||
foreach ($this->parameters as $k => $v) {
|
||||
if (substr($k, 0, 5) != "oauth") continue;
|
||||
if (is_array($v)) {
|
||||
throw new OAuthException('arrays not supported in headers');
|
||||
}
|
||||
$out .= ($first) ? ' ' : ',';
|
||||
$out .= OAuthUtil::urlencode_rfc3986($k) .
|
||||
'="' .
|
||||
OAuthUtil::urlencode_rfc3986($v) .
|
||||
'"';
|
||||
$first = false;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->to_url();
|
||||
}
|
||||
|
||||
|
||||
public function sign_request($signature_method, $consumer, $token) {
|
||||
$this->set_parameter(
|
||||
"oauth_signature_method",
|
||||
$signature_method->get_name(),
|
||||
false
|
||||
);
|
||||
$signature = $this->build_signature($signature_method, $consumer, $token);
|
||||
$this->set_parameter("oauth_signature", $signature, false);
|
||||
}
|
||||
|
||||
public function build_signature($signature_method, $consumer, $token) {
|
||||
$signature = $signature_method->build_signature($this, $consumer, $token);
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* util function: current timestamp
|
||||
*/
|
||||
private static function generate_timestamp() {
|
||||
return time();
|
||||
}
|
||||
|
||||
/**
|
||||
* util function: current nonce
|
||||
*/
|
||||
private static function generate_nonce() {
|
||||
$mt = microtime();
|
||||
$rand = mt_rand();
|
||||
|
||||
return md5($mt . $rand); // md5s look nicer than numbers
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthServer {
|
||||
protected $timestamp_threshold = 300; // in seconds, five minutes
|
||||
protected $version = '1.0'; // hi blaine
|
||||
protected $signature_methods = array();
|
||||
|
||||
protected $data_store;
|
||||
|
||||
function __construct($data_store) {
|
||||
$this->data_store = $data_store;
|
||||
}
|
||||
|
||||
public function add_signature_method($signature_method) {
|
||||
$this->signature_methods[$signature_method->get_name()] =
|
||||
$signature_method;
|
||||
}
|
||||
|
||||
// high level functions
|
||||
|
||||
/**
|
||||
* process a request_token request
|
||||
* returns the request token on success
|
||||
*/
|
||||
public function fetch_request_token(&$request) {
|
||||
$this->get_version($request);
|
||||
|
||||
$consumer = $this->get_consumer($request);
|
||||
|
||||
// no token required for the initial token request
|
||||
$token = null;
|
||||
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
|
||||
// Rev A change
|
||||
$callback = $request->get_parameter('oauth_callback');
|
||||
$new_token = $this->data_store->new_request_token($consumer, $callback);
|
||||
|
||||
return $new_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* process an access_token request
|
||||
* returns the access token on success
|
||||
*/
|
||||
public function fetch_access_token(&$request) {
|
||||
$this->get_version($request);
|
||||
|
||||
$consumer = $this->get_consumer($request);
|
||||
|
||||
// requires authorized request token
|
||||
$token = $this->get_token($request, $consumer, "request");
|
||||
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
|
||||
// Rev A change
|
||||
$verifier = $request->get_parameter('oauth_verifier');
|
||||
$new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
|
||||
|
||||
return $new_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* verify an api call, checks all the parameters
|
||||
*/
|
||||
public function verify_request(&$request) {
|
||||
$this->get_version($request);
|
||||
$consumer = $this->get_consumer($request);
|
||||
$token = $this->get_token($request, $consumer, "access");
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
return array($consumer, $token);
|
||||
}
|
||||
|
||||
// Internals from here
|
||||
/**
|
||||
* version 1
|
||||
*/
|
||||
private function get_version(&$request) {
|
||||
$version = $request->get_parameter("oauth_version");
|
||||
if (!$version) {
|
||||
// Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
|
||||
// Chapter 7.0 ("Accessing Protected Ressources")
|
||||
$version = '1.0';
|
||||
}
|
||||
if ($version !== $this->version) {
|
||||
throw new OAuthException("OAuth version '$version' not supported");
|
||||
}
|
||||
return $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* figure out the signature with some defaults
|
||||
*/
|
||||
private function get_signature_method($request) {
|
||||
$signature_method = $request instanceof OAuthRequest
|
||||
? $request->get_parameter("oauth_signature_method")
|
||||
: null;
|
||||
|
||||
if (!$signature_method) {
|
||||
// According to chapter 7 ("Accessing Protected Ressources") the signature-method
|
||||
// parameter is required, and we can't just fallback to PLAINTEXT
|
||||
throw new OAuthException('No signature method parameter. This parameter is required');
|
||||
}
|
||||
|
||||
if (!in_array($signature_method,
|
||||
array_keys($this->signature_methods))) {
|
||||
throw new OAuthException(
|
||||
"Signature method '$signature_method' not supported " .
|
||||
"try one of the following: " .
|
||||
implode(", ", array_keys($this->signature_methods))
|
||||
);
|
||||
}
|
||||
return $this->signature_methods[$signature_method];
|
||||
}
|
||||
|
||||
/**
|
||||
* try to find the consumer for the provided request's consumer key
|
||||
*/
|
||||
private function get_consumer($request) {
|
||||
$consumer_key = $request instanceof OAuthRequest
|
||||
? $request->get_parameter("oauth_consumer_key")
|
||||
: null;
|
||||
|
||||
if (!$consumer_key) {
|
||||
throw new OAuthException("Invalid consumer key");
|
||||
}
|
||||
|
||||
$consumer = $this->data_store->lookup_consumer($consumer_key);
|
||||
if (!$consumer) {
|
||||
throw new OAuthException("Invalid consumer");
|
||||
}
|
||||
|
||||
return $consumer;
|
||||
}
|
||||
|
||||
/**
|
||||
* try to find the token for the provided request's token key
|
||||
*/
|
||||
private function get_token($request, $consumer, $token_type="access") {
|
||||
$token_field = $request instanceof OAuthRequest
|
||||
? $request->get_parameter('oauth_token')
|
||||
: null;
|
||||
|
||||
$token = $this->data_store->lookup_token(
|
||||
$consumer, $token_type, $token_field
|
||||
);
|
||||
if (!$token) {
|
||||
throw new OAuthException("Invalid $token_type token: $token_field");
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* all-in-one function to check the signature on a request
|
||||
* should guess the signature method appropriately
|
||||
*/
|
||||
private function check_signature($request, $consumer, $token) {
|
||||
// this should probably be in a different method
|
||||
$timestamp = $request instanceof OAuthRequest
|
||||
? $request->get_parameter('oauth_timestamp')
|
||||
: null;
|
||||
$nonce = $request instanceof OAuthRequest
|
||||
? $request->get_parameter('oauth_nonce')
|
||||
: null;
|
||||
|
||||
$this->check_timestamp($timestamp);
|
||||
$this->check_nonce($consumer, $token, $nonce, $timestamp);
|
||||
|
||||
$signature_method = $this->get_signature_method($request);
|
||||
|
||||
$signature = $request->get_parameter('oauth_signature');
|
||||
$valid_sig = $signature_method->check_signature(
|
||||
$request,
|
||||
$consumer,
|
||||
$token,
|
||||
$signature
|
||||
);
|
||||
|
||||
if (!$valid_sig) {
|
||||
throw new OAuthException("Invalid signature");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check that the timestamp is new enough
|
||||
*/
|
||||
private function check_timestamp($timestamp) {
|
||||
if( ! $timestamp )
|
||||
throw new OAuthException(
|
||||
'Missing timestamp parameter. The parameter is required'
|
||||
);
|
||||
|
||||
// verify that timestamp is recentish
|
||||
$now = time();
|
||||
if (abs($now - $timestamp) > $this->timestamp_threshold) {
|
||||
throw new OAuthException(
|
||||
"Expired timestamp, yours $timestamp, ours $now"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check that the nonce is not repeated
|
||||
*/
|
||||
private function check_nonce($consumer, $token, $nonce, $timestamp) {
|
||||
if( ! $nonce )
|
||||
throw new OAuthException(
|
||||
'Missing nonce parameter. The parameter is required'
|
||||
);
|
||||
|
||||
// verify that the nonce is uniqueish
|
||||
$found = $this->data_store->lookup_nonce(
|
||||
$consumer,
|
||||
$token,
|
||||
$nonce,
|
||||
$timestamp
|
||||
);
|
||||
if ($found) {
|
||||
throw new OAuthException("Nonce already used: $nonce");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OAuthDataStore {
|
||||
function lookup_consumer($consumer_key) {
|
||||
// implement me
|
||||
}
|
||||
|
||||
function lookup_token($consumer, $token_type, $token) {
|
||||
// implement me
|
||||
}
|
||||
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) {
|
||||
// implement me
|
||||
}
|
||||
|
||||
function new_request_token($consumer, $callback = null) {
|
||||
// return a new token attached to this consumer
|
||||
}
|
||||
|
||||
function new_access_token($token, $consumer, $verifier = null) {
|
||||
// return a new access token attached to this consumer
|
||||
// for the user associated with this token if the request token
|
||||
// is authorized
|
||||
// should also invalidate the request token
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OAuthUtil {
|
||||
public static function urlencode_rfc3986($input) {
|
||||
if (is_array($input)) {
|
||||
return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
|
||||
} else if (is_scalar($input)) {
|
||||
return str_replace(
|
||||
'+',
|
||||
' ',
|
||||
str_replace('%7E', '~', rawurlencode($input))
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This decode function isn't taking into consideration the above
|
||||
// modifications to the encoding process. However, this method doesn't
|
||||
// seem to be used anywhere so leaving it as is.
|
||||
public static function urldecode_rfc3986($string) {
|
||||
return urldecode($string);
|
||||
}
|
||||
|
||||
// Utility function for turning the Authorization: header into
|
||||
// parameters, has to do some unescaping
|
||||
// Can filter out any non-oauth parameters if needed (default behaviour)
|
||||
// May 28th, 2010 - method updated to tjerk.meesters for a speed improvement.
|
||||
// see http://code.google.com/p/oauth/issues/detail?id=163
|
||||
public static function split_header($header, $only_allow_oauth_parameters = true) {
|
||||
$params = array();
|
||||
if (preg_match_all('/('.($only_allow_oauth_parameters ? 'oauth_' : '').'[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches)) {
|
||||
foreach ($matches[1] as $i => $h) {
|
||||
$params[$h] = OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]);
|
||||
}
|
||||
if (isset($params['realm'])) {
|
||||
unset($params['realm']);
|
||||
}
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
|
||||
// helper to try to sort out headers for people who aren't running apache
|
||||
public static function get_headers() {
|
||||
if (function_exists('apache_request_headers')) {
|
||||
// we need this to get the actual Authorization: header
|
||||
// because apache tends to tell us it doesn't exist
|
||||
$headers = apache_request_headers();
|
||||
|
||||
// sanitize the output of apache_request_headers because
|
||||
// we always want the keys to be Cased-Like-This and arh()
|
||||
// returns the headers in the same case as they are in the
|
||||
// request
|
||||
$out = array();
|
||||
foreach ($headers AS $key => $value) {
|
||||
$key = str_replace(
|
||||
" ",
|
||||
"-",
|
||||
ucwords(strtolower(str_replace("-", " ", $key)))
|
||||
);
|
||||
$out[$key] = $value;
|
||||
}
|
||||
} else {
|
||||
// otherwise we don't have apache and are just going to have to hope
|
||||
// that $_SERVER actually contains what we need
|
||||
$out = array();
|
||||
if( isset($_SERVER['CONTENT_TYPE']) )
|
||||
$out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
|
||||
if( isset($_ENV['CONTENT_TYPE']) )
|
||||
$out['Content-Type'] = $_ENV['CONTENT_TYPE'];
|
||||
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
if (substr($key, 0, 5) == "HTTP_") {
|
||||
// this is chaos, basically it is just there to capitalize the first
|
||||
// letter of every word that is not an initial HTTP and strip HTTP
|
||||
// code from przemek
|
||||
$key = str_replace(
|
||||
" ",
|
||||
"-",
|
||||
ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
|
||||
);
|
||||
$out[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
// This function takes a input like a=b&a=c&d=e and returns the parsed
|
||||
// parameters like this
|
||||
// array('a' => array('b','c'), 'd' => 'e')
|
||||
public static function parse_parameters( $input ) {
|
||||
if (!isset($input) || !$input) return array();
|
||||
|
||||
$pairs = explode('&', $input);
|
||||
|
||||
$parsed_parameters = array();
|
||||
foreach ($pairs as $pair) {
|
||||
$split = explode('=', $pair, 2);
|
||||
$parameter = OAuthUtil::urldecode_rfc3986($split[0]);
|
||||
$value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
|
||||
|
||||
if (isset($parsed_parameters[$parameter])) {
|
||||
// We have already recieved parameter(s) with this name, so add to the list
|
||||
// of parameters with this name
|
||||
|
||||
if (is_scalar($parsed_parameters[$parameter])) {
|
||||
// This is the first duplicate, so transform scalar (string) into an array
|
||||
// so we can add the duplicates
|
||||
$parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
|
||||
}
|
||||
|
||||
$parsed_parameters[$parameter][] = $value;
|
||||
} else {
|
||||
$parsed_parameters[$parameter] = $value;
|
||||
}
|
||||
}
|
||||
return $parsed_parameters;
|
||||
}
|
||||
|
||||
public static function build_http_query($params) {
|
||||
if (!$params) return '';
|
||||
|
||||
// Urlencode both keys and values
|
||||
$keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
|
||||
$values = OAuthUtil::urlencode_rfc3986(array_values($params));
|
||||
$params = array_combine($keys, $values);
|
||||
|
||||
// Parameters are sorted by name, using lexicographical byte value ordering.
|
||||
// Ref: Spec: 9.1.1 (1)
|
||||
uksort($params, 'strcmp');
|
||||
|
||||
$pairs = array();
|
||||
foreach ($params as $parameter => $value) {
|
||||
if (is_array($value)) {
|
||||
// If two or more parameters share the same name, they are sorted by their value
|
||||
// Ref: Spec: 9.1.1 (1)
|
||||
// June 12th, 2010 - changed to sort because of issue 164 by hidetaka
|
||||
sort($value, SORT_STRING);
|
||||
foreach ($value as $duplicate_value) {
|
||||
$pairs[] = $parameter . '=' . $duplicate_value;
|
||||
}
|
||||
} else {
|
||||
$pairs[] = $parameter . '=' . $value;
|
||||
}
|
||||
}
|
||||
// For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
|
||||
// Each name-value pair is separated by an '&' character (ASCII code 38)
|
||||
return implode('&', $pairs);
|
||||
}
|
||||
}
|
||||
264
plugin/social/Hybrid/thirdparty/OAuth/OAuth1Client.php
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
<?php
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2014, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
// A service client for the OAuth 1/1.0a flow.
|
||||
// v0.1
|
||||
class OAuth1Client{
|
||||
public $api_base_url = "";
|
||||
public $authorize_url = "";
|
||||
public $authenticate_url = "";
|
||||
public $request_token_url = "";
|
||||
public $access_token_url = "";
|
||||
|
||||
public $request_token_method = "GET";
|
||||
public $access_token_method = "GET";
|
||||
|
||||
public $redirect_uri = "";
|
||||
|
||||
public $decode_json = true;
|
||||
public $curl_time_out = 30;
|
||||
public $curl_connect_time_out = 30;
|
||||
public $curl_ssl_verifypeer = false;
|
||||
public $curl_auth_header = true;
|
||||
public $curl_useragent = "OAuth/1 Simple PHP Client v0.1; HybridAuth http://hybridauth.sourceforge.net/";
|
||||
public $curl_proxy = null;
|
||||
|
||||
//--
|
||||
|
||||
public $http_code = "";
|
||||
public $http_info = "";
|
||||
protected $response = null;
|
||||
|
||||
/**
|
||||
* OAuth client constructor
|
||||
*/
|
||||
function __construct( $consumer_key, $consumer_secret, $oauth_token = null, $oauth_token_secret = null )
|
||||
{
|
||||
$this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
$this->consumer = new OAuthConsumer( $consumer_key, $consumer_secret );
|
||||
$this->token = null;
|
||||
|
||||
if ( $oauth_token && $oauth_token_secret ){
|
||||
$this->token = new OAuthConsumer( $oauth_token, $oauth_token_secret );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build authorize url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function authorizeUrl( $token, $extras =array() )
|
||||
{
|
||||
if ( is_array( $token ) ){
|
||||
$token = $token['oauth_token'];
|
||||
}
|
||||
|
||||
$parameters = array( "oauth_token" => $token );
|
||||
|
||||
if( count($extras) )
|
||||
foreach( $extras as $k=>$v )
|
||||
$parameters[$k] = $v;
|
||||
|
||||
return $this->authorize_url . "?" . http_build_query( $parameters );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a request_token from provider
|
||||
*
|
||||
* @return array a key/value array containing oauth_token and oauth_token_secret
|
||||
*/
|
||||
function requestToken( $callback = null )
|
||||
{
|
||||
$parameters = array();
|
||||
|
||||
if ( $callback ) {
|
||||
$this->redirect_uri = $parameters['oauth_callback'] = $callback;
|
||||
}
|
||||
|
||||
$request = $this->signedRequest( $this->request_token_url, $this->request_token_method, $parameters );
|
||||
$token = OAuthUtil::parse_parameters( $request );
|
||||
$this->token = new OAuthConsumer( $token['oauth_token'], $token['oauth_token_secret'] );
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange the request token and secret for an access token and secret, to sign API calls.
|
||||
*
|
||||
* @return array array('oauth_token' => the access token, 'oauth_token_secret' => the access secret)
|
||||
*/
|
||||
function accessToken( $oauth_verifier = false, $oauth_token = false )
|
||||
{
|
||||
$parameters = array();
|
||||
|
||||
// 1.0a
|
||||
if ( $oauth_verifier ) {
|
||||
$parameters['oauth_verifier'] = $oauth_verifier;
|
||||
}
|
||||
|
||||
$request = $this->signedRequest( $this->access_token_url, $this->access_token_method, $parameters );
|
||||
$token = OAuthUtil::parse_parameters( $request );
|
||||
$this->token = new OAuthConsumer( $token['oauth_token'], $token['oauth_token_secret'] );
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET wrapper for provider apis request
|
||||
*/
|
||||
function get($url, $parameters = array(), $content_type = null)
|
||||
{
|
||||
return $this->api($url, 'GET', $parameters, null, $content_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST wrapper for provider apis request
|
||||
*/
|
||||
function post($url, $parameters = array(), $body = null, $content_type = null, $multipart = false)
|
||||
{
|
||||
return $this->api($url, 'POST', $parameters, $body, $content_type, $multipart );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and sign an oauth for provider api
|
||||
*/
|
||||
function api( $url, $method = 'GET', $parameters = array(), $body = null, $content_type = null, $multipart = false )
|
||||
{
|
||||
if ( strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0 ) {
|
||||
$url = $this->api_base_url . $url;
|
||||
}
|
||||
|
||||
$response = $this->signedRequest( $url, $method, $parameters, $body, $content_type, $multipart );
|
||||
|
||||
if( $this->decode_json ){
|
||||
$response = json_decode( $response );
|
||||
}
|
||||
|
||||
return $this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the response object afer the fact
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make signed request
|
||||
*/
|
||||
function signedRequest( $url, $method, $parameters, $body = null, $content_type = null, $multipart = false )
|
||||
{
|
||||
|
||||
$signature_parameters = array();
|
||||
|
||||
// when making a multipart request, use only oauth_* keys for signature
|
||||
foreach( $parameters AS $key => $value ){
|
||||
if( !$multipart || strpos( $key, 'oauth_' ) === 0 ){
|
||||
$signature_parameters[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $signature_parameters);
|
||||
$request->sign_request($this->sha1_method, $this->consumer, $this->token);
|
||||
switch ($method) {
|
||||
case 'GET': return $this->request( $request->to_url(), 'GET', null, null, $content_type );
|
||||
default :
|
||||
if ($body)
|
||||
return $this->request( $request->to_url(), $method, $body, $request->to_header(), $content_type );
|
||||
else
|
||||
return $this->request( $request->get_normalized_http_url(), $method, ($multipart ? $parameters : $request->to_postdata()), $request->to_header(), $content_type, $multipart ) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make http request
|
||||
*/
|
||||
function request( $url, $method, $postfields = null, $auth_header = null, $content_type = null, $multipart = false )
|
||||
{
|
||||
Hybrid_Logger::info( "Enter OAuth1Client::request( $method, $url )" );
|
||||
Hybrid_Logger::debug( "OAuth1Client::request(). dump post fields: ", serialize( $postfields ) );
|
||||
|
||||
$this->http_info = array();
|
||||
$ci = curl_init();
|
||||
|
||||
/* Curl settings */
|
||||
curl_setopt( $ci, CURLOPT_USERAGENT , $this->curl_useragent );
|
||||
curl_setopt( $ci, CURLOPT_CONNECTTIMEOUT, $this->curl_connect_time_out );
|
||||
curl_setopt( $ci, CURLOPT_TIMEOUT , $this->curl_time_out );
|
||||
curl_setopt( $ci, CURLOPT_RETURNTRANSFER, true );
|
||||
curl_setopt( $ci, CURLOPT_HTTPHEADER , array('Expect:') );
|
||||
curl_setopt( $ci, CURLOPT_SSL_VERIFYPEER, $this->curl_ssl_verifypeer );
|
||||
curl_setopt( $ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader') );
|
||||
curl_setopt( $ci, CURLOPT_HEADER , false );
|
||||
|
||||
if( $multipart ){
|
||||
curl_setopt( $ci, CURLOPT_HTTPHEADER, array( 'Expect:', $auth_header ) );
|
||||
|
||||
}elseif ($content_type)
|
||||
curl_setopt( $ci, CURLOPT_HTTPHEADER, array('Expect:', "Content-Type: $content_type") );
|
||||
|
||||
if($this->curl_proxy){
|
||||
curl_setopt( $ci, CURLOPT_PROXY , $this->curl_proxy);
|
||||
}
|
||||
|
||||
switch ($method){
|
||||
case 'POST':
|
||||
curl_setopt( $ci, CURLOPT_POST, true );
|
||||
|
||||
if ( !empty($postfields) ){
|
||||
curl_setopt( $ci, CURLOPT_POSTFIELDS, $postfields );
|
||||
}
|
||||
|
||||
if ( !empty($auth_header) && $this->curl_auth_header && !$multipart ){
|
||||
curl_setopt( $ci, CURLOPT_HTTPHEADER, array( 'Content-Type: application/atom+xml', $auth_header ) );
|
||||
}
|
||||
break;
|
||||
case 'DELETE':
|
||||
curl_setopt( $ci, CURLOPT_CUSTOMREQUEST, 'DELETE' );
|
||||
if ( !empty($postfields) ){
|
||||
$url = "{$url}?{$postfields}";
|
||||
}
|
||||
}
|
||||
|
||||
curl_setopt($ci, CURLOPT_URL, $url);
|
||||
$response = curl_exec($ci);
|
||||
if( $response === false ) {
|
||||
Hybrid_Logger::error( "OAuth1Client::request(). curl_exec error: ", curl_error($ci) );
|
||||
}
|
||||
|
||||
|
||||
Hybrid_Logger::debug( "OAuth1Client::request(). dump request info: ", serialize( curl_getinfo($ci) ) );
|
||||
Hybrid_Logger::debug( "OAuth1Client::request(). dump request result: ", serialize( $response ) );
|
||||
|
||||
$this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
|
||||
$this->http_info = array_merge($this->http_info, curl_getinfo($ci));
|
||||
|
||||
curl_close ($ci);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the header info to store.
|
||||
*/
|
||||
function getHeader($ch, $header) {
|
||||
$i = strpos($header, ':');
|
||||
|
||||
if ( !empty($i) ){
|
||||
$key = str_replace('-', '_', strtolower(substr($header, 0, $i)));
|
||||
$value = trim(substr($header, $i + 2));
|
||||
$this->http_header[$key] = $value;
|
||||
}
|
||||
|
||||
return strlen($header);
|
||||
}
|
||||
}
|
||||
302
plugin/social/Hybrid/thirdparty/OAuth/OAuth2Client.php
vendored
Normal file
@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
// A service client for the OAuth 2 flow.
|
||||
// v0.1.1
|
||||
class OAuth2Client
|
||||
{
|
||||
public $api_base_url = "";
|
||||
public $authorize_url = "";
|
||||
public $token_url = "";
|
||||
public $token_info_url = "";
|
||||
|
||||
public $client_id = "" ;
|
||||
public $client_secret = "" ;
|
||||
public $redirect_uri = "" ;
|
||||
public $access_token = "" ;
|
||||
public $refresh_token = "" ;
|
||||
|
||||
public $access_token_expires_in = "" ;
|
||||
public $access_token_expires_at = "" ;
|
||||
|
||||
//--
|
||||
|
||||
public $sign_token_name = "access_token";
|
||||
public $curl_time_out = 30;
|
||||
public $curl_connect_time_out = 30;
|
||||
public $curl_ssl_verifypeer = false;
|
||||
public $curl_ssl_verifyhost = false;
|
||||
public $curl_header = array();
|
||||
public $curl_useragent = "OAuth/2 Simple PHP Client v0.1.1; HybridAuth http://hybridauth.sourceforge.net/";
|
||||
public $curl_authenticate_method = "POST";
|
||||
public $curl_proxy = null;
|
||||
public $curl_compressed = false;
|
||||
//--
|
||||
|
||||
public $http_code = "";
|
||||
public $http_info = "";
|
||||
protected $response = null;
|
||||
|
||||
//--
|
||||
|
||||
public function __construct( $client_id = false, $client_secret = false, $redirect_uri='', $compressed = false )
|
||||
{
|
||||
$this->client_id = $client_id;
|
||||
$this->client_secret = $client_secret;
|
||||
$this->redirect_uri = $redirect_uri;
|
||||
$this->curl_compressed = $compressed;
|
||||
}
|
||||
|
||||
public function authorizeUrl( $extras = array() )
|
||||
{
|
||||
$params = array(
|
||||
"client_id" => $this->client_id,
|
||||
"redirect_uri" => $this->redirect_uri,
|
||||
"response_type" => "code"
|
||||
);
|
||||
|
||||
if( count($extras) )
|
||||
foreach( $extras as $k=>$v )
|
||||
$params[$k] = $v;
|
||||
|
||||
return $this->authorize_url . "?" . http_build_query($params, '', '&');
|
||||
}
|
||||
|
||||
public function authenticate( $code )
|
||||
{
|
||||
$params = array(
|
||||
"client_id" => $this->client_id,
|
||||
"client_secret" => $this->client_secret,
|
||||
"grant_type" => "authorization_code",
|
||||
"redirect_uri" => $this->redirect_uri,
|
||||
"code" => $code
|
||||
);
|
||||
|
||||
$response = $this->request( $this->token_url, $params, $this->curl_authenticate_method );
|
||||
|
||||
$response = $this->parseRequestResult( $response );
|
||||
|
||||
if( ! $response || ! isset( $response->access_token ) ){
|
||||
throw new Exception( "The Authorization Service has return: " . $response->error );
|
||||
}
|
||||
|
||||
if( isset( $response->access_token ) ) $this->access_token = $response->access_token;
|
||||
if( isset( $response->refresh_token ) ) $this->refresh_token = $response->refresh_token;
|
||||
if( isset( $response->expires_in ) ) $this->access_token_expires_in = $response->expires_in;
|
||||
|
||||
// calculate when the access token expire
|
||||
if( isset($response->expires_in)) {
|
||||
$this->access_token_expires_at = time() + $response->expires_in;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function authenticated()
|
||||
{
|
||||
if ( $this->access_token ){
|
||||
if ( $this->token_info_url && $this->refresh_token ){
|
||||
// check if this access token has expired,
|
||||
$tokeninfo = $this->tokenInfo( $this->access_token );
|
||||
|
||||
// if yes, access_token has expired, then ask for a new one
|
||||
if( $tokeninfo && isset( $tokeninfo->error ) ){
|
||||
$response = $this->refreshToken( $this->refresh_token );
|
||||
|
||||
// if wrong response
|
||||
if( ! isset( $response->access_token ) || ! $response->access_token ){
|
||||
throw new Exception( "The Authorization Service has return an invalid response while requesting a new access token. given up!" );
|
||||
}
|
||||
|
||||
// set new access_token
|
||||
$this->access_token = $response->access_token;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and sign an oauth for provider api
|
||||
*/
|
||||
public function api( $url, $method = "GET", $parameters = array(), $decode_json = true )
|
||||
{
|
||||
if ( strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0 ) {
|
||||
$url = $this->api_base_url . $url;
|
||||
}
|
||||
|
||||
$parameters[$this->sign_token_name] = $this->access_token;
|
||||
$response = null;
|
||||
|
||||
switch( $method ){
|
||||
case 'GET' : $response = $this->request( $url, $parameters, "GET" ); break;
|
||||
case 'POST' : $response = $this->request( $url, $parameters, "POST" ); break;
|
||||
case 'DELETE' : $response = $this->request( $url, $parameters, "DELETE" ); break;
|
||||
case 'PATCH' : $response = $this->request( $url, $parameters, "PATCH" ); break;
|
||||
}
|
||||
|
||||
if( $response && $decode_json ){
|
||||
return $this->response = json_decode( $response );
|
||||
}
|
||||
|
||||
return $this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the response object afer the fact
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET wrapper for provider apis request
|
||||
*/
|
||||
function get( $url, $parameters = array(), $decode_json = true )
|
||||
{
|
||||
return $this->api( $url, 'GET', $parameters, $decode_json );
|
||||
}
|
||||
|
||||
/**
|
||||
* POST wrapper for provider apis request
|
||||
*/
|
||||
function post( $url, $parameters = array(), $decode_json = true )
|
||||
{
|
||||
return $this->api( $url, 'POST', $parameters, $decode_json );
|
||||
}
|
||||
|
||||
// -- tokens
|
||||
|
||||
public function tokenInfo($accesstoken)
|
||||
{
|
||||
$params['access_token'] = $this->access_token;
|
||||
$response = $this->request( $this->token_info_url, $params );
|
||||
return $this->parseRequestResult( $response );
|
||||
}
|
||||
|
||||
public function refreshToken( $parameters = array() )
|
||||
{
|
||||
$params = array(
|
||||
"client_id" => $this->client_id,
|
||||
"client_secret" => $this->client_secret,
|
||||
"grant_type" => "refresh_token"
|
||||
);
|
||||
|
||||
foreach($parameters as $k=>$v ){
|
||||
$params[$k] = $v;
|
||||
}
|
||||
|
||||
$response = $this->request( $this->token_url, $params, "POST" );
|
||||
return $this->parseRequestResult( $response );
|
||||
}
|
||||
|
||||
// -- utilities
|
||||
|
||||
private function request( $url, $params=false, $type="GET" )
|
||||
{
|
||||
Hybrid_Logger::info( "Enter OAuth2Client::request( $url )" );
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request params: ", serialize( $params ) );
|
||||
|
||||
$urlEncodedParams = http_build_query($params, '', '&');
|
||||
|
||||
if( $type == "GET" ){
|
||||
$url = $url . ( strpos( $url, '?' ) ? '&' : '?' ) . $urlEncodedParams;
|
||||
}
|
||||
|
||||
$this->http_info = array();
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL , $url );
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1 );
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT , $this->curl_time_out );
|
||||
curl_setopt($ch, CURLOPT_USERAGENT , $this->curl_useragent );
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , $this->curl_connect_time_out );
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , $this->curl_ssl_verifypeer );
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST , $this->curl_ssl_verifyhost );
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER , $this->curl_header );
|
||||
|
||||
if ($this->curl_compressed){
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
|
||||
}
|
||||
|
||||
if($this->curl_proxy){
|
||||
curl_setopt( $ch, CURLOPT_PROXY , $this->curl_proxy);
|
||||
}
|
||||
|
||||
if ($type == "POST") {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
|
||||
// If request body exists then encode it for "application/json".
|
||||
if (isset($params['body'])) {
|
||||
$urlEncodedParams = json_encode($params['body']);
|
||||
}
|
||||
|
||||
// Using URL encoded params here instead of a more convenient array
|
||||
// cURL will set a wrong HTTP Content-Type header if using an array (cf. http://www.php.net/manual/en/function.curl-setopt.php, Notes section for "CURLOPT_POSTFIELDS")
|
||||
// OAuth requires application/x-www-form-urlencoded Content-Type (cf. https://tools.ietf.org/html/rfc6749#section-2.3.1)
|
||||
if ($params) {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $urlEncodedParams);
|
||||
}
|
||||
}
|
||||
|
||||
if( $type == "DELETE" ){
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
}
|
||||
if( $type == "PATCH" ){
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
if($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, $params );
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
if( $response === false ) {
|
||||
Hybrid_Logger::error( "OAuth2Client::request(). curl_exec error: ", curl_error($ch) );
|
||||
}
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request info: ", serialize( curl_getinfo($ch) ) );
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request result: ", serialize( $response ) );
|
||||
|
||||
$this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$this->http_info = array_merge($this->http_info, curl_getinfo($ch));
|
||||
|
||||
curl_close ($ch);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function parseRequestResult( $result )
|
||||
{
|
||||
if( json_decode( $result ) ) return json_decode( $result );
|
||||
|
||||
parse_str( $result, $output );
|
||||
|
||||
$result = new StdClass();
|
||||
|
||||
foreach( $output as $k => $v )
|
||||
$result->$k = $v;
|
||||
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* DELETE wrapper for provider apis request
|
||||
*/
|
||||
function delete( $url, $parameters = array() )
|
||||
{
|
||||
return $this->api( $url, 'DELETE', $parameters );
|
||||
}
|
||||
/**
|
||||
* PATCH wrapper for provider apis request
|
||||
*/
|
||||
function patch( $url, $parameters = array() )
|
||||
{
|
||||
return $this->api( $url, 'PATCH', $parameters );
|
||||
}
|
||||
}
|
||||
1051
plugin/social/Hybrid/thirdparty/OpenID/LightOpenID.php
vendored
Normal file
10
plugin/social/Hybrid/thirdparty/index.html
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
3
plugin/social/_common.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include_once('../../common.php');
|
||||
?>
|
||||
63
plugin/social/config.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// HybridAuth Config file: http://hybridauth.sourceforge.net/userguide/Configuration.html
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
return array(
|
||||
"base_url" => "http://localhost/hybridauth-git/hybridauth/",
|
||||
"providers" => array(
|
||||
// openid providers
|
||||
"OpenID" => array(
|
||||
"enabled" => true,
|
||||
),
|
||||
"Yahoo" => array(
|
||||
"enabled" => true,
|
||||
"keys" => array("id" => "", "secret" => ""),
|
||||
),
|
||||
"AOL" => array(
|
||||
"enabled" => true,
|
||||
),
|
||||
"Google" => array(
|
||||
"enabled" => true,
|
||||
"keys" => array("id" => "", "secret" => ""),
|
||||
),
|
||||
"Facebook" => array(
|
||||
"enabled" => true,
|
||||
"keys" => array("id" => "", "secret" => ""),
|
||||
"trustForwarded" => false,
|
||||
),
|
||||
"Twitter" => array(
|
||||
"enabled" => true,
|
||||
"keys" => array("key" => "", "secret" => ""),
|
||||
"includeEmail" => false,
|
||||
),
|
||||
// windows live
|
||||
"Live" => array(
|
||||
"enabled" => true,
|
||||
"keys" => array("id" => "", "secret" => ""),
|
||||
),
|
||||
"LinkedIn" => array(
|
||||
"enabled" => true,
|
||||
"keys" => array("id" => "", "secret" => ""),
|
||||
"fields" => array(),
|
||||
),
|
||||
"Foursquare" => array(
|
||||
"enabled" => true,
|
||||
"keys" => array("id" => "", "secret" => ""),
|
||||
),
|
||||
),
|
||||
// If you want to enable logging, set 'debug_mode' to true.
|
||||
// You can also set it to
|
||||
// - "error" To log only error messages. Useful in production
|
||||
// - "info" To log info and error messages (ignore debug messages)
|
||||
"debug_mode" => false,
|
||||
// Path to file writable by the web server. Required if 'debug_mode' is not false
|
||||
"debug_file" => "",
|
||||
);
|
||||
68
plugin/social/error.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta name="robots" content="NOINDEX, NOFOLLOW">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=yes">
|
||||
<title>소셜 로그인 - <?php echo $provider; ?></title>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||
<style>
|
||||
.error-container{padding:1em}
|
||||
.bs-callout {
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
border: 1px solid #eee;
|
||||
border-left-width: 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.bs-callout-danger {
|
||||
border-left-color: #ce4844;
|
||||
}
|
||||
.bs-callout-danger h4 {
|
||||
color: #ce4844;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="error-container">
|
||||
<h4>Error : <?php echo $code; ?></h4>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
||||
<span class="sr-only">Error:</span>
|
||||
<?php echo $get_error; ?>
|
||||
</div>
|
||||
<div class="bs-callout bs-callout-danger" id="callout-images-ie-rounded-corners">
|
||||
<?php if(isset($code) && ($code <= 0 && $code > 10) ){ ?>
|
||||
<p>잠시후에 다시 시도해 주세요.</p>
|
||||
<?php } ?>
|
||||
<a href="<?php echo G5_URL; ?>" class="btn btn-primary go_home">홈으로</a>
|
||||
<a href="<?php echo G5_URL; ?>" class="btn btn-default close" style="display:none">이 페이지 닫기</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
jQuery(function($){
|
||||
$(".go_home.btn").click(function(e){
|
||||
if( window.opener ){
|
||||
e.preventDefault();
|
||||
window.opener.location.href = $(this).attr("href");
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
|
||||
if( window.opener ){
|
||||
$(".close.btn").show();
|
||||
}
|
||||
|
||||
$(".close.btn").click(function(e){
|
||||
window.close();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
<?php
|
||||
die();
|
||||
?>
|
||||
BIN
plugin/social/img/loading_icon.gif
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
1039
plugin/social/includes/functions.php
Normal file
32
plugin/social/includes/g5_endpoint.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
//https://hybridauth.github.io/hybridauth/userguide/tuts/change-hybridauth-endpoint-url.html
|
||||
|
||||
class G5_Hybrid_Authentication {
|
||||
|
||||
public static function hybridauth_endpoint() {
|
||||
|
||||
require_once( G5_SOCIAL_LOGIN_PATH.'/Hybrid/Auth.php' );
|
||||
require_once( G5_SOCIAL_LOGIN_PATH.'/Hybrid/Endpoint.php' );
|
||||
require_once( G5_SOCIAL_LOGIN_PATH.'/includes/g5_endpoint_class.php' );
|
||||
|
||||
if( defined('G5_SOCIAL_LOGIN_START_PARAM') && G5_SOCIAL_LOGIN_START_PARAM !== 'hauth.start' && isset($_REQUEST[G5_SOCIAL_LOGIN_START_PARAM]) ){
|
||||
$_REQUEST['hauth_start'] = preg_replace('/[^a-zA-Z0-9\-\._]/i', '', $_REQUEST[G5_SOCIAL_LOGIN_START_PARAM]);
|
||||
}
|
||||
|
||||
if( defined('G5_SOCIAL_LOGIN_DONE_PARAM') && G5_SOCIAL_LOGIN_DONE_PARAM !== 'hauth.done' && isset($_REQUEST[G5_SOCIAL_LOGIN_DONE_PARAM]) ){
|
||||
$_REQUEST['hauth_done'] = preg_replace('/[^a-zA-Z0-9\-\._]/i', '', $_REQUEST[G5_SOCIAL_LOGIN_DONE_PARAM]);
|
||||
}
|
||||
|
||||
/*
|
||||
$key = 'hauth.' . $action; // either `hauth_start` or `hauth_done`
|
||||
|
||||
$_REQUEST[ $key ] = $provider; // provider will be something like `facebook` or `google`
|
||||
*/
|
||||
|
||||
G5_Hybrid_Endpoint::process();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
32
plugin/social/includes/g5_endpoint_class.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
|
||||
class G5_Hybrid_Endpoint extends Hybrid_Endpoint
|
||||
{
|
||||
protected function processAuthStart(){
|
||||
try {
|
||||
parent::processAuthStart();
|
||||
}
|
||||
catch( Exception $e ){
|
||||
$this->dieError( "412 Precondition Failed", $e->getMessage(), $e );
|
||||
}
|
||||
}
|
||||
|
||||
protected function processAuthDone()
|
||||
{
|
||||
try {
|
||||
parent::processAuthDone();
|
||||
}
|
||||
catch( Exception $e ){
|
||||
$this->dieError( "410 Gone", $e->getMessage(), $e );
|
||||
}
|
||||
}
|
||||
|
||||
public function dieError( $code, $message, $e )
|
||||
{
|
||||
$get_error = $message;
|
||||
include_once(G5_SOCIAL_LOGIN_PATH.'/error.php');
|
||||
die();
|
||||
}
|
||||
}
|
||||
?>
|
||||
0
plugin/social/includes/index.php
Normal file
68
plugin/social/includes/loading.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta name="robots" content="NOINDEX, NOFOLLOW">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=yes">
|
||||
<title>소셜 로그인 - <?php echo $provider; ?></title>
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" border="0">
|
||||
<tr>
|
||||
<td align="center" height="190px" valign="middle"><img src="<?php echo $img_url;?>loading_icon.gif" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><br /><h3>Loading...</h3><br /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><b><?php echo ucfirst( strtolower( strip_tags( $provider ) ) ) ; ?></b> 에 연결중입니다. 잠시만 기다려주세요.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php if( (defined('G5_SOCIAL_IS_LOADING') && G5_SOCIAL_IS_LOADING ) || (G5_SOCIAL_USE_POPUP && empty($login_action_url)) ){ ?>
|
||||
<script>
|
||||
window.location.href = window.location.href + "&redirect_to_idp=1";
|
||||
</script>
|
||||
<?php } else { ?>
|
||||
<form name="loginform" method="post" action="<?php echo $login_action_url; ?>">
|
||||
<input type="hidden" id="url" name="url" value="<?php echo $url ?>">
|
||||
<input type="hidden" id="provider" name="provider" value="<?php echo $provider ?>">
|
||||
<input type="hidden" id="mb_id" name="mb_id" value="<?php echo $mb_id ?>">
|
||||
<input type="hidden" id="mb_password" name="mb_password" value="<?php echo $mb_password ?>">
|
||||
</form>
|
||||
<script>
|
||||
function init()
|
||||
{
|
||||
<?php
|
||||
if( $use_popup == 1 || ! $use_popup ){
|
||||
?>
|
||||
if( window.opener )
|
||||
{
|
||||
window.opener.name = "social_login";
|
||||
document.loginform.target = window.opener.name;
|
||||
document.loginform.submit();
|
||||
window.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
document.loginform.submit();
|
||||
}
|
||||
<?php
|
||||
}
|
||||
elseif( $use_popup == 2 ){
|
||||
?>
|
||||
document.loginform.submit();
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
}
|
||||
init();
|
||||
</script>
|
||||
<?php } //end if ?>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
die();
|
||||
?>
|
||||
244
plugin/social/includes/providers.php
Normal file
@ -0,0 +1,244 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
|
||||
|
||||
$social_providers_config = array(
|
||||
ARRAY(
|
||||
"provider_id" => "Facebook",
|
||||
"provider_name" => "Facebook",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "https://developers.facebook.com/apps",
|
||||
"default_api_scope" => "email, public_profile, user_friends",
|
||||
|
||||
"default_network" => true,
|
||||
"cat" => "socialnetworks",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Google",
|
||||
"provider_name" => "Google",
|
||||
"callback" => true,
|
||||
"require_client_id" => true,
|
||||
"new_app_link" => "https://console.developers.google.com",
|
||||
"default_api_scope" => "profile https://www.googleapis.com/auth/plus.profile.emails.read",
|
||||
|
||||
"default_network" => true,
|
||||
"cat" => "socialnetworks",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Twitter",
|
||||
"provider_name" => "Twitter",
|
||||
"callback" => true,
|
||||
"new_app_link" => "https://dev.twitter.com/apps",
|
||||
|
||||
"default_network" => true,
|
||||
"cat" => "microblogging",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "WordPress",
|
||||
"provider_name" => "WordPress",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "https://developer.wordpress.com/apps/new/",
|
||||
|
||||
"cat" => "blogging",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Yahoo",
|
||||
"provider_name" => "Yahoo!",
|
||||
"new_app_link" => null,
|
||||
|
||||
"cat" => "pleasedie",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "LinkedIn",
|
||||
"provider_name" => "LinkedIn",
|
||||
"new_app_link" => "https://www.linkedin.com/secure/developer",
|
||||
|
||||
"cat" => "professional",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Disqus",
|
||||
"provider_name" => "Disqus",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "https://disqus.com/api/applications/",
|
||||
|
||||
"cat" => "misc",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Instagram",
|
||||
"provider_name" => "Instagram",
|
||||
"callback" => true,
|
||||
"require_client_id" => true,
|
||||
"new_app_link" => "http://instagr.am/developer/clients/manage/",
|
||||
|
||||
"cat" => "media",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Reddit",
|
||||
"provider_name" => "Reddit",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "https://ssl.reddit.com/prefs/apps",
|
||||
|
||||
"cat" => "socialnetworks",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Foursquare",
|
||||
"provider_name" => "Foursquare",
|
||||
"callback" => true,
|
||||
"require_client_id" => true,
|
||||
"new_app_link" => "https://www.foursquare.com/oauth/",
|
||||
|
||||
"cat" => "microblogging",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "LastFM",
|
||||
"provider_name" => "Last.FM",
|
||||
"new_app_link" => "http://www.lastfm.com/api/account",
|
||||
|
||||
"cat" => "media",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Tumblr",
|
||||
"provider_name" => "Tumblr",
|
||||
"new_app_link" => "http://www.tumblr.com/oauth/apps",
|
||||
|
||||
"cat" => "microblogging", // o well
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Goodreads",
|
||||
"provider_name" => "Goodreads",
|
||||
"callback" => true,
|
||||
"new_app_link" => "http://www.goodreads.com/api",
|
||||
|
||||
"cat" => "media",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Stackoverflow",
|
||||
"provider_name" => "Stackoverflow",
|
||||
"new_app_link" => null,
|
||||
|
||||
"cat" => "programmers",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "GitHub",
|
||||
"provider_name" => "GitHub",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "https://github.com/settings/applications/new",
|
||||
"default_api_scope" => "user:email",
|
||||
|
||||
"cat" => "programmers",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Dribbble",
|
||||
"provider_name" => "Dribbble",
|
||||
"require_client_id" => true,
|
||||
"custom_callback" => true,
|
||||
"new_app_link" => "https://dribbble.com/account/applications/new",
|
||||
|
||||
"cat" => "designers",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "500px",
|
||||
"provider_name" => "px500",
|
||||
"new_app_link" => "http://developers.500px.com/",
|
||||
|
||||
"cat" => "media",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Skyrock",
|
||||
"provider_name" => "Skyrock",
|
||||
"callback" => true,
|
||||
"new_app_link" => "https://www.skyrock.com/developer/application",
|
||||
|
||||
"cat" => "socialnetworks",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Mixi",
|
||||
"provider_name" => "Mixi",
|
||||
"new_app_link" => null,
|
||||
|
||||
"cat" => "socialnetworks",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Steam",
|
||||
"provider_name" => "Steam",
|
||||
"new_app_link" => "http://steamcommunity.com/dev/apikey",
|
||||
"require_api_key" => true,
|
||||
|
||||
"cat" => "gamers",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "TwitchTV",
|
||||
"provider_name" => "Twitch.tv",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "http://www.twitch.tv/settings?section=applications",
|
||||
|
||||
"cat" => "gamers",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Vkontakte",
|
||||
"provider_name" => "ВКонтакте",
|
||||
"callback" => true,
|
||||
"require_client_id" => true,
|
||||
"new_app_link" => "http://vk.com/developers.php",
|
||||
|
||||
"cat" => "socialnetworks",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Mailru",
|
||||
"provider_name" => "Mailru",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "http://api.mail.ru/",
|
||||
|
||||
"cat" => "misc",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Yandex",
|
||||
"provider_name" => "Yandex",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "https://oauth.yandex.ru",
|
||||
|
||||
"cat" => "misc",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Odnoklassniki",
|
||||
"provider_name" => "Odnoklassniki",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "http://dev.odnoklassniki.ru/",
|
||||
|
||||
"cat" => "socialnetworks",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "AOL",
|
||||
"provider_name" => "AOL",
|
||||
"new_app_link" => null,
|
||||
|
||||
"cat" => "pleasedie",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "Live",
|
||||
"provider_name" => "Windows Live",
|
||||
"require_client_id" => true,
|
||||
"new_app_link" => "https://account.live.com/developers/applications/create",
|
||||
|
||||
"cat" => "pleasedie",
|
||||
),
|
||||
ARRAY(
|
||||
"provider_id" => "PixelPin",
|
||||
"provider_name" => "PixelPin",
|
||||
"require_client_id" => true,
|
||||
"callback" => true,
|
||||
"new_app_link" => "https://login.pixelpin.co.uk/",
|
||||
|
||||
"cat" => "misc",
|
||||
),
|
||||
);
|
||||
|
||||
?>
|
||||
22
plugin/social/index.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// HybridAuth End Point
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
include_once('_common.php');
|
||||
|
||||
if( ! $config['cf_social_login_use']){
|
||||
die("소셜로그인을 사용하지 않습니다.");
|
||||
}
|
||||
|
||||
require_once( "includes/g5_endpoint.php" );
|
||||
|
||||
error_reporting(0); // Turn off all error reporting
|
||||
|
||||
G5_Hybrid_Authentication::hybridauth_endpoint();
|
||||
44
plugin/social/popup.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
include_once('_common.php');
|
||||
|
||||
if( ! $config['cf_social_login_use'] ){
|
||||
alert('소셜 로그인 설정이 비활성화 되어 있습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
if( ! G5_SOCIAL_USE_POPUP ){
|
||||
alert('새창 옵션이 비활성화 되어 있습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
$provider_name = social_get_request_provider();
|
||||
|
||||
if( !$provider_name ){
|
||||
alert('서비스 이름이 넘어오지 않았습니다.');
|
||||
}
|
||||
|
||||
if( isset( $_REQUEST["redirect_to_idp"] ) ){
|
||||
$content = social_check_login_before();
|
||||
|
||||
$get_login_url = G5_BBS_URL."/login.php?url=".$urlencode;
|
||||
|
||||
if( $content ){
|
||||
//팝업으로 뜨웠다면 아래
|
||||
?>
|
||||
<script>
|
||||
if( window.opener ){
|
||||
(function(){
|
||||
var login_url = "<?php echo $get_login_url; ?>";
|
||||
|
||||
window.opener.location.href = login_url+"&provider=<?php echo $provider_name; ?>";
|
||||
window.close();
|
||||
})();
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
} else {
|
||||
social_login_session_clear(1);
|
||||
social_return_from_provider_page( $provider_name, '', '', '', '' );
|
||||
}
|
||||
?>
|
||||
52
plugin/social/register_member.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
include_once('./_common.php');
|
||||
//include_once(G5_CAPTCHA_PATH.'/captcha.lib.php');
|
||||
include_once(G5_LIB_PATH.'/register.lib.php');
|
||||
|
||||
define('ASIDE_DISABLE', 1);
|
||||
|
||||
if( ! $config['cf_social_login_use'] ){
|
||||
alert('소셜 로그인을 사용하지 않습니다.');
|
||||
}
|
||||
|
||||
if( $is_member ){
|
||||
alert('이미 회원가입 하였습니다.', G5_URL);
|
||||
}
|
||||
|
||||
$provider_name = social_get_request_provider();
|
||||
$user_profile = social_session_exists_check();
|
||||
if( ! $user_profile ){
|
||||
alert( "소셜로그인을 하신 분만 접근할 수 있습니다.", G5_URL);
|
||||
}
|
||||
|
||||
// 소셜 가입된 내역이 있는지 확인 상수 G5_SOCIAL_DELETE_DAY 관련
|
||||
$is_exists_social_account = social_before_join_check($url);
|
||||
|
||||
$user_nick = social_relace_nick($user_profile->displayName);
|
||||
$user_email = isset($user_profile->emailVerified) ? $user_profile->emailVerified : $user_profile->email;
|
||||
$user_id = $user_profile->sid ? preg_replace("/[^0-9a-z_]+/i", "", $user_profile->sid) : get_social_convert_id($user_profile->identifier, $provider_name);
|
||||
|
||||
//$is_exists_id = exist_mb_id($user_id);
|
||||
//$is_exists_name = exist_mb_nick($user_nick, '');
|
||||
$user_id = exist_mb_id_recursive($user_id);
|
||||
$user_nick = exist_mb_nick_recursive($user_nick, '');
|
||||
$is_exists_email = $user_email ? exist_mb_email($user_email, '') : false;
|
||||
|
||||
// 불법접근을 막도록 토큰생성
|
||||
$token = md5(uniqid(rand(), true));
|
||||
set_session("ss_token", $token);
|
||||
|
||||
$g5['title'] = '소셜 회원 가입 - '.social_get_provider_service_name($provider_name);
|
||||
|
||||
include_once(G5_BBS_PATH.'/_head.php');
|
||||
|
||||
$register_action_url = https_url(G5_PLUGIN_DIR.'/'.G5_SOCIAL_LOGIN_DIR, true).'/register_member_update.php';
|
||||
$login_action_url = G5_HTTPS_BBS_URL."/login_check.php";
|
||||
$req_nick = !isset($member['mb_nick_date']) || (isset($member['mb_nick_date']) && $member['mb_nick_date'] <= date("Y-m-d", G5_SERVER_TIME - ($config['cf_nick_modify'] * 86400)));
|
||||
$required = ($w=='') ? 'required' : '';
|
||||
$readonly = ($w=='u') ? 'readonly' : '';
|
||||
|
||||
include_once(get_social_skin_path().'/social_register_member.skin.php');
|
||||
|
||||
include_once(G5_BBS_PATH.'/_tail.php');
|
||||
?>
|
||||
191
plugin/social/register_member_update.php
Normal file
@ -0,0 +1,191 @@
|
||||
<?php
|
||||
include_once('./_common.php');
|
||||
include_once(G5_LIB_PATH.'/register.lib.php');
|
||||
include_once(G5_LIB_PATH.'/mailer.lib.php');
|
||||
|
||||
if( ! $config['cf_social_login_use'] ){
|
||||
alert('소셜 로그인을 사용하지 않습니다.', G5_URL);
|
||||
}
|
||||
|
||||
if( $is_member ){
|
||||
alert('이미 회원가입 하였습니다.', G5_URL);
|
||||
}
|
||||
|
||||
$provider_name = social_get_request_provider();
|
||||
$user_profile = social_session_exists_check();
|
||||
if( ! $user_profile ){
|
||||
alert( "소셜로그인 을 하신 분만 접근할 수 있습니다.", G5_URL);
|
||||
}
|
||||
|
||||
// 소셜 가입된 내역이 있는지 확인 상수 G5_SOCIAL_DELETE_DAY 관련
|
||||
$is_exists_social_account = social_before_join_check(G5_URL);
|
||||
|
||||
$sm_id = $user_profile->sid;
|
||||
$mb_id = trim($_POST['mb_id']);
|
||||
$mb_password = trim($_POST['mb_password']);
|
||||
$mb_password_re = trim($_POST['mb_password_re']);
|
||||
$mb_nick = trim(strip_tags($_POST['mb_nick']));
|
||||
$mb_email = trim($_POST['mb_email']);
|
||||
$mb_name = clean_xss_tags(trim(strip_tags($_POST['mb_name'])));
|
||||
$mb_email = get_email_address($mb_email);
|
||||
|
||||
// 이름, 닉네임에 utf-8 이외의 문자가 포함됐다면 오류
|
||||
// 서버환경에 따라 정상적으로 체크되지 않을 수 있음.
|
||||
$tmp_mb_name = iconv('UTF-8', 'UTF-8//IGNORE', $mb_name);
|
||||
if($tmp_mb_name != $mb_name) {
|
||||
$mb_name = $tmp_mb_name;
|
||||
}
|
||||
$tmp_mb_nick = iconv('UTF-8', 'UTF-8//IGNORE', $mb_nick);
|
||||
if($tmp_mb_nick != $mb_nick) {
|
||||
$mb_nick = $tmp_mb_nick;
|
||||
}
|
||||
|
||||
if( ! $mb_nick || ! $mb_name ){
|
||||
$tmp = explode('@', $mb_email);
|
||||
$mb_nick = $mb_nick ? $mb_nick : $tmp[0];
|
||||
$mb_name = $mb_name ? $mb_name : $tmp[0];
|
||||
}
|
||||
|
||||
if( ! isset($mb_password) || ! $mb_password ){
|
||||
|
||||
$mb_password = md5(pack('V*', rand(), rand(), rand(), rand()));
|
||||
|
||||
}
|
||||
|
||||
if ($msg = empty_mb_name($mb_name)) alert($msg, "", true, true);
|
||||
if ($msg = empty_mb_nick($mb_nick)) alert($msg, "", true, true);
|
||||
if ($msg = empty_mb_email($mb_email)) alert($msg, "", true, true);
|
||||
if ($msg = reserve_mb_id($mb_id)) alert($msg, "", true, true);
|
||||
if ($msg = reserve_mb_nick($mb_nick)) alert($msg, "", true, true);
|
||||
// 이름에 한글명 체크를 하지 않는다.
|
||||
//if ($msg = valid_mb_name($mb_name)) alert($msg, "", true, true);
|
||||
if ($msg = valid_mb_nick($mb_nick)) alert($msg, "", true, true);
|
||||
if ($msg = valid_mb_email($mb_email)) alert($msg, "", true, true);
|
||||
if ($msg = prohibit_mb_email($mb_email))alert($msg, "", true, true);
|
||||
|
||||
if ($msg = exist_mb_id($mb_id)) alert($msg);
|
||||
if ($msg = exist_mb_nick($mb_nick, $mb_id)) alert($msg, "", true, true);
|
||||
if ($msg = exist_mb_email($mb_email, $mb_id)) alert($msg, "", true, true);
|
||||
|
||||
$data = array(
|
||||
'mb_id' => $mb_id,
|
||||
'mb_password' => get_encrypt_string($mb_password),
|
||||
'mb_nick' => $mb_nick,
|
||||
'mb_email' => $mb_email,
|
||||
'mb_name' => $mb_name,
|
||||
);
|
||||
|
||||
$mb_email_certify = G5_TIME_YMDHIS;
|
||||
|
||||
//메일인증을 사용한다면
|
||||
if( defined('G5_SOCIAL_CERTIFY_MAIL') && G5_SOCIAL_CERTIFY_MAIL && $config['cf_use_email_certify'] ){
|
||||
$mb_email_certify = '';
|
||||
}
|
||||
|
||||
//회원 메일 동의
|
||||
$mb_mailling = (isset($_POST['mb_mailling']) && $_POST['mb_mailling']) ? 1 : 0;
|
||||
//회원 정보 공개
|
||||
$mb_open = (isset($_POST['mb_open']) && $_POST['mb_open']) ? 1 : 0;
|
||||
|
||||
// 회원정보 입력
|
||||
$sql = " insert into {$g5['member_table']}
|
||||
set mb_id = '{$mb_id}',
|
||||
mb_password = '".get_encrypt_string($mb_password)."',
|
||||
mb_name = '{$mb_name}',
|
||||
mb_nick = '{$mb_nick}',
|
||||
mb_nick_date = '".G5_TIME_YMD."',
|
||||
mb_email = '{$mb_email}',
|
||||
mb_email_certify = '".$mb_email_certify."',
|
||||
mb_today_login = '".G5_TIME_YMDHIS."',
|
||||
mb_datetime = '".G5_TIME_YMDHIS."',
|
||||
mb_ip = '{$_SERVER['REMOTE_ADDR']}',
|
||||
mb_level = '{$config['cf_register_level']}',
|
||||
mb_login_ip = '{$_SERVER['REMOTE_ADDR']}',
|
||||
mb_mailling = '{$mb_mailling}',
|
||||
mb_sms = '0',
|
||||
mb_open = '{$mb_open}',
|
||||
mb_open_date = '".G5_TIME_YMD."' ";
|
||||
|
||||
$result = sql_query($sql, false);
|
||||
|
||||
if($result) {
|
||||
|
||||
// 회원가입 포인트 부여
|
||||
insert_point($mb_id, $config['cf_register_point'], '회원가입 축하', '@member', $mb_id, '회원가입');
|
||||
|
||||
// 최고관리자님께 메일 발송
|
||||
if ($config['cf_email_mb_super_admin']) {
|
||||
$subject = '['.$config['cf_title'].'] '.$mb_nick .' 님께서 회원으로 가입하셨습니다.';
|
||||
|
||||
ob_start();
|
||||
include_once (G5_BBS_PATH.'/register_form_update_mail2.php');
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
mailer($mb_nick, $mb_email, $config['cf_admin_email'], $subject, $content, 1);
|
||||
}
|
||||
|
||||
$mb = get_member($mb_id);
|
||||
|
||||
//소셜 로그인 계정 추가
|
||||
if( function_exists('social_login_success_after') ){
|
||||
social_login_success_after($mb, '', 'register');
|
||||
}
|
||||
|
||||
set_session('ss_mb_reg', $mb['mb_id']);
|
||||
|
||||
if( !empty($user_profile->photoURL) && ($config['cf_register_level'] >= $config['cf_icon_level']) ){ //회원 프로필 사진이 있고, 회원 아이콘를 올릴수 있는 조건이면
|
||||
|
||||
// 회원아이콘
|
||||
$mb_dir = G5_DATA_PATH.'/member/'.substr($mb_id,0,2);
|
||||
@mkdir($mb_dir, G5_DIR_PERMISSION);
|
||||
@chmod($mb_dir, G5_DIR_PERMISSION);
|
||||
$dest_path = "$mb_dir/$mb_id.gif";
|
||||
|
||||
social_profile_img_resize($dest_path, $user_profile->photoURL, $config['cf_member_icon_width'], $config['cf_member_icon_height'] );
|
||||
|
||||
// 회원이미지
|
||||
if( is_dir(G5_DATA_PATH.'/member_image/') ) {
|
||||
$mb_dir = G5_DATA_PATH.'/member_image/'.substr($mb_id,0,2);
|
||||
@mkdir($mb_dir, G5_DIR_PERMISSION);
|
||||
@chmod($mb_dir, G5_DIR_PERMISSION);
|
||||
$dest_path = "$mb_dir/$mb_id.gif";
|
||||
|
||||
social_profile_img_resize($dest_path, $user_profile->photoURL, $config['cf_member_img_width'], $config['cf_member_img_height'] );
|
||||
}
|
||||
}
|
||||
|
||||
if( $mb_email_certify ){ //메일인증 사용 안하면
|
||||
|
||||
//바로 로그인 처리
|
||||
set_session('ss_mb_id', $mb['mb_id']);
|
||||
|
||||
} else { // 메일인증을 사용한다면
|
||||
$subject = '['.$config['cf_title'].'] 인증확인 메일입니다.';
|
||||
|
||||
// 어떠한 회원정보도 포함되지 않은 일회용 난수를 생성하여 인증에 사용
|
||||
$mb_md5 = md5(pack('V*', rand(), rand(), rand(), rand()));
|
||||
|
||||
sql_query(" update {$g5['member_table']} set mb_email_certify2 = '$mb_md5' where mb_id = '$mb_id' ");
|
||||
|
||||
$certify_href = G5_BBS_URL.'/email_certify.php?mb_id='.$mb_id.'&mb_md5='.$mb_md5;
|
||||
|
||||
ob_start();
|
||||
include_once (G5_BBS_PATH.'/register_form_update_mail3.php');
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
mailer($config['cf_admin_email_name'], $config['cf_admin_email'], $mb_email, $subject, $content, 1);
|
||||
}
|
||||
|
||||
// 사용자 코드 실행
|
||||
@include_once ($member_skin_path.'/register_form_update.tail.skin.php');
|
||||
|
||||
goto_url(G5_HTTP_BBS_URL.'/register_result.php');
|
||||
|
||||
} else {
|
||||
|
||||
alert('회원 가입 오류!', G5_URL );
|
||||
|
||||
}
|
||||
?>
|
||||
48
plugin/social/unlink.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
include_once('_common.php');
|
||||
|
||||
$mp_no = isset($_REQUEST['mp_no']) ? (int) $_REQUEST['mp_no'] : 0;
|
||||
$nonce = isset($_POST['nonce']) ? preg_replace('/[^\da-z]/i', '',$_POST['nonce']) : 0;
|
||||
$provider = social_get_request_provider();
|
||||
|
||||
if( !($mp_no || $provider) || !$member['mb_id'] )
|
||||
die("{\"error\":\"회원이 아니거나 해당값이 넘어오지 않았습니다.\"}");
|
||||
|
||||
$mb_id = $member['mb_id'];
|
||||
|
||||
if($is_admin == 'super'){ //최고관리자인 경우
|
||||
if( isset($_REQUEST['mb_id']) && !empty($_REQUEST['mb_id']) ){ //mb_id 요청이 있다면
|
||||
$mb_id = addslashes(strip_tags($_REQUEST['mb_id']));
|
||||
}
|
||||
} else {
|
||||
// 비회원인 경우 nonce를 체크한다.
|
||||
|
||||
if( ! social_nonce_is_valid($nonce, strtolower($provider), session_id()) ){
|
||||
die("{\"error\":\"권한이 없거나 잘못된 요청입니다.\"}");
|
||||
}
|
||||
}
|
||||
|
||||
if($mp_no){
|
||||
$sql = "SELECT * from {$g5['social_profile_table']} where mb_id= '".$mb_id."' and mp_no= $mp_no";
|
||||
$row = sql_fetch($sql);
|
||||
} else if($provider){
|
||||
$sql = "SELECT * from {$g5['social_profile_table']} where mb_id= '".$mb_id."' and provider= '".$provider."'";
|
||||
$row = sql_fetch($sql);
|
||||
}
|
||||
|
||||
if( $row['mp_no'] ){
|
||||
|
||||
social_member_link_delete($mb_id, $row['mp_no']);
|
||||
|
||||
if( $provider === get_session('ss_social_provider') ){
|
||||
set_session('ss_social_provider', '');
|
||||
}
|
||||
|
||||
die("{\"error\":\"\", \"mp_no\":".$row['mp_no']."}");
|
||||
|
||||
} else {
|
||||
|
||||
die("{\"error\":\"잘못된 요청입니다.\"}");
|
||||
|
||||
}
|
||||
?>
|
||||