Printing with Google Cloud Print

This commit is contained in:
frederic34 2015-10-21 18:23:35 +02:00
parent b45f5039ed
commit 1694c690ed
107 changed files with 11017 additions and 190 deletions

View File

@ -218,6 +218,12 @@ source_file = htdocs/langs/en_US/members.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.oauth]
file_filter = htdocs/langs/<lang>/oauth.lang
source_file = htdocs/langs/en_US/oauth.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.opensurvey]
file_filter = htdocs/langs/<lang>/opensurvey.lang
source_file = htdocs/langs/en_US/opensurvey.lang

335
htdocs/admin/oauth.php Normal file
View File

@ -0,0 +1,335 @@
<?php
/* Copyright (C) 2015 Frederic France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* \file htdocs/admin/oauth.php
* \ingroup oauth
* \brief Setup page to configure oauth access api
*/
require '../main.inc.php';
// required Class
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
$langs->load("admin");
$langs->load("oauth");
// Security check
if (!$user->admin)
accessforbidden();
$action = GETPOST('action', 'alpha');
// API access parameters OAUTH
$list = array (
array(
'OAUTH_AMAZON_NAME',
'OAUTH_AMAZON_ID',
'OAUTH_AMAZON_SECRET',
),
array(
'OAUTH_BITBUCKET_NAME',
'OAUTH_BITBUCKET_ID',
'OAUTH_BITBUCKET_SECRET',
),
array(
'OAUTH_BITLY_NAME',
'OAUTH_BITLY_ID',
'OAUTH_BITLY_SECRET',
),
array(
'OAUTH_BITRIX24_NAME',
'OAUTH_BITRIX24_ID',
'OAUTH_BITRIX24_SECRET',
),
array(
'OAUTH_BOX_NAME',
'OAUTH_BOX_ID',
'OAUTH_BOX_SECRET',
),
array(
'OAUTH_BUFFER_NAME',
'OAUTH_BUFFER_ID',
'OAUTH_BUFFER_SECRET',
),
array(
'OAUTH_DAILYMOTION_NAME',
'OAUTH_DAILYMOTION_ID',
'OAUTH_DAILYMOTION_SECRET',
),
array(
'OAUTH_DEVIANTART_NAME',
'OAUTH_DEVIANTART_ID',
'OAUTH_DEVIANTART_SECRET',
),
array(
'OAUTH_DROPBOX_NAME',
'OAUTH_DROPBOX_ID',
'OAUTH_DROPBOX_SECRET',
),
array(
'OAUTH_ETSY_NAME',
'OAUTH_ETSY_ID',
'OAUTH_ETSY_SECRET',
),
array(
'OAUTH_EVEONLINE_NAME',
'OAUTH_EVEONLINE_ID',
'OAUTH_EVEONLINE_SECRET',
),
array(
'OAUTH_FACEBOOK_NAME',
'OAUTH_FACEBOOK_ID',
'OAUTH_FACEBOOK_SECRET',
),
array(
'OAUTH_FITBIT_NAME',
'OAUTH_FITBIT_ID',
'OAUTH_FITBIT_SECRET',
),
array(
'OAUTH_FIVEHUNDREDPX_NAME',
'OAUTH_FIVEHUNDREDPX_ID',
'OAUTH_FIVEHUNDREDPX_SECRET',
),
array(
'OAUTH_FLICKR_NAME',
'OAUTH_FLICKR_ID',
'OAUTH_FLICKR_SECRET',
),
array(
'OAUTH_FOURSQUARE_NAME',
'OAUTH_FOURSQUARE_ID',
'OAUTH_FOURSQUARE_SECRET',
),
array(
'OAUTH_GITHUB_NAME',
'OAUTH_GITHUB_ID',
'OAUTH_GITHUB_SECRET',
),
array(
'OAUTH_GOOGLE_NAME',
'OAUTH_GOOGLE_ID',
'OAUTH_GOOGLE_SECRET',
),
array(
'OAUTH_HUBIC_NAME',
'OAUTH_HUBIC_ID',
'OAUTH_HUBIC_SECRET',
),
array(
'OAUTH_INSTAGRAM_NAME',
'OAUTH_INSTAGRAM_ID',
'OAUTH_INSTAGRAM_SECRET',
),
array(
'OAUTH_LINKEDIN_NAME',
'OAUTH_LINKEDIN_ID',
'OAUTH_LINKEDIN_SECRET',
),
array(
'OAUTH_MAILCHIMP_NAME',
'OAUTH_MAILCHIMP_ID',
'OAUTH_MAILCHIMP_SECRET',
),
array(
'OAUTH_MICROSOFT_NAME',
'OAUTH_MICROSOFT_ID',
'OAUTH_MICROSOFT_SECRET',
),
array(
'OAUTH_NEST_NAME',
'OAUTH_NEST_ID',
'OAUTH_NEST_SECRET',
),
array(
'OAUTH_NETATMO_NAME',
'OAUTH_NETATMO_ID',
'OAUTH_NETATMO_SECRET',
),
array(
'OAUTH_PARROTFLOWERPOWER_NAME',
'OAUTH_PARROTFLOWERPOWER_ID',
'OAUTH_PARROTFLOWERPOWER_SECRET',
),
array(
'OAUTH_PAYPAL_NAME',
'OAUTH_PAYPAL_ID',
'OAUTH_PAYPAL_SECRET',
),
array(
'OAUTH_POCKET_NAME',
'OAUTH_POCKET_ID',
'OAUTH_POCKET_SECRET',
),
array(
'OAUTH_QUICKBOOKS_NAME',
'OAUTH_QUICKBOOKS_ID',
'OAUTH_QUICKBOOKS_SECRET',
),
array(
'OAUTH_REDDIT_NAME',
'OAUTH_REDDIT_ID',
'OAUTH_REDDIT_SECRET',
),
array(
'OAUTH_REDMINE_NAME',
'OAUTH_REDMINE_ID',
'OAUTH_REDMINE_SECRET',
),
array(
'OAUTH_RUNKEEPER_NAME',
'OAUTH_RUNKEEPER_ID',
'OAUTH_RUNKEEPER_SECRET',
),
array(
'OAUTH_SCOOPIT_NAME',
'OAUTH_SCOOPIT_ID',
'OAUTH_SCOOPIT_SECRET',
),
array(
'OAUTH_SOUNDCLOUD_NAME',
'OAUTH_SOUNDCLOUD_ID',
'OAUTH_SOUNDCLOUD_SECRET',
),
array(
'OAUTH_SPOTIFY_NAME',
'OAUTH_SPOTIFY_ID',
'OAUTH_SPOTIFY_SECRET',
),
array(
'OAUTH_STRAVA_NAME',
'OAUTH_STRAVA_ID',
'OAUTH_STRAVA_SECRET',
),
array(
'OAUTH_TUMBLR_NAME',
'OAUTH_TUMBLR_ID',
'OAUTH_TUMBLR_SECRET',
),
array(
'OAUTH_TWITTER_NAME',
'OAUTH_TWITTER_ID',
'OAUTH_TWITTER_SECRET',
),
array(
'OAUTH_USTREAM_NAME',
'OAUTH_USTREAM_ID',
'OAUTH_USTREAM_SECRET',
),
array(
'OAUTH_VIMEO_NAME',
'OAUTH_VIMEO_ID',
'OAUTH_VIMEO_SECRET',
),
array(
'OAUTH_YAHOO_NAME',
'OAUTH_YAHOO_ID',
'OAUTH_YAHOO_SECRET',
),
array(
'OAUTH_YAMMER_NAME',
'OAUTH_YAMMER_ID',
'OAUTH_YAMMER_SECRET',
),
);
/*
* Actions
*/
if ($action == 'update')
{
$error = 0;
foreach ($list as $constname) {
$constvalue = GETPOST($constname[1], 'alpha');
if (!dolibarr_set_const($db, $constname[1], $constvalue, 'chaine', 0, '', $conf->entity))
$error++;
$constvalue = GETPOST($constname[2], 'alpha');
if (!dolibarr_set_const($db, $constname[2], $constvalue, 'chaine', 0, '', $conf->entity))
$error++;
}
if (! $error)
{
setEventMessage($langs->trans("SetupSaved"));
} else {
setEventMessage($langs->trans("Error"),'errors');
}
}
/*
* View
*/
llxHeader();
$form = new Form($db);
$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans('ConfigOAuth'),$linkback,'title_setup');
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="update">';
/*
* Parameters
*/
dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic');
print '<table class="noborder" width="100%">';
$var = true;
foreach ($list as $key)
{
print '<tr class="liste_titre">';
// Api Name
$label = $langs->trans($key[0]);
print '<td colspan="2">'.$label.'</td></tr>';
// Api Id
$var = !$var;
print '<tr '.$bc[$var].' class="value">';
print '<td><label for="'.$key[1].'">'.$langs->trans($key[1]).'</label></td>';
print '<td><input type="text" size="100" id="'.$key[1].'" name="'.$key[1].'" value="'.$conf->global->$key[1].'">';
print '</td></tr>';
// Api Secret
$var = !$var;
print '<tr '.$bc[$var].' class="value">';
print '<td><label for="'.$key[2].'">'.$langs->trans($key[2]).'</label></td>';
print '<td><input type="password" size="100" id="'.$key[2].'" name="'.$key[2].'" value="'.$conf->global->$key[2].'">';
print '</td></tr>';
}
print '</tr>';
print '</form>';
print '</table>'."\n";
print '<br /><div style="text-align:center"><input type="submit" class="button" value="'.$langs->trans('Modify').'" name="button"></div>';
dol_fiche_end();
llxFooter();
$db->close();

View File

@ -46,11 +46,12 @@ if ($action == 'print_file' and $user->rights->printing->read)
if (! empty($conf->global->{$printer->active})) {
$subdir=(GETPOST('printer', 'alpha')=='expedition'?'sending':'');
$errorprint = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha'), $subdir);
//if ($errorprint < 0) {
// setEventMessage($interface->errors, 'errors');
//}
if ($errorprint=='') {
$ret = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha'), $subdir);
if ($ret < 0) {
setEventMessage($printer->error, 'errors');
}
if ($ret==0) {
setEventMessage($printer->error, 'warning');
setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file'))).' '.$langs->trans("ViaModule").' '.$printer->name);
$printed++;
}

View File

@ -0,0 +1,123 @@
<?php
/* Copyright (C) 2014-2015 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2015 Frederic France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \defgroup oauth Module oauth
* \brief Module for activation of Oauth for several Api Access
*/
/**
* \file htdocs/core/modules/modOauth.class.php
* \ingroup oauth
* \brief File of class to describe and activate module Oauth
*/
include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
/**
* Class to describe and activate module Direct Printing
*/
class modOauth extends DolibarrModules
{
/**
* Constructor
*
* @param DoliDB $db Database handler
*/
function __construct($db)
{
$this->db = $db ;
$this->numero = 66000;
// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
// It is used to group modules in module setup page
$this->family = "technic";
// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
$this->name = preg_replace('/^mod/i','',get_class($this));
// Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
$this->description = "Enable Oauth.";
$this->version = 'dolibarr'; // 'development' or 'experimental' or 'dolibarr' or version
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
// Where to store the module in setup page (0=common,1=interface,2=others,3=very specific)
$this->special = 1;
// Name of image file used for this module.
// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
$this->picto = 'technic';
// Data directories to create when module is enabled.
$this->dirs = array();
// Config pages
$this->config_page_url = array("oauth.php");
// Dependencies
$this->depends = array();
$this->requiredby = array();
$this->phpmin = array(5,1); // Minimum version of PHP required by module
$this->need_dolibarr_version = array(3,7,-2); // Minimum version of Dolibarr required by module
$this->conflictwith = array();
$this->langfiles = array("oauth");
// Constants
$this->const = array();
// Boxes
$this->boxes = array();
// Permissions
$this->rights = array();
$this->rights_class = 'oauth';
$r=0;
// $this->rights[$r][0] Id permission (unique tous modules confondus)
// $this->rights[$r][1] Libelle par defaut si traduction de cle "PermissionXXX" non trouvee (XXX = Id permission)
// $this->rights[$r][2] Non utilise
// $this->rights[$r][3] 1=Permis par defaut, 0=Non permis par defaut
// $this->rights[$r][4] Niveau 1 pour nommer permission dans code
// $this->rights[$r][5] Niveau 2 pour nommer permission dans code
$r++;
$this->rights[$r][0] = 66001;
$this->rights[$r][1] = 'OauthAccess';
$this->rights[$r][2] = 'r';
$this->rights[$r][3] = 1;
$this->rights[$r][4] = 'read';
// Main menu entries
$this->menus = array(); // List of menus to add
$r=0;
// This is to declare the Top Menu entry:
//$this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools', // Put 0 if this is a top menu
// 'type'=>'left', // This is a Top menu entry
// 'titre'=>'MenuOauth',
// 'mainmenu'=>'oauth',
// 'url'=>'/oauth/index.php',
// 'langs'=>'oauth', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
// 'position'=>300,
// 'enabled'=>'$conf->oauth->enabled && $leftmenu==\'modulesadmintools\'',
// 'perms'=>'$user->rights->oauth->read', // Use 'perms'=>'1' if you want your menu with no permission rules
// 'target'=>'',
// 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both
//$r++;
}
}

View File

@ -0,0 +1,110 @@
<?php
/*
* Copyright (C) 2015 Frederic France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/core/modules/oauth/getoauthcallback.php
* \ingroup oauth
* \brief Page to get oauth callback
*/
require '../../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
use OAuth\Common\Storage\Session;
use OAuth\Common\Storage\DoliStorage;
use OAuth\Common\Consumer\Credentials;
use OAuth\Common\Token\TokenInterface;
use OAuth\OAuth2\Service\Google;
/**
* Create a new instance of the URI class with the current URI, stripping the query string
*/
$uriFactory = new \OAuth\Common\Http\Uri\UriFactory();
$currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER);
$currentUri->setQuery('');
/**
* Load the credential for the service
*/
/** @var $serviceFactory \OAuth\ServiceFactory An OAuth service factory. */
$serviceFactory = new \OAuth\ServiceFactory();
// Dolibarr storage
$storage = new DoliStorage($db, $conf);
// Setup the credentials for the requests
$credentials = new Credentials(
$conf->global->OAUTH_GOOGLE_ID,
$conf->global->OAUTH_GOOGLE_SECRET,
$currentUri->getAbsoluteUri()
);
// Instantiate the Api service using the credentials, http client and storage mechanism for the token
/** @var $apiService Service */
// TODO remove hardcoded array
$apiService = $serviceFactory->createService('Google', $credentials, $storage, array('userinfo_email', 'userinfo_profile', 'cloud_print'));
// access type needed for google refresh token
$apiService->setAccessType('offline');
//print '<pre>'.print_r($apiService,true).'</pre>';
//print 'Has access Token: '.($storage->hasAccessToken('Google')?'Yes':'No').'</ br>';
//print 'Has Author State: '.($storage->hasAuthorizationState('Google')?'Yes':'No').'</ br>';
//print 'Authorization State: '.$storage->retrieveAuthorizationState('Google').'</ br>';
//print '<td><pre>'.print_r($token,true).'</pre></td>';
if (! empty($_GET['code'])) {
llxHeader('',$langs->trans("OAuthSetup"));
$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup');
// retrieve the CSRF state parameter
$state = isset($_GET['state']) ? $_GET['state'] : null;
try {
//$token = $storage->retrieveAccessToken('Google');
} catch (Exception $e) {
print $e->getMessage();
}
//print '<pre>'.print_r($token->getRefreshToken(),true).'</pre>';
//$refreshtoken = $token->getRefreshToken();
// This was a callback request from service, get the token
$apiService->requestAccessToken($_GET['code'], $state);
//print '<pre>'.print_r($apiService,true).'</pre>';
try {
$token = $storage->retrieveAccessToken('Google');
} catch (Exception $e) {
print $e->getMessage();
}
$newrefreshtoken = $token->getRefreshToken();
if (empty($newrefreshtoken) && ! empty($refreshtoken)) {
$token->setRefreshToken($refreshtoken);
$storage->storeAccessToken('Google', $token);
}
print '<td><pre>'.print_r($token,true).'</pre></td>';
//$apiService->refreshAccessToken($token);
//print '<pre>'.print_r($apiService,true).'</pre>';
//$token = $storage->retrieveAccessToken('Google');
//print '<td><pre>'.print_r($token,true).'</pre></td>';
} else {
$url = $apiService->getAuthorizationUri();
// we go on google authorization page
header('Location: ' . $url);
exit();
}
llxFooter();
$db->close();

View File

View File

@ -1,6 +1,6 @@
<?php
/*
* Copyright (C) 2014 Frederic France <frederic.france@free.fr>
* Copyright (C) 2014-2015 Frederic France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -56,8 +56,8 @@ class PrintingDriver
{
global $conf;
$type='printing';
$liste=array();
$type = 'printing';
$list = array();
$moduledir=DOL_DOCUMENT_ROOT."/core/modules/printing/";
$tmpfiles=dol_dir_list($moduledir,'all',0,'\modules.php','','name',SORT_ASC,0);

View File

@ -1,6 +1,6 @@
<?php
/*
* Copyright (C) 2014 Frederic France <frederic.france@free.fr>
* Copyright (C) 2014-2015 Frederic France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -24,6 +24,11 @@
*/
include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php';
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
use OAuth\Common\Storage\Session;
use OAuth\Common\Storage\DoliStorage;
use OAuth\Common\Consumer\Credentials;
use OAuth\OAuth2\Service\Google;
/**
* Class to provide printing with Google Cloud Print
@ -35,14 +40,13 @@ class printing_printgcp extends PrintingDriver
var $picto = 'printer';
var $active = 'PRINTING_PRINTGCP';
var $conf = array();
var $login = '';
var $password = '';
var $authtoken = '';
var $google_id = '';
var $google_secret = '';
var $db;
const LOGIN_URL = 'https://www.google.com/accounts/ClientLogin';
const PRINTERS_SEARCH_URL = 'https://www.google.com/cloudprint/interface/search';
const PRINT_URL = 'https://www.google.com/cloudprint/interface/submit';
const LOGIN_URL = 'https://accounts.google.com/o/oauth2/token';
const PRINTERS_SEARCH_URL = 'https://www.google.com/cloudprint/search';
const PRINT_URL = 'https://www.google.com/cloudprint/submit';
/**
* Constructor
@ -54,11 +58,66 @@ class printing_printgcp extends PrintingDriver
global $conf;
$this->db = $db;
$this->login = $conf->global->PRINTGCP_LOGIN;
$this->password = $conf->global->PRINTGCP_PASSWORD;
$this->authtoken = $conf->global->PRINTGCP_AUTHTOKEN;
$this->conf[] = array('varname'=>'PRINTGCP_LOGIN', 'required'=>1, 'example'=>'user@gmail.com', 'type'=>'text');
$this->conf[] = array('varname'=>'PRINTGCP_PASSWORD', 'required'=>1, 'example'=>'', 'type'=>'password');
$this->google_id = $conf->global->OAUTH_GOOGLE_ID;
$this->google_secret = $conf->global->OAUTH_GOOGLE_SECRET;
// Token storage
$storage = new DoliStorage($this->db, $this->conf);
//$storage->clearToken('Google');
// Setup the credentials for the requests
$credentials = new Credentials(
$this->google_id,
$this->google_secret,
DOL_MAIN_URL_ROOT.'/core/modules/oauth/getgoogleoauthcallback.php'
);
$access = ($storage->hasAccessToken('Google')?'HasAccessToken':'NoAccessToken');
$serviceFactory = new \OAuth\ServiceFactory();
$apiService = $serviceFactory->createService('Google', $credentials, $storage, array());
$token_ok=true;
try {
$token = $storage->retrieveAccessToken('Google');
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
$token_ok = false;
}
$expire = false;
// Is token expired or will token expire in the next 30 seconds
if ($token_ok) {
$expire = ($token->getEndOfLife() !== -9002 && $token->getEndOfLife() !== -9001 && time() > ($token->getEndOfLife() - 30));
}
// Token expired so we refresh it
if ($token_ok && $expire) {
try {
// il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
$refreshtoken = $token->getRefreshToken();
$token = $apiService->refreshAccessToken($token);
$token->setRefreshToken($refreshtoken);
$storage->storeAccessToken('Google', $token);
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
print '<pre>MissingRefreshToken: '.$e->getMessage().'</pre>';
//print '<pre>'.print_r($e,true).'</pre>';
}
}
if (!$conf->oauth->enabled) {
$this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'ModuleAuthNotActive', 'type'=>'info');
} else {
if ($this->google_id != '' && $this->google_secret != '') {
$this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthConfigured', 'type'=>'info');
$this->conf[] = array('varname'=>'PRINTGCP_TOKEN_ACCESS', 'info'=>$access, 'type'=>'info');
if ($token_ok) {
$refreshtoken = $token->getRefreshToken();
$this->conf[] = array('varname'=>'PRINTGCP_TOKEN_REFRESH', 'info'=>((! empty($refreshtoken))?'Yes':'No'), 'type'=>'info');
$this->conf[] = array('varname'=>'PRINTGCP_TOKEN_EXPIRED', 'info'=>($expire?'Yes':'No'), 'type'=>'info');
$this->conf[] = array('varname'=>'PRINTGCP_TOKEN_EXPIRE_AT', 'info'=>(date("Y-m-d H:i:s", $token->getEndOfLife())), 'type'=>'info');
}
$this->conf[] = array('varname'=>'PRINTGCP_AUTHLINK', 'link'=>DOL_MAIN_URL_ROOT.'/core/modules/oauth/getgoogleoauthcallback.php', 'type'=>'authlink');
} else {
$this->conf[] = array('varname'=>'PRINTGCP_INFO', 'info'=>'GoogleAuthNotConfigured', 'type'=>'info');
}
}
// do not display submit button
$this->conf[] = array('enabled'=>0, 'type'=>'submit');
}
/**
@ -111,48 +170,71 @@ class printing_printgcp extends PrintingDriver
return $html;
}
/**
* Return list of available printers
*
* @return array list of printers
* @return array list of printers
*/
function getlist_available_printers()
{
global $conf,$db;
if ($this->authtoken=='') {
$this->GoogleLogin();
}
$ret['available'] = $this->get_printer_detail();
return $ret;
}
/**
* List of printers
*
* @return array list of printers
*/
function get_printer_detail()
{
// Token storage
$storage = new DoliStorage($this->db, $this->conf);
// Setup the credentials for the requests
$credentials = new Credentials(
$this->google_id,
$this->google_secret,
DOL_MAIN_URL_ROOT.'/core/modules/oauth/getgoogleoauthcallback.php'
);
$serviceFactory = new \OAuth\ServiceFactory();
$apiService = $serviceFactory->createService('Google', $credentials, $storage, array());
// Check if we have auth token
if(empty($this->authtoken)) {
// We don't have auth token so throw exception
throw new Exception("Please first login to Google by calling loginToGoogle function");
$token_ok=true;
try {
$token = $storage->retrieveAccessToken('Google');
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
$token_ok = false;
}
// Prepare auth headers with auth token
$authheaders = array("Authorization: GoogleLogin auth=".$this->authtoken,
"GData-Version: 3.0",
);
// Make Http call to get printers added by user to Google Cloud Print
$responsedata = $this->makeCurl(self::PRINTERS_SEARCH_URL,array(),$authheaders);
$printers = json_decode($responsedata);
$expire = false;
// Is token expired or will token expire in the next 30 seconds
if ($token_ok) {
$expire = ($token->getEndOfLife() !== -9002 && $token->getEndOfLife() !== -9001 && time() > ($token->getEndOfLife() - 30));
}
// Token expired so we refresh it
if ($token_ok && $expire) {
try {
// il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
$refreshtoken = $token->getRefreshToken();
$token = $apiService->refreshAccessToken($token);
$token->setRefreshToken($refreshtoken);
$storage->storeAccessToken('Google', $token);
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
print '<pre>MissingRefreshToken: '.$e->getMessage().'</pre>';
//print '<pre>'.print_r($e,true).'</pre>';
}
}
// Send a request with api
try {
$response = $apiService->request(self::PRINTERS_SEARCH_URL);
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
print '<pre>'.print_r($e->getMessage(),true).'</pre>';
}
//print '<tr><td><pre>'.print_r($response, true).'</pre></td></tr>';
$responsedata = json_decode($response, true);
$printers = $responsedata['printers'];
// Check if we have printers?
if(is_null($printers)) {
if(count($printers)==0) {
// We dont have printers so return blank array
return array();
$ret['available'] = array();
} else {
// We have printers so returns printers as array
return $this->parsePrinters($printers);
$ret['available'] = $printers;
}
return $ret;
}
/**
@ -161,14 +243,11 @@ class printing_printgcp extends PrintingDriver
* @param string $file file
* @param string $module module
* @param string $subdir subdir for file
* @return string '' if OK, Error message if KO
* @return int 0 if OK, <0 if KO
*/
function print_file($file, $module, $subdir='')
{
global $conf, $user, $db;
if ($this->authtoken=='') {
$this->GoogleLogin();
}
// si $module=commande_fournisseur alors $conf->fournisseur->commande->dir_output
$fileprint=$conf->{$module}->dir_output;
if ($subdir!='') $fileprint.='/'.$subdir;
@ -181,7 +260,7 @@ class printing_printgcp extends PrintingDriver
$obj = $this->db->fetch_object($result);
if ($obj)
{
$printer_id=$obj->printer_id;
$printer_id = $obj->printer_id;
}
else
{
@ -197,7 +276,12 @@ class printing_printgcp extends PrintingDriver
}
else dol_print_error($db);
$this->sendPrintToPrinter($printer_id, $file, $fileprint, 'application/pdf');
$ret = $this->sendPrintToPrinter($printer_id, $file, $fileprint, 'application/pdf');
$this->error = 'PRINTGCP: '.$ret['errormessage'];
if ($ret['status']==1)
return 0;
else
return -1;
}
/**
@ -209,24 +293,16 @@ class printing_printgcp extends PrintingDriver
* @param string $contenttype File content type by example application/pdf, image/png
* @return array status array
*/
public function sendPrintToPrinter($printerid,$printjobtitle,$filepath,$contenttype)
public function sendPrintToPrinter($printerid, $printjobtitle, $filepath, $contenttype)
{
$errors=0;
// Check auth token
if(empty($this->authtoken)) {
$errors++;
setEventMessage('Please first login to Google', 'warning');
}
// Check if printer id
if(empty($printerid)) {
$errors++;
setEventMessage('No provided printer ID', 'warning');
return array('status' =>0, 'errorcode' =>'','errormessage'=>'No provided printer ID');
}
// Open the file which needs to be print
$handle = fopen($filepath, "rb");
if(!$handle) {
$errors++;
setEventMessage('Could not read the file.');
return array('status' =>0, 'errorcode' =>'','errormessage'=>'Could not read the file.');
}
// Read file content
$contents = fread($handle, filesize($filepath));
@ -238,118 +314,41 @@ class printing_printgcp extends PrintingDriver
'content' => base64_encode($contents), // encode file content as base64
'contentType' => $contenttype
);
// Prepare authorization headers
$authheaders = array("Authorization: GoogleLogin auth=" . $this->authtoken);
// Make http call for sending print Job
$response = json_decode($this->makeCurl(self::PRINT_URL,$post_fields,$authheaders));
// Has document been successfully sent?
if($response->success=="1") {
return array('status' =>true,'errorcode' =>'','errormessage'=>"");
} else {
return array('status' =>false,'errorcode' =>$response->errorCode,'errormessage'=>$response->message);
// Token storage
$storage = new DoliStorage($this->db, $this->conf);
// Setup the credentials for the requests
$credentials = new Credentials(
$this->google_id,
$this->google_secret,
DOL_MAIN_URL_ROOT.'/core/modules/oauth/getoauthcallback.php?service=google'
);
$serviceFactory = new \OAuth\ServiceFactory();
$apiService = $serviceFactory->createService('Google', $credentials, $storage, array());
// Check if we have auth token and refresh it
$token_ok=true;
try {
$token = $storage->retrieveAccessToken('Google');
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
$token_ok = false;
}
}
/**
* Login into Google Account
*
* @return boolean true or false
*/
function GoogleLogin()
{
global $db, $conf;
// Prepare post fields required for the login
$loginpostfields = array("accountType" => "HOSTED_OR_GOOGLE",
"Email" => $this->login,
"Passwd" => $this->password,
"service" => "cloudprint",
"source" => "GCP"
);
// Get the Auth token
$loginresponse = $this->makeCurl(self::LOGIN_URL,$loginpostfields);
$token = $this->getAuthToken($loginresponse);
if(! empty($token)&&!is_null($token)) {
$this->authtoken = $token;
$result=dolibarr_set_const($db, 'PRINTGCP_AUTHTOKEN', $token, 'chaine', 0, '', $conf->entity);
return true;
} else {
return false;
}
}
/**
* Parse json response and return printers array
*
* @param string $jsonobj Json response object
* @return array return array of printers
*/
private function parsePrinters($jsonobj)
{
$printers = array();
if (isset($jsonobj->printers)) {
foreach ($jsonobj->printers as $gcpprinter) {
$printers[] = array('id' =>$gcpprinter->id,
'name' =>$gcpprinter->name,
'defaultDisplayName' =>$gcpprinter->defaultDisplayName,
'displayName' =>$gcpprinter->displayName,
'ownerId' =>$gcpprinter->ownerId,
'ownerName' =>$gcpprinter->ownerName,
'connectionStatus' =>$gcpprinter->connectionStatus,
'status' =>$gcpprinter->status,
'type' =>$gcpprinter->type
);
if ($token_ok) {
try {
// il faut sauvegarder le refresh token car google ne le donne qu'une seule fois
$refreshtoken = $token->getRefreshToken();
$token = $apiService->refreshAccessToken($token);
$token->setRefreshToken($refreshtoken);
$storage->storeAccessToken('Google', $token);
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
}
return $printers;
}
/**
* Parse data to get auth token
*
* @param string $response response from curl
* @return string token
*/
private function getAuthToken($response)
{
// Search Auth tag
preg_match("/Auth=([a-z0-9_-]+)/i", $response, $matches);
$authtoken = @$matches[1];
return $authtoken;
// Send a request with api
$response = json_decode($apiService->request(self::PRINT_URL, 'POST', $post_fields), true);
//print '<tr><td><pre>'.print_r($response, true).'</pre></td></tr>';
return array('status' =>$response['success'],'errorcode' =>$response['errorCode'],'errormessage'=>$response['message']);
}
/**
* Make a curl request
*
* @param string $url url to hit
* @param array $postfields array of post fields
* @param string[] $headers array of http headers
* @return string response from curl
*/
private function makeCurl($url, $postfields=array(), $headers=array())
{
// Curl Init
$curl = curl_init($url);
// Curl post request
if(! empty($postfields)) {
// As is HTTP post curl request so set post fields
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
}
// Curl request headers
if(! empty($headers)) {
// As curl requires header so set headers here
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// Execute the curl and return response
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
}

View File

@ -1,6 +1,6 @@
<?php
/*
* Copyright (C) 2014 Frederic France <frederic.france@free.fr>
* Copyright (C) 2014-2015 Frederic France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -62,6 +62,7 @@ class printing_printipp extends PrintingDriver
$this->conf[] = array('varname'=>'PRINTIPP_PORT', 'required'=>1, 'example'=>'631', 'type'=>'text');
$this->conf[] = array('varname'=>'PRINTIPP_USER', 'required'=>0, 'example'=>'', 'type'=>'text', 'moreattributes'=>'autocomplete="off"');
$this->conf[] = array('varname'=>'PRINTIPP_PASSWORD', 'required'=>0, 'example'=>'', 'type'=>'password', 'moreattributes'=>'autocomplete="off"');
$this->conf[] = array('enabled'=>1, 'type'=>'submit');
}
/**
@ -71,7 +72,7 @@ class printing_printipp extends PrintingDriver
* @param string $module module
* @param string $subdir subdirectory of document like for expedition subdir is sendings
*
* @return string '' if OK, Error message if KO
* @return int 0 if OK, <0 if KO
*/
function print_file($file, $module, $subdir='')
{
@ -107,7 +108,8 @@ class printing_printipp extends PrintingDriver
}
else
{
return 'NoDefaultPrinterDefined';
$this->error = 'NoDefaultPrinterDefined';
return -1;
}
}
}
@ -121,7 +123,7 @@ class printing_printipp extends PrintingDriver
$ipp->setData($fileprint);
$ipp->printJob();
return '';
return 0;
}
/**

View File

@ -0,0 +1,81 @@
<?php
namespace OAuth\Common;
/**
* PSR-0 Autoloader
*
* @author ieter Hordijk <info@pieterhordijk.com>
*/
class AutoLoader
{
/**
* @var string The namespace prefix for this instance.
*/
protected $namespace = '';
/**
* @var string The filesystem prefix to use for this instance
*/
protected $path = '';
/**
* Build the instance of the autoloader
*
* @param string $namespace The prefixed namespace this instance will load
* @param string $path The filesystem path to the root of the namespace
*/
public function __construct($namespace, $path)
{
$this->namespace = ltrim($namespace, '\\');
$this->path = rtrim($path, '/\\') . DIRECTORY_SEPARATOR;
}
/**
* Try to load a class
*
* @param string $class The class name to load
*
* @return boolean If the loading was successful
*/
public function load($class)
{
$class = ltrim($class, '\\');
if (strpos($class, $this->namespace) === 0) {
$nsparts = explode('\\', $class);
$class = array_pop($nsparts);
$nsparts[] = '';
$path = $this->path . implode(DIRECTORY_SEPARATOR, $nsparts);
$path .= str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
if (file_exists($path)) {
require $path;
return true;
}
}
return false;
}
/**
* Register the autoloader to PHP
*
* @return boolean The status of the registration
*/
public function register()
{
return spl_autoload_register(array($this, 'load'));
}
/**
* Unregister the autoloader to PHP
*
* @return boolean The status of the unregistration
*/
public function unregister()
{
return spl_autoload_unregister(array($this, 'load'));
}
}

View File

@ -0,0 +1,60 @@
<?php
namespace OAuth\Common\Consumer;
/**
* Value object for the credentials of an OAuth service.
*/
class Credentials implements CredentialsInterface
{
/**
* @var string
*/
protected $consumerId;
/**
* @var string
*/
protected $consumerSecret;
/**
* @var string
*/
protected $callbackUrl;
/**
* @param string $consumerId
* @param string $consumerSecret
* @param string $callbackUrl
*/
public function __construct($consumerId, $consumerSecret, $callbackUrl)
{
$this->consumerId = $consumerId;
$this->consumerSecret = $consumerSecret;
$this->callbackUrl = $callbackUrl;
}
/**
* @return string
*/
public function getCallbackUrl()
{
return $this->callbackUrl;
}
/**
* @return string
*/
public function getConsumerId()
{
return $this->consumerId;
}
/**
* @return string
*/
public function getConsumerSecret()
{
return $this->consumerSecret;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace OAuth\Common\Consumer;
/**
* Credentials Interface, credentials should implement this.
*/
interface CredentialsInterface
{
/**
* @return string
*/
public function getCallbackUrl();
/**
* @return string
*/
public function getConsumerId();
/**
* @return string
*/
public function getConsumerSecret();
}

View File

@ -0,0 +1,10 @@
<?php
namespace OAuth\Common\Exception;
/**
* Generic library-level exception.
*/
class Exception extends \Exception
{
}

View File

@ -0,0 +1,73 @@
<?php
namespace OAuth\Common\Http\Client;
/**
* Abstract HTTP client
*/
abstract class AbstractClient implements ClientInterface
{
/**
* @var string The user agent string passed to services
*/
protected $userAgent;
/**
* @var int The maximum number of redirects
*/
protected $maxRedirects = 5;
/**
* @var int The maximum timeout
*/
protected $timeout = 15;
/**
* Creates instance
*
* @param string $userAgent The UA string the client will use
*/
public function __construct($userAgent = 'PHPoAuthLib')
{
$this->userAgent = $userAgent;
}
/**
* @param int $redirects Maximum redirects for client
*
* @return ClientInterface
*/
public function setMaxRedirects($redirects)
{
$this->maxRedirects = $redirects;
return $this;
}
/**
* @param int $timeout Request timeout time for client in seconds
*
* @return ClientInterface
*/
public function setTimeout($timeout)
{
$this->timeout = $timeout;
return $this;
}
/**
* @param array $headers
*/
public function normalizeHeaders(&$headers)
{
// Normalize headers
array_walk(
$headers,
function (&$val, &$key) {
$key = ucfirst(strtolower($key));
$val = ucfirst(strtolower($key)) . ': ' . $val;
}
);
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace OAuth\Common\Http\Client;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
/**
* Any HTTP clients to be used with the library should implement this interface.
*/
interface ClientInterface
{
/**
* Any implementing HTTP providers should send a request to the provided endpoint with the parameters.
* They should return, in string form, the response body and throw an exception on error.
*
* @param UriInterface $endpoint
* @param mixed $requestBody
* @param array $extraHeaders
* @param string $method
*
* @return string
*
* @throws TokenResponseException
*/
public function retrieveResponse(
UriInterface $endpoint,
$requestBody,
array $extraHeaders = array(),
$method = 'POST'
);
}

View File

@ -0,0 +1,142 @@
<?php
namespace OAuth\Common\Http\Client;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Client implementation for cURL
*/
class CurlClient extends AbstractClient
{
/**
* If true, explicitly sets cURL to use SSL version 3. Use this if cURL
* compiles with GnuTLS SSL.
*
* @var bool
*/
private $forceSSL3 = false;
/**
* Additional parameters (as `key => value` pairs) to be passed to `curl_setopt`
*
* @var array
*/
private $parameters = array();
/**
* Additional `curl_setopt` parameters
*
* @param array $parameters
*/
public function setCurlParameters(array $parameters)
{
$this->parameters = $parameters;
}
/**
* @param bool $force
*
* @return CurlClient
*/
public function setForceSSL3($force)
{
$this->forceSSL3 = $force;
return $this;
}
/**
* Any implementing HTTP providers should send a request to the provided endpoint with the parameters.
* They should return, in string form, the response body and throw an exception on error.
*
* @param UriInterface $endpoint
* @param mixed $requestBody
* @param array $extraHeaders
* @param string $method
*
* @return string
*
* @throws TokenResponseException
* @throws \InvalidArgumentException
*/
public function retrieveResponse(
UriInterface $endpoint,
$requestBody,
array $extraHeaders = array(),
$method = 'POST'
) {
// Normalize method name
$method = strtoupper($method);
$this->normalizeHeaders($extraHeaders);
if ($method === 'GET' && !empty($requestBody)) {
throw new \InvalidArgumentException('No body expected for "GET" request.');
}
if (!isset($extraHeaders['Content-Type']) && $method === 'POST' && is_array($requestBody)) {
$extraHeaders['Content-Type'] = 'Content-Type: application/x-www-form-urlencoded';
}
$extraHeaders['Host'] = 'Host: '.$endpoint->getHost();
$extraHeaders['Connection'] = 'Connection: close';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint->getAbsoluteUri());
if ($method === 'POST' || $method === 'PUT') {
if ($requestBody && is_array($requestBody)) {
$requestBody = http_build_query($requestBody, '', '&');
}
if ($method === 'PUT') {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
} else {
curl_setopt($ch, CURLOPT_POST, true);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
} else {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
}
if ($this->maxRedirects > 0) {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, $this->maxRedirects);
}
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $extraHeaders);
curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
foreach ($this->parameters as $key => $value) {
curl_setopt($ch, $key, $value);
}
if ($this->forceSSL3) {
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
}
$response = curl_exec($ch);
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (false === $response) {
$errNo = curl_errno($ch);
$errStr = curl_error($ch);
curl_close($ch);
if (empty($errStr)) {
throw new TokenResponseException('Failed to request resource.', $responseCode);
}
throw new TokenResponseException('cURL Error # '.$errNo.': '.$errStr, $responseCode);
}
curl_close($ch);
return $response;
}
}

View File

@ -0,0 +1,95 @@
<?php
namespace OAuth\Common\Http\Client;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Client implementation for streams/file_get_contents
*/
class StreamClient extends AbstractClient
{
/**
* Any implementing HTTP providers should send a request to the provided endpoint with the parameters.
* They should return, in string form, the response body and throw an exception on error.
*
* @param UriInterface $endpoint
* @param mixed $requestBody
* @param array $extraHeaders
* @param string $method
*
* @return string
*
* @throws TokenResponseException
* @throws \InvalidArgumentException
*/
public function retrieveResponse(
UriInterface $endpoint,
$requestBody,
array $extraHeaders = array(),
$method = 'POST'
) {
// Normalize method name
$method = strtoupper($method);
$this->normalizeHeaders($extraHeaders);
if ($method === 'GET' && !empty($requestBody)) {
throw new \InvalidArgumentException('No body expected for "GET" request.');
}
if (!isset($extraHeaders['Content-Type']) && $method === 'POST' && is_array($requestBody)) {
$extraHeaders['Content-Type'] = 'Content-Type: application/x-www-form-urlencoded';
}
$host = 'Host: '.$endpoint->getHost();
// Append port to Host if it has been specified
if ($endpoint->hasExplicitPortSpecified()) {
$host .= ':'.$endpoint->getPort();
}
$extraHeaders['Host'] = $host;
$extraHeaders['Connection'] = 'Connection: close';
if (is_array($requestBody)) {
$requestBody = http_build_query($requestBody, '', '&');
}
$extraHeaders['Content-length'] = 'Content-length: '.strlen($requestBody);
$context = $this->generateStreamContext($requestBody, $extraHeaders, $method);
$level = error_reporting(0);
$response = file_get_contents($endpoint->getAbsoluteUri(), false, $context);
error_reporting($level);
if (false === $response) {
$lastError = error_get_last();
if (is_null($lastError)) {
throw new TokenResponseException(
'Failed to request resource. HTTP Code: ' .
((isset($http_response_header[0]))?$http_response_header[0]:'No response')
);
}
throw new TokenResponseException($lastError['message']);
}
return $response;
}
private function generateStreamContext($body, $headers, $method)
{
return stream_context_create(
array(
'http' => array(
'method' => $method,
'header' => implode("\r\n", array_values($headers)),
'content' => $body,
'protocol_version' => '1.1',
'user_agent' => $this->userAgent,
'max_redirects' => $this->maxRedirects,
'timeout' => $this->timeout
),
)
);
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace OAuth\Common\Http\Exception;
use OAuth\Common\Exception\Exception;
/**
* Exception relating to token response from service.
*/
class TokenResponseException extends Exception
{
}

View File

@ -0,0 +1,408 @@
<?php
namespace OAuth\Common\Http\Uri;
use InvalidArgumentException;
/**
* Standards-compliant URI class.
*/
class Uri implements UriInterface
{
/**
* @var string
*/
private $scheme = 'http';
/**
* @var string
*/
private $userInfo = '';
/**
* @var string
*/
private $rawUserInfo = '';
/**
* @var string
*/
private $host;
/**
* @var int
*/
private $port = 80;
/**
* @var string
*/
private $path = '/';
/**
* @var string
*/
private $query = '';
/**
* @var string
*/
private $fragment = '';
/**
* @var bool
*/
private $explicitPortSpecified = false;
/**
* @var bool
*/
private $explicitTrailingHostSlash = false;
/**
* @param string $uri
*/
public function __construct($uri = null)
{
if (null !== $uri) {
$this->parseUri($uri);
}
}
/**
* @param string $uri
*
* @throws \InvalidArgumentException
*/
protected function parseUri($uri)
{
if (false === ($uriParts = parse_url($uri))) {
// congratulations if you've managed to get parse_url to fail,
// it seems to always return some semblance of a parsed url no matter what
throw new InvalidArgumentException("Invalid URI: $uri");
}
if (!isset($uriParts['scheme'])) {
throw new InvalidArgumentException('Invalid URI: http|https scheme required');
}
$this->scheme = $uriParts['scheme'];
$this->host = $uriParts['host'];
if (isset($uriParts['port'])) {
$this->port = $uriParts['port'];
$this->explicitPortSpecified = true;
} else {
$this->port = strcmp('https', $uriParts['scheme']) ? 80 : 443;
$this->explicitPortSpecified = false;
}
if (isset($uriParts['path'])) {
$this->path = $uriParts['path'];
if ('/' === $uriParts['path']) {
$this->explicitTrailingHostSlash = true;
}
} else {
$this->path = '/';
}
$this->query = isset($uriParts['query']) ? $uriParts['query'] : '';
$this->fragment = isset($uriParts['fragment']) ? $uriParts['fragment'] : '';
$userInfo = '';
if (!empty($uriParts['user'])) {
$userInfo .= $uriParts['user'];
}
if ($userInfo && !empty($uriParts['pass'])) {
$userInfo .= ':' . $uriParts['pass'];
}
$this->setUserInfo($userInfo);
}
/**
* @param string $rawUserInfo
*
* @return string
*/
protected function protectUserInfo($rawUserInfo)
{
$colonPos = strpos($rawUserInfo, ':');
// rfc3986-3.2.1 | http://tools.ietf.org/html/rfc3986#section-3.2
// "Applications should not render as clear text any data
// after the first colon (":") character found within a userinfo
// subcomponent unless the data after the colon is the empty string
// (indicating no password)"
if ($colonPos !== false && strlen($rawUserInfo)-1 > $colonPos) {
return substr($rawUserInfo, 0, $colonPos) . ':********';
} else {
return $rawUserInfo;
}
}
/**
* @return string
*/
public function getScheme()
{
return $this->scheme;
}
/**
* @return string
*/
public function getUserInfo()
{
return $this->userInfo;
}
/**
* @return string
*/
public function getRawUserInfo()
{
return $this->rawUserInfo;
}
/**
* @return string
*/
public function getHost()
{
return $this->host;
}
/**
* @return int
*/
public function getPort()
{
return $this->port;
}
/**
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* @return string
*/
public function getQuery()
{
return $this->query;
}
/**
* @return string
*/
public function getFragment()
{
return $this->fragment;
}
/**
* Uses protected user info by default as per rfc3986-3.2.1
* Uri::getRawAuthority() is available if plain-text password information is desirable.
*
* @return string
*/
public function getAuthority()
{
$authority = $this->userInfo ? $this->userInfo.'@' : '';
$authority .= $this->host;
if ($this->explicitPortSpecified) {
$authority .= ":{$this->port}";
}
return $authority;
}
/**
* @return string
*/
public function getRawAuthority()
{
$authority = $this->rawUserInfo ? $this->rawUserInfo.'@' : '';
$authority .= $this->host;
if ($this->explicitPortSpecified) {
$authority .= ":{$this->port}";
}
return $authority;
}
/**
* @return string
*/
public function getAbsoluteUri()
{
$uri = $this->scheme . '://' . $this->getRawAuthority();
if ('/' === $this->path) {
$uri .= $this->explicitTrailingHostSlash ? '/' : '';
} else {
$uri .= $this->path;
}
if (!empty($this->query)) {
$uri .= "?{$this->query}";
}
if (!empty($this->fragment)) {
$uri .= "#{$this->fragment}";
}
return $uri;
}
/**
* @return string
*/
public function getRelativeUri()
{
$uri = '';
if ('/' === $this->path) {
$uri .= $this->explicitTrailingHostSlash ? '/' : '';
} else {
$uri .= $this->path;
}
return $uri;
}
/**
* Uses protected user info by default as per rfc3986-3.2.1
* Uri::getAbsoluteUri() is available if plain-text password information is desirable.
*
* @return string
*/
public function __toString()
{
$uri = $this->scheme . '://' . $this->getAuthority();
if ('/' === $this->path) {
$uri .= $this->explicitTrailingHostSlash ? '/' : '';
} else {
$uri .= $this->path;
}
if (!empty($this->query)) {
$uri .= "?{$this->query}";
}
if (!empty($this->fragment)) {
$uri .= "#{$this->fragment}";
}
return $uri;
}
/**
* @param $path
*/
public function setPath($path)
{
if (empty($path)) {
$this->path = '/';
$this->explicitTrailingHostSlash = false;
} else {
$this->path = $path;
if ('/' === $this->path) {
$this->explicitTrailingHostSlash = true;
}
}
}
/**
* @param string $query
*/
public function setQuery($query)
{
$this->query = $query;
}
/**
* @param string $var
* @param string $val
*/
public function addToQuery($var, $val)
{
if (strlen($this->query) > 0) {
$this->query .= '&';
}
$this->query .= http_build_query(array($var => $val), '', '&');
}
/**
* @param string $fragment
*/
public function setFragment($fragment)
{
$this->fragment = $fragment;
}
/**
* @param string $scheme
*/
public function setScheme($scheme)
{
$this->scheme = $scheme;
}
/**
* @param string $userInfo
*/
public function setUserInfo($userInfo)
{
$this->userInfo = $userInfo ? $this->protectUserInfo($userInfo) : '';
$this->rawUserInfo = $userInfo;
}
/**
* @param int $port
*/
public function setPort($port)
{
$this->port = intval($port);
if (('https' === $this->scheme && $this->port === 443) || ('http' === $this->scheme && $this->port === 80)) {
$this->explicitPortSpecified = false;
} else {
$this->explicitPortSpecified = true;
}
}
/**
* @param string $host
*/
public function setHost($host)
{
$this->host = $host;
}
/**
* @return bool
*/
public function hasExplicitTrailingHostSlash()
{
return $this->explicitTrailingHostSlash;
}
/**
* @return bool
*/
public function hasExplicitPortSpecified()
{
return $this->explicitPortSpecified;
}
}

View File

@ -0,0 +1,168 @@
<?php
namespace OAuth\Common\Http\Uri;
use RuntimeException;
/**
* Factory class for uniform resource indicators
*/
class UriFactory implements UriFactoryInterface
{
/**
* Factory method to build a URI from a super-global $_SERVER array.
*
* @param array $_server
*
* @return UriInterface
*/
public function createFromSuperGlobalArray(array $_server)
{
if ($uri = $this->attemptProxyStyleParse($_server)) {
return $uri;
}
$scheme = $this->detectScheme($_server);
$host = $this->detectHost($_server);
$port = $this->detectPort($_server);
$path = $this->detectPath($_server);
$query = $this->detectQuery($_server);
return $this->createFromParts($scheme, '', $host, $port, $path, $query);
}
/**
* @param string $absoluteUri
*
* @return UriInterface
*/
public function createFromAbsolute($absoluteUri)
{
return new Uri($absoluteUri);
}
/**
* Factory method to build a URI from parts
*
* @param string $scheme
* @param string $userInfo
* @param string $host
* @param string $port
* @param string $path
* @param string $query
* @param string $fragment
*
* @return UriInterface
*/
public function createFromParts($scheme, $userInfo, $host, $port, $path = '', $query = '', $fragment = '')
{
$uri = new Uri();
$uri->setScheme($scheme);
$uri->setUserInfo($userInfo);
$uri->setHost($host);
$uri->setPort($port);
$uri->setPath($path);
$uri->setQuery($query);
$uri->setFragment($fragment);
return $uri;
}
/**
* @param array $_server
*
* @return UriInterface|null
*/
private function attemptProxyStyleParse($_server)
{
// If the raw HTTP request message arrives with a proxy-style absolute URI in the
// initial request line, the absolute URI is stored in $_SERVER['REQUEST_URI'] and
// we only need to parse that.
if (isset($_server['REQUEST_URI']) && parse_url($_server['REQUEST_URI'], PHP_URL_SCHEME)) {
return new Uri($_server['REQUEST_URI']);
}
return null;
}
/**
* @param array $_server
*
* @return string
*
* @throws RuntimeException
*/
private function detectPath($_server)
{
if (isset($_server['REQUEST_URI'])) {
$uri = $_server['REQUEST_URI'];
} elseif (isset($_server['REDIRECT_URL'])) {
$uri = $_server['REDIRECT_URL'];
} else {
throw new RuntimeException('Could not detect URI path from superglobal');
}
$queryStr = strpos($uri, '?');
if ($queryStr !== false) {
$uri = substr($uri, 0, $queryStr);
}
return $uri;
}
/**
* @param array $_server
*
* @return string
*/
private function detectHost(array $_server)
{
$host = isset($_server['HTTP_HOST']) ? $_server['HTTP_HOST'] : '';
if (strstr($host, ':')) {
$host = parse_url($host, PHP_URL_HOST);
}
return $host;
}
/**
* @param array $_server
*
* @return string
*/
private function detectPort(array $_server)
{
return isset($_server['SERVER_PORT']) ? $_server['SERVER_PORT'] : 80;
}
/**
* @param array $_server
*
* @return string
*/
private function detectQuery(array $_server)
{
return isset($_server['QUERY_STRING']) ? $_server['QUERY_STRING'] : '';
}
/**
* Determine URI scheme component from superglobal array
*
* When using ISAPI with IIS, the value will be "off" if the request was
* not made through the HTTPS protocol. As a result, we filter the
* value to a bool.
*
* @param array $_server A super-global $_SERVER array
*
* @return string Returns http or https depending on the URI scheme
*/
private function detectScheme(array $_server)
{
if (isset($_server['HTTPS']) && filter_var($_server['HTTPS'], FILTER_VALIDATE_BOOLEAN)) {
return 'https';
} else {
return 'http';
}
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace OAuth\Common\Http\Uri;
/**
* Factory interface for uniform resource indicators
*/
interface UriFactoryInterface
{
/**
* Factory method to build a URI from a super-global $_SERVER array.
*
* @param array $_server
*
* @return UriInterface
*/
public function createFromSuperGlobalArray(array $_server);
/**
* Creates a URI from an absolute URI
*
* @param string $absoluteUri
*
* @return UriInterface
*/
public function createFromAbsolute($absoluteUri);
/**
* Factory method to build a URI from parts
*
* @param string $scheme
* @param string $userInfo
* @param string $host
* @param string $port
* @param string $path
* @param string $query
* @param string $fragment
*
* @return UriInterface
*/
public function createFromParts($scheme, $userInfo, $host, $port, $path = '', $query = '', $fragment = '');
}

View File

@ -0,0 +1,133 @@
<?php
namespace OAuth\Common\Http\Uri;
interface UriInterface
{
/**
* @return string
*/
public function getScheme();
/**
* @param string $scheme
*/
public function setScheme($scheme);
/**
* @return string
*/
public function getHost();
/**
* @param string $host
*/
public function setHost($host);
/**
* @return int
*/
public function getPort();
/**
* @param int $port
*/
public function setPort($port);
/**
* @return string
*/
public function getPath();
/**
* @param string $path
*/
public function setPath($path);
/**
* @return string
*/
public function getQuery();
/**
* @param string $query
*/
public function setQuery($query);
/**
* Adds a param to the query string.
*
* @param string $var
* @param string $val
*/
public function addToQuery($var, $val);
/**
* @return string
*/
public function getFragment();
/**
* Should return URI user info, masking protected user info data according to rfc3986-3.2.1
*
* @return string
*/
public function getUserInfo();
/**
* @param string $userInfo
*/
public function setUserInfo($userInfo);
/**
* Should return the URI Authority, masking protected user info data according to rfc3986-3.2.1
*
* @return string
*/
public function getAuthority();
/**
* Should return the URI string, masking protected user info data according to rfc3986-3.2.1
*
* @return string the URI string with user protected info masked
*/
public function __toString();
/**
* Should return the URI Authority without masking protected user info data
*
* @return string
*/
public function getRawAuthority();
/**
* Should return the URI user info without masking protected user info data
*
* @return string
*/
public function getRawUserInfo();
/**
* Build the full URI based on all the properties
*
* @return string The full URI without masking user info
*/
public function getAbsoluteUri();
/**
* Build the relative URI based on all the properties
*
* @return string The relative URI
*/
public function getRelativeUri();
/**
* @return bool
*/
public function hasExplicitTrailingHostSlash();
/**
* @return bool
*/
public function hasExplicitPortSpecified();
}

View File

@ -0,0 +1,100 @@
<?php
namespace OAuth\Common\Service;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Exception\Exception;
use OAuth\Common\Storage\TokenStorageInterface;
/**
* Abstract OAuth service, version-agnostic
*/
abstract class AbstractService implements ServiceInterface
{
/** @var Credentials */
protected $credentials;
/** @var ClientInterface */
protected $httpClient;
/** @var TokenStorageInterface */
protected $storage;
/**
* @param CredentialsInterface $credentials
* @param ClientInterface $httpClient
* @param TokenStorageInterface $storage
*/
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage
) {
$this->credentials = $credentials;
$this->httpClient = $httpClient;
$this->storage = $storage;
}
/**
* @param UriInterface|string $path
* @param UriInterface $baseApiUri
*
* @return UriInterface
*
* @throws Exception
*/
protected function determineRequestUriFromPath($path, UriInterface $baseApiUri = null)
{
if ($path instanceof UriInterface) {
$uri = $path;
} elseif (stripos($path, 'http://') === 0 || stripos($path, 'https://') === 0) {
$uri = new Uri($path);
} else {
if (null === $baseApiUri) {
throw new Exception(
'An absolute URI must be passed to ServiceInterface::request as no baseApiUri is set.'
);
}
$uri = clone $baseApiUri;
if (false !== strpos($path, '?')) {
$parts = explode('?', $path, 2);
$path = $parts[0];
$query = $parts[1];
$uri->setQuery($query);
}
if ($path[0] === '/') {
$path = substr($path, 1);
}
$uri->setPath($uri->getPath() . $path);
}
return $uri;
}
/**
* Accessor to the storage adapter to be able to retrieve tokens
*
* @return TokenStorageInterface
*/
public function getStorage()
{
return $this->storage;
}
/**
* @return string
*/
public function service()
{
// get class name without backslashes
$classname = get_class($this);
return preg_replace('/^.*\\\\/', '', $classname);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace OAuth\Common\Service;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Defines methods common among all OAuth services.
*/
interface ServiceInterface
{
/**
* Sends an authenticated API request to the path provided.
* If the path provided is not an absolute URI, the base API Uri (service-specific) will be used.
*
* @param string|UriInterface $path
* @param string $method HTTP method
* @param array $body Request body if applicable (an associative array will
* automatically be converted into a urlencoded body)
* @param array $extraHeaders Extra headers if applicable. These will override service-specific
* any defaults.
*
* @return string
*/
public function request($path, $method = 'GET', $body = null, array $extraHeaders = array());
/**
* Returns the url to redirect to for authorization purposes.
*
* @param array $additionalParameters
*
* @return UriInterface
*/
public function getAuthorizationUri(array $additionalParameters = array());
/**
* Returns the authorization API endpoint.
*
* @return UriInterface
*/
public function getAuthorizationEndpoint();
/**
* Returns the access token API endpoint.
*
* @return UriInterface
*/
public function getAccessTokenEndpoint();
}

View File

@ -0,0 +1,254 @@
<?php
/*
* Copyright (C) 2015 Frederic France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/includes/OAuth/Common/Storage/DoliStorage.php
* \ingroup oauth
* \brief Dolibarr token storage class
*/
namespace OAuth\Common\Storage;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Storage\Exception\TokenNotFoundException;
use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
use DoliDB;
class DoliStorage implements TokenStorageInterface
{
/**
* @var DoliDB Database handler
*/
protected $db;
/**
* @var object|TokenInterface
*/
protected $tokens;
/**
* @var string Error code (or message)
*/
public $error;
/**
* @var string[] Several error codes (or messages)
*/
public $errors = array();
private $conf;
private $key;
private $stateKey;
/**
* @param Conf $conf
* @param string $key
* @param string $stateKey
*/
public function __construct(DoliDB $db, $conf)
{
$this->db = $db;
$this->conf = $conf;
$this->tokens = array();
$this->states = array();
//$this->key = $key;
//$this->stateKey = $stateKey;
}
/**
* {@inheritDoc}
*/
public function retrieveAccessToken($service)
{
if ($this->hasAccessToken($service)) {
return $this->tokens[$service];
}
throw new TokenNotFoundException('Token not found in db, are you sure you stored it?');
}
/**
* {@inheritDoc}
*/
public function storeAccessToken($service, TokenInterface $token)
{
$serializedToken = serialize($token);
$this->tokens[$service] = $token;
if (!is_array($this->tokens)) {
$this->tokens = array();
}
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."oauth_token";
$sql.= " WHERE service='".$service."' AND entity=1";
$resql = $this->db->query($sql);
$obj = $this->db->fetch_array($resql);
if ($obj) {
// update
$sql = "UPDATE ".MAIN_DB_PREFIX."oauth_token";
$sql.= " SET token='".$this->db->escape($serializedToken)."'";
$sql.= " WHERE rowid='".$obj['rowid']."'";
$resql = $this->db->query($sql);
} else {
// save
$sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, token, entity)";
$sql.= " VALUES ('".$service."', '".$this->db->escape($serializedToken)."', 1)";
$resql = $this->db->query($sql);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAccessToken($service)
{
// get from db
$sql = "SELECT token FROM ".MAIN_DB_PREFIX."oauth_token";
$sql.= " WHERE service='".$service."'";
$resql = $this->db->query($sql);
$result = $this->db->fetch_array($resql);
$token = unserialize($result[token]);
$this->tokens[$service] = $token;
return is_array($this->tokens)
&& isset($this->tokens[$service])
&& $this->tokens[$service] instanceof TokenInterface;
}
/**
* {@inheritDoc}
*/
public function clearToken($service)
{
// TODO
// get previously saved tokens
$tokens = $this->session->get($this->key);
if (is_array($tokens) && array_key_exists($service, $tokens)) {
unset($tokens[$service]);
// Replace the stored tokens array
$this->conf->set($this->key, $tokens);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllTokens()
{
// TODO
$this->conf->remove($this->key);
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function retrieveAuthorizationState($service)
{
if ($this->hasAuthorizationState($service)) {
return $this->states[$service];
}
throw new AuthorizationStateNotFoundException('State not found in conf, are you sure you stored it?');
}
/**
* {@inheritDoc}
*/
public function storeAuthorizationState($service, $state)
{
// TODO save or update
// get previously saved tokens
//$states = $this->conf->get($this->stateKey);
if (!is_array($states)) {
$states = array();
}
$states[$service] = $state;
$this->states[$service] = $state;
// save
$sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_state (service, state, entity)";
$sql.= " VALUES ('".$service."', '".$state."', 1)";
$resql = $this->db->query($sql);
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAuthorizationState($service)
{
// get from db
$sql = "SELECT state FROM ".MAIN_DB_PREFIX."oauth_state";
$sql.= " WHERE service='".$service."'";
$resql = $this->db->query($sql);
$result = $this->db->fetch_array($resql);
$states[$service] = $result[state];
$this->states[$service] = $states[$service];
return is_array($states)
&& isset($states[$service])
&& null !== $states[$service];
}
/**
* {@inheritDoc}
*/
public function clearAuthorizationState($service)
{
// TODO
// get previously saved tokens
//$states = $this->conf->get($this->stateKey);
if (is_array($states) && array_key_exists($service, $states)) {
unset($states[$service]);
// Replace the stored tokens array
//$this->conf->set($this->stateKey, $states);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllAuthorizationStates()
{
// TODO
//$this->conf->remove($this->stateKey);
// allow chaining
return $this;
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace OAuth\Common\Storage\Exception;
/**
* Exception thrown when a state is not found in storage.
*/
class AuthorizationStateNotFoundException extends StorageException
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace OAuth\Common\Storage\Exception;
use OAuth\Common\Exception\Exception;
/**
* Generic storage exception.
*/
class StorageException extends Exception
{
}

View File

@ -0,0 +1,10 @@
<?php
namespace OAuth\Common\Storage\Exception;
/**
* Exception thrown when a token is not found in storage.
*/
class TokenNotFoundException extends StorageException
{
}

View File

@ -0,0 +1,139 @@
<?php
namespace OAuth\Common\Storage;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Storage\Exception\TokenNotFoundException;
use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
/*
* Stores a token in-memory only (destroyed at end of script execution).
*/
class Memory implements TokenStorageInterface
{
/**
* @var object|TokenInterface
*/
protected $tokens;
/**
* @var array
*/
protected $states;
public function __construct()
{
$this->tokens = array();
$this->states = array();
}
/**
* {@inheritDoc}
*/
public function retrieveAccessToken($service)
{
if ($this->hasAccessToken($service)) {
return $this->tokens[$service];
}
throw new TokenNotFoundException('Token not stored');
}
/**
* {@inheritDoc}
*/
public function storeAccessToken($service, TokenInterface $token)
{
$this->tokens[$service] = $token;
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAccessToken($service)
{
return isset($this->tokens[$service]) && $this->tokens[$service] instanceof TokenInterface;
}
/**
* {@inheritDoc}
*/
public function clearToken($service)
{
if (array_key_exists($service, $this->tokens)) {
unset($this->tokens[$service]);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllTokens()
{
$this->tokens = array();
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function retrieveAuthorizationState($service)
{
if ($this->hasAuthorizationState($service)) {
return $this->states[$service];
}
throw new AuthorizationStateNotFoundException('State not stored');
}
/**
* {@inheritDoc}
*/
public function storeAuthorizationState($service, $state)
{
$this->states[$service] = $state;
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAuthorizationState($service)
{
return isset($this->states[$service]) && null !== $this->states[$service];
}
/**
* {@inheritDoc}
*/
public function clearAuthorizationState($service)
{
if (array_key_exists($service, $this->states)) {
unset($this->states[$service]);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllAuthorizationStates()
{
$this->states = array();
// allow chaining
return $this;
}
}

View File

@ -0,0 +1,230 @@
<?php
namespace OAuth\Common\Storage;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Storage\Exception\TokenNotFoundException;
use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
use Predis\Client as Predis;
/*
* Stores a token in a Redis server. Requires the Predis library available at https://github.com/nrk/predis
*/
class Redis implements TokenStorageInterface
{
/**
* @var string
*/
protected $key;
protected $stateKey;
/**
* @var object|\Redis
*/
protected $redis;
/**
* @var object|TokenInterface
*/
protected $cachedTokens;
/**
* @var object
*/
protected $cachedStates;
/**
* @param Predis $redis An instantiated and connected redis client
* @param string $key The key to store the token under in redis
* @param string $stateKey The key to store the state under in redis.
*/
public function __construct(Predis $redis, $key, $stateKey)
{
$this->redis = $redis;
$this->key = $key;
$this->stateKey = $stateKey;
$this->cachedTokens = array();
$this->cachedStates = array();
}
/**
* {@inheritDoc}
*/
public function retrieveAccessToken($service)
{
if (!$this->hasAccessToken($service)) {
throw new TokenNotFoundException('Token not found in redis');
}
if (isset($this->cachedTokens[$service])) {
return $this->cachedTokens[$service];
}
$val = $this->redis->hget($this->key, $service);
return $this->cachedTokens[$service] = unserialize($val);
}
/**
* {@inheritDoc}
*/
public function storeAccessToken($service, TokenInterface $token)
{
// (over)write the token
$this->redis->hset($this->key, $service, serialize($token));
$this->cachedTokens[$service] = $token;
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAccessToken($service)
{
if (isset($this->cachedTokens[$service])
&& $this->cachedTokens[$service] instanceof TokenInterface
) {
return true;
}
return $this->redis->hexists($this->key, $service);
}
/**
* {@inheritDoc}
*/
public function clearToken($service)
{
$this->redis->hdel($this->key, $service);
unset($this->cachedTokens[$service]);
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllTokens()
{
// memory
$this->cachedTokens = array();
// redis
$keys = $this->redis->hkeys($this->key);
$me = $this; // 5.3 compat
// pipeline for performance
$this->redis->pipeline(
function ($pipe) use ($keys, $me) {
foreach ($keys as $k) {
$pipe->hdel($me->getKey(), $k);
}
}
);
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function retrieveAuthorizationState($service)
{
if (!$this->hasAuthorizationState($service)) {
throw new AuthorizationStateNotFoundException('State not found in redis');
}
if (isset($this->cachedStates[$service])) {
return $this->cachedStates[$service];
}
$val = $this->redis->hget($this->stateKey, $service);
return $this->cachedStates[$service] = $val;
}
/**
* {@inheritDoc}
*/
public function storeAuthorizationState($service, $state)
{
// (over)write the token
$this->redis->hset($this->stateKey, $service, $state);
$this->cachedStates[$service] = $state;
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAuthorizationState($service)
{
if (isset($this->cachedStates[$service])
&& null !== $this->cachedStates[$service]
) {
return true;
}
return $this->redis->hexists($this->stateKey, $service);
}
/**
* {@inheritDoc}
*/
public function clearAuthorizationState($service)
{
$this->redis->hdel($this->stateKey, $service);
unset($this->cachedStates[$service]);
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllAuthorizationStates()
{
// memory
$this->cachedStates = array();
// redis
$keys = $this->redis->hkeys($this->stateKey);
$me = $this; // 5.3 compat
// pipeline for performance
$this->redis->pipeline(
function ($pipe) use ($keys, $me) {
foreach ($keys as $k) {
$pipe->hdel($me->getKey(), $k);
}
}
);
// allow chaining
return $this;
}
/**
* @return Predis $redis
*/
public function getRedis()
{
return $this->redis;
}
/**
* @return string $key
*/
public function getKey()
{
return $this->key;
}
}

View File

@ -0,0 +1,188 @@
<?php
namespace OAuth\Common\Storage;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Storage\Exception\TokenNotFoundException;
use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
/**
* Stores a token in a PHP session.
*/
class Session implements TokenStorageInterface
{
/**
* @var bool
*/
protected $startSession;
/**
* @var string
*/
protected $sessionVariableName;
/**
* @var string
*/
protected $stateVariableName;
/**
* @param bool $startSession Whether or not to start the session upon construction.
* @param string $sessionVariableName the variable name to use within the _SESSION superglobal
* @param string $stateVariableName
*/
public function __construct(
$startSession = true,
$sessionVariableName = 'lusitanian-oauth-token',
$stateVariableName = 'lusitanian-oauth-state'
) {
if ($startSession && !isset($_SESSION)) {
session_start();
}
$this->startSession = $startSession;
$this->sessionVariableName = $sessionVariableName;
$this->stateVariableName = $stateVariableName;
if (!isset($_SESSION[$sessionVariableName])) {
$_SESSION[$sessionVariableName] = array();
}
if (!isset($_SESSION[$stateVariableName])) {
$_SESSION[$stateVariableName] = array();
}
}
/**
* {@inheritDoc}
*/
public function retrieveAccessToken($service)
{
if ($this->hasAccessToken($service)) {
return unserialize($_SESSION[$this->sessionVariableName][$service]);
}
throw new TokenNotFoundException('Token not found in session, are you sure you stored it?');
}
/**
* {@inheritDoc}
*/
public function storeAccessToken($service, TokenInterface $token)
{
$serializedToken = serialize($token);
if (isset($_SESSION[$this->sessionVariableName])
&& is_array($_SESSION[$this->sessionVariableName])
) {
$_SESSION[$this->sessionVariableName][$service] = $serializedToken;
} else {
$_SESSION[$this->sessionVariableName] = array(
$service => $serializedToken,
);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAccessToken($service)
{
return isset($_SESSION[$this->sessionVariableName], $_SESSION[$this->sessionVariableName][$service]);
}
/**
* {@inheritDoc}
*/
public function clearToken($service)
{
if (array_key_exists($service, $_SESSION[$this->sessionVariableName])) {
unset($_SESSION[$this->sessionVariableName][$service]);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllTokens()
{
unset($_SESSION[$this->sessionVariableName]);
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function storeAuthorizationState($service, $state)
{
if (isset($_SESSION[$this->stateVariableName])
&& is_array($_SESSION[$this->stateVariableName])
) {
$_SESSION[$this->stateVariableName][$service] = $state;
} else {
$_SESSION[$this->stateVariableName] = array(
$service => $state,
);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAuthorizationState($service)
{
return isset($_SESSION[$this->stateVariableName], $_SESSION[$this->stateVariableName][$service]);
}
/**
* {@inheritDoc}
*/
public function retrieveAuthorizationState($service)
{
if ($this->hasAuthorizationState($service)) {
return $_SESSION[$this->stateVariableName][$service];
}
throw new AuthorizationStateNotFoundException('State not found in session, are you sure you stored it?');
}
/**
* {@inheritDoc}
*/
public function clearAuthorizationState($service)
{
if (array_key_exists($service, $_SESSION[$this->stateVariableName])) {
unset($_SESSION[$this->stateVariableName][$service]);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllAuthorizationStates()
{
unset($_SESSION[$this->stateVariableName]);
// allow chaining
return $this;
}
public function __destruct()
{
if ($this->startSession) {
session_write_close();
}
}
}

View File

@ -0,0 +1,200 @@
<?php
namespace OAuth\Common\Storage;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Storage\Exception\TokenNotFoundException;
use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class SymfonySession implements TokenStorageInterface
{
private $session;
private $sessionVariableName;
private $stateVariableName;
/**
* @param SessionInterface $session
* @param bool $startSession
* @param string $sessionVariableName
* @param string $stateVariableName
*/
public function __construct(
SessionInterface $session,
$startSession = true,
$sessionVariableName = 'lusitanian_oauth_token',
$stateVariableName = 'lusitanian_oauth_state'
) {
$this->session = $session;
$this->sessionVariableName = $sessionVariableName;
$this->stateVariableName = $stateVariableName;
}
/**
* {@inheritDoc}
*/
public function retrieveAccessToken($service)
{
if ($this->hasAccessToken($service)) {
// get from session
$tokens = $this->session->get($this->sessionVariableName);
// one item
return $tokens[$service];
}
throw new TokenNotFoundException('Token not found in session, are you sure you stored it?');
}
/**
* {@inheritDoc}
*/
public function storeAccessToken($service, TokenInterface $token)
{
// get previously saved tokens
$tokens = $this->session->get($this->sessionVariableName);
if (!is_array($tokens)) {
$tokens = array();
}
$tokens[$service] = $token;
// save
$this->session->set($this->sessionVariableName, $tokens);
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAccessToken($service)
{
// get from session
$tokens = $this->session->get($this->sessionVariableName);
return is_array($tokens)
&& isset($tokens[$service])
&& $tokens[$service] instanceof TokenInterface;
}
/**
* {@inheritDoc}
*/
public function clearToken($service)
{
// get previously saved tokens
$tokens = $this->session->get($this->sessionVariableName);
if (is_array($tokens) && array_key_exists($service, $tokens)) {
unset($tokens[$service]);
// Replace the stored tokens array
$this->session->set($this->sessionVariableName, $tokens);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllTokens()
{
$this->session->remove($this->sessionVariableName);
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function retrieveAuthorizationState($service)
{
if ($this->hasAuthorizationState($service)) {
// get from session
$states = $this->session->get($this->stateVariableName);
// one item
return $states[$service];
}
throw new AuthorizationStateNotFoundException('State not found in session, are you sure you stored it?');
}
/**
* {@inheritDoc}
*/
public function storeAuthorizationState($service, $state)
{
// get previously saved tokens
$states = $this->session->get($this->stateVariableName);
if (!is_array($states)) {
$states = array();
}
$states[$service] = $state;
// save
$this->session->set($this->stateVariableName, $states);
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function hasAuthorizationState($service)
{
// get from session
$states = $this->session->get($this->stateVariableName);
return is_array($states)
&& isset($states[$service])
&& null !== $states[$service];
}
/**
* {@inheritDoc}
*/
public function clearAuthorizationState($service)
{
// get previously saved tokens
$states = $this->session->get($this->stateVariableName);
if (is_array($states) && array_key_exists($service, $states)) {
unset($states[$service]);
// Replace the stored tokens array
$this->session->set($this->stateVariableName, $states);
}
// allow chaining
return $this;
}
/**
* {@inheritDoc}
*/
public function clearAllAuthorizationStates()
{
$this->session->remove($this->stateVariableName);
// allow chaining
return $this;
}
/**
* @return Session
*/
public function getSession()
{
return $this->session;
}
}

View File

@ -0,0 +1,98 @@
<?php
namespace OAuth\Common\Storage;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Storage\Exception\TokenNotFoundException;
/**
* All token storage providers must implement this interface.
*/
interface TokenStorageInterface
{
/**
* @param string $service
*
* @return TokenInterface
*
* @throws TokenNotFoundException
*/
public function retrieveAccessToken($service);
/**
* @param string $service
* @param TokenInterface $token
*
* @return TokenStorageInterface
*/
public function storeAccessToken($service, TokenInterface $token);
/**
* @param string $service
*
* @return bool
*/
public function hasAccessToken($service);
/**
* Delete the users token. Aka, log out.
*
* @param string $service
*
* @return TokenStorageInterface
*/
public function clearToken($service);
/**
* Delete *ALL* user tokens. Use with care. Most of the time you will likely
* want to use clearToken() instead.
*
* @return TokenStorageInterface
*/
public function clearAllTokens();
/**
* Store the authorization state related to a given service
*
* @param string $service
* @param string $state
*
* @return TokenStorageInterface
*/
public function storeAuthorizationState($service, $state);
/**
* Check if an authorization state for a given service exists
*
* @param string $service
*
* @return bool
*/
public function hasAuthorizationState($service);
/**
* Retrieve the authorization state for a given service
*
* @param string $service
*
* @return string
*/
public function retrieveAuthorizationState($service);
/**
* Clear the authorization state of a given service
*
* @param string $service
*
* @return TokenStorageInterface
*/
public function clearAuthorizationState($service);
/**
* Delete *ALL* user authorization states. Use with care. Most of the time you will likely
* want to use clearAuthorization() instead.
*
* @return TokenStorageInterface
*/
public function clearAllAuthorizationStates();
}

View File

@ -0,0 +1,128 @@
<?php
namespace OAuth\Common\Token;
/**
* Base token implementation for any OAuth version.
*/
abstract class AbstractToken implements TokenInterface
{
/**
* @var string
*/
protected $accessToken;
/**
* @var string
*/
protected $refreshToken;
/**
* @var int
*/
protected $endOfLife;
/**
* @var array
*/
protected $extraParams = array();
/**
* @param string $accessToken
* @param string $refreshToken
* @param int $lifetime
* @param array $extraParams
*/
public function __construct($accessToken = null, $refreshToken = null, $lifetime = null, $extraParams = array())
{
$this->accessToken = $accessToken;
$this->refreshToken = $refreshToken;
$this->setLifetime($lifetime);
$this->extraParams = $extraParams;
}
/**
* @return string
*/
public function getAccessToken()
{
return $this->accessToken;
}
/**
* @return string
*/
public function getRefreshToken()
{
return $this->refreshToken;
}
/**
* @return int
*/
public function getEndOfLife()
{
return $this->endOfLife;
}
/**
* @param array $extraParams
*/
public function setExtraParams(array $extraParams)
{
$this->extraParams = $extraParams;
}
/**
* @return array
*/
public function getExtraParams()
{
return $this->extraParams;
}
/**
* @param string $accessToken
*/
public function setAccessToken($accessToken)
{
$this->accessToken = $accessToken;
}
/**
* @param int $endOfLife
*/
public function setEndOfLife($endOfLife)
{
$this->endOfLife = $endOfLife;
}
/**
* @param int $lifetime
*/
public function setLifetime($lifetime)
{
if (0 === $lifetime || static::EOL_NEVER_EXPIRES === $lifetime) {
$this->endOfLife = static::EOL_NEVER_EXPIRES;
} elseif (null !== $lifetime) {
$this->endOfLife = intval($lifetime) + time();
} else {
$this->endOfLife = static::EOL_UNKNOWN;
}
}
/**
* @param string $refreshToken
*/
public function setRefreshToken($refreshToken)
{
$this->refreshToken = $refreshToken;
}
public function isExpired()
{
return ($this->getEndOfLife() !== TokenInterface::EOL_NEVER_EXPIRES
&& $this->getEndOfLife() !== TokenInterface::EOL_UNKNOWN
&& time() > $this->getEndOfLife());
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace OAuth\Common\Token\Exception;
use OAuth\Common\Exception\Exception;
/**
* Exception thrown when an expired token is attempted to be used.
*/
class ExpiredTokenException extends Exception
{
}

View File

@ -0,0 +1,64 @@
<?php
namespace OAuth\Common\Token;
/**
* Base token interface for any OAuth version.
*/
interface TokenInterface
{
/**
* Denotes an unknown end of life time.
*/
const EOL_UNKNOWN = -9001;
/**
* Denotes a token which never expires, should only happen in OAuth1.
*/
const EOL_NEVER_EXPIRES = -9002;
/**
* @return string
*/
public function getAccessToken();
/**
* @return int
*/
public function getEndOfLife();
/**
* @return array
*/
public function getExtraParams();
/**
* @param string $accessToken
*/
public function setAccessToken($accessToken);
/**
* @param int $endOfLife
*/
public function setEndOfLife($endOfLife);
/**
* @param int $lifetime
*/
public function setLifetime($lifetime);
/**
* @param array $extraParams
*/
public function setExtraParams(array $extraParams);
/**
* @return string
*/
public function getRefreshToken();
/**
* @param string $refreshToken
*/
public function setRefreshToken($refreshToken);
}

View File

@ -0,0 +1,320 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\TokenInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Service\AbstractService as BaseAbstractService;
abstract class AbstractService extends BaseAbstractService implements ServiceInterface
{
/** @const OAUTH_VERSION */
const OAUTH_VERSION = 1;
/** @var SignatureInterface */
protected $signature;
/** @var UriInterface|null */
protected $baseApiUri;
/**
* {@inheritDoc}
*/
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage);
$this->signature = $signature;
$this->baseApiUri = $baseApiUri;
$this->signature->setHashingAlgorithm($this->getSignatureMethod());
}
/**
* {@inheritDoc}
*/
public function requestRequestToken()
{
$authorizationHeader = array('Authorization' => $this->buildAuthorizationHeaderForTokenRequest());
$headers = array_merge($authorizationHeader, $this->getExtraOAuthHeaders());
$responseBody = $this->httpClient->retrieveResponse($this->getRequestTokenEndpoint(), array(), $headers);
$token = $this->parseRequestTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationUri(array $additionalParameters = array())
{
// Build the url
$url = clone $this->getAuthorizationEndpoint();
foreach ($additionalParameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
/**
* {@inheritDoc}
*/
public function requestAccessToken($token, $verifier, $tokenSecret = null)
{
if (is_null($tokenSecret)) {
$storedRequestToken = $this->storage->retrieveAccessToken($this->service());
$tokenSecret = $storedRequestToken->getRequestTokenSecret();
}
$this->signature->setTokenSecret($tokenSecret);
$bodyParams = array(
'oauth_verifier' => $verifier,
);
$authorizationHeader = array(
'Authorization' => $this->buildAuthorizationHeaderForAPIRequest(
'POST',
$this->getAccessTokenEndpoint(),
$this->storage->retrieveAccessToken($this->service()),
$bodyParams
)
);
$headers = array_merge($authorizationHeader, $this->getExtraOAuthHeaders());
$responseBody = $this->httpClient->retrieveResponse($this->getAccessTokenEndpoint(), $bodyParams, $headers);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
/**
* Refreshes an OAuth1 access token
* @param TokenInterface $token
* @return TokenInterface $token
*/
public function refreshAccessToken(TokenInterface $token)
{
}
/**
* Sends an authenticated API request to the path provided.
* If the path provided is not an absolute URI, the base API Uri (must be passed into constructor) will be used.
*
* @param string|UriInterface $path
* @param string $method HTTP method
* @param array $body Request body if applicable (key/value pairs)
* @param array $extraHeaders Extra headers if applicable.
* These will override service-specific any defaults.
*
* @return string
*/
public function request($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
$uri = $this->determineRequestUriFromPath($path, $this->baseApiUri);
/** @var $token StdOAuth1Token */
$token = $this->storage->retrieveAccessToken($this->service());
$extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders);
$authorizationHeader = array(
'Authorization' => $this->buildAuthorizationHeaderForAPIRequest($method, $uri, $token, $body)
);
$headers = array_merge($authorizationHeader, $extraHeaders);
return $this->httpClient->retrieveResponse($uri, $body, $headers, $method);
}
/**
* Return any additional headers always needed for this service implementation's OAuth calls.
*
* @return array
*/
protected function getExtraOAuthHeaders()
{
return array();
}
/**
* Return any additional headers always needed for this service implementation's API calls.
*
* @return array
*/
protected function getExtraApiHeaders()
{
return array();
}
/**
* Builds the authorization header for getting an access or request token.
*
* @param array $extraParameters
*
* @return string
*/
protected function buildAuthorizationHeaderForTokenRequest(array $extraParameters = array())
{
$parameters = $this->getBasicAuthorizationHeaderInfo();
$parameters = array_merge($parameters, $extraParameters);
$parameters['oauth_signature'] = $this->signature->getSignature(
$this->getRequestTokenEndpoint(),
$parameters,
'POST'
);
$authorizationHeader = 'OAuth ';
$delimiter = '';
foreach ($parameters as $key => $value) {
$authorizationHeader .= $delimiter . rawurlencode($key) . '="' . rawurlencode($value) . '"';
$delimiter = ', ';
}
return $authorizationHeader;
}
/**
* Builds the authorization header for an authenticated API request
*
* @param string $method
* @param UriInterface $uri The uri the request is headed
* @param TokenInterface $token
* @param array $bodyParams Request body if applicable (key/value pairs)
*
* @return string
*/
protected function buildAuthorizationHeaderForAPIRequest(
$method,
UriInterface $uri,
TokenInterface $token,
$bodyParams = null
) {
$this->signature->setTokenSecret($token->getAccessTokenSecret());
$authParameters = $this->getBasicAuthorizationHeaderInfo();
if (isset($authParameters['oauth_callback'])) {
unset($authParameters['oauth_callback']);
}
$authParameters = array_merge($authParameters, array('oauth_token' => $token->getAccessToken()));
$authParameters = (is_array($bodyParams)) ? array_merge($authParameters, $bodyParams) : $authParameters;
$authParameters['oauth_signature'] = $this->signature->getSignature($uri, $authParameters, $method);
if (isset($bodyParams['oauth_session_handle'])) {
$authParameters['oauth_session_handle'] = $bodyParams['oauth_session_handle'];
unset($bodyParams['oauth_session_handle']);
}
$authorizationHeader = 'OAuth ';
$delimiter = '';
foreach ($authParameters as $key => $value) {
$authorizationHeader .= $delimiter . rawurlencode($key) . '="' . rawurlencode($value) . '"';
$delimiter = ', ';
}
return $authorizationHeader;
}
/**
* Builds the authorization header array.
*
* @return array
*/
protected function getBasicAuthorizationHeaderInfo()
{
$dateTime = new \DateTime();
$headerParameters = array(
'oauth_callback' => $this->credentials->getCallbackUrl(),
'oauth_consumer_key' => $this->credentials->getConsumerId(),
'oauth_nonce' => $this->generateNonce(),
'oauth_signature_method' => $this->getSignatureMethod(),
'oauth_timestamp' => $dateTime->format('U'),
'oauth_version' => $this->getVersion(),
);
return $headerParameters;
}
/**
* Pseudo random string generator used to build a unique string to sign each request
*
* @param int $length
*
* @return string
*/
protected function generateNonce($length = 32)
{
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$nonce = '';
$maxRand = strlen($characters)-1;
for ($i = 0; $i < $length; $i++) {
$nonce.= $characters[rand(0, $maxRand)];
}
return $nonce;
}
/**
* @return string
*/
protected function getSignatureMethod()
{
return 'HMAC-SHA1';
}
/**
* This returns the version used in the authorization header of the requests
*
* @return string
*/
protected function getVersion()
{
return '1.0';
}
/**
* Parses the request token response and returns a TokenInterface.
* This is only needed to verify the `oauth_callback_confirmed` parameter. The actual
* parsing logic is contained in the access token parser.
*
* @abstract
*
* @param string $responseBody
*
* @return TokenInterface
*
* @throws TokenResponseException
*/
abstract protected function parseRequestTokenResponse($responseBody);
/**
* Parses the access token response and returns a TokenInterface.
*
* @abstract
*
* @param string $responseBody
*
* @return TokenInterface
*
* @throws TokenResponseException
*/
abstract protected function parseAccessTokenResponse($responseBody);
}

View File

@ -0,0 +1,96 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
class BitBucket extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://bitbucket.org/api/1.0/');
}
}
/**
* {@inheritDoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri('https://bitbucket.org/!api/1.0/oauth/request_token');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://bitbucket.org/!api/1.0/oauth/authenticate');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://bitbucket.org/!api/1.0/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,132 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
class Etsy extends AbstractService
{
protected $scopes = array();
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://openapi.etsy.com/v2/');
}
}
/**
* {@inheritdoc}
*/
public function getRequestTokenEndpoint()
{
$uri = new Uri($this->baseApiUri . 'oauth/request_token');
$scopes = $this->getScopes();
if (count($scopes)) {
$uri->setQuery('scope=' . implode('%20', $scopes));
}
return $uri;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri($this->baseApiUri);
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri($this->baseApiUri . 'oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
/**
* Set the scopes for permissions
* @see https://www.etsy.com/developers/documentation/getting_started/oauth#section_permission_scopes
* @param array $scopes
*
* @return $this
*/
public function setScopes(array $scopes)
{
if (!is_array($scopes)) {
$scopes = array();
}
$this->scopes = $scopes;
return $this;
}
/**
* Return the defined scopes
* @return array
*/
public function getScopes()
{
return $this->scopes;
}
}

View File

@ -0,0 +1,96 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
class FitBit extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.fitbit.com/1/');
}
}
/**
* {@inheritdoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri('https://api.fitbit.com/oauth/request_token');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.fitbit.com/oauth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.fitbit.com/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* 500px service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://developers.500px.com/
*/
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
/**
* 500px service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://developers.500px.com/
*/
class FiveHundredPx extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct(
$credentials,
$httpClient,
$storage,
$signature,
$baseApiUri
);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.500px.com/v1/');
}
}
/**
* {@inheritDoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri('https://api.500px.com/v1/oauth/request_token');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://api.500px.com/v1/oauth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.500px.com/v1/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed'])
|| $data['oauth_callback_confirmed'] !== 'true'
) {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error'] . '"'
);
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,133 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
class Flickr extends AbstractService
{
protected $format;
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if ($baseApiUri === null) {
$this->baseApiUri = new Uri('https://api.flickr.com/services/rest/');
}
}
public function getRequestTokenEndpoint()
{
return new Uri('https://www.flickr.com/services/oauth/request_token');
}
public function getAuthorizationEndpoint()
{
return new Uri('https://www.flickr.com/services/oauth/authorize');
}
public function getAccessTokenEndpoint()
{
return new Uri('https://www.flickr.com/services/oauth/access_token');
}
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] != 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if ($data === null || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
public function request($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
$uri = $this->determineRequestUriFromPath('/', $this->baseApiUri);
$uri->addToQuery('method', $path);
if (!empty($this->format)) {
$uri->addToQuery('format', $this->format);
if ($this->format === 'json') {
$uri->addToQuery('nojsoncallback', 1);
}
}
$token = $this->storage->retrieveAccessToken($this->service());
$extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders);
$authorizationHeader = array(
'Authorization' => $this->buildAuthorizationHeaderForAPIRequest($method, $uri, $token, $body)
);
$headers = array_merge($authorizationHeader, $extraHeaders);
return $this->httpClient->retrieveResponse($uri, $body, $headers, $method);
}
public function requestRest($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
return $this->request($path, $method, $body, $extraHeaders);
}
public function requestXmlrpc($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
$this->format = 'xmlrpc';
return $this->request($path, $method, $body, $extraHeaders);
}
public function requestSoap($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
$this->format = 'soap';
return $this->request($path, $method, $body, $extraHeaders);
}
public function requestJson($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
$this->format = 'json';
return $this->request($path, $method, $body, $extraHeaders);
}
public function requestPhp($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
$this->format = 'php_serial';
return $this->request($path, $method, $body, $extraHeaders);
}
}

View File

@ -0,0 +1,120 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\OAuth1\Signature\SignatureInterface;
class QuickBooks extends AbstractService
{
/**
* {@inheritdoc}
*/
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct(
$credentials,
$httpClient,
$storage,
$signature,
$baseApiUri
);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://quickbooks.api.intuit.com/');
}
}
/**
* {@inheritdoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri('https://oauth.intuit.com/oauth/v1/get_request_token');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://appcenter.intuit.com/Connect/Begin');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://oauth.intuit.com/oauth/v1/get_access_token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed'])
|| $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
$message = 'Error in retrieving token: "' . $data['error'] . '"';
throw new TokenResponseException($message);
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritDoc}
*/
public function request(
$path,
$method = 'GET',
$body = null,
array $extraHeaders = array()
) {
$extraHeaders['Accept'] = 'application/json';
return parent::request($path, $method, $body, $extraHeaders);
}
}

View File

@ -0,0 +1,96 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
class Redmine extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if (null === $baseApiUri) {
throw new \Exception('baseApiUri is a required argument.');
}
}
/**
* {@inheritDoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri($this->baseApiUri->getAbsoluteUri() . '/request_token');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri($this->baseApiUri->getAbsoluteUri() . '/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri($this->baseApiUri->getAbsoluteUri() . '/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,96 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
class ScoopIt extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://www.scoop.it/api/1/');
}
}
/**
* {@inheritDoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri('https://www.scoop.it/oauth/request');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.scoop.it/oauth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://www.scoop.it/oauth/access');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Service\ServiceInterface as BaseServiceInterface;
use OAuth\OAuth1\Signature\SignatureInterface;
/**
* Defines the common methods across OAuth 1 services.
*/
interface ServiceInterface extends BaseServiceInterface
{
/**
* Retrieves and stores/returns the OAuth1 request token obtained from the service.
*
* @return TokenInterface $token
*
* @throws TokenResponseException
*/
public function requestRequestToken();
/**
* Retrieves and stores/returns the OAuth1 access token after a successful authorization.
*
* @param string $token The request token from the callback.
* @param string $verifier
* @param string $tokenSecret
*
* @return TokenInterface $token
*
* @throws TokenResponseException
*/
public function requestAccessToken($token, $verifier, $tokenSecret);
/**
* @return UriInterface
*/
public function getRequestTokenEndpoint();
}

View File

@ -0,0 +1,96 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
class Tumblr extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.tumblr.com/v2/');
}
}
/**
* {@inheritdoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri('https://www.tumblr.com/oauth/request_token');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.tumblr.com/oauth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://www.tumblr.com/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,123 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Exception\Exception;
class Twitter extends AbstractService
{
const ENDPOINT_AUTHENTICATE = "https://api.twitter.com/oauth/authenticate";
const ENDPOINT_AUTHORIZE = "https://api.twitter.com/oauth/authorize";
protected $authorizationEndpoint = self::ENDPOINT_AUTHENTICATE;
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.twitter.com/1.1/');
}
}
/**
* {@inheritdoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri('https://api.twitter.com/oauth/request_token');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
if ($this->authorizationEndpoint != self::ENDPOINT_AUTHENTICATE
&& $this->authorizationEndpoint != self::ENDPOINT_AUTHORIZE) {
$this->authorizationEndpoint = self::ENDPOINT_AUTHENTICATE;
}
return new Uri($this->authorizationEndpoint);
}
/**
* @param string $authorizationEndpoint
*
* @throws Exception
*/
public function setAuthorizationEndpoint($endpoint)
{
if ($endpoint != self::ENDPOINT_AUTHENTICATE && $endpoint != self::ENDPOINT_AUTHORIZE) {
throw new Exception(
sprintf("'%s' is not a correct Twitter authorization endpoint.", $endpoint)
);
}
$this->authorizationEndpoint = $endpoint;
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.twitter.com/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response: ' . $responseBody);
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
} elseif (!isset($data["oauth_token"]) || !isset($data["oauth_token_secret"])) {
throw new TokenResponseException('Invalid response. OAuth Token data not set: ' . $responseBody);
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,97 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
class Xing extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.xing.com/v1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://api.xing.com/v1/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.xing.com/v1/access_token');
}
/**
* {@inheritdoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri('https://api.xing.com/v1/request_token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
$errors = json_decode($responseBody);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif ($errors) {
throw new TokenResponseException('Error in retrieving token: "' . $errors->error_name . '"');
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,131 @@
<?php
namespace OAuth\OAuth1\Service;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\OAuth1\Token\TokenInterface;
class Yahoo extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
SignatureInterface $signature,
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://social.yahooapis.com/v1/');
}
}
/**
* {@inheritDoc}
*/
public function getRequestTokenEndpoint()
{
return new Uri('https://api.login.yahoo.com/oauth/v2/get_request_token');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://api.login.yahoo.com/oauth/v2/request_auth');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.login.yahoo.com/oauth/v2/get_token');
}
/**
* {@inheritdoc}
*/
public function refreshAccessToken(TokenInterface $token)
{
$extraParams = $token->getExtraParams();
$bodyParams = array('oauth_session_handle' => $extraParams['oauth_session_handle']);
$authorizationHeader = array(
'Authorization' => $this->buildAuthorizationHeaderForAPIRequest(
'POST',
$this->getAccessTokenEndpoint(),
$this->storage->retrieveAccessToken($this->service()),
$bodyParams
)
);
$headers = array_merge($authorizationHeader, $this->getExtraOAuthHeaders(), array());
$responseBody = $this->httpClient->retrieveResponse($this->getAccessTokenEndpoint(), $bodyParams, $headers);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
if (isset($data['oauth_expires_in'])) {
$token->setLifetime($data['oauth_expires_in']);
} else {
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
}
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace OAuth\OAuth1\Signature\Exception;
use OAuth\Common\Exception\Exception;
/**
* Thrown when an unsupported hash mechanism is requested in signature class.
*/
class UnsupportedHashAlgorithmException extends Exception
{
}

View File

@ -0,0 +1,132 @@
<?php
namespace OAuth\OAuth1\Signature;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\OAuth1\Signature\Exception\UnsupportedHashAlgorithmException;
class Signature implements SignatureInterface
{
/**
* @var Credentials
*/
protected $credentials;
/**
* @var string
*/
protected $algorithm;
/**
* @var string
*/
protected $tokenSecret = null;
/**
* @param CredentialsInterface $credentials
*/
public function __construct(CredentialsInterface $credentials)
{
$this->credentials = $credentials;
}
/**
* @param string $algorithm
*/
public function setHashingAlgorithm($algorithm)
{
$this->algorithm = $algorithm;
}
/**
* @param string $token
*/
public function setTokenSecret($token)
{
$this->tokenSecret = $token;
}
/**
* @param UriInterface $uri
* @param array $params
* @param string $method
*
* @return string
*/
public function getSignature(UriInterface $uri, array $params, $method = 'POST')
{
parse_str($uri->getQuery(), $queryStringData);
foreach (array_merge($queryStringData, $params) as $key => $value) {
$signatureData[rawurlencode($key)] = rawurlencode($value);
}
ksort($signatureData);
// determine base uri
$baseUri = $uri->getScheme() . '://' . $uri->getRawAuthority();
if ('/' === $uri->getPath()) {
$baseUri .= $uri->hasExplicitTrailingHostSlash() ? '/' : '';
} else {
$baseUri .= $uri->getPath();
}
$baseString = strtoupper($method) . '&';
$baseString .= rawurlencode($baseUri) . '&';
$baseString .= rawurlencode($this->buildSignatureDataString($signatureData));
return base64_encode($this->hash($baseString));
}
/**
* @param array $signatureData
*
* @return string
*/
protected function buildSignatureDataString(array $signatureData)
{
$signatureString = '';
$delimiter = '';
foreach ($signatureData as $key => $value) {
$signatureString .= $delimiter . $key . '=' . $value;
$delimiter = '&';
}
return $signatureString;
}
/**
* @return string
*/
protected function getSigningKey()
{
$signingKey = rawurlencode($this->credentials->getConsumerSecret()) . '&';
if ($this->tokenSecret !== null) {
$signingKey .= rawurlencode($this->tokenSecret);
}
return $signingKey;
}
/**
* @param string $data
*
* @return string
*
* @throws UnsupportedHashAlgorithmException
*/
protected function hash($data)
{
switch (strtoupper($this->algorithm)) {
case 'HMAC-SHA1':
return hash_hmac('sha1', $data, $this->getSigningKey(), true);
default:
throw new UnsupportedHashAlgorithmException(
'Unsupported hashing algorithm (' . $this->algorithm . ') used.'
);
}
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace OAuth\OAuth1\Signature;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
interface SignatureInterface
{
/**
* @param string $algorithm
*/
public function setHashingAlgorithm($algorithm);
/**
* @param string $token
*/
public function setTokenSecret($token);
/**
* @param UriInterface $uri
* @param array $params
* @param string $method
*
* @return string
*/
public function getSignature(UriInterface $uri, array $params, $method = 'POST');
}

View File

@ -0,0 +1,75 @@
<?php
namespace OAuth\OAuth1\Token;
use OAuth\Common\Token\AbstractToken;
/**
* Standard OAuth1 token implementation.
* Implements OAuth\OAuth1\Token\TokenInterface in case of any OAuth1 specific features.
*/
class StdOAuth1Token extends AbstractToken implements TokenInterface
{
/**
* @var string
*/
protected $requestToken;
/**
* @var string
*/
protected $requestTokenSecret;
/**
* @var string
*/
protected $accessTokenSecret;
/**
* @param string $requestToken
*/
public function setRequestToken($requestToken)
{
$this->requestToken = $requestToken;
}
/**
* @return string
*/
public function getRequestToken()
{
return $this->requestToken;
}
/**
* @param string $requestTokenSecret
*/
public function setRequestTokenSecret($requestTokenSecret)
{
$this->requestTokenSecret = $requestTokenSecret;
}
/**
* @return string
*/
public function getRequestTokenSecret()
{
return $this->requestTokenSecret;
}
/**
* @param string $accessTokenSecret
*/
public function setAccessTokenSecret($accessTokenSecret)
{
$this->accessTokenSecret = $accessTokenSecret;
}
/**
* @return string
*/
public function getAccessTokenSecret()
{
return $this->accessTokenSecret;
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace OAuth\OAuth1\Token;
use OAuth\Common\Token\TokenInterface as BaseTokenInterface;
/**
* OAuth1 specific token interface
*/
interface TokenInterface extends BaseTokenInterface
{
/**
* @return string
*/
public function getAccessTokenSecret();
/**
* @param string $accessTokenSecret
*/
public function setAccessTokenSecret($accessTokenSecret);
/**
* @return string
*/
public function getRequestTokenSecret();
/**
* @param string $requestTokenSecret
*/
public function setRequestTokenSecret($requestTokenSecret);
/**
* @return string
*/
public function getRequestToken();
/**
* @param string $requestToken
*/
public function setRequestToken($requestToken);
}

View File

@ -0,0 +1,364 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Exception\Exception;
use OAuth\Common\Service\AbstractService as BaseAbstractService;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\OAuth2\Service\Exception\InvalidAuthorizationStateException;
use OAuth\OAuth2\Service\Exception\InvalidScopeException;
use OAuth\OAuth2\Service\Exception\MissingRefreshTokenException;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Token\Exception\ExpiredTokenException;
abstract class AbstractService extends BaseAbstractService implements ServiceInterface
{
/** @const OAUTH_VERSION */
const OAUTH_VERSION = 2;
/** @var array */
protected $scopes;
/** @var UriInterface|null */
protected $baseApiUri;
/** @var bool */
protected $stateParameterInAuthUrl;
/** @var string */
protected $apiVersion;
/**
* @param CredentialsInterface $credentials
* @param ClientInterface $httpClient
* @param TokenStorageInterface $storage
* @param array $scopes
* @param UriInterface|null $baseApiUri
* @param bool $stateParameterInAutUrl
* @param string $apiVersion
*
* @throws InvalidScopeException
*/
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null,
$stateParameterInAutUrl = false,
$apiVersion = ""
) {
parent::__construct($credentials, $httpClient, $storage);
$this->stateParameterInAuthUrl = $stateParameterInAutUrl;
foreach ($scopes as $scope) {
if (!$this->isValidScope($scope)) {
throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this));
}
}
$this->scopes = $scopes;
$this->baseApiUri = $baseApiUri;
$this->apiVersion = $apiVersion;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationUri(array $additionalParameters = array())
{
$parameters = array_merge(
$additionalParameters,
array(
'type' => 'web_server',
'client_id' => $this->credentials->getConsumerId(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'response_type' => 'code',
)
);
$parameters['scope'] = implode($this->getScopesDelimiter(), $this->scopes);
if ($this->needsStateParameterInAuthUrl()) {
if (!isset($parameters['state'])) {
$parameters['state'] = $this->generateAuthorizationState();
}
$this->storeAuthorizationState($parameters['state']);
}
// Build the url
$url = clone $this->getAuthorizationEndpoint();
foreach ($parameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
/**
* {@inheritdoc}
*/
public function requestAccessToken($code, $state = null)
{
if (null !== $state) {
$this->validateAuthorizationState($state);
}
$bodyParams = array(
'code' => $code,
'client_id' => $this->credentials->getConsumerId(),
'client_secret' => $this->credentials->getConsumerSecret(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'grant_type' => 'authorization_code',
);
$responseBody = $this->httpClient->retrieveResponse(
$this->getAccessTokenEndpoint(),
$bodyParams,
$this->getExtraOAuthHeaders()
);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
/**
* Sends an authenticated API request to the path provided.
* If the path provided is not an absolute URI, the base API Uri (must be passed into constructor) will be used.
*
* @param string|UriInterface $path
* @param string $method HTTP method
* @param array $body Request body if applicable.
* @param array $extraHeaders Extra headers if applicable. These will override service-specific
* any defaults.
*
* @return string
*
* @throws ExpiredTokenException
* @throws Exception
*/
public function request($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
$uri = $this->determineRequestUriFromPath($path, $this->baseApiUri);
$token = $this->storage->retrieveAccessToken($this->service());
if ($token->getEndOfLife() !== TokenInterface::EOL_NEVER_EXPIRES
&& $token->getEndOfLife() !== TokenInterface::EOL_UNKNOWN
&& time() > $token->getEndOfLife()
) {
throw new ExpiredTokenException(
sprintf(
'Token expired on %s at %s',
date('m/d/Y', $token->getEndOfLife()),
date('h:i:s A', $token->getEndOfLife())
)
);
}
// add the token where it may be needed
if (static::AUTHORIZATION_METHOD_HEADER_OAUTH === $this->getAuthorizationMethod()) {
$extraHeaders = array_merge(array('Authorization' => 'OAuth ' . $token->getAccessToken()), $extraHeaders);
} elseif (static::AUTHORIZATION_METHOD_QUERY_STRING === $this->getAuthorizationMethod()) {
$uri->addToQuery('access_token', $token->getAccessToken());
} elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V2 === $this->getAuthorizationMethod()) {
$uri->addToQuery('oauth2_access_token', $token->getAccessToken());
} elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V3 === $this->getAuthorizationMethod()) {
$uri->addToQuery('apikey', $token->getAccessToken());
} elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V4 === $this->getAuthorizationMethod()) {
$uri->addToQuery('auth', $token->getAccessToken());
} elseif (static::AUTHORIZATION_METHOD_HEADER_BEARER === $this->getAuthorizationMethod()) {
$extraHeaders = array_merge(array('Authorization' => 'Bearer ' . $token->getAccessToken()), $extraHeaders);
}
$extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders);
return $this->httpClient->retrieveResponse($uri, $body, $extraHeaders, $method);
}
/**
* Accessor to the storage adapter to be able to retrieve tokens
*
* @return TokenStorageInterface
*/
public function getStorage()
{
return $this->storage;
}
/**
* Refreshes an OAuth2 access token.
*
* @param TokenInterface $token
*
* @return TokenInterface $token
*
* @throws MissingRefreshTokenException
*/
public function refreshAccessToken(TokenInterface $token)
{
$refreshToken = $token->getRefreshToken();
if (empty($refreshToken)) {
throw new MissingRefreshTokenException();
}
$parameters = array(
'grant_type' => 'refresh_token',
'type' => 'web_server',
'client_id' => $this->credentials->getConsumerId(),
'client_secret' => $this->credentials->getConsumerSecret(),
'refresh_token' => $refreshToken,
);
$responseBody = $this->httpClient->retrieveResponse(
$this->getAccessTokenEndpoint(),
$parameters,
$this->getExtraOAuthHeaders()
);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
/**
* Return whether or not the passed scope value is valid.
*
* @param string $scope
*
* @return bool
*/
public function isValidScope($scope)
{
$reflectionClass = new \ReflectionClass(get_class($this));
return in_array($scope, $reflectionClass->getConstants(), true);
}
/**
* Check if the given service need to generate a unique state token to build the authorization url
*
* @return bool
*/
public function needsStateParameterInAuthUrl()
{
return $this->stateParameterInAuthUrl;
}
/**
* Validates the authorization state against a given one
*
* @param string $state
* @throws InvalidAuthorizationStateException
*/
protected function validateAuthorizationState($state)
{
if ($this->retrieveAuthorizationState() !== $state) {
throw new InvalidAuthorizationStateException();
}
}
/**
* Generates a random string to be used as state
*
* @return string
*/
protected function generateAuthorizationState()
{
return md5(rand());
}
/**
* Retrieves the authorization state for the current service
*
* @return string
*/
protected function retrieveAuthorizationState()
{
return $this->storage->retrieveAuthorizationState($this->service());
}
/**
* Stores a given authorization state into the storage
*
* @param string $state
*/
protected function storeAuthorizationState($state)
{
$this->storage->storeAuthorizationState($this->service(), $state);
}
/**
* Return any additional headers always needed for this service implementation's OAuth calls.
*
* @return array
*/
protected function getExtraOAuthHeaders()
{
return array();
}
/**
* Return any additional headers always needed for this service implementation's API calls.
*
* @return array
*/
protected function getExtraApiHeaders()
{
return array();
}
/**
* Parses the access token response and returns a TokenInterface.
*
* @abstract
*
* @param string $responseBody
*
* @return TokenInterface
*
* @throws TokenResponseException
*/
abstract protected function parseAccessTokenResponse($responseBody);
/**
* Returns a class constant from ServiceInterface defining the authorization method used for the API
* Header is the sane default.
*
* @return int
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_OAUTH;
}
/**
* Returns api version string if is set else retrun empty string
*
* @return string
*/
protected function getApiVersionString()
{
return !(empty($this->apiVersion)) ? "/".$this->apiVersion : "" ;
}
/**
* Returns delimiter to scopes in getAuthorizationUri
* For services that do not fully respect the Oauth's RFC,
* and use scopes with commas as delimiter
*
* @return string
*/
protected function getScopesDelimiter()
{
return ' ';
}
}

View File

@ -0,0 +1,97 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Amazon service.
*
* @author Flávio Heleno <flaviohbatista@gmail.com>
* @link https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf
*/
class Amazon extends AbstractService
{
/**
* Defined scopes
* @link https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf
*/
const SCOPE_PROFILE = 'profile';
const SCOPE_POSTAL_CODE = 'postal_code';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.amazon.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.amazon.com/ap/oa');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://www.amazon.com/ap/oatoken');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error_description'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error_description'] . '"');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,111 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Bitly extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api-ssl.bitly.com/v3/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://bitly.com/oauth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api-ssl.bitly.com/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
// I'm invincible!!!
$token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
public function requestAccessToken($code, $state = null)
{
if (null !== $state) {
$this->validateAuthorizationState($state);
}
$bodyParams = array(
'code' => $code,
'client_id' => $this->credentials->getConsumerId(),
'client_secret' => $this->credentials->getConsumerSecret(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'grant_type' => 'authorization_code',
);
$responseBody = $this->httpClient->retrieveResponse(
$this->getAccessTokenEndpoint(),
$bodyParams,
$this->getExtraOAuthHeaders()
);
// we can scream what we want that we want bitly to return a json encoded string (format=json), but the
// WOAH WATCH YOUR LANGUAGE ;) service doesn't seem to like screaming, hence we need to manually
// parse the result
$parsedResult = array();
parse_str($responseBody, $parsedResult);
$token = $this->parseAccessTokenResponse(json_encode($parsedResult));
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
}

View File

@ -0,0 +1,118 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Bitrix24 extends AbstractService
{
const SCOPE_DEPARTMENT = 'department';
const SCOPE_CRM = 'crm';
const SCOPE_CALENDAR = 'calendar';
const SCOPE_USER = 'user';
const SCOPE_ENTITY = 'entity';
const SCOPE_TASK = 'task';
const SCOPE_TASKS_EXTENDED = 'tasks_extended';
const SCOPE_IM = 'im';
const SCOPE_LOG = 'log';
const SCOPE_SONET_GROUP = 'sonet_group';
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri(sprintf('%s/oauth/authorize/', $this->baseApiUri));
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri(sprintf('%s/oauth/token/', $this->baseApiUri));
}
/**
* {@inheritdoc}
*/
public function requestAccessToken($code, $state = null)
{
if (null !== $state) {
$this->validateAuthorizationState($state);
}
$responseBody = $this->httpClient->retrieveResponse(
$this->getAccessTokenUri($code),
array(),
$this->getExtraOAuthHeaders(),
'GET'
);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
/**
* {@inheritdoc}
*/
public function getAccessTokenUri($code)
{
$parameters = array(
'code' => $code,
'client_id' => $this->credentials->getConsumerId(),
'client_secret' => $this->credentials->getConsumerSecret(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'grant_type' => 'authorization_code',
'scope' => $this->scopes
);
$parameters['scope'] = implode(' ', $this->scopes);
// Build the url
$url = $this->getAccessTokenEndpoint();
foreach ($parameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifetime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,88 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Box service.
*
* @author Antoine Corcy <contact@sbin.dk>
* @link https://developers.box.com/oauth/
*/
class Box extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.box.com/2.0/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.box.com/api/oauth2/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://www.box.com/api/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,151 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
/**
* Buffer API.
* @author Sumukh Sridhara <@sumukhsridhara>
* @link https://bufferapp.com/developers/api
*/
class Buffer extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if ($baseApiUri === null) {
$this->baseApiUri = new Uri('https://api.bufferapp.com/1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://bufferapp.com/oauth2/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.bufferapp.com/1/oauth2/token.json');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationUri(array $additionalParameters = array())
{
$parameters = array_merge(
$additionalParameters,
array(
'client_id' => $this->credentials->getConsumerId(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'response_type' => 'code',
)
);
// Build the url
$url = clone $this->getAuthorizationEndpoint();
foreach ($parameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
/**
* {@inheritdoc}
*/
public function requestRequestToken()
{
$responseBody = $this->httpClient->retrieveResponse(
$this->getRequestTokenEndpoint(),
array(
'client_key' => $this->credentials->getConsumerId(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'response_type' => 'code',
)
);
$code = $this->parseRequestTokenResponse($responseBody);
return $code;
}
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['code'])) {
throw new TokenResponseException('Error in retrieving code.');
}
return $data['code'];
}
public function requestAccessToken($code)
{
$bodyParams = array(
'client_id' => $this->credentials->getConsumerId(),
'client_secret' => $this->credentials->getConsumerSecret(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'code' => $code,
'grant_type' => 'authorization_code',
);
$responseBody = $this->httpClient->retrieveResponse(
$this->getAccessTokenEndpoint(),
$bodyParams,
$this->getExtraOAuthHeaders()
);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if ($data === null || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,129 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Dailymotion service.
*
* @author Mouhamed SEYE <mouhamed@seye.pro>
* @link http://www.dailymotion.com/doc/api/authentication.html
*/
class Dailymotion extends AbstractService
{
/**
* Scopes
*
* @var string
*/
const SCOPE_EMAIL = 'email',
SCOPE_PROFILE = 'userinfo',
SCOPE_VIDEOS = 'manage_videos',
SCOPE_COMMENTS = 'manage_comments',
SCOPE_PLAYLIST = 'manage_playlists',
SCOPE_TILES = 'manage_tiles',
SCOPE_SUBSCRIPTIONS = 'manage_subscriptions',
SCOPE_FRIENDS = 'manage_friends',
SCOPE_FAVORITES = 'manage_favorites',
SCOPE_GROUPS = 'manage_groups';
/**
* Dialog form factors
*
* @var string
*/
const DISPLAY_PAGE = 'page',
DISPLAY_POPUP = 'popup',
DISPLAY_MOBILE = 'mobile';
/**
* {@inheritdoc}
*/
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.dailymotion.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://api.dailymotion.com/oauth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.dailymotion.com/oauth/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_OAUTH;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error_description']) || isset($data['error'])) {
throw new TokenResponseException(
sprintf(
'Error in retrieving token: "%s"',
isset($data['error_description']) ? $data['error_description'] : $data['error']
)
);
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getExtraOAuthHeaders()
{
return array('Accept' => 'application/json');
}
}

View File

@ -0,0 +1,139 @@
<?php
/**
* Delicious service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://github.com/SciDevs/delicious-api/blob/master/api/oauth.md
*/
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Delicious service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://github.com/SciDevs/delicious-api/blob/master/api/oauth.md
*/
class Delicious extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct(
$credentials,
$httpClient,
$storage,
$scopes,
$baseApiUri,
true
);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.del.icio.us/v1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://delicious.com/auth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://avosapi.delicious.com/api/v1/oauth/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error'] . '"'
);
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
if (isset($data['expires_in'])) {
$token->setLifetime($data['expires_in']);
unset($data['expires_in']);
}
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
// Special, delicious didn't respect the oauth2 RFC and need a grant_type='code'
/**
* {@inheritdoc}
*/
public function requestAccessToken($code, $state = null)
{
if (null !== $state) {
$this->validateAuthorizationState($state);
}
$bodyParams = array(
'code' => $code,
'client_id' => $this->credentials->getConsumerId(),
'client_secret' => $this->credentials->getConsumerSecret(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'grant_type' => 'code',
);
$responseBody = $this->httpClient->retrieveResponse(
$this->getAccessTokenEndpoint(),
$bodyParams,
$this->getExtraOAuthHeaders()
);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\Common\Exception\Exception;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class DeviantArt extends AbstractService
{
/**
* DeviantArt www url - used to build dialog urls
*/
const WWW_URL = 'https://www.deviantart.com/';
/**
* Defined scopes
*
* If you don't think this is scary you should not be allowed on the web at all
*
* @link https://www.deviantart.com/developers/authentication
* @link https://www.deviantart.com/developers/http/v1/20150217
*/
const SCOPE_FEED = 'feed';
const SCOPE_BROWSE = 'browse';
const SCOPE_COMMENT = 'comment.post';
const SCOPE_STASH = 'stash';
const SCOPE_USER = 'user';
const SCOPE_USERMANAGE = 'user.manage';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://www.deviantart.com/api/v1/oauth2/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.deviantart.com/oauth2/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://www.deviantart.com/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
if (isset($data['expires_in'])) {
$token->setLifeTime($data['expires_in']);
}
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,111 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Dropbox service.
*
* @author Flávio Heleno <flaviohbatista@gmail.com>
* @link https://www.dropbox.com/developers/core/docs
*/
class Dropbox extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.dropbox.com/1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationUri(array $additionalParameters = array())
{
$parameters = array_merge(
$additionalParameters,
array(
'client_id' => $this->credentials->getConsumerId(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'response_type' => 'code',
)
);
$parameters['scope'] = implode(' ', $this->scopes);
// Build the url
$url = clone $this->getAuthorizationEndpoint();
foreach ($parameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.dropbox.com/1/oauth2/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.dropbox.com/1/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,100 @@
<?php
/**
* Contains EveOnline class.
* PHP version 5.4
* @copyright 2014 Michael Cummings
* @author Michael Cummings <mgcummings@yahoo.com>
*/
namespace OAuth\OAuth2\Service;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Token\TokenInterface;
use OAuth\OAuth2\Token\StdOAuth2Token;
/**
* Class EveOnline
*/
class EveOnline extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://login.eveonline.com');
}
}
/**
* Returns the authorization API endpoint.
* @return UriInterface
*/
public function getAuthorizationEndpoint()
{
return new Uri($this->baseApiUri . '/oauth/authorize');
}
/**
* Returns the access token API endpoint.
* @return UriInterface
*/
public function getAccessTokenEndpoint()
{
return new Uri($this->baseApiUri . '/oauth/token');
}
/**
* Parses the access token response and returns a TokenInterface.
*
* @param string $responseBody
*
* @return TokenInterface
* @throws TokenResponseException
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error_description'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error_description'] . '"');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace OAuth\OAuth2\Service\Exception;
use OAuth\Common\Exception\Exception;
/**
* Exception thrown when an invalid accessType for the Google Service is specified
*/
class InvalidAccessTypeException extends Exception
{
}

View File

@ -0,0 +1,10 @@
<?php
namespace OAuth\OAuth2\Service\Exception;
/**
* Exception thrown when the state parameter received during the authorization process is invalid.
*/
class InvalidAuthorizationStateException extends \Exception
{
}

View File

@ -0,0 +1,17 @@
<?php
/**
* @author David Desberg <david@daviddesberg.com>
* Released under the MIT license.
*/
namespace OAuth\OAuth2\Service\Exception;
use OAuth\Common\Exception\Exception;
/**
* Exception thrown when a scope provided to a service is invalid.
*/
class InvalidScopeException extends Exception
{
}

View File

@ -0,0 +1,17 @@
<?php
/**
* @author David Desberg <david@daviddesberg.com>
* Released under the MIT license.
*/
namespace OAuth\OAuth2\Service\Exception;
use OAuth\Common\Exception\Exception;
/**
* Exception thrown when service is requested to refresh the access token but no refresh token can be found.
*/
class MissingRefreshTokenException extends Exception
{
}

View File

@ -0,0 +1,208 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\Common\Exception\Exception;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Facebook extends AbstractService
{
/**
* Facebook www url - used to build dialog urls
*/
const WWW_URL = 'https://www.facebook.com/';
/**
* Defined scopes
*
* If you don't think this is scary you should not be allowed on the web at all
*
* @link https://developers.facebook.com/docs/reference/login/
* @link https://developers.facebook.com/tools/explorer For a list of permissions use 'Get Access Token'
*/
// Default scope
const SCOPE_PUBLIC_PROFILE = 'public_profile';
// Email scopes
const SCOPE_EMAIL = 'email';
// Extended permissions
const SCOPE_READ_FRIENDLIST = 'read_friendlists';
const SCOPE_READ_INSIGHTS = 'read_insights';
const SCOPE_READ_MAILBOX = 'read_mailbox';
const SCOPE_READ_PAGE_MAILBOXES = 'read_page_mailboxes';
const SCOPE_READ_REQUESTS = 'read_requests';
const SCOPE_READ_STREAM = 'read_stream';
const SCOPE_VIDEO_UPLOAD = 'video_upload';
const SCOPE_XMPP_LOGIN = 'xmpp_login';
const SCOPE_USER_ONLINE_PRESENCE = 'user_online_presence';
const SCOPE_FRIENDS_ONLINE_PRESENCE = 'friends_online_presence';
const SCOPE_ADS_MANAGEMENT = 'ads_management';
const SCOPE_ADS_READ = 'ads_read';
const SCOPE_CREATE_EVENT = 'create_event';
const SCOPE_CREATE_NOTE = 'create_note';
const SCOPE_EXPORT_STREAM = 'export_stream';
const SCOPE_MANAGE_FRIENDLIST = 'manage_friendlists';
const SCOPE_MANAGE_NOTIFICATIONS = 'manage_notifications';
const SCOPE_PHOTO_UPLOAD = 'photo_upload';
const SCOPE_PUBLISH_ACTIONS = 'publish_actions';
const SCOPE_PUBLISH_CHECKINS = 'publish_checkins';
const SCOPE_PUBLISH_STREAM = 'publish_stream';
const SCOPE_RSVP_EVENT = 'rsvp_event';
const SCOPE_SHARE_ITEM = 'share_item';
const SCOPE_SMS = 'sms';
const SCOPE_STATUS_UPDATE = 'status_update';
// Extended Profile Properties
const SCOPE_USER_POSTS = 'user_posts';
const SCOPE_USER_FRIENDS = 'user_friends';
const SCOPE_USER_ABOUT = 'user_about_me';
const SCOPE_USER_TAGGED_PLACES = 'user_tagged_places';
const SCOPE_FRIENDS_ABOUT = 'friends_about_me';
const SCOPE_USER_ACTIVITIES = 'user_activities';
const SCOPE_FRIENDS_ACTIVITIES = 'friends_activities';
const SCOPE_USER_BIRTHDAY = 'user_birthday';
const SCOPE_FRIENDS_BIRTHDAY = 'friends_birthday';
const SCOPE_USER_CHECKINS = 'user_checkins';
const SCOPE_FRIENDS_CHECKINS = 'friends_checkins';
const SCOPE_USER_EDUCATION = 'user_education_history';
const SCOPE_FRIENDS_EDUCATION = 'friends_education_history';
const SCOPE_USER_EVENTS = 'user_events';
const SCOPE_FRIENDS_EVENTS = 'friends_events';
const SCOPE_USER_GROUPS = 'user_groups';
const SCOPE_USER_MANAGED_GROUPS = 'user_managed_groups';
const SCOPE_FRIENDS_GROUPS = 'friends_groups';
const SCOPE_USER_HOMETOWN = 'user_hometown';
const SCOPE_FRIENDS_HOMETOWN = 'friends_hometown';
const SCOPE_USER_INTERESTS = 'user_interests';
const SCOPE_FRIEND_INTERESTS = 'friends_interests';
const SCOPE_USER_LIKES = 'user_likes';
const SCOPE_FRIENDS_LIKES = 'friends_likes';
const SCOPE_USER_LOCATION = 'user_location';
const SCOPE_FRIENDS_LOCATION = 'friends_location';
const SCOPE_USER_NOTES = 'user_notes';
const SCOPE_FRIENDS_NOTES = 'friends_notes';
const SCOPE_USER_PHOTOS = 'user_photos';
const SCOPE_USER_PHOTO_VIDEO_TAGS = 'user_photo_video_tags';
const SCOPE_FRIENDS_PHOTOS = 'friends_photos';
const SCOPE_FRIENDS_PHOTO_VIDEO_TAGS = 'friends_photo_video_tags';
const SCOPE_USER_QUESTIONS = 'user_questions';
const SCOPE_FRIENDS_QUESTIONS = 'friends_questions';
const SCOPE_USER_RELATIONSHIPS = 'user_relationships';
const SCOPE_FRIENDS_RELATIONSHIPS = 'friends_relationships';
const SCOPE_USER_RELATIONSHIPS_DETAILS = 'user_relationship_details';
const SCOPE_FRIENDS_RELATIONSHIPS_DETAILS = 'friends_relationship_details';
const SCOPE_USER_RELIGION = 'user_religion_politics';
const SCOPE_FRIENDS_RELIGION = 'friends_religion_politics';
const SCOPE_USER_STATUS = 'user_status';
const SCOPE_FRIENDS_STATUS = 'friends_status';
const SCOPE_USER_SUBSCRIPTIONS = 'user_subscriptions';
const SCOPE_FRIENDS_SUBSCRIPTIONS = 'friends_subscriptions';
const SCOPE_USER_VIDEOS = 'user_videos';
const SCOPE_FRIENDS_VIDEOS = 'friends_videos';
const SCOPE_USER_WEBSITE = 'user_website';
const SCOPE_FRIENDS_WEBSITE = 'friends_website';
const SCOPE_USER_WORK = 'user_work_history';
const SCOPE_FRIENDS_WORK = 'friends_work_history';
// Open Graph Permissions
const SCOPE_USER_MUSIC = 'user_actions.music';
const SCOPE_FRIENDS_MUSIC = 'friends_actions.music';
const SCOPE_USER_NEWS = 'user_actions.news';
const SCOPE_FRIENDS_NEWS = 'friends_actions.news';
const SCOPE_USER_VIDEO = 'user_actions.video';
const SCOPE_FRIENDS_VIDEO = 'friends_actions.video';
const SCOPE_USER_APP = 'user_actions:APP_NAMESPACE';
const SCOPE_FRIENDS_APP = 'friends_actions:APP_NAMESPACE';
const SCOPE_USER_GAMES = 'user_games_activity';
const SCOPE_FRIENDS_GAMES = 'friends_games_activity';
//Page Permissions
const SCOPE_PAGES = 'manage_pages';
const SCOPE_PUBLISH_PAGES = 'publish_pages';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null,
$apiVersion = ""
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true, $apiVersion);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://graph.facebook.com'.$this->getApiVersionString().'/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.facebook.com'.$this->getApiVersionString().'/dialog/oauth');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://graph.facebook.com'.$this->getApiVersionString().'/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
// Facebook gives us a query string ... Oh wait. JSON is too simple, understand ?
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
if (isset($data['expires'])) {
$token->setLifeTime($data['expires']);
}
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires']);
$token->setExtraParams($data);
return $token;
}
public function getDialogUri($dialogPath, array $parameters)
{
if (!isset($parameters['redirect_uri'])) {
throw new Exception("Redirect uri is mandatory for this request");
}
$parameters['app_id'] = $this->credentials->getConsumerId();
$baseUrl = self::WWW_URL .$this->getApiVersionString(). '/dialog/' . $dialogPath;
$query = http_build_query($parameters);
return new Uri($baseUrl . '?' . $query);
}
/**
* {@inheritdoc}
*/
protected function getScopesDelimiter()
{
return ',';
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Foursquare extends AbstractService
{
private $apiVersionDate = '20130829';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.foursquare.com/v2/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://foursquare.com/oauth2/authenticate');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://foursquare.com/oauth2/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
// Foursquare tokens evidently never expire...
$token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
public function request($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
$uri = $this->determineRequestUriFromPath($path, $this->baseApiUri);
$uri->addToQuery('v', $this->apiVersionDate);
return parent::request($uri, $method, $body, $extraHeaders);
}
}

View File

@ -0,0 +1,216 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class GitHub extends AbstractService
{
/**
* Defined scopes, see http://developer.github.com/v3/oauth/ for definitions.
*/
/**
* Public read-only access (includes public user profile info, public repo info, and gists)
*/
const SCOPE_READONLY = '';
/**
* Read/write access to profile info only.
*
* Includes SCOPE_USER_EMAIL and SCOPE_USER_FOLLOW.
*/
const SCOPE_USER = 'user';
/**
* Read access to a users email addresses.
*/
const SCOPE_USER_EMAIL = 'user:email';
/**
* Access to follow or unfollow other users.
*/
const SCOPE_USER_FOLLOW = 'user:follow';
/**
* Read/write access to public repos and organizations.
*/
const SCOPE_PUBLIC_REPO = 'public_repo';
/**
* Read/write access to public and private repos and organizations.
*
* Includes SCOPE_REPO_STATUS.
*/
const SCOPE_REPO = 'repo';
/**
* Grants access to deployment statuses for public and private repositories.
* This scope is only necessary to grant other users or services access to deployment statuses,
* without granting access to the code.
*/
const SCOPE_REPO_DEPLOYMENT = 'repo_deployment';
/**
* Read/write access to public and private repository commit statuses. This scope is only necessary to grant other
* users or services access to private repository commit statuses without granting access to the code. The repo and
* public_repo scopes already include access to commit status for private and public repositories, respectively.
*/
const SCOPE_REPO_STATUS = 'repo:status';
/**
* Delete access to adminable repositories.
*/
const SCOPE_DELETE_REPO = 'delete_repo';
/**
* Read access to a users notifications. repo is accepted too.
*/
const SCOPE_NOTIFICATIONS = 'notifications';
/**
* Write access to gists.
*/
const SCOPE_GIST = 'gist';
/**
* Grants read and ping access to hooks in public or private repositories.
*/
const SCOPE_HOOKS_READ = 'read:repo_hook';
/**
* Grants read, write, and ping access to hooks in public or private repositories.
*/
const SCOPE_HOOKS_WRITE = 'write:repo_hook';
/**
* Grants read, write, ping, and delete access to hooks in public or private repositories.
*/
const SCOPE_HOOKS_ADMIN = 'admin:repo_hook';
/**
* Read-only access to organization, teams, and membership.
*/
const SCOPE_ORG_READ = 'read:org';
/**
* Publicize and unpublicize organization membership.
*/
const SCOPE_ORG_WRITE = 'write:org';
/**
* Fully manage organization, teams, and memberships.
*/
const SCOPE_ORG_ADMIN = 'admin:org';
/**
* List and view details for public keys.
*/
const SCOPE_PUBLIC_KEY_READ = 'read:public_key';
/**
* Create, list, and view details for public keys.
*/
const SCOPE_PUBLIC_KEY_WRITE = 'write:public_key';
/**
* Fully manage public keys.
*/
const SCOPE_PUBLIC_KEY_ADMIN = 'admin:public_key';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.github.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://github.com/login/oauth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://github.com/login/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
// Github tokens evidently never expire...
$token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
/**
* Used to configure response type -- we want JSON from github, default is query string format
*
* @return array
*/
protected function getExtraOAuthHeaders()
{
return array('Accept' => 'application/json');
}
/**
* Required for GitHub API calls.
*
* @return array
*/
protected function getExtraApiHeaders()
{
return array('Accept' => 'application/vnd.github.beta+json');
}
/**
* {@inheritdoc}
*/
protected function getScopesDelimiter()
{
return ',';
}
}

View File

@ -0,0 +1,188 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\OAuth2\Service\Exception\InvalidAccessTypeException;
use OAuth\Common\Http\Uri\Uri;
class Google extends AbstractService
{
/**
* Defined scopes - More scopes are listed here:
* https://developers.google.com/oauthplayground/
*
* Make a pull request if you need more scopes.
*/
// Basic
const SCOPE_EMAIL = 'email';
const SCOPE_PROFILE = 'profile';
const SCOPE_USERINFO_EMAIL = 'https://www.googleapis.com/auth/userinfo.email';
const SCOPE_USERINFO_PROFILE = 'https://www.googleapis.com/auth/userinfo.profile';
// Google+
const SCOPE_GPLUS_ME = 'https://www.googleapis.com/auth/plus.me';
const SCOPE_GPLUS_LOGIN = 'https://www.googleapis.com/auth/plus.login';
const SCOPE_GPLUS_CIRCLES_READ = 'https://www.googleapis.com/auth/plus.circles.read';
const SCOPE_GPLUS_CIRCLES_WRITE = 'https://www.googleapis.com/auth/plus.circles.write';
const SCOPE_GPLUS_STREAM_READ = 'https://www.googleapis.com/auth/plus.stream.read';
const SCOPE_GPLUS_STREAM_WRITE = 'https://www.googleapis.com/auth/plus.stream.write';
const SCOPE_GPLUS_MEDIA = 'https://www.googleapis.com/auth/plus.media.upload';
// Google Drive
const SCOPE_DOCUMENTSLIST = 'https://docs.google.com/feeds/';
const SCOPE_SPREADSHEETS = 'https://spreadsheets.google.com/feeds/';
const SCOPE_GOOGLEDRIVE = 'https://www.googleapis.com/auth/drive';
const SCOPE_DRIVE_APPS = 'https://www.googleapis.com/auth/drive.appdata';
const SCOPE_DRIVE_APPS_READ_ONLY = 'https://www.googleapis.com/auth/drive.apps.readonly';
const SCOPE_GOOGLEDRIVE_FILES = 'https://www.googleapis.com/auth/drive.file';
const SCOPE_DRIVE_METADATA_READ_ONLY = 'https://www.googleapis.com/auth/drive.metadata.readonly';
const SCOPE_DRIVE_READ_ONLY = 'https://www.googleapis.com/auth/drive.readonly';
const SCOPE_DRIVE_SCRIPTS = 'https://www.googleapis.com/auth/drive.scripts';
// Cloud Print
const SCOPE_CLOUD_PRINT = 'https://www.googleapis.com/auth/cloudprint';
// Adwords
const SCOPE_ADSENSE = 'https://www.googleapis.com/auth/adsense';
const SCOPE_ADWORDS = 'https://www.googleapis.com/auth/adwords/';
const SCOPE_GAN = 'https://www.googleapis.com/auth/gan'; // google affiliate network...?
// Google Analytics
const SCOPE_ANALYTICS = 'https://www.googleapis.com/auth/analytics';
const SCOPE_ANALYTICS_EDIT = 'https://www.googleapis.com/auth/analytics.edit';
const SCOPE_ANALYTICS_MANAGE_USERS = 'https://www.googleapis.com/auth/analytics.manage.users';
const SCOPE_ANALYTICS_READ_ONLY = 'https://www.googleapis.com/auth/analytics.readonly';
//Gmail
const SCOPE_GMAIL_MODIFY = 'https://www.googleapis.com/auth/gmail.modify';
const SCOPE_GMAIL_READONLY = 'https://www.googleapis.com/auth/gmail.readonly';
const SCOPE_GMAIL_COMPOSE = 'https://www.googleapis.com/auth/gmail.compose';
const SCOPE_GMAIL_SEND = 'https://www.googleapis.com/auth/gmail.send';
const SCOPE_GMAIL_INSERT = 'https://www.googleapis.com/auth/gmail.insert';
const SCOPE_GMAIL_LABELS = 'https://www.googleapis.com/auth/gmail.labels';
const SCOPE_GMAIL_FULL = 'https://mail.google.com/';
// Other services
const SCOPE_BOOKS = 'https://www.googleapis.com/auth/books';
const SCOPE_BLOGGER = 'https://www.googleapis.com/auth/blogger';
const SCOPE_CALENDAR = 'https://www.googleapis.com/auth/calendar';
const SCOPE_CALENDAR_READ_ONLY = 'https://www.googleapis.com/auth/calendar.readonly';
const SCOPE_CONTACT = 'https://www.google.com/m8/feeds/';
const SCOPE_CONTACTS_RO = 'https://www.googleapis.com/auth/contacts.readonly';
const SCOPE_CHROMEWEBSTORE = 'https://www.googleapis.com/auth/chromewebstore.readonly';
const SCOPE_GMAIL = 'https://mail.google.com/mail/feed/atom';
const SCOPE_GMAIL_IMAP_SMTP = 'https://mail.google.com';
const SCOPE_PICASAWEB = 'https://picasaweb.google.com/data/';
const SCOPE_SITES = 'https://sites.google.com/feeds/';
const SCOPE_URLSHORTENER = 'https://www.googleapis.com/auth/urlshortener';
const SCOPE_WEBMASTERTOOLS = 'https://www.google.com/webmasters/tools/feeds/';
const SCOPE_TASKS = 'https://www.googleapis.com/auth/tasks';
// Cloud services
const SCOPE_CLOUDSTORAGE = 'https://www.googleapis.com/auth/devstorage.read_write';
const SCOPE_CONTENTFORSHOPPING = 'https://www.googleapis.com/auth/structuredcontent'; // what even is this
const SCOPE_USER_PROVISIONING = 'https://apps-apis.google.com/a/feeds/user/';
const SCOPE_GROUPS_PROVISIONING = 'https://apps-apis.google.com/a/feeds/groups/';
const SCOPE_NICKNAME_PROVISIONING = 'https://apps-apis.google.com/a/feeds/alias/';
// Old
const SCOPE_ORKUT = 'https://www.googleapis.com/auth/orkut';
const SCOPE_GOOGLELATITUDE =
'https://www.googleapis.com/auth/latitude.all.best https://www.googleapis.com/auth/latitude.all.city';
const SCOPE_OPENID = 'openid';
// YouTube
const SCOPE_YOUTUBE_GDATA = 'https://gdata.youtube.com';
const SCOPE_YOUTUBE_ANALYTICS_MONETARY = 'https://www.googleapis.com/auth/yt-analytics-monetary.readonly';
const SCOPE_YOUTUBE_ANALYTICS = 'https://www.googleapis.com/auth/yt-analytics.readonly';
const SCOPE_YOUTUBE = 'https://www.googleapis.com/auth/youtube';
const SCOPE_YOUTUBE_READ_ONLY = 'https://www.googleapis.com/auth/youtube.readonly';
const SCOPE_YOUTUBE_UPLOAD = 'https://www.googleapis.com/auth/youtube.upload';
const SCOPE_YOUTUBE_PARTNER = 'https://www.googleapis.com/auth/youtubepartner';
const SCOPE_YOUTUBE_PARTNER_AUDIT = 'https://www.googleapis.com/auth/youtubepartner-channel-audit';
// Google Glass
const SCOPE_GLASS_TIMELINE = 'https://www.googleapis.com/auth/glass.timeline';
const SCOPE_GLASS_LOCATION = 'https://www.googleapis.com/auth/glass.location';
// Android Publisher
const SCOPE_ANDROID_PUBLISHER = 'https://www.googleapis.com/auth/androidpublisher';
protected $accessType = 'online';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://www.googleapis.com/oauth2/v1/');
}
}
public function setAccessType($accessType)
{
if (!in_array($accessType, array('online', 'offline'), true)) {
throw new InvalidAccessTypeException('Invalid accessType, expected either online or offline');
}
$this->accessType = $accessType;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://accounts.google.com/o/oauth2/auth?access_type=' . $this->accessType);
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://accounts.google.com/o/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifetime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,157 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Token\TokenInterface;
use OAuth\OAuth2\Token\StdOAuth2Token;
class Harvest extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.harvestapp.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationUri(array $additionalParameters = array())
{
$parameters = array_merge(
$additionalParameters,
array(
'client_id' => $this->credentials->getConsumerId(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'state' => 'optional-csrf-token',
'response_type' => 'code',
)
);
// Build the url
$url = clone $this->getAuthorizationEndpoint();
foreach ($parameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://api.harvestapp.com/oauth2/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.harvestapp.com/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || ! is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifetime($data['expires_in']);
$token->setRefreshToken($data['refresh_token']);
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
/**
* Refreshes an OAuth2 access token.
*
* @param TokenInterface $token
*
* @return TokenInterface $token
*
* @throws MissingRefreshTokenException
*/
public function refreshAccessToken(TokenInterface $token)
{
$refreshToken = $token->getRefreshToken();
if (empty($refreshToken)) {
throw new MissingRefreshTokenException();
}
$parameters = array(
'grant_type' => 'refresh_token',
'type' => 'web_server',
'client_id' => $this->credentials->getConsumerId(),
'client_secret' => $this->credentials->getConsumerSecret(),
'refresh_token' => $refreshToken,
);
$responseBody = $this->httpClient->retrieveResponse(
$this->getAccessTokenEndpoint(),
$parameters,
$this->getExtraOAuthHeaders()
);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
/**
* @return array
*/
protected function getExtraOAuthHeaders()
{
return array('Accept' => 'application/json');
}
/**
* Return any additional headers always needed for this service implementation's API calls.
*
* @return array
*/
protected function getExtraApiHeaders()
{
return array('Accept' => 'application/json');
}
}

View File

@ -0,0 +1,123 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Heroku service.
*
* @author Thomas Welton <thomaswelton@me.com>
* @link https://devcenter.heroku.com/articles/oauth
*/
class Heroku extends AbstractService
{
/**
* Defined scopes
* @link https://devcenter.heroku.com/articles/oauth#scopes
*/
const SCOPE_GLOBAL = 'global';
const SCOPE_IDENTITY = 'identity';
const SCOPE_READ = 'read';
const SCOPE_WRITE = 'write';
const SCOPE_READ_PROTECTED = 'read-protected';
const SCOPE_WRITE_PROTECTED = 'write-protected';
/**
* {@inheritdoc}
*/
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.heroku.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://id.heroku.com/oauth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://id.heroku.com/oauth/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error_description']) || isset($data['error'])) {
throw new TokenResponseException(
sprintf(
'Error in retrieving token: "%s"',
isset($data['error_description']) ? $data['error_description'] : $data['error']
)
);
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getExtraOAuthHeaders()
{
return array('Accept' => 'application/vnd.heroku+json; version=3');
}
/**
* {@inheritdoc}
*/
protected function getExtraApiHeaders()
{
return array('Accept' => 'application/vnd.heroku+json; version=3', 'Content-Type' => 'application/json');
}
}

View File

@ -0,0 +1,155 @@
<?php
/**
* Hubic service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://api.hubic.com/docs/
*/
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Hubic service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://api.hubic.com/docs/
*/
class Hubic extends AbstractService
{
// Scopes
const SCOPE_USAGE_GET = 'usage.r';
const SCOPE_ACCOUNT_GET = 'account.r';
const SCOPE_GETALLLINKS_GET = 'getAllLinks.r';
const SCOPE_CREDENTIALS_GET = 'credentials.r';
const SCOPE_SPONSORCODE_GET = 'sponsorCode.r';
const SCOPE_ACTIVATE_POST = 'activate.w';
const SCOPE_SPONSORED_GET = 'sponsored.r';
const SCOPE_LINKS_GET = 'links.r';
const SCOPE_LINKS_POST = 'links.rw';
const SCOPE_LINKS_ALL = 'links.drw';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct(
$credentials,
$httpClient,
$storage,
$scopes,
$baseApiUri,
true
);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.hubic.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://api.hubic.com/oauth/auth');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.hubic.com/oauth/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error'] . '"'
);
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifetime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationUri(array $additionalParameters = array())
{
$parameters = array_merge(
$additionalParameters,
array(
'type' => 'web_server',
'client_id' => $this->credentials->getConsumerId(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'response_type' => 'code',
)
);
// special, hubic use a param scope with commas
// between scopes instead of spaces
$parameters['scope'] = implode(',', $this->scopes);
if ($this->needsStateParameterInAuthUrl()) {
if (!isset($parameters['state'])) {
$parameters['state'] = $this->generateAuthorizationState();
}
$this->storeAuthorizationState($parameters['state']);
}
// Build the url
$url = clone $this->getAuthorizationEndpoint();
foreach ($parameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
}

View File

@ -0,0 +1,85 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Instagram extends AbstractService
{
/**
* Defined scopes
* @link http://instagram.com/developer/authentication/#scope
*/
const SCOPE_BASIC = 'basic';
const SCOPE_COMMENTS = 'comments';
const SCOPE_RELATIONSHIPS = 'relationships';
const SCOPE_LIKES = 'likes';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.instagram.com/v1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://api.instagram.com/oauth/authorize/');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.instagram.com/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
// Instagram tokens evidently never expire...
$token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,144 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Jawbone UP service.
*
* @author Andrii Gakhov <andrii.gakhov@gmail.com>
* @link https://jawbone.com/up/developer/authentication
*/
class JawboneUP extends AbstractService
{
/**
* Defined scopes
*
*
* @link https://jawbone.com/up/developer/authentication
*/
// general information scopes
const SCOPE_BASIC_READ = 'basic_read';
const SCOPE_EXTENDED_READ = 'extended_read';
const SCOPE_LOCATION_READ = 'location_read';
const SCOPE_FRIENDS_READ = 'friends_read';
// mood scopes
const SCOPE_MOOD_READ = 'mood_read';
const SCOPE_MOOD_WRITE = 'mood_write';
// move scopes
const SCOPE_MOVE_READ = 'move_read';
const SCOPE_MOVE_WRITE = 'move_write';
// sleep scopes
const SCOPE_SLEEP_READ = 'sleep_read';
const SCOPE_SLEEP_WRITE = 'sleep_write';
// meal scopes
const SCOPE_MEAL_READ = 'meal_read';
const SCOPE_MEAL_WRITE = 'meal_write';
// weight scopes
const SCOPE_WEIGHT_READ = 'weight_read';
const SCOPE_WEIGHT_WRITE = 'weight_write';
// generic event scopes
const SCOPE_GENERIC_EVENT_READ = 'generic_event_read';
const SCOPE_GENERIC_EVENT_WRITE = 'generic_event_write';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://jawbone.com/nudge/api/v.1.1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationUri(array $additionalParameters = array())
{
$parameters = array_merge(
$additionalParameters,
array(
'client_id' => $this->credentials->getConsumerId(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'response_type' => 'code',
)
);
$parameters['scope'] = implode(' ', $this->scopes);
// Build the url
$url = clone $this->getAuthorizationEndpoint();
foreach ($parameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://jawbone.com/auth/oauth2/auth');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://jawbone.com/auth/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,103 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Linkedin service.
*
* @author Antoine Corcy <contact@sbin.dk>
* @link http://developer.linkedin.com/documents/authentication
*/
class Linkedin extends AbstractService
{
/**
* Defined scopes
* @link http://developer.linkedin.com/documents/authentication#granting
*/
const SCOPE_R_BASICPROFILE = 'r_basicprofile';
const SCOPE_R_FULLPROFILE = 'r_fullprofile';
const SCOPE_R_EMAILADDRESS = 'r_emailaddress';
const SCOPE_R_NETWORK = 'r_network';
const SCOPE_R_CONTACTINFO = 'r_contactinfo';
const SCOPE_RW_NUS = 'rw_nus';
const SCOPE_RW_COMPANY_ADMIN = 'rw_company_admin';
const SCOPE_RW_GROUPS = 'rw_groups';
const SCOPE_W_MESSAGES = 'w_messages';
const SCOPE_W_SHARE = 'w_share';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.linkedin.com/v1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.linkedin.com/uas/oauth2/authorization');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://www.linkedin.com/uas/oauth2/accessToken');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING_V2;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,114 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Mailchimp extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (is_null($this->baseApiUri) && $storage->hasAccessToken($this->service())) {
$this->setBaseApiUri($storage->retrieveAccessToken($this->service()));
}
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING_V3;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://login.mailchimp.com/oauth2/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://login.mailchimp.com/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
// Parse JSON
$data = json_decode($responseBody, true);
// Do validation.
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
// Create token object.
$token = new StdOAuth2Token($data['access_token']);
// Set the right API endpoint.
$this->setBaseApiUri($token);
// Mailchimp tokens evidently never expire...
$token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
return $token;
}
/**
* {@inheritdoc}
*/
public function request($path, $method = 'GET', $body = null, array $extraHeaders = array())
{
if (is_null($this->baseApiUri)) {
$this->setBaseApiUri($this->storage->retrieveAccessToken($this->service()));
}
return parent::request($path, $method, $body, $extraHeaders);
}
/**
* Set the right base endpoint.
*
* @param StdOAuth2Token $token
*/
protected function setBaseApiUri(StdOAuth2Token $token)
{
// Make request uri.
$endpoint = 'https://login.mailchimp.com/oauth2/metadata?oauth_token='. $token->getAccessToken();
// Grab meta data about the token.
$response = $this->httpClient->retrieveResponse(new Uri($endpoint), array(), array(), 'GET');
// Parse JSON.
$meta = json_decode($response, true);
// Set base api uri.
$this->baseApiUri = new Uri('https://'. $meta['dc'] .'.api.mailchimp.com/2.0/');
// Allow chaining.
return $this;
}
}

View File

@ -0,0 +1,120 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Microsoft extends AbstractService
{
const SCOPE_BASIC = 'wl.basic';
const SCOPE_OFFLINE = 'wl.offline_access';
const SCOPE_SIGNIN = 'wl.signin';
const SCOPE_BIRTHDAY = 'wl.birthday';
const SCOPE_CALENDARS = 'wl.calendars';
const SCOPE_CALENDARS_UPDATE = 'wl.calendars_update';
const SCOPE_CONTACTS_BIRTHDAY = 'wl.contacts_birthday';
const SCOPE_CONTACTS_CREATE = 'wl.contacts_create';
const SCOPE_CONTACTS_CALENDARS = 'wl.contacts_calendars';
const SCOPE_CONTACTS_PHOTOS = 'wl.contacts_photos';
const SCOPE_CONTACTS_SKYDRIVE = 'wl.contacts_skydrive';
const SCOPE_EMAILS = 'wl.emails';
const SCOPE_EVENTS_CREATE = 'wl.events_create';
const SCOPE_MESSENGER = 'wl.messenger';
const SCOPE_PHONE_NUMBERS = 'wl.phone_numbers';
const SCOPE_PHOTOS = 'wl.photos';
const SCOPE_POSTAL_ADDRESSES = 'wl.postal_addresses';
const SCOPE_SHARE = 'wl.share';
const SCOPE_SKYDRIVE = 'wl.skydrive';
const SCOPE_SKYDRIVE_UPDATE = 'wl.skydrive_update';
const SCOPE_WORK_PROFILE = 'wl.work_profile';
const SCOPE_APPLICATIONS = 'wl.applications';
const SCOPE_APPLICATIONS_CREATE = 'wl.applications_create';
const SCOPE_IMAP = 'wl.imap';
/**
* MS uses some magical not officialy supported scope to get even moar info like full emailaddresses.
* They agree that giving 3rd party apps access to 3rd party emailaddresses is a pretty lame thing to do so in all
* their wisdom they added this scope because fuck you that's why.
*
* https://github.com/Lusitanian/PHPoAuthLib/issues/214
* http://social.msdn.microsoft.com/Forums/live/en-US/c6dcb9ab-aed4-400a-99fb-5650c393a95d/how-retrieve-users-
* contacts-email-address?forum=messengerconnect
*
* Considering this scope is not officially supported: use with care
*/
const SCOPE_CONTACTS_EMAILS = 'wl.contacts_emails';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://apis.live.net/v5.0/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://login.live.com/oauth20_authorize.srf');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://login.live.com/oauth20_token.srf');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifetime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* Nest service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://developer.nest.com/documentation
*/
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Nest service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://developer.nest.com/documentation
*/
class Nest extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct(
$credentials,
$httpClient,
$storage,
$scopes,
$baseApiUri,
true
);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://developer-api.nest.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://home.nest.com/login/oauth2');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.home.nest.com/oauth2/access_token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING_V4;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error'] . '"'
);
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,117 @@
<?php
/**
* Netatmo service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://dev.netatmo.com/doc/
*/
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Netatmo service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://dev.netatmo.com/doc/
*/
class Netatmo extends AbstractService
{
// SCOPES
// @link https://dev.netatmo.com/doc/authentication/scopes
// Used to read weather station's data (devicelist, getmeasure)
const SCOPE_STATION_READ = 'read_station';
// Used to read thermostat's data (devicelist, getmeasure, getthermstate)
const SCOPE_THERMOSTAT_READ = 'read_thermostat';
// Used to configure the thermostat (syncschedule, setthermpoint)
const SCOPE_THERMOSTAT_WRITE = 'write_thermostat';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct(
$credentials,
$httpClient,
$storage,
$scopes,
$baseApiUri,
true // use parameter state
);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.netatmo.net/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri($this->baseApiUri.'oauth2/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri($this->baseApiUri.'oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error'] . '"'
);
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifetime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,142 @@
<?php
/**
* ParrotFlowerPower service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://flowerpowerdev.parrot.com/projects/flower-power-web-service-api/wiki
*/
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\OAuth2\Service\Exception\MissingRefreshTokenException;
use OAuth\Common\Token\TokenInterface;
/**
* ParrotFlowerPower service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://flowerpowerdev.parrot.com/projects/flower-power-web-service-api/wiki
*/
class ParrotFlowerPower extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct(
$credentials,
$httpClient,
$storage,
$scopes,
$baseApiUri,
true
);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://apiflowerpower.parrot.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri($this->baseApiUri.'oauth2/v1/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri($this->baseApiUri.'user/v1/authenticate');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error'] . '"'
);
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifetime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
/**
* Parrot use a different endpoint for refresh a token
*
* {@inheritdoc}
*/
public function refreshAccessToken(TokenInterface $token)
{
$refreshToken = $token->getRefreshToken();
if (empty($refreshToken)) {
throw new MissingRefreshTokenException();
}
$parameters = array(
'grant_type' => 'refresh_token',
'type' => 'web_server',
'client_id' => $this->credentials->getConsumerId(),
'client_secret' => $this->credentials->getConsumerSecret(),
'refresh_token' => $refreshToken,
);
$responseBody = $this->httpClient->retrieveResponse(
new Uri($this->baseApiUri.'user/v1/refresh'),
$parameters,
$this->getExtraOAuthHeaders()
);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
}

View File

@ -0,0 +1,103 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* PayPal service.
*
* @author Flávio Heleno <flaviohbatista@gmail.com>
* @link https://developer.paypal.com/webapps/developer/docs/integration/direct/log-in-with-paypal/detailed/
*/
class Paypal extends AbstractService
{
/**
* Defined scopes
* @link https://developer.paypal.com/webapps/developer/docs/integration/direct/log-in-with-paypal/detailed/
* @see #attributes
*/
const SCOPE_OPENID = 'openid';
const SCOPE_PROFILE = 'profile';
const SCOPE_PAYPALATTRIBUTES = 'https://uri.paypal.com/services/paypalattributes';
const SCOPE_EMAIL = 'email';
const SCOPE_ADDRESS = 'address';
const SCOPE_PHONE = 'phone';
const SCOPE_EXPRESSCHECKOUT = 'https://uri.paypal.com/services/expresscheckout';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.paypal.com/v1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.paypal.com/v1/identity/openidconnect/tokenservice');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['message'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['message'] . '"');
} elseif (isset($data['name'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['name'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,125 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Client\ClientInterface;
class Pocket extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if ($baseApiUri === null) {
$this->baseApiUri = new Uri('https://getpocket.com/v3/');
}
}
public function getRequestTokenEndpoint()
{
return new Uri('https://getpocket.com/v3/oauth/request');
}
public function getAuthorizationEndpoint()
{
return new Uri('https://getpocket.com/auth/authorize');
}
public function getAccessTokenEndpoint()
{
return new Uri('https://getpocket.com/v3/oauth/authorize');
}
public function getAuthorizationUri(array $additionalParameters = array())
{
$parameters = array_merge(
$additionalParameters,
array(
'redirect_uri' => $this->credentials->getCallbackUrl(),
)
);
// Build the url
$url = clone $this->getAuthorizationEndpoint();
foreach ($parameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
public function requestRequestToken()
{
$responseBody = $this->httpClient->retrieveResponse(
$this->getRequestTokenEndpoint(),
array(
'consumer_key' => $this->credentials->getConsumerId(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
)
);
$code = $this->parseRequestTokenResponse($responseBody);
return $code;
}
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['code'])) {
throw new TokenResponseException('Error in retrieving code.');
}
return $data['code'];
}
public function requestAccessToken($code)
{
$bodyParams = array(
'consumer_key' => $this->credentials->getConsumerId(),
'code' => $code,
);
$responseBody = $this->httpClient->retrieveResponse(
$this->getAccessTokenEndpoint(),
$bodyParams,
$this->getExtraOAuthHeaders()
);
$token = $this->parseAccessTokenResponse($responseBody);
$this->storage->storeAccessToken($this->service(), $token);
return $token;
}
protected function parseAccessTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if ($data === null || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
#$token->setRequestToken($data['access_token']);
$token->setAccessToken($data['access_token']);
$token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,114 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Reddit extends AbstractService
{
/**
* Defined scopes
*
* @link http://www.reddit.com/dev/api/oauth
*/
// User scopes
const SCOPE_EDIT = 'edit';
const SCOPE_HISTORY = 'history';
const SCOPE_IDENTITY = 'identity';
const SCOPE_MYSUBREDDITS = 'mysubreddits';
const SCOPE_PRIVATEMESSAGES = 'privatemessages';
const SCOPE_READ = 'read';
const SCOPE_SAVE = 'save';
const SCOPE_SUBMIT = 'submit';
const SCOPE_SUBSCRIBE = 'subscribe';
const SCOPE_VOTE = 'vote';
// Mod Scopes
const SCOPE_MODCONFIG = 'modconfig';
const SCOPE_MODFLAIR = 'modflair';
const SCOPE_MODLOG = 'modlog';
const SCOPE_MODPOST = 'modpost';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://oauth.reddit.com');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://ssl.reddit.com/api/v1/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://ssl.reddit.com/api/v1/access_token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getExtraOAuthHeaders()
{
// Reddit uses a Basic OAuth header
return array('Authorization' => 'Basic ' .
base64_encode($this->credentials->getConsumerId() . ':' . $this->credentials->getConsumerSecret()));
}
}

View File

@ -0,0 +1,105 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* RunKeeper service.
*
* @link http://runkeeper.com/developer/healthgraph/registration-authorization
*/
class RunKeeper extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.runkeeper.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationUri(array $additionalParameters = array())
{
$parameters = array_merge(
$additionalParameters,
array(
'client_id' => $this->credentials->getConsumerId(),
'redirect_uri' => $this->credentials->getCallbackUrl(),
'response_type' => 'code',
)
);
$parameters['scope'] = implode(' ', $this->scopes);
// Build the url
$url = clone $this->getAuthorizationEndpoint();
foreach ($parameters as $key => $val) {
$url->addToQuery($key, $val);
}
return $url;
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://runkeeper.com/apps/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://runkeeper.com/apps/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,92 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Service\AbstractService;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Salesforce extends AbstractService
{
/**
* Scopes
*
* @var string
*/
const SCOPE_API = 'api',
SCOPE_REFRESH_TOKEN = 'refresh_token';
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://login.salesforce.com/services/oauth2/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://na1.salesforce.com/services/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function parseRequestTokenResponse($responseBody)
{
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') {
throw new TokenResponseException('Error in retrieving token.');
}
return $this->parseAccessTokenResponse($responseBody);
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
// Salesforce tokens evidently never expire...
$token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
unset($data['access_token']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getExtraOAuthHeaders()
{
return array('Accept' => 'application/json');
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Service\ServiceInterface as BaseServiceInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Defines the common methods across OAuth 2 services.
*/
interface ServiceInterface extends BaseServiceInterface
{
/**
* Authorization methods for various services
*/
const AUTHORIZATION_METHOD_HEADER_OAUTH = 0;
const AUTHORIZATION_METHOD_HEADER_BEARER = 1;
const AUTHORIZATION_METHOD_QUERY_STRING = 2;
const AUTHORIZATION_METHOD_QUERY_STRING_V2 = 3;
const AUTHORIZATION_METHOD_QUERY_STRING_V3 = 4;
const AUTHORIZATION_METHOD_QUERY_STRING_V4 = 5;
/**
* Retrieves and stores/returns the OAuth2 access token after a successful authorization.
*
* @param string $code The access code from the callback.
*
* @return TokenInterface $token
*
* @throws TokenResponseException
*/
public function requestAccessToken($code);
}

View File

@ -0,0 +1,77 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class SoundCloud extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.soundcloud.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://soundcloud.com/connect');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.soundcloud.com/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
if (isset($data['expires_in'])) {
$token->setLifetime($data['expires_in']);
unset($data['expires_in']);
}
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,109 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Spotify extends AbstractService
{
/**
* Scopes
*
* @var string
*/
const SCOPE_PLAYLIST_MODIFY_PUBLIC = 'playlist-modify-public';
const SCOPE_PLAYLIST_MODIFY_PRIVATE = 'playlist-modify-private';
const SCOPE_PLAYLIST_READ_PRIVATE = 'playlist-read-private';
const SCOPE_STREAMING = 'streaming';
const SCOPE_USER_LIBRARY_MODIFY = 'user-library-modify';
const SCOPE_USER_LIBRARY_READ = 'user-library-read';
const SCOPE_USER_READ_PRIVATE = 'user-read-private';
const SCOPE_USER_READ_EMAIL = 'user-read-email';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.spotify.com/v1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://accounts.spotify.com/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://accounts.spotify.com/api/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
if (isset($data['expires_in'])) {
$token->setLifetime($data['expires_in']);
unset($data['expires_in']);
}
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getExtraOAuthHeaders()
{
return array('Authorization' => 'Basic ' .
base64_encode($this->credentials->getConsumerId() . ':' . $this->credentials->getConsumerSecret()));
}
}

View File

@ -0,0 +1,147 @@
<?php
/**
* Strava service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://strava.github.io/
* @link http://strava.github.io/api/v3/oauth/
*/
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\OAuth2\Service\Exception\InvalidAccessTypeException;
/**
* Strava service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://strava.github.io/
* @link http://strava.github.io/api/v3/oauth/
*/
class Strava extends AbstractService
{
/**
* Scopes
*/
// default
const SCOPE_PUBLIC = 'public';
// Modify activities, upload on the users behalf
const SCOPE_WRITE = 'write';
// View private activities and data within privacy zones
const SCOPE_VIEW_PRIVATE = 'view_private';
protected $approvalPrompt = 'auto';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
if (empty($scopes)) {
$scopes = array(self::SCOPE_PUBLIC);
}
parent::__construct(
$credentials,
$httpClient,
$storage,
$scopes,
$baseApiUri,
true
);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://www.strava.com/api/v3/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.strava.com/oauth/authorize?approval_prompt=' . $this->approvalPrompt);
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://www.strava.com/oauth/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error_description'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error_description'] . '"'
);
} elseif (isset($data['error'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error'] . '"'
);
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
if (isset($data['expires_in'])) {
$token->setLifeTime($data['expires_in']);
unset($data['expires_in']);
}
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
public function setApprouvalPrompt($prompt)
{
if (!in_array($prompt, array('auto', 'force'), true)) {
// @todo Maybe could we rename this exception
throw new InvalidAccessTypeException('Invalid approuvalPrompt, expected either auto or force.');
}
$this->approvalPrompt = $prompt;
}
/**
* {@inheritdoc}
*/
protected function getScopesDelimiter()
{
return ',';
}
}

View File

@ -0,0 +1,98 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Ustream extends AbstractService
{
/**
* Scopes
*
* @var string
*/
const SCOPE_OFFLINE = 'offline';
const SCOPE_BROADCASTER = 'broadcaster';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.ustream.tv/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.ustream.tv/oauth2/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://www.ustream.tv/oauth2/token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getExtraOAuthHeaders()
{
return array('Authorization' => 'Basic ' . $this->credentials->getConsumerSecret());
}
}

View File

@ -0,0 +1,156 @@
<?php
/**
* Vimeo service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://developer.vimeo.com/
* @link https://developer.vimeo.com/api/authentication
*/
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Vimeo service.
*
* @author Pedro Amorim <contact@pamorim.fr>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://developer.vimeo.com/
* @link https://developer.vimeo.com/api/authentication
*/
class Vimeo extends AbstractService
{
// API version
const VERSION = '3.2';
// API Header Accept
const HEADER_ACCEPT = 'application/vnd.vimeo.*+json;version=3.2';
/**
* Scopes
* @see https://developer.vimeo.com/api/authentication#scope
*/
// View public videos
const SCOPE_PUBLIC = 'public';
// View private videos
const SCOPE_PRIVATE = 'private';
// View Vimeo On Demand purchase history
const SCOPE_PURCHASED = 'purchased';
// Create new videos, groups, albums, etc.
const SCOPE_CREATE = 'create';
// Edit videos, groups, albums, etc.
const SCOPE_EDIT = 'edit';
// Delete videos, groups, albums, etc.
const SCOPE_DELETE = 'delete';
// Interact with a video on behalf of a user, such as liking
// a video or adding it to your watch later queue
const SCOPE_INTERACT = 'interact';
// Upload a video
const SCOPE_UPLOAD = 'upload';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct(
$credentials,
$httpClient,
$storage,
$scopes,
$baseApiUri,
true
);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.vimeo.com/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://api.vimeo.com/oauth/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.vimeo.com/oauth/access_token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error_description'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error_description'] . '"'
);
} elseif (isset($data['error'])) {
throw new TokenResponseException(
'Error in retrieving token: "' . $data['error'] . '"'
);
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
if (isset($data['expires_in'])) {
$token->setLifeTime($data['expires_in']);
unset($data['expires_in']);
}
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getExtraOAuthHeaders()
{
return array('Accept' => self::HEADER_ACCEPT);
}
/**
* {@inheritdoc}
*/
protected function getExtraApiHeaders()
{
return array('Accept' => self::HEADER_ACCEPT);
}
}

View File

@ -0,0 +1,109 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Vkontakte extends AbstractService
{
/**
* Defined scopes
*
* @link http://vk.com/dev/permissions
*/
const SCOPE_EMAIL = 'email';
const SCOPE_NOTIFY = 'notify';
const SCOPE_FRIENDS = 'friends';
const SCOPE_PHOTOS = 'photos';
const SCOPE_AUDIO = 'audio';
const SCOPE_VIDEO = 'video';
const SCOPE_DOCS = 'docs';
const SCOPE_NOTES = 'notes';
const SCOPE_PAGES = 'pages';
const SCOPE_APP_LINK = '';
const SCOPE_STATUS = 'status';
const SCOPE_OFFERS = 'offers';
const SCOPE_QUESTIONS = 'questions';
const SCOPE_WALL = 'wall';
const SCOPE_GROUPS = 'groups';
const SCOPE_MESSAGES = 'messages';
const SCOPE_NOTIFICATIONS = 'notifications';
const SCOPE_STATS = 'stats';
const SCOPE_ADS = 'ads';
const SCOPE_OFFLINE = 'offline';
const SCOPE_NOHTTPS = 'nohttps';
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://api.vk.com/method/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://oauth.vk.com/authorize');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://oauth.vk.com/access_token');
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifeTime($data['expires_in']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_QUERY_STRING;
}
}

View File

@ -0,0 +1,78 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
class Yahoo extends AbstractService
{
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://api.login.yahoo.com/oauth2/request_auth');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://api.login.yahoo.com/oauth2/get_token');
}
/**
* {@inheritdoc}
*/
protected function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data))
{
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error']))
{
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']);
$token->setLifetime($data['expires_in']);
if (isset($data['refresh_token']))
{
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
/**
* {@inheritdoc}
*/
protected function getExtraOAuthHeaders()
{
$encodedCredentials = base64_encode($this->credentials->getConsumerId() . ':' . $this->credentials->getConsumerSecret());
return array('Authorization' => 'Basic ' . $encodedCredentials);
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace OAuth\OAuth2\Service;
use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;
class Yammer extends AbstractService
{
public function __construct(
CredentialsInterface $credentials,
ClientInterface $httpClient,
TokenStorageInterface $storage,
$scopes = array(),
UriInterface $baseApiUri = null
) {
parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
if (null === $baseApiUri) {
$this->baseApiUri = new Uri('https://www.yammer.com/api/v1/');
}
}
/**
* {@inheritdoc}
*/
public function getAuthorizationEndpoint()
{
return new Uri('https://www.yammer.com/dialog/oauth');
}
/**
* {@inheritdoc}
*/
public function getAccessTokenEndpoint()
{
return new Uri('https://www.yammer.com/oauth2/access_token.json');
}
/**
* {@inheritdoc}
*/
public function getAuthorizationMethod()
{
return static::AUTHORIZATION_METHOD_HEADER_BEARER;
}
/**
* {@inheritdoc}
*/
protected function parseAccessTokenResponse($responseBody)
{
$data = json_decode($responseBody, true);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
}
$token = new StdOAuth2Token();
$token->setAccessToken($data['access_token']['token']);
$token->setLifetime($data['access_token']['expires_at']);
if (isset($data['refresh_token'])) {
$token->setRefreshToken($data['refresh_token']);
unset($data['refresh_token']);
}
unset($data['access_token']);
unset($data['expires_in']);
$token->setExtraParams($data);
return $token;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace OAuth\OAuth2\Token;
use OAuth\Common\Token\AbstractToken;
/**
* Standard OAuth2 token implementation.
* Implements OAuth\OAuth2\Token\TokenInterface for any functionality that might not be provided by AbstractToken.
*/
class StdOAuth2Token extends AbstractToken implements TokenInterface
{
}

Some files were not shown because too many files have changed in this diff Show More