Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge
This commit is contained in:
commit
e7143a265a
114
CHANGELOG
114
CHANGELOG
@ -1,3 +1,117 @@
|
||||
Hubzilla 3.0 (????-??-??)
|
||||
- Don't zidify all permalinks, only zot permalinks
|
||||
- Make remote homelink link to the home host and not to the home channel
|
||||
- Auto promote beginner (techlevel 0) accounts to level 1 after they show signs of active participation.
|
||||
- Go back to including the photo thumbnail data in the export file.
|
||||
- Improvements to file import/export
|
||||
- Default value for xlink_rating_text
|
||||
- Implement IMoveTarget and recursive file/directory move/rename - github issue #680
|
||||
- Synchronise an attach_move operation to clones
|
||||
- Provide a themed page with an error notification on errors instead of an obtuse XML error structure in mod cloud
|
||||
- Disallow backslashes in wiki and wiki-page names
|
||||
- We only require one update module. The rest are superfluous.
|
||||
- Render installable elements as buttons instead of links
|
||||
- Implement chunked uploads for photos page
|
||||
- Remove warning for large files on cloud upload
|
||||
- Add a filter for notification to show new posts only
|
||||
- Implement chunked uploads for cloud
|
||||
- Use httpsig auth for getfile
|
||||
- Load the profile images in the custom acl selector only if we actually need them
|
||||
- Rework liveUpdate() and notificationsUpdate() (aka ping) to first do the liveUpdate and when this is done only do the ping once.
|
||||
- Don't include invisible "update activities" in category widget
|
||||
- Default profile assign
|
||||
- Provide system config option for minimum registration age.
|
||||
- Remove deprecated $a argument from advanced_profile()
|
||||
- Change to bbcode calling parameters
|
||||
- Extra checking of server headers in upload functions
|
||||
- Provide a handler for chunked uploads in mod file_upload
|
||||
- Optional divider between item header and body
|
||||
- Allow toggle to SMBC scaling mode.
|
||||
- Add thumbnail hook
|
||||
- Implement SVG thumbnails and expose security setting
|
||||
- Implement video thumbnail generator
|
||||
- Implement pdf thumbnails
|
||||
- Implement thumbnail generator for epubs
|
||||
- Make browser history buttons work with ajax calls in mod display and hq
|
||||
- Implement tile view for mod cloud (read only)
|
||||
- Add mp3 audio thumbnail generator
|
||||
- Set display_path for photo_upload from the DAV File interface
|
||||
- Provide a generalised interface for thumbnail generators to support various content types
|
||||
- Add ID3Parser library.
|
||||
- Text thumbnails in cloud tile mode
|
||||
- Revisit media breakpoints - do not switch to mobile view to early.
|
||||
- Add French to help pages language dropdown selector
|
||||
- Inroduce the HQ module - an alternative landing page for hubzilla
|
||||
- Strip author name from notify messages in notifications - github issue #911
|
||||
- Remove column item.diaspora_meta
|
||||
- Provide ability to pin apps to navbar from mod apps
|
||||
- Add private forums to forum widget
|
||||
- Move notifications style to widgets.css
|
||||
- Sort out a few more large image upload issues
|
||||
- Move notifications full-screen handling to notifications widget
|
||||
- Move mailhost settings from plugin to core
|
||||
- Sort combined private mail conversations by latest updated conversation instead of created parent
|
||||
- Filter atokens on acl search
|
||||
- Allow a site to block (public) the directory separately from other resources.
|
||||
- Improve removed_channel final cleanup - github issue #386
|
||||
- Cleanup of upload_to_comments(
|
||||
- Dedicate the first click to slideup the cover again but make sure the nav buttons remain functional
|
||||
- Set os_syspath in DAV file put operation so that photos will scale correctly.
|
||||
- Unit tests for Zotlabs\Access classes
|
||||
- Bring back tabindex to submit comments
|
||||
- attach.php minor cleanup and doc
|
||||
- Allow cloud filenames to include ampersands without messing up auth tokens (zid, owt, and zat, and the constant placeholder 'f=')
|
||||
- Provide short localised summary for likes that will end up in displayed notifications
|
||||
- Improving Doxygen documentation.
|
||||
- Update item_normal() to not include ACTIVITY_OBJ_FILE obj_type
|
||||
- Sort out issues with pubstream item interactions
|
||||
- Don't perform zot_refresh on dead sites unless $force is set
|
||||
- Do not send message_list responses to dead sites (this delivery method bypassed the notifier)
|
||||
- Support for netselect query
|
||||
- Add another delivery control parameter (queue threshold)
|
||||
- Add some documentation about shareable widgets
|
||||
- Allow plugin class widgets
|
||||
- Some more work on unit tests
|
||||
- Encrypt the owa token
|
||||
- Bring back the markdown post feature
|
||||
- We call Theme:url() statically, make it also static.
|
||||
- Table structure for pseudo or proxy channels (pchan)
|
||||
|
||||
Bugfixes
|
||||
- Fix issue with long filenames in mod cloud
|
||||
- Fix misc. issues with new 'insert photo from photo album' github issue #475
|
||||
- Fix regression in channel sources delivery
|
||||
- Fix loading of theme-specific widgets
|
||||
- Fix unable to add wiki pages with spaces
|
||||
- Fix mod display and others that require a non-zero profile_uid for updates
|
||||
- Fix various PHP 7.2 issues
|
||||
- Fix typo in HTTPSig
|
||||
- Fix pagetitle lost importing a pdl element from conversation
|
||||
- Fix js warning - getelementbyid (id doesn't exist)
|
||||
- Fix some pubstream on/off weirdness
|
||||
- Fix default addressbook has no name - github issue #921
|
||||
- Fix double html ids in caldav widget if more than one sharee
|
||||
- Fix regression in cdav calendar widget
|
||||
- Fix sync packet not generated when deleting a file using the web browser interface
|
||||
- Fix album cover thumb generator
|
||||
- Fix like-button for images - github issue #826
|
||||
- Fix typo - github issue #910
|
||||
- Fix issue with group_rmv()
|
||||
- Fix php warnings on photo delete
|
||||
- Fix some conflicts between private tags and forum tags
|
||||
- Fix some schema issues
|
||||
- Fix wiki pages not updating after creating new page
|
||||
- Fix a PHP warning in Permissions::FilledPerms()
|
||||
- Fix unicode characters in urls tripping up url regexes - github issue #901
|
||||
- Fix second half of github issue #893
|
||||
- Fix common connections on suggestion page showing wildly different results than remote profile, and is consistently off by one
|
||||
- Fix cloud redirects with owt tokens
|
||||
- Fix issues with diaspora xchans
|
||||
- Fix memory overflow trying to delete a connection with a very high noise to signal ratio
|
||||
- Fix sql error in page module
|
||||
- Fix unstar
|
||||
|
||||
|
||||
Hubzilla 2.8.1 (2017-11-11)
|
||||
- Rename channel app events to calendar and add nav_set_selected() to /cal
|
||||
- Load notifications links to /display via ajax if we are already in /display
|
||||
|
@ -98,6 +98,8 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
$sys = get_sys_channel();
|
||||
$sql_extra = item_permissions_sql($sys['channel_id']);
|
||||
|
||||
$sys_item = false;
|
||||
|
||||
}
|
||||
|
||||
if(! $update) {
|
||||
@ -215,6 +217,8 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if(!$r) {
|
||||
$sys_item = true;
|
||||
|
||||
$r = q("SELECT item.id AS item_id FROM item
|
||||
LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
|
||||
WHERE mid = '%s' AND item.uid = %d $item_normal
|
||||
@ -243,6 +247,8 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if(!$r) {
|
||||
$sys_item = true;
|
||||
|
||||
$r = q("SELECT item.parent AS item_id FROM item
|
||||
LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
|
||||
WHERE mid = '%s' AND item.uid = %d $item_normal_update $simple_update
|
||||
@ -268,7 +274,7 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
dbesc($parents_str)
|
||||
);
|
||||
|
||||
xchan_query($items,true,local_channel());
|
||||
xchan_query($items,true,(($sys_item) ? local_channel() : 0));
|
||||
$items = fetch_post_tags($items,true);
|
||||
$items = conv_sort($items,'created');
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ class Item extends \Zotlabs\Web\Controller {
|
||||
if(! x($_REQUEST,'type'))
|
||||
$_REQUEST['type'] = 'net-comment';
|
||||
|
||||
if($obj_type == ACTIVITY_OBJ_POST)
|
||||
if($obj_type == ACTIVITY_OBJ_NOTE)
|
||||
$obj_type = ACTIVITY_OBJ_COMMENT;
|
||||
|
||||
if($parent) {
|
||||
|
@ -279,8 +279,8 @@ class Ping extends \Zotlabs\Web\Controller {
|
||||
'photo' => $tt['photo'],
|
||||
'when' => relative_date($tt['created']),
|
||||
'hclass' => (($tt['seen']) ? 'notify-seen' : 'notify-unseen'),
|
||||
'b64mid' => $b64mid,
|
||||
'notify_id' => (($tt['otype'] == 'item') ? $tt['id'] : ''),
|
||||
'b64mid' => (($tt['otype'] == 'item') ? $b64mid : 'undefined'),
|
||||
'notify_id' => (($tt['otype'] == 'item') ? $tt['id'] : 'undefined'),
|
||||
'message' => $message
|
||||
);
|
||||
}
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace Zotlabs\Render;
|
||||
|
||||
require_once('library/Smarty/libs/Smarty.class.php');
|
||||
|
||||
class SmartyInterface extends \Smarty {
|
||||
|
||||
public $filename;
|
||||
|
@ -36,15 +36,17 @@
|
||||
"league/html-to-markdown": "^4.4",
|
||||
"pear/text_languagedetect": "^1.0",
|
||||
"commerceguys/intl": "~0.7",
|
||||
"lukasreschke/id3parser": "^0.0.1"
|
||||
"lukasreschke/id3parser": "^0.0.1",
|
||||
"smarty/smarty": "~3.1"
|
||||
},
|
||||
"require-dev" : {
|
||||
"php" : ">=7.0",
|
||||
"phpunit/phpunit" : "^6.1",
|
||||
"phpunit/phpunit" : "~6.4.4",
|
||||
"behat/behat" : "@stable",
|
||||
"behat/mink-extension": "@stable",
|
||||
"behat/mink-goutte-driver": "@stable",
|
||||
"php-mock/php-mock-phpunit": "^2.0"
|
||||
"php-mock/php-mock-phpunit": "^2.0",
|
||||
"phpunit/dbunit": "^3.0"
|
||||
},
|
||||
"autoload" : {
|
||||
"psr-4" : {
|
||||
|
618
composer.lock
generated
618
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,9 @@
|
||||
[h3]Zot API[/h3]
|
||||
|
||||
Many existing social applications and tools can interface directly using the Twitter/StatusNet API, which is available using the 'twitter_api' addon.
|
||||
|
||||
This document describes the native API; which allows direct programmatic access to several internal data structures and libraries extending beyond the basic social interface.
|
||||
|
||||
The API endpoints detailed below are relative to [code]api/z/1.0[/code], meaning that if an API is listed as [code]channel/stream[/code] the full API URL is [code][baseurl]/api/z/1.0/channel/stream[/code].
|
||||
|
||||
[h3]channel/export/basic[/h3]
|
||||
|
@ -941,27 +941,34 @@ function bbcode($Text, $options = []) {
|
||||
// Check for h1
|
||||
if (strpos($Text,'[h1]') !== false) {
|
||||
$Text = preg_replace("(\[h1\](.*?)\[\/h1\])ism",'<h1>$1</h1>',$Text);
|
||||
$Text = str_replace('</h1><br />', '</h1>', $Text);
|
||||
}
|
||||
// Check for h2
|
||||
if (strpos($Text,'[h2]') !== false) {
|
||||
$Text = preg_replace("(\[h2\](.*?)\[\/h2\])ism",'<h2>$1</h2>',$Text);
|
||||
$Text = str_replace('</h2><br />', '</h2>', $Text);
|
||||
}
|
||||
// Check for h3
|
||||
if (strpos($Text,'[h3]') !== false) {
|
||||
$Text = preg_replace("(\[h3\](.*?)\[\/h3\])ism",'<h3>$1</h3>',$Text);
|
||||
$Text = str_replace('</h3><br />', '</h3>', $Text);
|
||||
}
|
||||
// Check for h4
|
||||
if (strpos($Text,'[h4]') !== false) {
|
||||
$Text = preg_replace("(\[h4\](.*?)\[\/h4\])ism",'<h4>$1</h4>',$Text);
|
||||
$Text = str_replace('</h4><br />', '</h4>', $Text);
|
||||
}
|
||||
// Check for h5
|
||||
if (strpos($Text,'[h5]') !== false) {
|
||||
$Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$Text);
|
||||
$Text = str_replace('</h5><br />', '</h5>', $Text);
|
||||
}
|
||||
// Check for h6
|
||||
if (strpos($Text,'[h6]') !== false) {
|
||||
$Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text);
|
||||
$Text = str_replace('</h6><br />', '</h6>', $Text);
|
||||
}
|
||||
|
||||
// Check for table of content without params
|
||||
while(strpos($Text,'[toc]') !== false) {
|
||||
$toc_id = 'toc-' . random_string(10);
|
||||
|
@ -1305,7 +1305,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
||||
|
||||
// allow likes of comments
|
||||
|
||||
if($item_parent_mid && activity_match($datarray['verb'],ACTVITY_LIKE)) {
|
||||
if($item_parent_mid && activity_match($datarray['verb'],ACTIVITY_LIKE)) {
|
||||
$datarray['thr_parent'] = $item_parent_mid[0]['parent_mid'];
|
||||
}
|
||||
|
||||
|
@ -196,12 +196,12 @@ function html2bbcode($message)
|
||||
//node2bbcode($doc, 'tr', array(), "[tr]", "[/tr]");
|
||||
//node2bbcode($doc, 'td', array(), "[td]", "[/td]");
|
||||
|
||||
node2bbcode($doc, 'h1', array(), "\n\n[size=xx-large][b]", "[/b][/size]\n");
|
||||
node2bbcode($doc, 'h2', array(), "\n\n[size=x-large][b]", "[/b][/size]\n");
|
||||
node2bbcode($doc, 'h3', array(), "\n\n[size=large][b]", "[/b][/size]\n");
|
||||
node2bbcode($doc, 'h4', array(), "\n\n[size=medium][b]", "[/b][/size]\n");
|
||||
node2bbcode($doc, 'h5', array(), "\n\n[size=small][b]", "[/b][/size]\n");
|
||||
node2bbcode($doc, 'h6', array(), "\n\n[size=x-small][b]", "[/b][/size]\n");
|
||||
node2bbcode($doc, 'h1', array(), "\n\n[h1]", "[/h1]\n");
|
||||
node2bbcode($doc, 'h2', array(), "\n\n[h2]", "[/h2]\n");
|
||||
node2bbcode($doc, 'h3', array(), "\n\n[h3]", "[/h3]\n");
|
||||
node2bbcode($doc, 'h4', array(), "\n\n[h4]", "[/h4]\n");
|
||||
node2bbcode($doc, 'h5', array(), "\n\n[h5]", "[/h5]\n");
|
||||
node2bbcode($doc, 'h6', array(), "\n\n[h6]", "[/h6]\n");
|
||||
|
||||
node2bbcode($doc, 'a', array('href'=>'/(.+)/'), '[url=$1]', '[/url]');
|
||||
|
||||
|
@ -215,7 +215,7 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(count($images)) {
|
||||
if($images) {
|
||||
foreach($images as $image) {
|
||||
if(! stristr($image,z_root() . '/photo/'))
|
||||
continue;
|
||||
|
@ -1754,9 +1754,14 @@ function get_plink($item,$conversation_mode = true) {
|
||||
else
|
||||
$key = 'llink';
|
||||
|
||||
$zidify = true;
|
||||
|
||||
if(array_key_exists('author',$item) && $item['author']['xchan_network'] !== 'zot')
|
||||
$zidify = false;
|
||||
|
||||
if(x($item,$key)) {
|
||||
return array(
|
||||
'href' => zid($item[$key]),
|
||||
'href' => (($zidify) ? zid($item[$key]) : $item[$key]),
|
||||
'title' => t('Link to Source'),
|
||||
);
|
||||
}
|
||||
|
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {counter} function plugin
|
||||
* Type: function<br>
|
||||
* Name: counter<br>
|
||||
* Purpose: print out a counter value
|
||||
*
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @link http://www.smarty.net/manual/en/language.function.counter.php {counter}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function smarty_function_counter($params, $template)
|
||||
{
|
||||
static $counters = array();
|
||||
|
||||
$name = (isset($params['name'])) ? $params['name'] : 'default';
|
||||
if (!isset($counters[$name])) {
|
||||
$counters[$name] = array(
|
||||
'start' => 1,
|
||||
'skip' => 1,
|
||||
'direction' => 'up',
|
||||
'count' => 1
|
||||
);
|
||||
}
|
||||
$counter =& $counters[$name];
|
||||
|
||||
if (isset($params['start'])) {
|
||||
$counter['start'] = $counter['count'] = (int) $params['start'];
|
||||
}
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$counter['assign'] = $params['assign'];
|
||||
}
|
||||
|
||||
if (isset($counter['assign'])) {
|
||||
$template->assign($counter['assign'], $counter['count']);
|
||||
}
|
||||
|
||||
if (isset($params['print'])) {
|
||||
$print = (bool) $params['print'];
|
||||
} else {
|
||||
$print = empty($counter['assign']);
|
||||
}
|
||||
|
||||
if ($print) {
|
||||
$retval = $counter['count'];
|
||||
} else {
|
||||
$retval = null;
|
||||
}
|
||||
|
||||
if (isset($params['skip'])) {
|
||||
$counter['skip'] = $params['skip'];
|
||||
}
|
||||
|
||||
if (isset($params['direction'])) {
|
||||
$counter['direction'] = $params['direction'];
|
||||
}
|
||||
|
||||
if ($counter['direction'] == "down") {
|
||||
$counter['count'] -= $counter['skip'];
|
||||
} else {
|
||||
$counter['count'] += $counter['skip'];
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* This plugin is only for Smarty2 BC
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {math} function plugin
|
||||
* Type: function<br>
|
||||
* Name: math<br>
|
||||
* Purpose: handle math computations in template
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.math.php {math}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function smarty_function_math($params, $template)
|
||||
{
|
||||
static $_allowed_funcs = array(
|
||||
'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true,
|
||||
'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true,
|
||||
'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true, 'tan' => true
|
||||
);
|
||||
// be sure equation parameter is present
|
||||
if (empty($params['equation'])) {
|
||||
trigger_error("math: missing equation parameter", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$equation = $params['equation'];
|
||||
|
||||
// make sure parenthesis are balanced
|
||||
if (substr_count($equation, "(") != substr_count($equation, ")")) {
|
||||
trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// match all vars in equation, make sure all are passed
|
||||
preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!", $equation, $match);
|
||||
|
||||
foreach ($match[1] as $curr_var) {
|
||||
if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) {
|
||||
trigger_error("math: function call $curr_var not allowed", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($params as $key => $val) {
|
||||
if ($key != "equation" && $key != "format" && $key != "assign") {
|
||||
// make sure value is not empty
|
||||
if (strlen($val) == 0) {
|
||||
trigger_error("math: parameter $key is empty", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
if (!is_numeric($val)) {
|
||||
trigger_error("math: parameter $key: is not numeric", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
$equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
|
||||
}
|
||||
}
|
||||
$smarty_math_result = null;
|
||||
eval("\$smarty_math_result = " . $equation . ";");
|
||||
|
||||
if (empty($params['format'])) {
|
||||
if (empty($params['assign'])) {
|
||||
return $smarty_math_result;
|
||||
} else {
|
||||
$template->assign($params['assign'], $smarty_math_result);
|
||||
}
|
||||
} else {
|
||||
if (empty($params['assign'])) {
|
||||
printf($params['format'], $smarty_math_result);
|
||||
} else {
|
||||
$template->assign($params['assign'], sprintf($params['format'], $smarty_math_result));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsModifierCompiler
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty unescape modifier plugin
|
||||
* Type: modifier<br>
|
||||
* Name: unescape<br>
|
||||
* Purpose: unescape html entities
|
||||
*
|
||||
* @author Rodney Rehm
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* @return string with compiled code
|
||||
*/
|
||||
function smarty_modifiercompiler_unescape($params)
|
||||
{
|
||||
if (!isset($params[1])) {
|
||||
$params[1] = 'html';
|
||||
}
|
||||
if (!isset($params[2])) {
|
||||
$params[2] = '\'' . addslashes(Smarty::$_CHARSET) . '\'';
|
||||
} else {
|
||||
$params[2] = "'" . $params[2] . "'";
|
||||
}
|
||||
|
||||
switch (trim($params[1], '"\'')) {
|
||||
case 'entity':
|
||||
case 'htmlall':
|
||||
if (Smarty::$_MBSTRING) {
|
||||
return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')';
|
||||
}
|
||||
|
||||
return 'html_entity_decode(' . $params[0] . ', ENT_NOQUOTES, ' . $params[2] . ')';
|
||||
|
||||
case 'html':
|
||||
return 'htmlspecialchars_decode(' . $params[0] . ', ENT_QUOTES)';
|
||||
|
||||
case 'url':
|
||||
return 'rawurldecode(' . $params[0] . ')';
|
||||
|
||||
default:
|
||||
return $params[0];
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty shared plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsShared
|
||||
*/
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
|
||||
/**
|
||||
* escape_special_chars common function
|
||||
* Function: smarty_function_escape_special_chars<br>
|
||||
* Purpose: used by other smarty functions to escape
|
||||
* special chars except for already escaped ones
|
||||
*
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
*
|
||||
* @param string $string text that should by escaped
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_escape_special_chars($string)
|
||||
{
|
||||
if (!is_array($string)) {
|
||||
$string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* escape_special_chars common function
|
||||
* Function: smarty_function_escape_special_chars<br>
|
||||
* Purpose: used by other smarty functions to escape
|
||||
* special chars except for already escaped ones
|
||||
*
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
*
|
||||
* @param string $string text that should by escaped
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_escape_special_chars($string)
|
||||
{
|
||||
if (!is_array($string)) {
|
||||
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
|
||||
$string = htmlspecialchars($string);
|
||||
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Assign
|
||||
* Compiles the {assign} tag
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Assign Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Valid scope names
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $valid_scopes = array('local' => true, 'parent' => true, 'root' => true, 'global' => true,
|
||||
'smarty' => true, 'tpl_root' => true);
|
||||
|
||||
/**
|
||||
* Compiles code for the {assign} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return string compiled code
|
||||
* @throws \SmartyCompilerException
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
// the following must be assigned at runtime because it will be overwritten in Smarty_Internal_Compile_Append
|
||||
$this->required_attributes = array('var', 'value');
|
||||
$this->shorttag_order = array('var', 'value');
|
||||
$this->optional_attributes = array('scope', 'bubble_up');
|
||||
$_nocache = 'null';
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
// nocache ?
|
||||
if ($compiler->tag_nocache || $compiler->nocache) {
|
||||
$_nocache = 'true';
|
||||
// create nocache var to make it know for further compiling
|
||||
if (isset($compiler->template->tpl_vars[trim($_attr['var'], "'")])) {
|
||||
$compiler->template->tpl_vars[trim($_attr['var'], "'")]->nocache = true;
|
||||
} else {
|
||||
$compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_Variable(null, true);
|
||||
}
|
||||
}
|
||||
// scope setup
|
||||
$_scope = Smarty::SCOPE_LOCAL;
|
||||
if (isset($_attr['scope'])) {
|
||||
$_attr['scope'] = trim($_attr['scope'], "'\"");
|
||||
if (!isset($this->valid_scopes[$_attr['scope']])) {
|
||||
$compiler->trigger_template_error("illegal value '{$_attr['scope']}' for \"scope\" attribute", null, true);
|
||||
}
|
||||
if ($_attr['scope'] != 'local') {
|
||||
if ($_attr['scope'] == 'parent') {
|
||||
$_scope = Smarty::SCOPE_PARENT;
|
||||
} elseif ($_attr['scope'] == 'root') {
|
||||
$_scope = Smarty::SCOPE_ROOT;
|
||||
} elseif ($_attr['scope'] == 'global') {
|
||||
$_scope = Smarty::SCOPE_GLOBAL;
|
||||
} elseif ($_attr['scope'] == 'smarty') {
|
||||
$_scope = Smarty::SCOPE_SMARTY;
|
||||
} elseif ($_attr['scope'] == 'tpl_root') {
|
||||
$_scope = Smarty::SCOPE_TPL_ROOT;
|
||||
}
|
||||
$_scope += (isset($_attr['bubble_up']) && $_attr['bubble_up'] == 'false') ? 0 : Smarty::SCOPE_BUBBLE_UP;
|
||||
}
|
||||
}
|
||||
// compiled output
|
||||
if (isset($parameter['smarty_internal_index'])) {
|
||||
$output =
|
||||
"<?php \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, $_attr[var], $_nocache);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];";
|
||||
} else {
|
||||
// implement Smarty2's behaviour of variables assigned by reference
|
||||
if ($compiler->template->smarty instanceof SmartyBC) {
|
||||
$output =
|
||||
"<?php if (isset(\$_smarty_tpl->tpl_vars[$_attr[var]])) {\$_smarty_tpl->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
|
||||
$output .= "\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value = $_attr[value]; \$_smarty_tpl->tpl_vars[$_attr[var]]->nocache = $_nocache;";
|
||||
$output .= "\n} else \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache);";
|
||||
} else {
|
||||
$output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache);";
|
||||
}
|
||||
}
|
||||
$output .= "\n\$_smarty_tpl->ext->_updateScope->updateScope(\$_smarty_tpl, $_attr[var], $_scope);";
|
||||
$output .= '?>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
@ -1,292 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Smarty.
|
||||
*
|
||||
* (c) 2015 Uwe Tews
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Block Class
|
||||
*
|
||||
* @author Uwe Tews <uwe.tews@googlemail.com>
|
||||
*/
|
||||
class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inheritance
|
||||
{
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $required_attributes = array('name');
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $shorttag_order = array('name');
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $option_flags = array('hide', 'nocache');
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $optional_attributes = array('assign');
|
||||
|
||||
/**
|
||||
* nesting level of block tags
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $blockTagNestingLevel = 0;
|
||||
|
||||
/**
|
||||
* Saved compiler object
|
||||
*
|
||||
* @var Smarty_Internal_TemplateCompilerBase
|
||||
*/
|
||||
public $compiler = null;
|
||||
|
||||
/**
|
||||
* Compiles code for the {block} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return bool true
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
if (!isset($compiler->_cache['blockNesting'])) {
|
||||
$compiler->_cache['blockNesting'] = 0;
|
||||
}
|
||||
if ($compiler->_cache['blockNesting'] == 0) {
|
||||
// make sure that inheritance gets initialized in template code
|
||||
$this->registerInit($compiler);
|
||||
$this->option_flags = array('hide', 'nocache', 'append', 'prepend');
|
||||
} else {
|
||||
$this->option_flags = array('hide', 'nocache');
|
||||
}
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
$compiler->_cache['blockNesting'] ++;
|
||||
$compiler->_cache['blockName'][$compiler->_cache['blockNesting']] = $_attr['name'];
|
||||
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']][0] = 'block_' . preg_replace('![^\w]+!', '_', uniqid(rand(), true));
|
||||
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']][1] = false;
|
||||
$this->openTag($compiler, 'block', array($_attr, $compiler->nocache, $compiler->parser->current_buffer,
|
||||
$compiler->template->compiled->has_nocache_code,
|
||||
$compiler->template->caching));
|
||||
// must whole block be nocache ?
|
||||
if ($compiler->tag_nocache) {
|
||||
$i = 0;
|
||||
}
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
// $compiler->suppressNocacheProcessing = true;
|
||||
if ($_attr['nocache'] === true) {
|
||||
//$compiler->trigger_template_error('nocache option not allowed', $compiler->parser->lex->taglineno);
|
||||
}
|
||||
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
|
||||
$compiler->template->compiled->has_nocache_code = false;
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile saved child block source
|
||||
*
|
||||
* @param \Smarty_Internal_TemplateCompilerBase compiler object
|
||||
* @param string $_name optional name of child block
|
||||
*
|
||||
* @return string compiled code of child block
|
||||
*/
|
||||
static function compileChildBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
|
||||
{
|
||||
if (!isset($compiler->_cache['blockNesting'])) {
|
||||
$compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ',
|
||||
$compiler->parser->lex->taglineno);
|
||||
}
|
||||
$compiler->has_code = true;
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']][1] = true;
|
||||
$output = "<?php \n\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 2, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n";
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile $smarty.block.parent
|
||||
*
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param string $_name optional name of child block
|
||||
*
|
||||
* @return string compiled code of child block
|
||||
*/
|
||||
static function compileParentBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
|
||||
{
|
||||
if (!isset($compiler->_cache['blockNesting'])) {
|
||||
$compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ',
|
||||
$compiler->parser->lex->taglineno);
|
||||
}
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
$compiler->has_code = true;
|
||||
$output = "<?php \n\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 4, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n";
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile BlockClose Class
|
||||
*
|
||||
*/
|
||||
class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_Inheritance
|
||||
{
|
||||
/**
|
||||
* Compiles code for the {/block} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return bool true
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
list($_attr, $_nocache, $_buffer, $_has_nocache_code, $_caching) = $this->closeTag($compiler, array('block'));
|
||||
// init block parameter
|
||||
$_block = $compiler->_cache['blockParams'][$compiler->_cache['blockNesting']];
|
||||
unset($compiler->_cache['blockParams'][$compiler->_cache['blockNesting']]);
|
||||
$_block[2] = $_block[3] = 0;
|
||||
$_name = trim($_attr['name'], "'\"");
|
||||
$_assign = isset($_attr['assign']) ? $_attr['assign'] : null;
|
||||
unset($_attr['assign'], $_attr['name']);
|
||||
foreach ($_attr as $name => $stat) {
|
||||
if ((is_bool($stat) && $stat !== false) || (!is_bool($stat) && $stat != 'false')) {
|
||||
$_block[$name] = is_string($stat) ? trim($stat, "'\"") : $stat;
|
||||
}
|
||||
}
|
||||
$_funcName = $_block[0];
|
||||
// get compiled block code
|
||||
$_functionCode = $compiler->parser->current_buffer;
|
||||
// setup buffer for template function code
|
||||
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
|
||||
|
||||
if ($compiler->template->compiled->has_nocache_code) {
|
||||
// $compiler->parent_compiler->template->tpl_function[$_name]['call_name_caching'] = $_funcNameCaching;
|
||||
$_block[6] = $_funcNameCaching = $_funcName . '_nocache';
|
||||
$output = "<?php\n";
|
||||
$output .= "/* {block '{$_name}'} {$compiler->template->source->type}:{$compiler->template->source->name} */\n";
|
||||
$output .= "function {$_funcNameCaching} (\$_smarty_tpl, \$_blockParentStack) {\n";
|
||||
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
|
||||
$output .= "\$_smarty_tpl->cached->hashes['{$compiler->template->compiled->nocache_hash}'] = true;\n";
|
||||
if (isset($_assign)) {
|
||||
$output .= "ob_start();\n";
|
||||
}
|
||||
$output .= "?>\n";
|
||||
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
||||
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||
$output));
|
||||
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
|
||||
$output = "<?php\n";
|
||||
if (isset($_assign)) {
|
||||
$output .= "\$_smarty_tpl->tpl_vars[{$_assign}] = new Smarty_Variable(ob_get_clean());\n";
|
||||
}
|
||||
$output .= "/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
|
||||
$output .= "}\n";
|
||||
$output .= "/* {/block '{$_name}'} */\n\n";
|
||||
$output .= "?>\n";
|
||||
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
||||
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||
$output));
|
||||
$compiler->blockOrFunctionCode .= $f = $compiler->parser->current_buffer->to_smarty_php($compiler->parser);
|
||||
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
|
||||
$this->compiler = $compiler;
|
||||
$_functionCode = new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||
preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/",
|
||||
array($this, 'removeNocache'),
|
||||
$_functionCode->to_smarty_php($compiler->parser)));
|
||||
$this->compiler = null;
|
||||
}
|
||||
$output = "<?php\n";
|
||||
$output .= "/* {block '{$_name}'} {$compiler->template->source->type}:{$compiler->template->source->name} */\n";
|
||||
$output .= "function {$_funcName}(\$_smarty_tpl, \$_blockParentStack) {\n";
|
||||
if (isset($_assign)) {
|
||||
$output .= "ob_start();\n";
|
||||
}
|
||||
$output .= "?>\n";
|
||||
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
||||
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||
$output));
|
||||
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
|
||||
$output = "<?php\n";
|
||||
if (isset($_assign)) {
|
||||
$output .= "\$_smarty_tpl->tpl_vars[{$_assign}] = new Smarty_Variable(ob_get_clean());\n";
|
||||
}
|
||||
$output .= "}\n";
|
||||
$output .= "/* {/block '{$_name}'} */\n\n";
|
||||
$output .= "?>\n";
|
||||
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
||||
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||
$output));
|
||||
$compiler->blockOrFunctionCode .= $compiler->parser->current_buffer->to_smarty_php($compiler->parser);
|
||||
// nocache plugins must be copied
|
||||
if (!empty($compiler->template->compiled->required_plugins['nocache'])) {
|
||||
foreach ($compiler->template->compiled->required_plugins['nocache'] as $plugin => $tmp) {
|
||||
foreach ($tmp as $type => $data) {
|
||||
$compiler->parent_compiler->template->compiled->required_plugins['compiled'][$plugin][$type] =
|
||||
$data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// restore old status
|
||||
$compiler->template->compiled->has_nocache_code = $_has_nocache_code;
|
||||
$compiler->tag_nocache = $compiler->nocache;
|
||||
$compiler->nocache = $_nocache;
|
||||
$compiler->parser->current_buffer = $_buffer;
|
||||
$output = "<?php \n";
|
||||
if ($compiler->_cache['blockNesting'] == 1) {
|
||||
$output .= "\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 0, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, " .
|
||||
var_export($_block, true) . ");\n";
|
||||
} else {
|
||||
$output .= "\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 0, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, " .
|
||||
var_export($_block, true) . ", \$_blockParentStack);\n";
|
||||
|
||||
}
|
||||
$output .= "?>\n";
|
||||
$compiler->_cache['blockNesting'] --;
|
||||
if ($compiler->_cache['blockNesting'] == 0) {
|
||||
unset($compiler->_cache['blockNesting']);
|
||||
}
|
||||
$compiler->has_code = true;
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $match
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function removeNocache($match)
|
||||
{
|
||||
$code =
|
||||
preg_replace("/((<\?php )?echo '\/\*%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/)|(\/\*\/%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/",
|
||||
'', $match[0]);
|
||||
$code = str_replace(array('\\\'', '\\\\\''), array('\'', '\\\''), $code);
|
||||
return $code;
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Break
|
||||
* Compiles the {break} tag
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Break Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $optional_attributes = array('levels');
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $shorttag_order = array('levels');
|
||||
|
||||
/**
|
||||
* Compiles code for the {break} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return string compiled code
|
||||
* @throws \SmartyCompilerException
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
|
||||
if ($_attr['nocache'] === true) {
|
||||
$compiler->trigger_template_error('nocache option not allowed', null, true);
|
||||
}
|
||||
|
||||
if (isset($_attr['levels'])) {
|
||||
if (!is_numeric($_attr['levels'])) {
|
||||
$compiler->trigger_template_error('level attribute must be a numeric constant', null, true);
|
||||
}
|
||||
$_levels = $_attr['levels'];
|
||||
} else {
|
||||
$_levels = 1;
|
||||
}
|
||||
$level_count = $_levels;
|
||||
$stack_count = count($compiler->_tag_stack) - 1;
|
||||
while ($level_count > 0 && $stack_count >= 0) {
|
||||
if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
|
||||
$level_count --;
|
||||
}
|
||||
$stack_count --;
|
||||
}
|
||||
if ($level_count != 0) {
|
||||
$compiler->trigger_template_error("cannot break {$_levels} level(s)", null, true);
|
||||
}
|
||||
|
||||
return "<?php break {$_levels};?>";
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Continue
|
||||
* Compiles the {continue} tag
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Continue Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $optional_attributes = array('levels');
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $shorttag_order = array('levels');
|
||||
|
||||
/**
|
||||
* Compiles code for the {continue} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return string compiled code
|
||||
* @throws \SmartyCompilerException
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
|
||||
if ($_attr['nocache'] === true) {
|
||||
$compiler->trigger_template_error('nocache option not allowed', null, true);
|
||||
}
|
||||
|
||||
if (isset($_attr['levels'])) {
|
||||
if (!is_numeric($_attr['levels'])) {
|
||||
$compiler->trigger_template_error('level attribute must be a numeric constant', null, true);
|
||||
}
|
||||
$_levels = $_attr['levels'];
|
||||
} else {
|
||||
$_levels = 1;
|
||||
}
|
||||
$level_count = $_levels;
|
||||
$stack_count = count($compiler->_tag_stack) - 1;
|
||||
while ($level_count > 0 && $stack_count >= 0) {
|
||||
if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
|
||||
$level_count --;
|
||||
}
|
||||
$stack_count --;
|
||||
}
|
||||
if ($level_count != 0) {
|
||||
$compiler->trigger_template_error("cannot continue {$_levels} level(s)", null, true);
|
||||
}
|
||||
|
||||
return "<?php continue {$_levels};?>";
|
||||
}
|
||||
}
|
@ -1,252 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Compile If
|
||||
* Compiles the {if} {else} {elseif} {/if} tags
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile If Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Compiles code for the {if} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return string compiled code
|
||||
* @throws \SmartyCompilerException
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
$this->openTag($compiler, 'if', array(1, $compiler->nocache));
|
||||
// must whole block be nocache ?
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
|
||||
if (!array_key_exists("if condition", $parameter)) {
|
||||
$compiler->trigger_template_error("missing if condition", null, true);
|
||||
}
|
||||
|
||||
if (is_array($parameter['if condition'])) {
|
||||
if ($compiler->nocache) {
|
||||
$_nocache = ',true';
|
||||
// create nocache var to make it know for further compiling
|
||||
if (is_array($parameter['if condition']['var'])) {
|
||||
$var = trim($parameter['if condition']['var']['var'], "'");
|
||||
} else {
|
||||
$var = trim($parameter['if condition']['var'], "'");
|
||||
}
|
||||
if (isset($compiler->template->tpl_vars[$var])) {
|
||||
$compiler->template->tpl_vars[$var]->nocache = true;
|
||||
} else {
|
||||
$compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
|
||||
}
|
||||
} else {
|
||||
$_nocache = '';
|
||||
}
|
||||
if (is_array($parameter['if condition']['var'])) {
|
||||
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] .
|
||||
"]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] .
|
||||
"]->value)) \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, " . $parameter['if condition']['var']['var'] .
|
||||
"$_nocache);\n";
|
||||
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" .
|
||||
$parameter['if condition']['var']['smarty_internal_index'] . " = " .
|
||||
$parameter['if condition']['value'] . ") {?>";
|
||||
} else {
|
||||
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] .
|
||||
"])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] .
|
||||
"] = new Smarty_Variable(null{$_nocache});";
|
||||
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " .
|
||||
$parameter['if condition']['value'] . ") {?>";
|
||||
}
|
||||
|
||||
return $_output;
|
||||
} else {
|
||||
return "<?php if ({$parameter['if condition']}) {?>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Else Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Else extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Compiles code for the {else} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
|
||||
$this->openTag($compiler, 'else', array($nesting, $compiler->tag_nocache));
|
||||
|
||||
return "<?php } else { ?>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile ElseIf Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Compiles code for the {elseif} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return string compiled code
|
||||
* @throws \SmartyCompilerException
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
|
||||
list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
|
||||
|
||||
if (!array_key_exists("if condition", $parameter)) {
|
||||
$compiler->trigger_template_error("missing elseif condition", null, true);
|
||||
}
|
||||
|
||||
if (is_array($parameter['if condition'])) {
|
||||
$condition_by_assign = true;
|
||||
if ($compiler->nocache) {
|
||||
$_nocache = ',true';
|
||||
// create nocache var to make it know for further compiling
|
||||
if (is_array($parameter['if condition']['var'])) {
|
||||
$var = trim($parameter['if condition']['var']['var'], "'");
|
||||
} else {
|
||||
$var = trim($parameter['if condition']['var'], "'");
|
||||
}
|
||||
if (isset($compiler->template->tpl_vars[$var])) {
|
||||
$compiler->template->tpl_vars[$var]->nocache = true;
|
||||
} else {
|
||||
$compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
|
||||
}
|
||||
} else {
|
||||
$_nocache = '';
|
||||
}
|
||||
} else {
|
||||
$condition_by_assign = false;
|
||||
}
|
||||
|
||||
if (empty($compiler->prefix_code)) {
|
||||
if ($condition_by_assign) {
|
||||
$this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
|
||||
if (is_array($parameter['if condition']['var'])) {
|
||||
$_output = "<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" .
|
||||
$parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" .
|
||||
$parameter['if condition']['var']['var'] .
|
||||
"]->value)) \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, " .
|
||||
$parameter['if condition']['var']['var'] . "$_nocache);\n";
|
||||
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" .
|
||||
$parameter['if condition']['var']['smarty_internal_index'] . " = " .
|
||||
$parameter['if condition']['value'] . ") {?>";
|
||||
} else {
|
||||
$_output = "<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" .
|
||||
$parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" .
|
||||
$parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
|
||||
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " .
|
||||
$parameter['if condition']['value'] . ") {?>";
|
||||
}
|
||||
|
||||
return $_output;
|
||||
} else {
|
||||
$this->openTag($compiler, 'elseif', array($nesting, $compiler->tag_nocache));
|
||||
|
||||
return "<?php } elseif ({$parameter['if condition']}) {?>";
|
||||
}
|
||||
} else {
|
||||
$tmp = '';
|
||||
foreach ($compiler->prefix_code as $code) {
|
||||
$tmp = $compiler->appendCode($tmp, $code);
|
||||
}
|
||||
$compiler->prefix_code = array();
|
||||
$tmp = $compiler->appendCode("<?php } else {?>", $tmp);
|
||||
$this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
|
||||
if ($condition_by_assign) {
|
||||
if (is_array($parameter['if condition']['var'])) {
|
||||
$_output = $compiler->appendCode($tmp, "<?php if (!isset(\$_smarty_tpl->tpl_vars[" .
|
||||
$parameter['if condition']['var']['var'] .
|
||||
"]) || !is_array(\$_smarty_tpl->tpl_vars[" .
|
||||
$parameter['if condition']['var']['var'] .
|
||||
"]->value)) \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, " .
|
||||
$parameter['if condition']['var']['var'] . "$_nocache);\n");
|
||||
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" .
|
||||
$parameter['if condition']['var']['smarty_internal_index'] . " = " .
|
||||
$parameter['if condition']['value'] . ") {?>";
|
||||
} else {
|
||||
$_output = $compiler->appendCode($tmp, "<?php if (!isset(\$_smarty_tpl->tpl_vars[" .
|
||||
$parameter['if condition']['var'] .
|
||||
"])) \$_smarty_tpl->tpl_vars[" .
|
||||
$parameter['if condition']['var'] .
|
||||
"] = new Smarty_Variable(null{$_nocache});");
|
||||
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " .
|
||||
$parameter['if condition']['value'] . ") {?>";
|
||||
}
|
||||
|
||||
return $_output;
|
||||
} else {
|
||||
return $compiler->appendCode($tmp, "<?php if ({$parameter['if condition']}) {?>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Ifclose Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Ifclose extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Compiles code for the {/if} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
list($nesting, $compiler->nocache) = $this->closeTag($compiler, array('if', 'else', 'elseif'));
|
||||
$tmp = '';
|
||||
for ($i = 0; $i < $nesting; $i ++) {
|
||||
$tmp .= '}';
|
||||
}
|
||||
|
||||
return "<?php {$tmp}?>";
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Block Plugin
|
||||
* Compiles code for the execution of block plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Block Plugin Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $optional_attributes = array('_any');
|
||||
|
||||
/**
|
||||
* Compiles code for the execution of block plugin
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
* @param string $tag name of block plugin
|
||||
* @param string $function PHP function name
|
||||
*
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag, $function)
|
||||
{
|
||||
if (!isset($tag[5]) || substr($tag, - 5) != 'close') {
|
||||
// opening tag of block plugin
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
if ($_attr['nocache'] === true) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
unset($_attr['nocache']);
|
||||
// convert attributes into parameter array string
|
||||
$_paramsArray = array();
|
||||
foreach ($_attr as $_key => $_value) {
|
||||
if (is_int($_key)) {
|
||||
$_paramsArray[] = "$_key=>$_value";
|
||||
} else {
|
||||
$_paramsArray[] = "'$_key'=>$_value";
|
||||
}
|
||||
}
|
||||
$_params = 'array(' . implode(",", $_paramsArray) . ')';
|
||||
|
||||
$this->openTag($compiler, $tag, array($_params, $compiler->nocache));
|
||||
// maybe nocache because of nocache variables or nocache plugin
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
// compile code
|
||||
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
|
||||
} else {
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
// closing tag of block plugin, restore nocache
|
||||
list($_params, $compiler->nocache) = $this->closeTag($compiler, substr($tag, 0, - 5));
|
||||
// This tag does create output
|
||||
$compiler->has_output = true;
|
||||
// compile code
|
||||
if (!isset($parameter['modifier_list'])) {
|
||||
$mod_pre = $mod_post = '';
|
||||
} else {
|
||||
$mod_pre = ' ob_start(); ';
|
||||
$mod_post = 'echo ' .
|
||||
$compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'],
|
||||
'value' => 'ob_get_clean()')) . ';';
|
||||
}
|
||||
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
|
||||
" echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post .
|
||||
" } array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
|
||||
}
|
||||
|
||||
return $output . "\n";
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Object Block Function
|
||||
* Compiles code for registered objects as block function
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Object Block Function Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $optional_attributes = array('_any');
|
||||
|
||||
/**
|
||||
* Compiles code for the execution of block plugin
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
* @param string $tag name of block object
|
||||
* @param string $method name of method to call
|
||||
*
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag, $method)
|
||||
{
|
||||
if (!isset($tag[5]) || substr($tag, - 5) != 'close') {
|
||||
// opening tag of block plugin
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
if ($_attr['nocache'] === true) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
unset($_attr['nocache']);
|
||||
// convert attributes into parameter array string
|
||||
$_paramsArray = array();
|
||||
foreach ($_attr as $_key => $_value) {
|
||||
if (is_int($_key)) {
|
||||
$_paramsArray[] = "$_key=>$_value";
|
||||
} else {
|
||||
$_paramsArray[] = "'$_key'=>$_value";
|
||||
}
|
||||
}
|
||||
$_params = 'array(' . implode(",", $_paramsArray) . ')';
|
||||
|
||||
$this->openTag($compiler, $tag . '->' . $method, array($_params, $compiler->nocache));
|
||||
// maybe nocache because of nocache variables or nocache plugin
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
// compile code
|
||||
$output =
|
||||
"<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}->{$method}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
|
||||
} else {
|
||||
$base_tag = substr($tag, 0, - 5);
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
// closing tag of block plugin, restore nocache
|
||||
list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag . '->' . $method);
|
||||
// This tag does create output
|
||||
$compiler->has_output = true;
|
||||
// compile code
|
||||
if (!isset($parameter['modifier_list'])) {
|
||||
$mod_pre = $mod_post = '';
|
||||
} else {
|
||||
$mod_pre = ' ob_start(); ';
|
||||
$mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(),
|
||||
array('modifierlist' => $parameter['modifier_list'],
|
||||
'value' => 'ob_get_clean()')) . ';';
|
||||
}
|
||||
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
|
||||
" echo \$_smarty_tpl->smarty->registered_objects['{$base_tag}'][0]->{$method}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " .
|
||||
$mod_post . " } array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
|
||||
}
|
||||
|
||||
return $output . "\n";
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Registered Block
|
||||
* Compiles code for the execution of a registered block function
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Registered Block Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Private_Registered_Block extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $optional_attributes = array('_any');
|
||||
|
||||
/**
|
||||
* Compiles code for the execution of a block function
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
* @param string $tag name of block function
|
||||
*
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag)
|
||||
{
|
||||
if (!isset($tag[5]) || substr($tag, - 5) != 'close') {
|
||||
// opening tag of block plugin
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
if ($_attr['nocache']) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
unset($_attr['nocache']);
|
||||
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag])) {
|
||||
$tag_info = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag];
|
||||
} else {
|
||||
$tag_info = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$tag];
|
||||
}
|
||||
// convert attributes into parameter array string
|
||||
$_paramsArray = array();
|
||||
foreach ($_attr as $_key => $_value) {
|
||||
if (is_int($_key)) {
|
||||
$_paramsArray[] = "$_key=>$_value";
|
||||
} elseif ($compiler->template->caching && in_array($_key, $tag_info[2])) {
|
||||
$_value = str_replace("'", "^#^", $_value);
|
||||
$_paramsArray[] = "'$_key'=>^#^.var_export($_value,true).^#^";
|
||||
} else {
|
||||
$_paramsArray[] = "'$_key'=>$_value";
|
||||
}
|
||||
}
|
||||
$_params = 'array(' . implode(",", $_paramsArray) . ')';
|
||||
|
||||
$this->openTag($compiler, $tag, array($_params, $compiler->nocache));
|
||||
// maybe nocache because of nocache variables or nocache plugin
|
||||
$compiler->nocache = !$tag_info[1] | $compiler->nocache | $compiler->tag_nocache;
|
||||
$function = $tag_info[0];
|
||||
// compile code
|
||||
if (!is_array($function)) {
|
||||
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
|
||||
} elseif (is_object($function[0])) {
|
||||
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_plugins['block']['{$tag}'][0][0]->{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
|
||||
} else {
|
||||
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function[0]}::{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
|
||||
}
|
||||
} else {
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
$base_tag = substr($tag, 0, - 5);
|
||||
// closing tag of block plugin, restore nocache
|
||||
list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag);
|
||||
// This tag does create output
|
||||
$compiler->has_output = true;
|
||||
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag])) {
|
||||
$function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0];
|
||||
} else {
|
||||
$function = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0];
|
||||
}
|
||||
// compile code
|
||||
if (!isset($parameter['modifier_list'])) {
|
||||
$mod_pre = $mod_post = '';
|
||||
} else {
|
||||
$mod_pre = ' ob_start(); ';
|
||||
$mod_post = 'echo ' .
|
||||
$compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'],
|
||||
'value' => 'ob_get_clean()')) . ';';
|
||||
}
|
||||
if (!is_array($function)) {
|
||||
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
|
||||
" echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat);" . $mod_post .
|
||||
" } array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
|
||||
} elseif (is_object($function[0])) {
|
||||
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
|
||||
" echo \$_smarty_tpl->smarty->registered_plugins['block']['{$base_tag}'][0][0]->{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " .
|
||||
$mod_post . "} array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
|
||||
} else {
|
||||
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
|
||||
" echo {$function[0]}::{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " .
|
||||
$mod_post . "} array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
|
||||
}
|
||||
}
|
||||
|
||||
return $output . "\n";
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Compile While
|
||||
* Compiles the {while} tag
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile While Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_While extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Compiles code for the {while} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return string compiled code
|
||||
* @throws \SmartyCompilerException
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
$compiler->loopNesting++;
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
$this->openTag($compiler, 'while', $compiler->nocache);
|
||||
|
||||
if (!array_key_exists("if condition", $parameter)) {
|
||||
$compiler->trigger_template_error("missing while condition", null, true);
|
||||
}
|
||||
|
||||
// maybe nocache because of nocache variables
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
$_output = "<?php\n";
|
||||
if (is_array($parameter['if condition'])) {
|
||||
if ($compiler->nocache) {
|
||||
$_nocache = ',true';
|
||||
// create nocache var to make it know for further compiling
|
||||
if (is_array($parameter['if condition']['var'])) {
|
||||
$var = trim($parameter['if condition']['var']['var'], "'");
|
||||
} else {
|
||||
$var = trim($parameter['if condition']['var'], "'");
|
||||
}
|
||||
if (isset($compiler->template->tpl_vars[$var])) {
|
||||
$compiler->template->tpl_vars[$var]->nocache = true;
|
||||
} else {
|
||||
$compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
|
||||
}
|
||||
} else {
|
||||
$_nocache = '';
|
||||
}
|
||||
if (is_array($parameter['if condition']['var'])) {
|
||||
$_output .= "if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] .
|
||||
"]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] .
|
||||
"]->value)) \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, " . $parameter['if condition']['var']['var'] .
|
||||
"$_nocache);\n";
|
||||
$_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" .
|
||||
$parameter['if condition']['var']['smarty_internal_index'] . " = " .
|
||||
$parameter['if condition']['value'] . ") {?>";
|
||||
} else {
|
||||
$_output .= "if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] .
|
||||
"])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] .
|
||||
"] = new Smarty_Variable(null{$_nocache});";
|
||||
$_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " .
|
||||
$parameter['if condition']['value'] . ") {?>";
|
||||
}
|
||||
} else {
|
||||
$_output .= "while ({$parameter['if condition']}) {?>";
|
||||
}
|
||||
return $_output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Whileclose Class
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
*/
|
||||
class Smarty_Internal_Compile_Whileclose extends Smarty_Internal_CompileBase
|
||||
{
|
||||
/**
|
||||
* Compiles code for the {/while} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||
*
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
|
||||
{
|
||||
$compiler->loopNesting--;
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
$compiler->nocache = $this->closeTag($compiler, array('while'));
|
||||
return "<?php }?>\n";
|
||||
}
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Smarty Extension handler
|
||||
*
|
||||
* Load extensions dynamically
|
||||
*
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
* @property Smarty_Internal_Runtime_Inheritance $_inheritance
|
||||
* @property Smarty_Internal_Runtime_SubTemplate $_subTemplate
|
||||
* @property Smarty_Internal_Runtime_TplFunction $_tplFunction
|
||||
* @property Smarty_Internal_Runtime_Var $_var
|
||||
* @property Smarty_Internal_Runtime_Config $_config
|
||||
* @property Smarty_Internal_Runtime_Foreach $_foreach
|
||||
* @property Smarty_Internal_Runtime_Hhvm $_hhvm
|
||||
* @property Smarty_Internal_Runtime_WriteFile $_writeFile
|
||||
* @property Smarty_Internal_Runtime_ValidateCompiled $_validateCompiled
|
||||
* @property Smarty_Internal_Runtime_CodeFrame $_codeFrame
|
||||
* @property Smarty_Internal_Runtime_FilterHandler $_filterHandler
|
||||
* @property Smarty_Internal_Runtime_GetIncludePath $_getIncludePath
|
||||
* @property Smarty_Internal_Runtime_UpdateScope $_updateScope
|
||||
* @property Smarty_Internal_Runtime_IsCached $_isCached
|
||||
* @property Smarty_Internal_Runtime_CacheModify $_cacheModify
|
||||
* @property Smarty_Internal_Runtime_UpdateCache $_updateCache
|
||||
* @property Smarty_Internal_Method_GetTemplateVars $getTemplateVars
|
||||
* @property Smarty_Internal_Method_Append $append
|
||||
* @property Smarty_Internal_Method_AppendByRef $appendByRef
|
||||
* @property Smarty_Internal_Method_AssignGlobal $assignGlobal
|
||||
* @property Smarty_Internal_Method_AssignByRef $assignByRef
|
||||
* @property Smarty_Internal_Method_LoadFilter $loadFilter
|
||||
* @property Smarty_Internal_Method_LoadPlugin $loadPlugin
|
||||
* @property Smarty_Internal_Method_RegisterFilter $registerFilter
|
||||
* @property Smarty_Internal_Method_RegisterObject $registerObject
|
||||
* @property Smarty_Internal_Method_RegisterPlugin $registerPlugin
|
||||
*/
|
||||
class Smarty_Internal_Extension_Handler
|
||||
{
|
||||
|
||||
public $objType = null;
|
||||
|
||||
/**
|
||||
* Cache for property information from generic getter/setter
|
||||
* Preloaded with names which should not use with generic getter/setter
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_property_info = array('AutoloadFilters' => 0, 'DefaultModifiers' => 0, 'ConfigVars' => 0,
|
||||
'DebugTemplate' => 0, 'RegisteredObject' => 0, 'StreamVariable' => 0,
|
||||
'TemplateVars' => 0,);#
|
||||
|
||||
private $resolvedProperties = array();
|
||||
|
||||
/**
|
||||
* Call external Method
|
||||
*
|
||||
* @param \Smarty_Internal_Data $data
|
||||
* @param string $name external method names
|
||||
* @param array $args argument array
|
||||
*
|
||||
* @return mixed
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public function _callExternalMethod(Smarty_Internal_Data $data, $name, $args)
|
||||
{
|
||||
/* @var Smarty $data ->smarty */
|
||||
$smarty = isset($data->smarty) ? $data->smarty : $data;
|
||||
if (!isset($smarty->ext->$name)) {
|
||||
$class = 'Smarty_Internal_Method_' . ucfirst($name);
|
||||
if (preg_match('/^(set|get)([A-Z].*)$/', $name, $match)) {
|
||||
if (!isset($this->_property_info[$prop = $match[2]])) {
|
||||
// convert camel case to underscored name
|
||||
$this->resolvedProperties[$prop] = $pn = strtolower(join('_',
|
||||
preg_split('/([A-Z][^A-Z]*)/', $prop, - 1,
|
||||
PREG_SPLIT_NO_EMPTY |
|
||||
PREG_SPLIT_DELIM_CAPTURE)));
|
||||
$this->_property_info[$prop] = property_exists($data, $pn) ? 1 :
|
||||
($data->_objType == 2 && property_exists($smarty, $pn) ? 2 : 0);
|
||||
}
|
||||
if ($this->_property_info[$prop]) {
|
||||
$pn = $this->resolvedProperties[$prop];
|
||||
if ($match[1] == 'get') {
|
||||
return $this->_property_info[$prop] == 1 ? $data->$pn : $data->smarty->$pn;
|
||||
} else {
|
||||
return $this->_property_info[$prop] == 1 ? $data->$pn = $args[0] :
|
||||
$data->smarty->$pn = $args[0];
|
||||
}
|
||||
} elseif (!class_exists($class)) {
|
||||
throw new SmartyException("property '$pn' does not exist.");
|
||||
}
|
||||
}
|
||||
if (class_exists($class)) {
|
||||
$callback = array($smarty->ext->$name = new $class(), $name);
|
||||
}
|
||||
} else {
|
||||
$callback = array($smarty->ext->$name, $name);
|
||||
}
|
||||
array_unshift($args, $data);
|
||||
if (isset($callback) && $callback[0]->objMap | $data->_objType) {
|
||||
return call_user_func_array($callback, $args);
|
||||
}
|
||||
return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* set extension property
|
||||
*
|
||||
* @param string $property_name property name
|
||||
* @param mixed $value value
|
||||
*
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public function __set($property_name, $value)
|
||||
{
|
||||
$this->$property_name = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* get extension object
|
||||
*
|
||||
* @param string $property_name property name
|
||||
*
|
||||
* @return mixed|Smarty_Template_Cached
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public function __get($property_name)
|
||||
{
|
||||
// object properties of runtime template extensions will start with '_'
|
||||
if ($property_name[0] == '_') {
|
||||
$class = 'Smarty_Internal_Runtime_' . ucfirst(substr($property_name, 1));
|
||||
} else {
|
||||
$class = 'Smarty_Internal_Method_' . ucfirst($property_name);
|
||||
}
|
||||
if (class_exists($class)) {
|
||||
return $this->$property_name = new $class();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call error handler for undefined method
|
||||
*
|
||||
* @param string $name unknown method-name
|
||||
* @param array $args argument array
|
||||
*
|
||||
* @return mixed
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public function __call($name, $args)
|
||||
{
|
||||
return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), $args);
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Foreach Runtime Methods count
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
**/
|
||||
class Smarty_Internal_Runtime_Foreach
|
||||
{
|
||||
/**
|
||||
* [util function] counts an array, arrayAccess/traversable or PDOStatement object
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return int the count for arrays and objects that implement countable, 1 for other objects that don't, and 0
|
||||
* for empty elements
|
||||
*/
|
||||
public function count($value)
|
||||
{
|
||||
if (is_array($value) === true || $value instanceof Countable) {
|
||||
return count($value);
|
||||
} elseif ($value instanceof IteratorAggregate) {
|
||||
// Note: getIterator() returns a Traversable, not an Iterator
|
||||
// thus rewind() and valid() methods may not be present
|
||||
return iterator_count($value->getIterator());
|
||||
} elseif ($value instanceof Iterator) {
|
||||
if ($value instanceof Generator) {
|
||||
return 1;
|
||||
}
|
||||
return iterator_count($value);
|
||||
} elseif ($value instanceof PDOStatement) {
|
||||
return $value->rowCount();
|
||||
} elseif ($value instanceof Traversable) {
|
||||
return iterator_count($value);
|
||||
} elseif ($value instanceof ArrayAccess) {
|
||||
if ($value->offsetExists(0)) {
|
||||
return 1;
|
||||
}
|
||||
} elseif (is_object($value)) {
|
||||
return count($value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runtime Extension Hhvm
|
||||
*
|
||||
* include patch for modified compiled or cached templates
|
||||
* HHVM does not check if file was modified when including same file multiple times
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
class Smarty_Internal_Runtime_Hhvm
|
||||
{
|
||||
/**
|
||||
* @param \Smarty_Internal_Template $_template
|
||||
* @param string $file file name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function includeHhvm(Smarty_Internal_Template $_template, $file)
|
||||
{
|
||||
$_smarty_tpl = $_template;
|
||||
$tmp_file = $file . preg_replace('![^\w]+!', '_', uniqid(rand(), true)) . '.php';
|
||||
file_put_contents($tmp_file, file_get_contents($file));
|
||||
$result = @include $tmp_file;
|
||||
@unlink($tmp_file);
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -1,233 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Inheritance Runtime Methods processBlock, endChild, init
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
**/
|
||||
class Smarty_Internal_Runtime_Inheritance
|
||||
{
|
||||
|
||||
/**
|
||||
* State machine
|
||||
* - 0 idle next extends will create a new inheritance tree
|
||||
* - 1 processing child template
|
||||
* - 2 wait for next inheritance template
|
||||
* - 3 assume parent template, if child will loaded goto state 1
|
||||
* a call to a sub template resets the state to 0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $state = 0;
|
||||
|
||||
/**
|
||||
* Array of block parameter of known {block} tags
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $blockParameter = array();
|
||||
|
||||
/**
|
||||
* inheritance template nesting level
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $inheritanceLevel = 0;
|
||||
|
||||
/**
|
||||
* inheritance template index
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tplIndex = - 1;
|
||||
|
||||
/**
|
||||
* Array of compiled template file path
|
||||
* - key template index
|
||||
* only used when caching is enabled
|
||||
*
|
||||
* @var []string
|
||||
*/
|
||||
public $compiledFilePath = array();
|
||||
|
||||
/**
|
||||
* Current {block} nesting level
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $blockNesting = 0;
|
||||
|
||||
/**
|
||||
* Initialize inheritance
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||
* @param bool $initChild if true init for child template
|
||||
* @param array $blockNames outer level block name
|
||||
*
|
||||
*/
|
||||
public function init(Smarty_Internal_Template $tpl, $initChild, $blockNames = array())
|
||||
{
|
||||
// if template was from an inner block or template is a parent template create new inheritance root
|
||||
if ($initChild && ($this->blockNesting || $this->state == 3)) {
|
||||
$tpl->ext->_inheritance = new Smarty_Internal_Runtime_Inheritance();
|
||||
$tpl->ext->_inheritance->init($tpl, $initChild, $blockNames);
|
||||
return;
|
||||
}
|
||||
// start of child sub template(s)
|
||||
if ($initChild) {
|
||||
$this->state = 1;
|
||||
if (!$this->inheritanceLevel) {
|
||||
//grab any output of child templates
|
||||
ob_start();
|
||||
}
|
||||
$this->inheritanceLevel ++;
|
||||
}
|
||||
// in parent state {include} will not increment template index
|
||||
if ($this->state != 3) {
|
||||
$this->tplIndex ++;
|
||||
}
|
||||
// if state was waiting for parent change state to parent
|
||||
if ($this->state == 2) {
|
||||
$this->state = 3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End of child template(s)
|
||||
* - if outer level is reached flush output buffer and switch to wait for parent template state
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||
*/
|
||||
public function endChild(Smarty_Internal_Template $tpl)
|
||||
{
|
||||
$this->inheritanceLevel --;
|
||||
if (!$this->inheritanceLevel) {
|
||||
ob_end_clean();
|
||||
$this->state = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process inheritance {block} tag
|
||||
*
|
||||
* $type 0 = {block}:
|
||||
* - search in inheritance template hierarchy for child blocks
|
||||
* if found call it, otherwise call current block
|
||||
* - ignored for outer level blocks in child templates
|
||||
*
|
||||
* $type 1 = {block}:
|
||||
* - nested {block}
|
||||
* - search in inheritance template hierarchy for child blocks
|
||||
* if found call it, otherwise call current block
|
||||
*
|
||||
* $type 2 = {$smarty.block.child}:
|
||||
* - search in inheritance template hierarchy for child blocks
|
||||
* if found call it, otherwise ignore
|
||||
*
|
||||
* $type 3 = {block append} {block prepend}:
|
||||
* - call parent block
|
||||
*
|
||||
* $type 4 = {$smarty.block.parent}:
|
||||
* - call parent block
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||
* @param int $type call type see above
|
||||
* @param string $name block name
|
||||
* @param array $block block parameter
|
||||
* @param array $callStack call stack with block parameters
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function processBlock(Smarty_Internal_Template $tpl, $type = 0, $name, $block, $callStack = array())
|
||||
{
|
||||
if (!isset($this->blockParameter[ $name ])) {
|
||||
$this->blockParameter[ $name ] = array();
|
||||
}
|
||||
if ($this->state == 1) {
|
||||
$block[ 2 ] = count($this->blockParameter[ $name ]);
|
||||
$block[ 3 ] = $this->tplIndex;
|
||||
$this->blockParameter[ $name ][] = $block;
|
||||
return;
|
||||
}
|
||||
if ($type == 3) {
|
||||
if (!empty($callStack)) {
|
||||
$block = array_shift($callStack);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} elseif ($type == 4) {
|
||||
if (!empty($callStack)) {
|
||||
array_shift($callStack);
|
||||
if (empty($callStack)) {
|
||||
throw new SmartyException("inheritance: tag {\$smarty.block.parent} used in parent template block '{$name}'");
|
||||
}
|
||||
$block = array_shift($callStack);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$index = 0;
|
||||
$blockParameter = &$this->blockParameter[ $name ];
|
||||
if ($type == 0) {
|
||||
$index = $block[ 2 ] = count($blockParameter);
|
||||
$block[ 3 ] = $this->tplIndex;
|
||||
$callStack = array(&$block);
|
||||
} elseif ($type == 1) {
|
||||
$block[ 3 ] = $callStack[ 0 ][ 3 ];
|
||||
for ($i = 0; $i < count($blockParameter); $i ++) {
|
||||
if ($blockParameter[ $i ][ 3 ] <= $block[ 3 ]) {
|
||||
$index = $blockParameter[ $i ][ 2 ];
|
||||
}
|
||||
}
|
||||
$block[ 2 ] = $index;
|
||||
$callStack = array(&$block);
|
||||
} elseif ($type == 2) {
|
||||
$index = $callStack[ 0 ][ 2 ];
|
||||
if ($index == 0) {
|
||||
return;
|
||||
}
|
||||
$callStack = $block = array(1 => false);
|
||||
}
|
||||
$index --;
|
||||
// find lowest level child block
|
||||
while ($index >= 0 && ($type || !$block[ 1 ])) {
|
||||
$block = &$blockParameter[ $index ];
|
||||
array_unshift($callStack, $block);
|
||||
if ($block[ 1 ]) {
|
||||
break;
|
||||
}
|
||||
$index --;
|
||||
}
|
||||
if (isset($block[ 'hide' ]) && $index <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->blockNesting ++;
|
||||
// {block append} ?
|
||||
if (isset($block[ 'append' ])) {
|
||||
$appendStack = $callStack;
|
||||
if ($type == 0) {
|
||||
array_shift($appendStack);
|
||||
}
|
||||
$this->processBlock($tpl, 3, $name, null, $appendStack);
|
||||
}
|
||||
// call block of current stack level
|
||||
if (isset($block[6])) {
|
||||
$block[6]($tpl, $callStack);
|
||||
} else {
|
||||
$block[0]($tpl, $callStack);
|
||||
}
|
||||
// {block prepend} ?
|
||||
if (isset($block[ 'prepend' ])) {
|
||||
$prependStack = $callStack;
|
||||
if ($type == 0) {
|
||||
array_shift($prependStack);
|
||||
}
|
||||
$this->processBlock($tpl, 3, $name, null, $prependStack);
|
||||
}
|
||||
$this->blockNesting --;
|
||||
}
|
||||
}
|
@ -1,203 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Sub Template Runtime Methods render, setupSubTemplate
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
**/
|
||||
class Smarty_Internal_Runtime_SubTemplate
|
||||
{
|
||||
|
||||
/**
|
||||
* Subtemplate template object cache
|
||||
*
|
||||
* @var Smarty_Internal_Template[]
|
||||
*/
|
||||
public $tplObjects = array();
|
||||
|
||||
/**
|
||||
* Subtemplate call count
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
public $subTplInfo = array();
|
||||
|
||||
/**
|
||||
* Runtime function to render subtemplate
|
||||
*
|
||||
* @param \Smarty_Internal_Template $parent
|
||||
* @param string $template template name
|
||||
* @param mixed $cache_id cache id
|
||||
* @param mixed $compile_id compile id
|
||||
* @param integer $caching cache mode
|
||||
* @param integer $cache_lifetime life time of cache data
|
||||
* @param array $data passed parameter template variables
|
||||
* @param int $scope scope in which {include} should execute
|
||||
* @param bool $forceTplCache cache template object
|
||||
* @param string $uid file dependency uid
|
||||
* @param string $content_func function name
|
||||
*
|
||||
*/
|
||||
public function render(Smarty_Internal_Template $parent, $template, $cache_id, $compile_id, $caching,
|
||||
$cache_lifetime, $data, $scope, $forceTplCache, $uid = null, $content_func = null)
|
||||
{
|
||||
// if there are cached template objects calculate $templateID
|
||||
$_templateId =
|
||||
!empty($this->tplObjects) ? $parent->smarty->_getTemplateId($template, $cache_id, $compile_id, $caching) :
|
||||
null;
|
||||
// already in template cache?
|
||||
/* @var Smarty_Internal_Template $tpl */
|
||||
if (isset($_templateId) && isset($this->tplObjects[$_templateId])) {
|
||||
// clone cached template object because of possible recursive call
|
||||
$tpl = clone $this->tplObjects[$_templateId];
|
||||
$tpl->parent = $parent;
|
||||
// if $caching mode changed the compiled resource is invalid
|
||||
if ((bool) $tpl->caching !== (bool) $caching) {
|
||||
unset($tpl->compiled);
|
||||
}
|
||||
// get variables from calling scope
|
||||
$tpl->tpl_vars = $parent->tpl_vars;
|
||||
$tpl->config_vars = $parent->config_vars;
|
||||
// get template functions
|
||||
$tpl->tpl_function = $parent->tpl_function;
|
||||
// copy inheritance object?
|
||||
if (isset($parent->ext->_inheritance)) {
|
||||
$tpl->ext->_inheritance = $parent->ext->_inheritance;
|
||||
} else {
|
||||
unset($tpl->ext->_inheritance);
|
||||
}
|
||||
} else {
|
||||
$tpl = clone $parent;
|
||||
$tpl->parent = $parent;
|
||||
if (!isset($tpl->templateId) || $tpl->templateId !== $_templateId) {
|
||||
$tpl->templateId = $_templateId;
|
||||
$tpl->template_resource = $template;
|
||||
$tpl->cache_id = $cache_id;
|
||||
$tpl->compile_id = $compile_id;
|
||||
if (isset($uid)) {
|
||||
// for inline templates we can get all resource information from file dependency
|
||||
if (isset($tpl->compiled->file_dependency[$uid])) {
|
||||
list($filepath, $timestamp, $resource) = $tpl->compiled->file_dependency[$uid];
|
||||
$tpl->source =
|
||||
new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$resource]) ?
|
||||
$tpl->smarty->_cache['resource_handlers'][$resource] :
|
||||
Smarty_Resource::load($tpl->smarty, $resource), $tpl->smarty,
|
||||
$filepath, $resource, $filepath);
|
||||
$tpl->source->filepath = $filepath;
|
||||
$tpl->source->timestamp = $timestamp;
|
||||
$tpl->source->exists = true;
|
||||
$tpl->source->uid = $uid;
|
||||
} else {
|
||||
$tpl->source = null;
|
||||
}
|
||||
} else {
|
||||
$tpl->source = null;
|
||||
}
|
||||
if (!isset($tpl->source)) {
|
||||
$tpl->source = Smarty_Template_Source::load($tpl);
|
||||
unset($tpl->compiled);
|
||||
}
|
||||
unset($tpl->cached);
|
||||
}
|
||||
}
|
||||
$tpl->caching = $caching;
|
||||
$tpl->cache_lifetime = $cache_lifetime;
|
||||
if ($caching == 9999) {
|
||||
$tpl->cached = $parent->cached;
|
||||
}
|
||||
// set template scope
|
||||
$tpl->scope = $scope;
|
||||
$scopePtr = false;
|
||||
if ($scope & ~Smarty::SCOPE_BUBBLE_UP) {
|
||||
if ($scope == Smarty::SCOPE_GLOBAL) {
|
||||
$tpl->tpl_vars = Smarty::$global_tpl_vars;
|
||||
$tpl->config_vars = $tpl->smarty->config_vars;
|
||||
$scopePtr = true;
|
||||
} else {
|
||||
if ($scope == Smarty::SCOPE_PARENT) {
|
||||
$scopePtr = $parent;
|
||||
} elseif ($scope == Smarty::SCOPE_SMARTY) {
|
||||
$scopePtr = $tpl->smarty;
|
||||
} else {
|
||||
$scopePtr = $tpl;
|
||||
while (isset($scopePtr->parent)) {
|
||||
if ($scopePtr->parent->_objType != 2 && $scope & Smarty::SCOPE_TPL_ROOT) {
|
||||
break;
|
||||
}
|
||||
$scopePtr = $scopePtr->parent;
|
||||
}
|
||||
}
|
||||
$tpl->tpl_vars = $scopePtr->tpl_vars;
|
||||
$tpl->config_vars = $scopePtr->config_vars;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->tplObjects[$tpl->_getTemplateId()]) && !$tpl->source->handler->recompiled) {
|
||||
// if template is called multiple times set flag to to cache template objects
|
||||
$forceTplCache = $forceTplCache ||
|
||||
(isset($this->subTplInfo[$tpl->template_resource]) && $this->subTplInfo[$tpl->template_resource] > 1);
|
||||
// check if template object should be cached
|
||||
if ($tpl->parent->_objType == 2 && isset($this->tplObjects[$tpl->parent->templateId]) ||
|
||||
($forceTplCache && $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC) ||
|
||||
($tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)
|
||||
) {
|
||||
$this->tplObjects[$tpl->_getTemplateId()] = $tpl;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($data)) {
|
||||
// set up variable values
|
||||
foreach ($data as $_key => $_val) {
|
||||
$tpl->tpl_vars[$_key] = new Smarty_Variable($_val);
|
||||
}
|
||||
}
|
||||
if (isset($uid)) {
|
||||
if ($parent->smarty->debugging) {
|
||||
$parent->smarty->_debug->start_template($tpl);
|
||||
$parent->smarty->_debug->start_render($tpl);
|
||||
}
|
||||
$tpl->compiled->getRenderedTemplateCode($tpl, $content_func);
|
||||
if ($parent->smarty->debugging) {
|
||||
$parent->smarty->_debug->end_template($tpl);
|
||||
$parent->smarty->_debug->end_render($tpl);
|
||||
}
|
||||
if ($tpl->caching == 9999 && $tpl->compiled->has_nocache_code) {
|
||||
$parent->cached->hashes[$tpl->compiled->nocache_hash] = true;
|
||||
}
|
||||
} else {
|
||||
if (isset($tpl->compiled)) {
|
||||
$tpl->compiled->render($tpl);
|
||||
} else {
|
||||
$tpl->render();
|
||||
}
|
||||
}
|
||||
if ($scopePtr) {
|
||||
if ($scope == Smarty::SCOPE_GLOBAL) {
|
||||
Smarty::$global_tpl_vars = $tpl->tpl_vars;
|
||||
$tpl->smarty->config_vars = $tpl->config_vars;
|
||||
} else {
|
||||
$scopePtr->tpl_vars = $tpl->tpl_vars;
|
||||
$scopePtr->config_vars = $tpl->config_vars;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get called subtemplates from compiled template and save call count
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
*/
|
||||
public function registerSubTemplates(Smarty_Internal_Template $tpl)
|
||||
{
|
||||
foreach ($tpl->compiled->includes as $name => $count) {
|
||||
if (isset($this->subTplInfo[$name])) {
|
||||
$this->subTplInfo[$name] += $count;
|
||||
} else {
|
||||
$this->subTplInfo[$name] = $count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tplfunc Runtime Methods callTemplateFunction
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
**/
|
||||
class Smarty_Internal_Runtime_TplFunction
|
||||
{
|
||||
/**
|
||||
* Call template function
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object
|
||||
* @param string $name template function name
|
||||
* @param array $params parameter array
|
||||
* @param bool $nocache true if called nocache
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function callTemplateFunction(Smarty_Internal_Template $tpl, $name, $params, $nocache)
|
||||
{
|
||||
if (isset($tpl->tpl_function[$name])) {
|
||||
if (!$tpl->caching || ($tpl->caching && $nocache)) {
|
||||
$function = $tpl->tpl_function[$name]['call_name'];
|
||||
} else {
|
||||
if (isset($tpl->tpl_function[$name]['call_name_caching'])) {
|
||||
$function = $tpl->tpl_function[$name]['call_name_caching'];
|
||||
} else {
|
||||
$function = $tpl->tpl_function[$name]['call_name'];
|
||||
}
|
||||
}
|
||||
if (function_exists($function)) {
|
||||
$function ($tpl, $params);
|
||||
return;
|
||||
}
|
||||
// try to load template function dynamically
|
||||
if ($this->addTplFuncToCache($tpl, $name, $function)) {
|
||||
$function ($tpl, $params);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new SmartyException("Unable to find template function '{$name}'");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Add template function to cache file for nocache calls
|
||||
*
|
||||
* @param Smarty_Internal_Template $tpl
|
||||
* @param string $_name template function name
|
||||
* @param string $_function PHP function name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function addTplFuncToCache(Smarty_Internal_Template $tpl, $_name, $_function)
|
||||
{
|
||||
$funcParam = $tpl->tpl_function[$_name];
|
||||
if (is_file($funcParam['compiled_filepath'])) {
|
||||
// read compiled file
|
||||
$code = file_get_contents($funcParam['compiled_filepath']);
|
||||
// grab template function
|
||||
if (preg_match("/\/\* {$_function} \*\/([\S\s]*?)\/\*\/ {$_function} \*\//", $code, $match)) {
|
||||
// grab source info from file dependency
|
||||
preg_match("/\s*'{$funcParam['uid']}'([\S\s]*?)\),/", $code, $match1);
|
||||
unset($code);
|
||||
// make PHP function known
|
||||
eval($match[0]);
|
||||
if (function_exists($_function)) {
|
||||
// search cache file template
|
||||
$tplPtr = $tpl;
|
||||
while (!isset($tplPtr->cached) && isset($tplPtr->parent)) {
|
||||
$tplPtr = $tplPtr->parent;
|
||||
}
|
||||
// add template function code to cache file
|
||||
if (isset($tplPtr->cached)) {
|
||||
$cache = $tplPtr->cached;
|
||||
$content = $cache->read($tplPtr);
|
||||
if ($content) {
|
||||
// check if we must update file dependency
|
||||
if (!preg_match("/'{$funcParam['uid']}'(.*?)'nocache_hash'/", $content, $match2)) {
|
||||
$content = preg_replace("/('file_dependency'(.*?)\()/", "\\1{$match1[0]}", $content);
|
||||
}
|
||||
$tplPtr->smarty->ext->_updateCache->write($cache, $tplPtr, preg_replace('/\s*\?>\s*$/', "\n", $content) . "\n" .
|
||||
preg_replace(array('/^\s*<\?php\s+/', '/\s*\?>\s*$/'), "\n",
|
||||
$match[0]));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runtime Methods updateScope
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
**/
|
||||
class Smarty_Internal_Runtime_UpdateScope
|
||||
{
|
||||
/**
|
||||
* Update new assigned template variable in other effected scopes
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object
|
||||
* @param string $varName variable name
|
||||
* @param int $scope scope to which bubble up variable value
|
||||
*/
|
||||
public function updateScope(Smarty_Internal_Template $tpl, $varName, $scope = Smarty::SCOPE_LOCAL)
|
||||
{
|
||||
if (!$scope && !$tpl->scope) {
|
||||
return;
|
||||
}
|
||||
foreach (array($scope, $tpl->scope) as $s) {
|
||||
$s = ($bubble_up = $s >= Smarty::SCOPE_BUBBLE_UP) ? $s - Smarty::SCOPE_BUBBLE_UP : $s;
|
||||
if ($bubble_up && $s) {
|
||||
$ptr = $tpl->parent;
|
||||
if (isset($ptr)) {
|
||||
$ptr->tpl_vars[$varName] = $tpl->tpl_vars[$varName];
|
||||
$ptr = $ptr->parent;
|
||||
}
|
||||
if ($s == Smarty::SCOPE_PARENT) {
|
||||
continue;
|
||||
}
|
||||
while (isset($ptr) && $ptr->_objType == 2) {
|
||||
$ptr->tpl_vars[$varName] = $tpl->tpl_vars[$varName];
|
||||
$ptr = $ptr->parent;
|
||||
}
|
||||
if ($s == Smarty::SCOPE_TPL_ROOT) {
|
||||
continue;
|
||||
} elseif ($s == Smarty::SCOPE_SMARTY) {
|
||||
$tpl->smarty->tpl_vars[$varName] = $tpl->tpl_vars[$varName];
|
||||
} elseif ($s == Smarty::SCOPE_GLOBAL) {
|
||||
Smarty::$global_tpl_vars[$varName] = $tpl->tpl_vars[$varName];
|
||||
} elseif ($s == Smarty::SCOPE_ROOT) {
|
||||
while (isset($ptr->parent)) {
|
||||
$ptr = $ptr->parent;
|
||||
}
|
||||
$ptr->tpl_vars[$varName] = $tpl->tpl_vars[$varName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runtime Methods decodeProperties
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
**/
|
||||
class Smarty_Internal_Runtime_ValidateCompiled
|
||||
{
|
||||
/**
|
||||
* This function is executed automatically when a compiled or cached template file is included
|
||||
* - Decode saved properties from compiled template and cache files
|
||||
* - Check if compiled or cache file is valid
|
||||
*
|
||||
* @param array $properties special template properties
|
||||
* @param bool $cache flag if called from cache file
|
||||
*
|
||||
* @return bool flag if compiled or cache file is valid
|
||||
*/
|
||||
public function decodeProperties(Smarty_Internal_Template $tpl, $properties, $cache = false)
|
||||
{
|
||||
$is_valid = true;
|
||||
if (Smarty::SMARTY_VERSION != $properties['version']) {
|
||||
// new version must rebuild
|
||||
$is_valid = false;
|
||||
} elseif ($is_valid && !empty($properties['file_dependency']) &&
|
||||
((!$cache && $tpl->smarty->compile_check) || $tpl->smarty->compile_check == 1)
|
||||
) {
|
||||
// check file dependencies at compiled code
|
||||
foreach ($properties['file_dependency'] as $_file_to_check) {
|
||||
if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'extends' || $_file_to_check[2] == 'php') {
|
||||
if ($tpl->source->filepath == $_file_to_check[0]) {
|
||||
// do not recheck current template
|
||||
continue;
|
||||
//$mtime = $tpl->source->getTimeStamp();
|
||||
} else {
|
||||
// file and php types can be checked without loading the respective resource handlers
|
||||
$mtime = is_file($_file_to_check[0]) ? filemtime($_file_to_check[0]) : false;
|
||||
}
|
||||
} elseif ($_file_to_check[2] == 'string') {
|
||||
continue;
|
||||
} else {
|
||||
$handler = Smarty_Resource::load($tpl->smarty, $_file_to_check[2]);
|
||||
if ($handler->checkTimestamps()) {
|
||||
$source = Smarty_Template_Source::load($tpl, $tpl->smarty, $_file_to_check[ 0 ]);
|
||||
$mtime = $source->getTimeStamp();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!$mtime || $mtime > $_file_to_check[1]) {
|
||||
$is_valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($cache) {
|
||||
// CACHING_LIFETIME_SAVED cache expiry has to be validated here since otherwise we'd define the unifunc
|
||||
if ($tpl->caching === Smarty::CACHING_LIFETIME_SAVED && $properties['cache_lifetime'] >= 0 &&
|
||||
(time() > ($tpl->cached->timestamp + $properties['cache_lifetime']))
|
||||
) {
|
||||
$is_valid = false;
|
||||
}
|
||||
$tpl->cached->cache_lifetime = $properties['cache_lifetime'];
|
||||
$tpl->cached->valid = $is_valid;
|
||||
$resource = $tpl->cached;
|
||||
} else {
|
||||
$tpl->mustCompile = !$is_valid;
|
||||
$resource = $tpl->compiled;
|
||||
$resource->includes = isset($properties['includes']) ? $properties['includes'] : array();
|
||||
}
|
||||
if ($is_valid) {
|
||||
$resource->unifunc = $properties['unifunc'];
|
||||
$resource->has_nocache_code = $properties['has_nocache_code'];
|
||||
// $tpl->compiled->nocache_hash = $properties['nocache_hash'];
|
||||
$resource->file_dependency = $properties['file_dependency'];
|
||||
if (isset($properties['tpl_function'])) {
|
||||
$tpl->tpl_function = $properties['tpl_function'];
|
||||
}
|
||||
}
|
||||
return $is_valid && !function_exists($properties['unifunc']);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runtime Methods createLocalArrayVariable
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
**/
|
||||
class Smarty_Internal_Runtime_Var
|
||||
{
|
||||
/**
|
||||
* Template code runtime function to create a local Smarty variable for array assignments
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object
|
||||
* @param string $varName template variable name
|
||||
* @param bool $nocache cache mode of variable
|
||||
*/
|
||||
public function createLocalArrayVariable(Smarty_Internal_Template $tpl, $varName, $nocache = false)
|
||||
{
|
||||
if (!isset($tpl->tpl_vars[$varName])) {
|
||||
$tpl->tpl_vars[$varName] = new Smarty_Variable(array(), $nocache);
|
||||
} else {
|
||||
$tpl->tpl_vars[$varName] = clone $tpl->tpl_vars[$varName];
|
||||
if (!(is_array($tpl->tpl_vars[$varName]->value) ||
|
||||
$tpl->tpl_vars[$varName]->value instanceof ArrayAccess)
|
||||
) {
|
||||
settype($tpl->tpl_vars[$varName]->value, 'array');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,376 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Template
|
||||
* This file contains the Smarty template engine
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Template
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main class with template data structures and methods
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Template
|
||||
*
|
||||
* @property Smarty_Template_Source|Smarty_Template_Config $source
|
||||
* @property Smarty_Template_Compiled $compiled
|
||||
* @property Smarty_Template_Cached $cached
|
||||
* @method bool mustCompile()
|
||||
*/
|
||||
class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
{
|
||||
/**
|
||||
* This object type (Smarty = 1, template = 2, data = 4)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $_objType = 2;
|
||||
|
||||
/**
|
||||
* Global smarty instance
|
||||
*
|
||||
* @var Smarty
|
||||
*/
|
||||
public $smarty = null;
|
||||
|
||||
/**
|
||||
* Source instance
|
||||
*
|
||||
* @var Smarty_Template_Source|Smarty_Template_Config
|
||||
*/
|
||||
public $source = null;
|
||||
|
||||
/**
|
||||
* Template resource
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $template_resource = null;
|
||||
|
||||
/**
|
||||
* flag if compiled template is invalid and must be (re)compiled
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $mustCompile = null;
|
||||
|
||||
/**
|
||||
* Template Id
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
public $templateId = null;
|
||||
|
||||
/**
|
||||
* Known template functions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tpl_function = array();
|
||||
|
||||
/**
|
||||
* Scope in which template is rendered
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $scope = 0;
|
||||
|
||||
/**
|
||||
* Create template data object
|
||||
* Some of the global Smarty settings copied to template scope
|
||||
* It load the required template resources and caching plugins
|
||||
*
|
||||
* @param string $template_resource template resource string
|
||||
* @param Smarty $smarty Smarty instance
|
||||
* @param \Smarty_Internal_Template|\Smarty|\Smarty_Internal_Data $_parent back pointer to parent object
|
||||
* with variables or null
|
||||
* @param mixed $_cache_id cache id or null
|
||||
* @param mixed $_compile_id compile id or null
|
||||
* @param bool $_caching use caching?
|
||||
* @param int $_cache_lifetime cache life-time in seconds
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function __construct($template_resource, Smarty $smarty, Smarty_Internal_Data $_parent = null,
|
||||
$_cache_id = null, $_compile_id = null, $_caching = null, $_cache_lifetime = null)
|
||||
{
|
||||
$this->smarty = &$smarty;
|
||||
// Smarty parameter
|
||||
$this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id;
|
||||
$this->compile_id = $_compile_id === null ? $this->smarty->compile_id : $_compile_id;
|
||||
$this->caching = $_caching === null ? $this->smarty->caching : $_caching;
|
||||
if ($this->caching === true) {
|
||||
$this->caching = Smarty::CACHING_LIFETIME_CURRENT;
|
||||
}
|
||||
$this->cache_lifetime = $_cache_lifetime === null ? $this->smarty->cache_lifetime : $_cache_lifetime;
|
||||
$this->parent = $_parent;
|
||||
// Template resource
|
||||
$this->template_resource = $template_resource;
|
||||
$this->source = Smarty_Template_Source::load($this);
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* render template
|
||||
*
|
||||
* @param bool $merge_tpl_vars if true parent template variables merged in to local scope
|
||||
* @param bool $no_output_filter if true do not run output filter
|
||||
* @param bool $display true: display, false: fetch null: subtemplate
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws SmartyException
|
||||
* @return string rendered template output
|
||||
*/
|
||||
public function render($no_output_filter = true, $display = null)
|
||||
{
|
||||
$parentIsTpl = isset($this->parent) && $this->parent->_objType == 2;
|
||||
if ($this->smarty->debugging) {
|
||||
$this->smarty->_debug->start_template($this, $display);
|
||||
}
|
||||
// checks if template exists
|
||||
if (!$this->source->exists) {
|
||||
if ($parentIsTpl) {
|
||||
$parent_resource = " in '{$this->parent->template_resource}'";
|
||||
} else {
|
||||
$parent_resource = '';
|
||||
}
|
||||
throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}");
|
||||
}
|
||||
// disable caching for evaluated code
|
||||
if ($this->source->handler->recompiled) {
|
||||
$this->caching = false;
|
||||
}
|
||||
// read from cache or render
|
||||
$isCacheTpl =
|
||||
$this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED;
|
||||
if ($isCacheTpl) {
|
||||
if (!isset($this->cached)) {
|
||||
$this->loadCached();
|
||||
}
|
||||
$this->cached->render($this, $no_output_filter);
|
||||
} elseif ($this->source->handler->uncompiled) {
|
||||
$this->source->render($this);
|
||||
} else {
|
||||
if (!isset($this->compiled)) {
|
||||
$this->loadCompiled();
|
||||
}
|
||||
$this->compiled->render($this);
|
||||
}
|
||||
|
||||
// display or fetch
|
||||
if ($display) {
|
||||
if ($this->caching && $this->smarty->cache_modified_check) {
|
||||
$this->smarty->ext->_cachemodify->cacheModifiedCheck($this->cached, $this,
|
||||
isset($content) ? $content : ob_get_clean());
|
||||
} else {
|
||||
if ((!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled) &&
|
||||
!$no_output_filter && (isset($this->smarty->autoload_filters['output']) ||
|
||||
isset($this->smarty->registered_filters['output']))
|
||||
) {
|
||||
echo $this->smarty->ext->_filterHandler->runFilter('output', ob_get_clean(), $this);
|
||||
} else {
|
||||
ob_end_flush();
|
||||
flush();
|
||||
}
|
||||
}
|
||||
if ($this->smarty->debugging) {
|
||||
$this->smarty->_debug->end_template($this);
|
||||
// debug output
|
||||
$this->smarty->_debug->display_debug($this, true);
|
||||
}
|
||||
return '';
|
||||
} else {
|
||||
if ($this->smarty->debugging) {
|
||||
$this->smarty->_debug->end_template($this);
|
||||
if ($this->smarty->debugging === 2 && $display === false) {
|
||||
$this->smarty->_debug->display_debug($this, true);
|
||||
}
|
||||
}
|
||||
if ($parentIsTpl) {
|
||||
if (!empty($this->tpl_function)) {
|
||||
$this->parent->tpl_function = array_merge($this->parent->tpl_function, $this->tpl_function);
|
||||
}
|
||||
foreach ($this->compiled->required_plugins as $code => $tmp1) {
|
||||
foreach ($tmp1 as $name => $tmp) {
|
||||
foreach ($tmp as $type => $data) {
|
||||
$this->parent->compiled->required_plugins[$code][$name][$type] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$no_output_filter &&
|
||||
(!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled) &&
|
||||
(isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))
|
||||
) {
|
||||
return $this->smarty->ext->_filterHandler->runFilter('output', ob_get_clean(), $this);
|
||||
}
|
||||
// return cache content
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the template
|
||||
* If the template is not evaluated the compiled template is saved on disk
|
||||
*/
|
||||
public function compileTemplateSource()
|
||||
{
|
||||
return $this->compiled->compileTemplateSource($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the content to cache resource
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function writeCachedContent($content)
|
||||
{
|
||||
return $this->smarty->ext->_updateCache->writeCachedContent($this->cached, $this, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique template id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function _getTemplateId()
|
||||
{
|
||||
return isset($this->templateId) ? $this->templateId : $this->templateId =
|
||||
$this->smarty->_getTemplateId($this->template_resource, $this->cache_id, $this->compile_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* runtime error not matching capture tags
|
||||
*/
|
||||
public function capture_error()
|
||||
{
|
||||
throw new SmartyException("Not matching {capture} open/close in \"{$this->template_resource}\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* Load compiled object
|
||||
*
|
||||
*/
|
||||
public function loadCompiled()
|
||||
{
|
||||
if (!isset($this->compiled)) {
|
||||
$this->compiled = Smarty_Template_Compiled::load($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load cached object
|
||||
*
|
||||
*/
|
||||
public function loadCached()
|
||||
{
|
||||
if (!isset($this->cached)) {
|
||||
$this->cached = Smarty_Template_Cached::load($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load compiler object
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function loadCompiler()
|
||||
{
|
||||
if (!class_exists($this->source->handler->compiler_class)) {
|
||||
$this->smarty->loadPlugin($this->source->handler->compiler_class);
|
||||
}
|
||||
$this->compiler = new $this->source->handler->compiler_class($this->source->handler->template_lexer_class,
|
||||
$this->source->handler->template_parser_class,
|
||||
$this->smarty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle unknown class methods
|
||||
*
|
||||
* @param string $name unknown method-name
|
||||
* @param array $args argument array
|
||||
*
|
||||
* @return mixed
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public function __call($name, $args)
|
||||
{
|
||||
// method of Smarty object?
|
||||
if (method_exists($this->smarty, $name)) {
|
||||
return call_user_func_array(array($this->smarty, $name), $args);
|
||||
}
|
||||
// parent
|
||||
return parent::__call($name, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* set Smarty property in template context
|
||||
*
|
||||
* @param string $property_name property name
|
||||
* @param mixed $value value
|
||||
*
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public function __set($property_name, $value)
|
||||
{
|
||||
switch ($property_name) {
|
||||
case 'compiled':
|
||||
case 'cached':
|
||||
case 'compiler':
|
||||
$this->$property_name = $value;
|
||||
return;
|
||||
default:
|
||||
// Smarty property ?
|
||||
if (property_exists($this->smarty, $property_name)) {
|
||||
$this->smarty->$property_name = $value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new SmartyException("invalid template property '$property_name'.");
|
||||
}
|
||||
|
||||
/**
|
||||
* get Smarty property in template context
|
||||
*
|
||||
* @param string $property_name property name
|
||||
*
|
||||
* @return mixed|Smarty_Template_Cached
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public function __get($property_name)
|
||||
{
|
||||
switch ($property_name) {
|
||||
case 'compiled':
|
||||
$this->loadCompiled();
|
||||
return $this->compiled;
|
||||
|
||||
case 'cached':
|
||||
$this->loadCached();
|
||||
return $this->cached;
|
||||
|
||||
case 'compiler':
|
||||
$this->loadCompiler();
|
||||
return $this->compiler;
|
||||
default:
|
||||
// Smarty property ?
|
||||
if (property_exists($this->smarty, $property_name)) {
|
||||
return $this->smarty->$property_name;
|
||||
}
|
||||
}
|
||||
throw new SmartyException("template property '$property_name' does not exist.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Template data object destructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) {
|
||||
$this->cached->handler->releaseLock($this->smarty, $this->cached);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Smarty Method AppendByRef
|
||||
*
|
||||
* Smarty::appendByRef() method
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
class Smarty_Internal_Undefined
|
||||
{
|
||||
|
||||
/**
|
||||
* This function is executed automatically when a compiled or cached template file is included
|
||||
* - Decode saved properties from compiled template and cache files
|
||||
* - Check if compiled or cache file is valid
|
||||
*
|
||||
* @param array $properties special template properties
|
||||
* @param bool $cache flag if called from cache file
|
||||
*
|
||||
* @return bool flag if compiled or cache file is valid
|
||||
*/
|
||||
public function decodeProperties($tpl, $properties, $cache = false)
|
||||
{
|
||||
if ($cache) {
|
||||
$tpl->cached->valid = false;
|
||||
} else {
|
||||
$tpl->mustCompile = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call error handler for undefined method
|
||||
*
|
||||
* @param string $name unknown method-name
|
||||
* @param array $args argument array
|
||||
*
|
||||
* @return mixed
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public function __call($name, $args)
|
||||
{
|
||||
throw new SmartyException(get_class($args[0]) . "->{$name}() undefined method");
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Resource Plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage TemplateResources
|
||||
* @author Rodney Rehm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Resource Plugin
|
||||
* Base implementation for resource plugins that don't compile cache
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage TemplateResources
|
||||
*/
|
||||
abstract class Smarty_Resource_Recompiled extends Smarty_Resource
|
||||
{
|
||||
/**
|
||||
* Flag that it's an recompiled resource
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $recompiled = true;
|
||||
|
||||
/**
|
||||
* Resource does implement populateCompiledFilepath() method
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $hasCompiledHandler = true;
|
||||
|
||||
/**
|
||||
* populate Compiled Object with compiled filepath
|
||||
*
|
||||
* @param Smarty_Template_Compiled $compiled compiled object
|
||||
* @param Smarty_Internal_Template $_template template object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template)
|
||||
{
|
||||
$compiled->filepath = false;
|
||||
$compiled->timestamp = false;
|
||||
$compiled->exists = false;
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Resource Plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage TemplateResources
|
||||
* @author Rodney Rehm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Resource Plugin
|
||||
* Base implementation for resource plugins that don't use the compiler
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage TemplateResources
|
||||
*/
|
||||
abstract class Smarty_Resource_Uncompiled extends Smarty_Resource
|
||||
{
|
||||
/**
|
||||
* Flag that it's an uncompiled resource
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $uncompiled = true;
|
||||
|
||||
/**
|
||||
* Resource does implement populateCompiledFilepath() method
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $hasCompiledHandler = true;
|
||||
|
||||
/**
|
||||
* Render and output the template (without using the compiler)
|
||||
*
|
||||
* @param Smarty_Template_Source $source source object
|
||||
* @param Smarty_Internal_Template $_template template object
|
||||
*
|
||||
* @throws SmartyException on failure
|
||||
*/
|
||||
abstract public function renderUncompiled(Smarty_Template_Source $source, Smarty_Internal_Template $_template);
|
||||
|
||||
/**
|
||||
* populate compiled object with compiled filepath
|
||||
*
|
||||
* @param Smarty_Template_Compiled $compiled compiled object
|
||||
* @param Smarty_Internal_Template $_template template object (is ignored)
|
||||
*/
|
||||
public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template)
|
||||
{
|
||||
$compiled->filepath = false;
|
||||
$compiled->timestamp = false;
|
||||
$compiled->exists = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* render compiled template code
|
||||
*
|
||||
* @param Smarty_Internal_Template $_template
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function render($_template)
|
||||
{
|
||||
$level = ob_get_level();
|
||||
ob_start();
|
||||
try {
|
||||
$this->renderUncompiled($_template->source, $_template);
|
||||
return ob_get_clean();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
while (ob_get_level() > $level) {
|
||||
ob_end_clean();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,297 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Smarty Resource Data Object
|
||||
* Meta Data Container for Template Files
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage TemplateResources
|
||||
* @author Rodney Rehm
|
||||
* @property string $content compiled content
|
||||
*/
|
||||
class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
|
||||
{
|
||||
|
||||
/**
|
||||
* nocache hash
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $nocache_hash = null;
|
||||
|
||||
/**
|
||||
* get a Compiled Object of this source
|
||||
*
|
||||
* @param Smarty_Internal_Template $_template template object
|
||||
*
|
||||
* @return Smarty_Template_Compiled compiled object
|
||||
*/
|
||||
static function load($_template)
|
||||
{
|
||||
// check runtime cache
|
||||
if (!$_template->source->handler->recompiled &&
|
||||
($_template->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)
|
||||
) {
|
||||
$_cache_key = $_template->source->unique_resource . '#';
|
||||
if ($_template->caching) {
|
||||
$_cache_key .= 'caching#';
|
||||
}
|
||||
$_cache_key .= $_template->compile_id;
|
||||
if (isset($_template->source->compileds[$_cache_key])) {
|
||||
return $_template->source->compileds[$_cache_key];
|
||||
}
|
||||
}
|
||||
$compiled = new Smarty_Template_Compiled();
|
||||
if ($_template->source->handler->hasCompiledHandler) {
|
||||
$_template->source->handler->populateCompiledFilepath($compiled, $_template);
|
||||
} else {
|
||||
$compiled->populateCompiledFilepath($_template);
|
||||
}
|
||||
// runtime cache
|
||||
if (!$_template->source->handler->recompiled &&
|
||||
($_template->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)
|
||||
) {
|
||||
$_template->source->compileds[$_cache_key] = $compiled;
|
||||
}
|
||||
return $compiled;
|
||||
}
|
||||
|
||||
/**
|
||||
* populate Compiled Object with compiled filepath
|
||||
*
|
||||
* @param Smarty_Internal_Template $_template template object
|
||||
**/
|
||||
public function populateCompiledFilepath(Smarty_Internal_Template $_template)
|
||||
{
|
||||
$_compile_id = isset($_template->compile_id) ? preg_replace('![^\w]+!', '_', $_template->compile_id) : null;
|
||||
if ($_template->source->isConfig) {
|
||||
$_flag = '_' .
|
||||
((int) $_template->smarty->config_read_hidden + (int) $_template->smarty->config_booleanize * 2 +
|
||||
(int) $_template->smarty->config_overwrite * 4);
|
||||
} else {
|
||||
$_flag =
|
||||
'_' . ((int) $_template->smarty->merge_compiled_includes + (int) $_template->smarty->escape_html * 2);
|
||||
}
|
||||
$_filepath = $_template->source->uid . $_flag;
|
||||
// if use_sub_dirs, break file into directories
|
||||
if ($_template->smarty->use_sub_dirs) {
|
||||
$_filepath = substr($_filepath, 0, 2) . DS . substr($_filepath, 2, 2) . DS . substr($_filepath, 4, 2) . DS .
|
||||
$_filepath;
|
||||
}
|
||||
$_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
|
||||
if (isset($_compile_id)) {
|
||||
$_filepath = $_compile_id . $_compile_dir_sep . $_filepath;
|
||||
}
|
||||
// caching token
|
||||
if ($_template->caching) {
|
||||
$_cache = '.cache';
|
||||
} else {
|
||||
$_cache = '';
|
||||
}
|
||||
$_compile_dir = $_template->smarty->getCompileDir();
|
||||
// set basename if not specified
|
||||
$_basename = $_template->source->handler->getBasename($_template->source);
|
||||
if ($_basename === null) {
|
||||
$_basename = basename(preg_replace('![^\w]+!', '_', $_template->source->name));
|
||||
}
|
||||
// separate (optional) basename by dot
|
||||
if ($_basename) {
|
||||
$_basename = '.' . $_basename;
|
||||
}
|
||||
|
||||
$this->filepath = $_compile_dir . $_filepath . '.' . $_template->source->type . $_basename . $_cache . '.php';
|
||||
$this->exists = is_file($this->filepath);
|
||||
if (!$this->exists) {
|
||||
$this->timestamp = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* load compiled template or compile from source
|
||||
*
|
||||
* @param Smarty_Internal_Template $_template
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function process(Smarty_Internal_Template $_template)
|
||||
{
|
||||
$_smarty_tpl = $_template;
|
||||
if ($_template->source->handler->recompiled || !$_template->compiled->exists ||
|
||||
$_template->smarty->force_compile || ($_template->smarty->compile_check &&
|
||||
$_template->source->getTimeStamp() > $_template->compiled->getTimeStamp())
|
||||
) {
|
||||
$this->compileTemplateSource($_template);
|
||||
$compileCheck = $_template->smarty->compile_check;
|
||||
$_template->smarty->compile_check = false;
|
||||
if ($_template->source->handler->recompiled) {
|
||||
$level = ob_get_level();
|
||||
ob_start();
|
||||
try {
|
||||
eval("?>" . $this->content);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
while (ob_get_level() > $level) {
|
||||
ob_end_clean();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
ob_get_clean();
|
||||
$this->content = null;
|
||||
} else {
|
||||
$this->loadCompiledTemplate($_template);
|
||||
}
|
||||
$_template->smarty->compile_check = $compileCheck;
|
||||
} else {
|
||||
$_template->mustCompile = true;
|
||||
@include($_template->compiled->filepath);
|
||||
if ($_template->mustCompile) {
|
||||
$this->compileTemplateSource($_template);
|
||||
$compileCheck = $_template->smarty->compile_check;
|
||||
$_template->smarty->compile_check = false;
|
||||
$this->loadCompiledTemplate($_template);
|
||||
$_template->smarty->compile_check = $compileCheck;
|
||||
}
|
||||
}
|
||||
$_template->smarty->ext->_subTemplate->registerSubTemplates($_template);
|
||||
|
||||
$this->processed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load fresh compiled template by including the PHP file
|
||||
* HHVM requires a work around because of a PHP incompatibility
|
||||
*
|
||||
* @param \Smarty_Internal_Template $_template
|
||||
*/
|
||||
private function loadCompiledTemplate(Smarty_Internal_Template $_template)
|
||||
{
|
||||
if (function_exists('opcache_invalidate')) {
|
||||
opcache_invalidate($_template->compiled->filepath);
|
||||
}
|
||||
$_smarty_tpl = $_template;
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$_template->smarty->ext->_hhvm->includeHhvm($_template, $_template->compiled->filepath);
|
||||
} else {
|
||||
include($_template->compiled->filepath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* render compiled template code
|
||||
*
|
||||
* @param Smarty_Internal_Template $_template
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function render(Smarty_Internal_Template $_template)
|
||||
{
|
||||
if ($_template->smarty->debugging) {
|
||||
$_template->smarty->_debug->start_render($_template);
|
||||
}
|
||||
if (!$this->processed) {
|
||||
$this->process($_template);
|
||||
}
|
||||
if (isset($_template->cached)) {
|
||||
$_template->cached->file_dependency =
|
||||
array_merge($_template->cached->file_dependency, $this->file_dependency);
|
||||
}
|
||||
$this->getRenderedTemplateCode($_template);
|
||||
if ($_template->caching && $this->has_nocache_code) {
|
||||
$_template->cached->hashes[$this->nocache_hash] = true;
|
||||
}
|
||||
if (isset($_template->parent) && $_template->parent->_objType == 2 && !empty($_template->tpl_function)) {
|
||||
$_template->parent->tpl_function = array_merge($_template->parent->tpl_function, $_template->tpl_function);
|
||||
}
|
||||
if ($_template->smarty->debugging) {
|
||||
$_template->smarty->_debug->end_render($_template);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* compile template from source
|
||||
*
|
||||
* @param Smarty_Internal_Template $_template
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function compileTemplateSource(Smarty_Internal_Template $_template)
|
||||
{
|
||||
$_template->source->compileds = array();
|
||||
$this->file_dependency = array();
|
||||
$this->tpl_function = array();
|
||||
$this->includes = array();
|
||||
$this->nocache_hash = null;
|
||||
$this->unifunc = null;
|
||||
// compile locking
|
||||
if (!$_template->source->handler->recompiled) {
|
||||
if ($saved_timestamp = $_template->compiled->getTimeStamp()) {
|
||||
touch($_template->compiled->filepath);
|
||||
}
|
||||
}
|
||||
// call compiler
|
||||
try {
|
||||
$_template->loadCompiler();
|
||||
$code = $_template->compiler->compileTemplate($_template);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
// restore old timestamp in case of error
|
||||
if (!$_template->source->handler->recompiled && $saved_timestamp) {
|
||||
touch($_template->compiled->filepath, $saved_timestamp);
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
// compiling succeeded
|
||||
if ($_template->compiler->write_compiled_code) {
|
||||
// write compiled template
|
||||
$this->write($_template, $code);
|
||||
$code = '';
|
||||
}
|
||||
// release compiler object to free memory
|
||||
unset($_template->compiler);
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write compiled code by handler
|
||||
*
|
||||
* @param Smarty_Internal_Template $_template template object
|
||||
* @param string $code compiled code
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
public function write(Smarty_Internal_Template $_template, $code)
|
||||
{
|
||||
if (!$_template->source->handler->recompiled) {
|
||||
if ($_template->smarty->ext->_writeFile->writeFile($this->filepath, $code, $_template->smarty) === true) {
|
||||
$this->timestamp = $this->exists = is_file($this->filepath);
|
||||
if ($this->exists) {
|
||||
$this->timestamp = filemtime($this->filepath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
$this->content = $code;
|
||||
}
|
||||
$this->timestamp = time();
|
||||
$this->exists = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read compiled content from handler
|
||||
*
|
||||
* @param Smarty_Internal_Template $_template template object
|
||||
*
|
||||
* @return string content
|
||||
*/
|
||||
public function read(Smarty_Internal_Template $_template)
|
||||
{
|
||||
if (!$_template->source->handler->recompiled) {
|
||||
return file_get_contents($this->filepath);
|
||||
}
|
||||
return isset($this->content) ? $this->content : false;
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Config Source Plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage TemplateResources
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Connfig Resource Data Object
|
||||
* Meta Data Container for Template Files
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage TemplateResources
|
||||
* @author Uwe Tews
|
||||
*
|
||||
*/
|
||||
class Smarty_Template_Config extends Smarty_Template_Source
|
||||
{
|
||||
/**
|
||||
* array of section names, single section or null
|
||||
*
|
||||
* @var null|string|array
|
||||
*/
|
||||
public $config_sections = null;
|
||||
|
||||
/**
|
||||
* scope into which the config variables shall be loaded
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $scope = 'local';
|
||||
|
||||
/**
|
||||
* Flag that source is a config file
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $isConfig = true;
|
||||
|
||||
/**
|
||||
* create Source Object container
|
||||
*
|
||||
* @param Smarty_Resource $handler Resource Handler this source object communicates with
|
||||
* @param Smarty $smarty Smarty instance this source object belongs to
|
||||
* @param string $resource full template_resource
|
||||
* @param string $type type of resource
|
||||
* @param string $name resource name
|
||||
*/
|
||||
public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name)
|
||||
{
|
||||
// must clone handler as we change class names
|
||||
$this->handler = clone $handler; // Note: prone to circular references
|
||||
$this->handler->compiler_class = 'Smarty_Internal_Config_File_Compiler';
|
||||
$this->handler->template_lexer_class = 'Smarty_Internal_Configfilelexer';
|
||||
$this->handler->template_parser_class = 'Smarty_Internal_Configfileparser';
|
||||
$this->resource = $resource;
|
||||
$this->type = $type;
|
||||
$this->name = $name;
|
||||
$this->smarty = $smarty;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize Source Object for given resource
|
||||
* Either [$_template] or [$smarty, $template_resource] must be specified
|
||||
*
|
||||
* @param Smarty_Internal_Template $_template template object
|
||||
* @param Smarty $smarty smarty object
|
||||
* @param string $template_resource resource identifier
|
||||
*
|
||||
* @return Smarty_Template_Config Source Object
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public static function load(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null)
|
||||
{
|
||||
static $_incompatible_resources = array('extends' => true, 'php' => true);
|
||||
$template_resource = $_template->template_resource;
|
||||
if (empty($template_resource)) {
|
||||
throw new SmartyException('Missing config name');
|
||||
}
|
||||
// parse resource_name, load resource handler
|
||||
list($name, $type) = Smarty_Resource::parseResourceName($template_resource, $_template->smarty->default_config_type);
|
||||
// make sure configs are not loaded via anything smarty can't handle
|
||||
if (isset($_incompatible_resources[$type])) {
|
||||
throw new SmartyException ("Unable to use resource '{$type}' for config");
|
||||
}
|
||||
$resource = Smarty_Resource::load($_template->smarty, $type);
|
||||
$source = new Smarty_Template_Config($resource, $_template->smarty, $template_resource, $type, $name);
|
||||
$resource->populate($source, $_template);
|
||||
if (!$source->exists && isset($_template->smarty->default_config_handler_func)) {
|
||||
Smarty_Internal_Method_RegisterDefaultTemplateHandler::_getDefaultTemplate($source);
|
||||
}
|
||||
$source->unique_resource = $resource->buildUniqueResourceName($_template->smarty, $name, true);
|
||||
return $source;
|
||||
}
|
||||
}
|
20
vendor/bshaffer/oauth2-server-php/CHANGELOG.md
vendored
20
vendor/bshaffer/oauth2-server-php/CHANGELOG.md
vendored
@ -8,6 +8,24 @@ To see the files changed for a given bug, go to https://github.com/bshaffer/oaut
|
||||
To get the diff between two versions, go to https://github.com/bshaffer/oauth2-server-php/compare/v1.0...v1.1
|
||||
To get the diff for a specific change, go to https://github.com/bshaffer/oauth2-server-php/commit/XXX where XXX is the change hash
|
||||
|
||||
* 1.10.0 (2017-12-14)
|
||||
|
||||
PR: https://github.com/bshaffer/oauth2-server-php/pull/889
|
||||
|
||||
* #795 - [feature] added protected createPayload method to allow easier customization of JWT payload
|
||||
* #807 - [refactor] simplifies UserInfoController constructor
|
||||
* #814 - [docs] Adds https to README link
|
||||
* #827 - [testing] Explicitly pulls in phpunit 4
|
||||
* #828 - [docs] PHPDoc improvements and type hinting of variables.
|
||||
* #829 - [bug] Fix CORS issue for revoking and requesting an access token
|
||||
* #869 - [testing] Remove php 5.3 from travis and use vendored phpunit
|
||||
* #834 - [feature] use random_bytes if available
|
||||
* #851 - [docs] Fix PHPDoc
|
||||
* #872 - [bug] Fix count() error on PHP 7.2
|
||||
* #873 - [testing] adds php 7.2 to travis
|
||||
* #794 - [docs] Fix typo in composer.json
|
||||
* #885 - [testing] Use PHPUnit\Framework\TestCase instead of PHPUnit_Framework_TestCase
|
||||
|
||||
* 1.9.0 (2016-01-06)
|
||||
|
||||
PR: https://github.com/bshaffer/oauth2-server-php/pull/788
|
||||
@ -87,7 +105,7 @@ To get the diff for a specific change, go to https://github.com/bshaffer/oauth2-
|
||||
* bug #346 Fixes open_basedir warning
|
||||
* bug #351 Adds OpenID Connect support
|
||||
* bug #355 Adds php 5.6 and HHVM to travis.ci testing
|
||||
* [BC] bug #358 Adds `getQuerystringIdentifier()` to the GrantType interface
|
||||
* [BC] bug #358 Adds `getQueryStringIdentifier()` to the GrantType interface
|
||||
* bug #363 Encryption\JWT - Allows for subclassing JWT Headers
|
||||
* bug #349 Bearer Tokens - adds requestHasToken method for when access tokens are optional
|
||||
* bug #301 Encryption\JWT - fixes urlSafeB64Encode(): ensures newlines are replaced as expected
|
||||
|
2
vendor/bshaffer/oauth2-server-php/README.md
vendored
2
vendor/bshaffer/oauth2-server-php/README.md
vendored
@ -5,4 +5,4 @@ oauth2-server-php
|
||||
|
||||
[](https://packagist.org/packages/bshaffer/oauth2-server-php)
|
||||
|
||||
View the [complete documentation](http://bshaffer.github.io/oauth2-server-php-docs/)
|
||||
View the [complete documentation](https://bshaffer.github.io/oauth2-server-php-docs/)
|
||||
|
@ -19,6 +19,7 @@
|
||||
"php":">=5.3.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.0",
|
||||
"aws/aws-sdk-php": "~2.8",
|
||||
"firebase/php-jwt": "~2.2",
|
||||
"predis/predis": "dev-master",
|
||||
@ -29,6 +30,7 @@
|
||||
"predis/predis": "Required to use Redis storage",
|
||||
"thobbs/phpcassa": "Required to use Cassandra storage",
|
||||
"aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
|
||||
"firebase/php-jwt": "~1.1 is required to use MondoDB storage"
|
||||
"firebase/php-jwt": "~2.2 is required to use JWT features",
|
||||
"mongodb/mongodb": "^1.1 is required to use MongoDB storage"
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,14 @@ namespace OAuth2;
|
||||
*/
|
||||
class Autoloader
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $dir;
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
*/
|
||||
public function __construct($dir = null)
|
||||
{
|
||||
if (is_null($dir)) {
|
||||
@ -19,6 +25,7 @@ class Autoloader
|
||||
}
|
||||
$this->dir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers OAuth2\Autoloader as an SPL autoloader.
|
||||
*/
|
||||
@ -31,9 +38,8 @@ class Autoloader
|
||||
/**
|
||||
* Handles autoloading of classes.
|
||||
*
|
||||
* @param string $class A class name.
|
||||
*
|
||||
* @return boolean Returns true if the class has been loaded
|
||||
* @param string $class - A class name.
|
||||
* @return boolean - Returns true if the class has been loaded
|
||||
*/
|
||||
public function autoload($class)
|
||||
{
|
||||
|
@ -10,6 +10,19 @@ use OAuth2\ResponseInterface;
|
||||
*/
|
||||
interface ClientAssertionTypeInterface
|
||||
{
|
||||
/**
|
||||
* Validate the OAuth request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return mixed
|
||||
*/
|
||||
public function validateRequest(RequestInterface $request, ResponseInterface $response);
|
||||
|
||||
/**
|
||||
* Get the client id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientId();
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ namespace OAuth2\ClientAssertionType;
|
||||
use OAuth2\Storage\ClientCredentialsInterface;
|
||||
use OAuth2\RequestInterface;
|
||||
use OAuth2\ResponseInterface;
|
||||
use LogicException;
|
||||
|
||||
/**
|
||||
* Validate a client via Http Basic authentication
|
||||
@ -19,14 +20,16 @@ class HttpBasic implements ClientAssertionTypeInterface
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @param OAuth2\Storage\ClientCredentialsInterface $clientStorage REQUIRED Storage class for retrieving client credentials information
|
||||
* @param array $config OPTIONAL Configuration options for the server
|
||||
* <code>
|
||||
* $config = array(
|
||||
* 'allow_credentials_in_request_body' => true, // whether to look for credentials in the POST body in addition to the Authorize HTTP Header
|
||||
* 'allow_public_clients' => true // if true, "public clients" (clients without a secret) may be authenticated
|
||||
* );
|
||||
* </code>
|
||||
* Config array $config should look as follows:
|
||||
* @code
|
||||
* $config = array(
|
||||
* 'allow_credentials_in_request_body' => true, // whether to look for credentials in the POST body in addition to the Authorize HTTP Header
|
||||
* 'allow_public_clients' => true // if true, "public clients" (clients without a secret) may be authenticated
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* @param ClientCredentialsInterface $storage Storage
|
||||
* @param array $config Configuration options for the server
|
||||
*/
|
||||
public function __construct(ClientCredentialsInterface $storage, array $config = array())
|
||||
{
|
||||
@ -37,6 +40,14 @@ class HttpBasic implements ClientAssertionTypeInterface
|
||||
), $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the OAuth request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return bool|mixed
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function validateRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (!$clientData = $this->getClientCredentials($request, $response)) {
|
||||
@ -44,7 +55,7 @@ class HttpBasic implements ClientAssertionTypeInterface
|
||||
}
|
||||
|
||||
if (!isset($clientData['client_id'])) {
|
||||
throw new \LogicException('the clientData array must have "client_id" set');
|
||||
throw new LogicException('the clientData array must have "client_id" set');
|
||||
}
|
||||
|
||||
if (!isset($clientData['client_secret']) || $clientData['client_secret'] == '') {
|
||||
@ -70,6 +81,11 @@ class HttpBasic implements ClientAssertionTypeInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientId()
|
||||
{
|
||||
return $this->clientData['client_id'];
|
||||
@ -82,13 +98,14 @@ class HttpBasic implements ClientAssertionTypeInterface
|
||||
* According to the spec (draft 20), the client_id can be provided in
|
||||
* the Basic Authorization header (recommended) or via GET/POST.
|
||||
*
|
||||
* @return
|
||||
* A list containing the client identifier and password, for example
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return array|null A list containing the client identifier and password, for example:
|
||||
* @code
|
||||
* return array(
|
||||
* "client_id" => CLIENT_ID, // REQUIRED the client id
|
||||
* "client_secret" => CLIENT_SECRET, // OPTIONAL the client secret (may be omitted for public clients)
|
||||
* );
|
||||
* return array(
|
||||
* "client_id" => CLIENT_ID, // REQUIRED the client id
|
||||
* "client_secret" => CLIENT_SECRET, // OPTIONAL the client secret (may be omitted for public clients)
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-2.3.1
|
||||
@ -108,7 +125,6 @@ class HttpBasic implements ClientAssertionTypeInterface
|
||||
* client_secret can be null if the client's password is an empty string
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-2.3.1
|
||||
*/
|
||||
|
||||
return array('client_id' => $request->request('client_id'), 'client_secret' => $request->request('client_secret'));
|
||||
}
|
||||
}
|
||||
|
@ -7,37 +7,76 @@ use OAuth2\ScopeInterface;
|
||||
use OAuth2\RequestInterface;
|
||||
use OAuth2\ResponseInterface;
|
||||
use OAuth2\Scope;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @see OAuth2\Controller\AuthorizeControllerInterface
|
||||
* @see AuthorizeControllerInterface
|
||||
*/
|
||||
class AuthorizeController implements AuthorizeControllerInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $scope;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $client_id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $redirect_uri;
|
||||
|
||||
/**
|
||||
* The response type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $response_type;
|
||||
|
||||
/**
|
||||
* @var ClientInterface
|
||||
*/
|
||||
protected $clientStorage;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $responseTypes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var ScopeInterface
|
||||
*/
|
||||
protected $scopeUtil;
|
||||
|
||||
/**
|
||||
* @param OAuth2\Storage\ClientInterface $clientStorage REQUIRED Instance of OAuth2\Storage\ClientInterface to retrieve client information
|
||||
* @param array $responseTypes OPTIONAL Array of OAuth2\ResponseType\ResponseTypeInterface objects. Valid array
|
||||
* keys are "code" and "token"
|
||||
* @param array $config OPTIONAL Configuration options for the server
|
||||
* <code>
|
||||
* $config = array(
|
||||
* 'allow_implicit' => false, // if the controller should allow the "implicit" grant type
|
||||
* 'enforce_state' => true // if the controller should require the "state" parameter
|
||||
* 'require_exact_redirect_uri' => true, // if the controller should require an exact match on the "redirect_uri" parameter
|
||||
* 'redirect_status_code' => 302, // HTTP status code to use for redirect responses
|
||||
* );
|
||||
* </code>
|
||||
* @param OAuth2\ScopeInterface $scopeUtil OPTIONAL Instance of OAuth2\ScopeInterface to validate the requested scope
|
||||
* Constructor
|
||||
*
|
||||
* @param ClientInterface $clientStorage REQUIRED Instance of OAuth2\Storage\ClientInterface to retrieve client information
|
||||
* @param array $responseTypes OPTIONAL Array of OAuth2\ResponseType\ResponseTypeInterface objects. Valid array
|
||||
* keys are "code" and "token"
|
||||
* @param array $config OPTIONAL Configuration options for the server:
|
||||
* @param ScopeInterface $scopeUtil OPTIONAL Instance of OAuth2\ScopeInterface to validate the requested scope
|
||||
* @code
|
||||
* $config = array(
|
||||
* 'allow_implicit' => false, // if the controller should allow the "implicit" grant type
|
||||
* 'enforce_state' => true // if the controller should require the "state" parameter
|
||||
* 'require_exact_redirect_uri' => true, // if the controller should require an exact match on the "redirect_uri" parameter
|
||||
* 'redirect_status_code' => 302, // HTTP status code to use for redirect responses
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
public function __construct(ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), ScopeInterface $scopeUtil = null)
|
||||
{
|
||||
@ -56,10 +95,20 @@ class AuthorizeController implements AuthorizeControllerInterface
|
||||
$this->scopeUtil = $scopeUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the authorization request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param boolean $is_authorized
|
||||
* @param mixed $user_id
|
||||
* @return mixed|void
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function handleAuthorizeRequest(RequestInterface $request, ResponseInterface $response, $is_authorized, $user_id = null)
|
||||
{
|
||||
if (!is_bool($is_authorized)) {
|
||||
throw new \InvalidArgumentException('Argument "is_authorized" must be a boolean. This method must know if the user has granted access to the client.');
|
||||
throw new InvalidArgumentException('Argument "is_authorized" must be a boolean. This method must know if the user has granted access to the client.');
|
||||
}
|
||||
|
||||
// We repeat this, because we need to re-validate. The request could be POSTed
|
||||
@ -101,6 +150,14 @@ class AuthorizeController implements AuthorizeControllerInterface
|
||||
$response->setRedirect($this->config['redirect_status_code'], $uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set not authorized response
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param string $redirect_uri
|
||||
* @param mixed $user_id
|
||||
*/
|
||||
protected function setNotAuthorizedResponse(RequestInterface $request, ResponseInterface $response, $redirect_uri, $user_id = null)
|
||||
{
|
||||
$error = 'access_denied';
|
||||
@ -108,9 +165,16 @@ class AuthorizeController implements AuthorizeControllerInterface
|
||||
$response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $this->state, $error, $error_message);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* We have made this protected so this class can be extended to add/modify
|
||||
* these parameters
|
||||
*
|
||||
* @TODO: add dependency injection for the parameters in this method
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param mixed $user_id
|
||||
* @return array
|
||||
*/
|
||||
protected function buildAuthorizeParameters($request, $response, $user_id)
|
||||
{
|
||||
@ -127,6 +191,8 @@ class AuthorizeController implements AuthorizeControllerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the OAuth request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return bool
|
||||
@ -186,7 +252,7 @@ class AuthorizeController implements AuthorizeControllerInterface
|
||||
$redirect_uri = $registered_redirect_uri;
|
||||
}
|
||||
|
||||
// Select the redirect URI
|
||||
// Select the response type
|
||||
$response_type = $request->query('response_type', $request->request('response_type'));
|
||||
|
||||
// for multiple-valued response types - make them alphabetical
|
||||
@ -281,10 +347,10 @@ class AuthorizeController implements AuthorizeControllerInterface
|
||||
/**
|
||||
* Build the absolute URI based on supplied URI and parameters.
|
||||
*
|
||||
* @param $uri An absolute URI.
|
||||
* @param $params Parameters to be append as GET.
|
||||
* @param string $uri An absolute URI.
|
||||
* @param array $params Parameters to be append as GET.
|
||||
*
|
||||
* @return
|
||||
* @return string
|
||||
* An absolute URI with supplied parameters.
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
@ -302,9 +368,9 @@ class AuthorizeController implements AuthorizeControllerInterface
|
||||
}
|
||||
}
|
||||
|
||||
// Put humpty dumpty back together
|
||||
// Put the uri back together
|
||||
return
|
||||
((isset($parse_url["scheme"])) ? $parse_url["scheme"] . "://" : "")
|
||||
((isset($parse_url["scheme"])) ? $parse_url["scheme"] . "://" : "")
|
||||
. ((isset($parse_url["user"])) ? $parse_url["user"]
|
||||
. ((isset($parse_url["pass"])) ? ":" . $parse_url["pass"] : "") . "@" : "")
|
||||
. ((isset($parse_url["host"])) ? $parse_url["host"] : "")
|
||||
@ -326,10 +392,10 @@ class AuthorizeController implements AuthorizeControllerInterface
|
||||
/**
|
||||
* Internal method for validating redirect URI supplied
|
||||
*
|
||||
* @param string $inputUri The submitted URI to be validated
|
||||
* @param string $inputUri The submitted URI to be validated
|
||||
* @param string $registeredUriString The allowed URI(s) to validate against. Can be a space-delimited string of URIs to
|
||||
* allow for multiple URIs
|
||||
*
|
||||
* @return bool
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-3.1.2
|
||||
*/
|
||||
protected function validateRedirectUri($inputUri, $registeredUriString)
|
||||
@ -363,29 +429,50 @@ class AuthorizeController implements AuthorizeControllerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience methods to access the parameters derived from the validated request
|
||||
* Convenience method to access the scope
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
public function getScope()
|
||||
{
|
||||
return $this->scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to access the state
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to access the client id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientId()
|
||||
{
|
||||
return $this->client_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to access the redirect url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRedirectUri()
|
||||
{
|
||||
return $this->redirect_uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to access the response type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getResponseType()
|
||||
{
|
||||
return $this->response_type;
|
||||
|
@ -11,17 +11,18 @@ use OAuth2\ResponseInterface;
|
||||
* authorization directly, this controller ensures the request is valid, but
|
||||
* requires the application to determine the value of $is_authorized
|
||||
*
|
||||
* ex:
|
||||
* > $user_id = $this->somehowDetermineUserId();
|
||||
* > $is_authorized = $this->somehowDetermineUserAuthorization();
|
||||
* > $response = new OAuth2\Response();
|
||||
* > $authorizeController->handleAuthorizeRequest(
|
||||
* > OAuth2\Request::createFromGlobals(),
|
||||
* > $response,
|
||||
* > $is_authorized,
|
||||
* > $user_id);
|
||||
* > $response->send();
|
||||
*
|
||||
* @code
|
||||
* $user_id = $this->somehowDetermineUserId();
|
||||
* $is_authorized = $this->somehowDetermineUserAuthorization();
|
||||
* $response = new OAuth2\Response();
|
||||
* $authorizeController->handleAuthorizeRequest(
|
||||
* OAuth2\Request::createFromGlobals(),
|
||||
* $response,
|
||||
* $is_authorized,
|
||||
* $user_id
|
||||
* );
|
||||
* $response->send();
|
||||
* @endcode
|
||||
*/
|
||||
interface AuthorizeControllerInterface
|
||||
{
|
||||
@ -37,7 +38,21 @@ interface AuthorizeControllerInterface
|
||||
const RESPONSE_TYPE_AUTHORIZATION_CODE = 'code';
|
||||
const RESPONSE_TYPE_ACCESS_TOKEN = 'token';
|
||||
|
||||
/**
|
||||
* Handle the OAuth request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param $is_authorized
|
||||
* @param null $user_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function handleAuthorizeRequest(RequestInterface $request, ResponseInterface $response, $is_authorized, $user_id = null);
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return bool
|
||||
*/
|
||||
public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response);
|
||||
}
|
||||
|
@ -10,17 +10,43 @@ use OAuth2\ResponseInterface;
|
||||
use OAuth2\Scope;
|
||||
|
||||
/**
|
||||
* @see OAuth2\Controller\ResourceControllerInterface
|
||||
* @see ResourceControllerInterface
|
||||
*/
|
||||
class ResourceController implements ResourceControllerInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $token;
|
||||
|
||||
/**
|
||||
* @var TokenTypeInterface
|
||||
*/
|
||||
protected $tokenType;
|
||||
|
||||
/**
|
||||
* @var AccessTokenInterface
|
||||
*/
|
||||
protected $tokenStorage;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var ScopeInterface
|
||||
*/
|
||||
protected $scopeUtil;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param TokenTypeInterface $tokenType
|
||||
* @param AccessTokenInterface $tokenStorage
|
||||
* @param array $config
|
||||
* @param ScopeInterface $scopeUtil
|
||||
*/
|
||||
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, $config = array(), ScopeInterface $scopeUtil = null)
|
||||
{
|
||||
$this->tokenType = $tokenType;
|
||||
@ -36,6 +62,14 @@ class ResourceController implements ResourceControllerInterface
|
||||
$this->scopeUtil = $scopeUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the resource request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param null $scope
|
||||
* @return bool
|
||||
*/
|
||||
public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response, $scope = null)
|
||||
{
|
||||
$token = $this->getAccessTokenData($request, $response);
|
||||
@ -71,6 +105,13 @@ class ResourceController implements ResourceControllerInterface
|
||||
return (bool) $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access token data.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return array|null
|
||||
*/
|
||||
public function getAccessTokenData(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
// Get the token parameter
|
||||
@ -103,7 +144,11 @@ class ResourceController implements ResourceControllerInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
// convenience method to allow retrieval of the token
|
||||
/**
|
||||
* convenience method to allow retrieval of the token.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return $this->token;
|
||||
|
@ -10,17 +10,32 @@ use OAuth2\ResponseInterface;
|
||||
* call verifyResourceRequest in order to determine if the request
|
||||
* contains a valid token.
|
||||
*
|
||||
* ex:
|
||||
* > if (!$resourceController->verifyResourceRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response())) {
|
||||
* > $response->send(); // authorization failed
|
||||
* > die();
|
||||
* > }
|
||||
* > return json_encode($resource); // valid token! Send the stuff!
|
||||
*
|
||||
* @code
|
||||
* if (!$resourceController->verifyResourceRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response())) {
|
||||
* $response->send(); // authorization failed
|
||||
* die();
|
||||
* }
|
||||
* return json_encode($resource); // valid token! Send the stuff!
|
||||
* @endcode
|
||||
*/
|
||||
interface ResourceControllerInterface
|
||||
{
|
||||
/**
|
||||
* Verify the resource request
|
||||
*
|
||||
* @param RequestInterface $request - Request object
|
||||
* @param ResponseInterface $response - Response object
|
||||
* @param string $scope
|
||||
* @return mixed
|
||||
*/
|
||||
public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response, $scope = null);
|
||||
|
||||
/**
|
||||
* Get access token data.
|
||||
*
|
||||
* @param RequestInterface $request - Request object
|
||||
* @param ResponseInterface $response - Response object
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAccessTokenData(RequestInterface $request, ResponseInterface $response);
|
||||
}
|
||||
|
@ -10,9 +10,12 @@ use OAuth2\Scope;
|
||||
use OAuth2\Storage\ClientInterface;
|
||||
use OAuth2\RequestInterface;
|
||||
use OAuth2\ResponseInterface;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @see \OAuth2\Controller\TokenControllerInterface
|
||||
* @see TokenControllerInterface
|
||||
*/
|
||||
class TokenController implements TokenControllerInterface
|
||||
{
|
||||
@ -22,7 +25,7 @@ class TokenController implements TokenControllerInterface
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<GrantTypeInterface>
|
||||
*/
|
||||
protected $grantTypes;
|
||||
|
||||
@ -32,7 +35,7 @@ class TokenController implements TokenControllerInterface
|
||||
protected $clientAssertionType;
|
||||
|
||||
/**
|
||||
* @var Scope|ScopeInterface
|
||||
* @var ScopeInterface
|
||||
*/
|
||||
protected $scopeUtil;
|
||||
|
||||
@ -41,12 +44,22 @@ class TokenController implements TokenControllerInterface
|
||||
*/
|
||||
protected $clientStorage;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param AccessTokenInterface $accessToken
|
||||
* @param ClientInterface $clientStorage
|
||||
* @param array $grantTypes
|
||||
* @param ClientAssertionTypeInterface $clientAssertionType
|
||||
* @param ScopeInterface $scopeUtil
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(AccessTokenInterface $accessToken, ClientInterface $clientStorage, array $grantTypes = array(), ClientAssertionTypeInterface $clientAssertionType = null, ScopeInterface $scopeUtil = null)
|
||||
{
|
||||
if (is_null($clientAssertionType)) {
|
||||
foreach ($grantTypes as $grantType) {
|
||||
if (!$grantType instanceof ClientAssertionTypeInterface) {
|
||||
throw new \InvalidArgumentException('You must supply an instance of OAuth2\ClientAssertionType\ClientAssertionTypeInterface or only use grant types which implement OAuth2\ClientAssertionType\ClientAssertionTypeInterface');
|
||||
throw new InvalidArgumentException('You must supply an instance of OAuth2\ClientAssertionType\ClientAssertionTypeInterface or only use grant types which implement OAuth2\ClientAssertionType\ClientAssertionTypeInterface');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,6 +76,12 @@ class TokenController implements TokenControllerInterface
|
||||
$this->scopeUtil = $scopeUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the token request.
|
||||
*
|
||||
* @param RequestInterface $request - Request object to grant access token
|
||||
* @param ResponseInterface $response - Response object
|
||||
*/
|
||||
public function handleTokenRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if ($token = $this->grantAccessToken($request, $response)) {
|
||||
@ -83,8 +102,10 @@ class TokenController implements TokenControllerInterface
|
||||
* This would be called from the "/token" endpoint as defined in the spec.
|
||||
* You can call your endpoint whatever you want.
|
||||
*
|
||||
* @param RequestInterface $request Request object to grant access token
|
||||
* @param ResponseInterface $response
|
||||
* @param RequestInterface $request - Request object to grant access token
|
||||
* @param ResponseInterface $response - Response object
|
||||
*
|
||||
* @return bool|null|array
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \LogicException
|
||||
@ -97,9 +118,15 @@ class TokenController implements TokenControllerInterface
|
||||
*/
|
||||
public function grantAccessToken(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (strtolower($request->server('REQUEST_METHOD')) != 'post') {
|
||||
if (strtolower($request->server('REQUEST_METHOD')) === 'options') {
|
||||
$response->addHttpHeaders(array('Allow' => 'POST, OPTIONS'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (strtolower($request->server('REQUEST_METHOD')) !== 'post') {
|
||||
$response->setError(405, 'invalid_request', 'The request method must be POST when requesting an access token', '#section-3.2');
|
||||
$response->addHttpHeaders(array('Allow' => 'POST'));
|
||||
$response->addHttpHeaders(array('Allow' => 'POST, OPTIONS'));
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -121,6 +148,7 @@ class TokenController implements TokenControllerInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var GrantTypeInterface $grantType */
|
||||
$grantType = $this->grantTypes[$grantTypeIdentifier];
|
||||
|
||||
/**
|
||||
@ -128,8 +156,8 @@ class TokenController implements TokenControllerInterface
|
||||
* ClientAssertionTypes allow for grant types which also assert the client data
|
||||
* in which case ClientAssertion is handled in the validateRequest method
|
||||
*
|
||||
* @see OAuth2\GrantType\JWTBearer
|
||||
* @see OAuth2\GrantType\ClientCredentials
|
||||
* @see \OAuth2\GrantType\JWTBearer
|
||||
* @see \OAuth2\GrantType\ClientCredentials
|
||||
*/
|
||||
if (!$grantType instanceof ClientAssertionTypeInterface) {
|
||||
if (!$this->clientAssertionType->validateRequest($request, $response)) {
|
||||
@ -178,7 +206,6 @@ class TokenController implements TokenControllerInterface
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-3.3
|
||||
*/
|
||||
|
||||
$requestedScope = $this->scopeUtil->getScopeFromRequest($request);
|
||||
$availableScope = $grantType->getScope();
|
||||
|
||||
@ -225,20 +252,24 @@ class TokenController implements TokenControllerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* addGrantType
|
||||
* Add grant type
|
||||
*
|
||||
* @param GrantTypeInterface $grantType the grant type to add for the specified identifier
|
||||
* @param string $identifier a string passed in as "grant_type" in the response that will call this grantType
|
||||
* @param GrantTypeInterface $grantType - the grant type to add for the specified identifier
|
||||
* @param string|null $identifier - a string passed in as "grant_type" in the response that will call this grantType
|
||||
*/
|
||||
public function addGrantType(GrantTypeInterface $grantType, $identifier = null)
|
||||
{
|
||||
if (is_null($identifier) || is_numeric($identifier)) {
|
||||
$identifier = $grantType->getQuerystringIdentifier();
|
||||
$identifier = $grantType->getQueryStringIdentifier();
|
||||
}
|
||||
|
||||
$this->grantTypes[$identifier] = $grantType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*/
|
||||
public function handleRevokeRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if ($this->revokeToken($request, $response)) {
|
||||
@ -257,13 +288,20 @@ class TokenController implements TokenControllerInterface
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @throws RuntimeException
|
||||
* @return bool|null
|
||||
*/
|
||||
public function revokeToken(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (strtolower($request->server('REQUEST_METHOD')) != 'post') {
|
||||
if (strtolower($request->server('REQUEST_METHOD')) === 'options') {
|
||||
$response->addHttpHeaders(array('Allow' => 'POST, OPTIONS'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (strtolower($request->server('REQUEST_METHOD')) !== 'post') {
|
||||
$response->setError(405, 'invalid_request', 'The request method must be POST when revoking an access token', '#section-3.2');
|
||||
$response->addHttpHeaders(array('Allow' => 'POST'));
|
||||
$response->addHttpHeaders(array('Allow' => 'POST, OPTIONS'));
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -285,7 +323,7 @@ class TokenController implements TokenControllerInterface
|
||||
// @todo remove this check for v2.0
|
||||
if (!method_exists($this->accessToken, 'revokeToken')) {
|
||||
$class = get_class($this->accessToken);
|
||||
throw new \RuntimeException("AccessToken {$class} does not implement required revokeToken method");
|
||||
throw new RuntimeException("AccessToken {$class} does not implement required revokeToken method");
|
||||
}
|
||||
|
||||
$this->accessToken->revokeToken($token, $token_type_hint);
|
||||
|
@ -10,23 +10,30 @@ use OAuth2\ResponseInterface;
|
||||
* it is called to handle all grant types the application supports.
|
||||
* It also validates the client's credentials
|
||||
*
|
||||
* ex:
|
||||
* > $tokenController->handleTokenRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response());
|
||||
* > $response->send();
|
||||
*
|
||||
* @code
|
||||
* $tokenController->handleTokenRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response());
|
||||
* $response->send();
|
||||
* @endcode
|
||||
*/
|
||||
interface TokenControllerInterface
|
||||
{
|
||||
/**
|
||||
* handleTokenRequest
|
||||
*
|
||||
* @param $request
|
||||
* OAuth2\RequestInterface - The current http request
|
||||
* @param $response
|
||||
* OAuth2\ResponseInterface - An instance of OAuth2\ResponseInterface to contain the response data
|
||||
* Handle the token request
|
||||
*
|
||||
* @param RequestInterface $request - The current http request
|
||||
* @param ResponseInterface $response - An instance of OAuth2\ResponseInterface to contain the response data
|
||||
*/
|
||||
public function handleTokenRequest(RequestInterface $request, ResponseInterface $response);
|
||||
|
||||
/**
|
||||
* Grant or deny a requested access token.
|
||||
* This would be called from the "/token" endpoint as defined in the spec.
|
||||
* You can call your endpoint whatever you want.
|
||||
*
|
||||
* @param RequestInterface $request - Request object to grant access token
|
||||
* @param ResponseInterface $response - Response object
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function grantAccessToken(RequestInterface $request, ResponseInterface $response);
|
||||
}
|
||||
|
@ -4,8 +4,31 @@ namespace OAuth2\Encryption;
|
||||
|
||||
interface EncryptionInterface
|
||||
{
|
||||
/**
|
||||
* @param $payload
|
||||
* @param $key
|
||||
* @param null $algorithm
|
||||
* @return mixed
|
||||
*/
|
||||
public function encode($payload, $key, $algorithm = null);
|
||||
|
||||
/**
|
||||
* @param $payload
|
||||
* @param $key
|
||||
* @param null $algorithm
|
||||
* @return mixed
|
||||
*/
|
||||
public function decode($payload, $key, $algorithm = null);
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function urlSafeB64Encode($data);
|
||||
|
||||
/**
|
||||
* @param $b64
|
||||
* @return mixed
|
||||
*/
|
||||
public function urlSafeB64Decode($b64);
|
||||
}
|
||||
|
@ -2,12 +2,21 @@
|
||||
|
||||
namespace OAuth2\Encryption;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @link https://github.com/F21/jwt
|
||||
* @author F21
|
||||
*/
|
||||
class Jwt implements EncryptionInterface
|
||||
{
|
||||
/**
|
||||
* @param $payload
|
||||
* @param $key
|
||||
* @param string $algo
|
||||
* @return string
|
||||
*/
|
||||
public function encode($payload, $key, $algo = 'HS256')
|
||||
{
|
||||
$header = $this->generateJwtHeader($payload, $algo);
|
||||
@ -25,6 +34,12 @@ class Jwt implements EncryptionInterface
|
||||
return implode('.', $segments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $jwt
|
||||
* @param null $key
|
||||
* @param array|bool $allowedAlgorithms
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function decode($jwt, $key = null, $allowedAlgorithms = true)
|
||||
{
|
||||
if (!strpos($jwt, '.')) {
|
||||
@ -67,6 +82,14 @@ class Jwt implements EncryptionInterface
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $signature
|
||||
* @param $input
|
||||
* @param $key
|
||||
* @param string $algo
|
||||
* @return bool
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function verifySignature($signature, $input, $key, $algo = 'HS256')
|
||||
{
|
||||
// use constants when possible, for HipHop support
|
||||
@ -89,10 +112,17 @@ class Jwt implements EncryptionInterface
|
||||
return @openssl_verify($input, $signature, $key, defined('OPENSSL_ALGO_SHA512') ? OPENSSL_ALGO_SHA512 : 'sha512') === 1;
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException("Unsupported or invalid signing algorithm.");
|
||||
throw new InvalidArgumentException("Unsupported or invalid signing algorithm.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $input
|
||||
* @param $key
|
||||
* @param string $algo
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function sign($input, $key, $algo = 'HS256')
|
||||
{
|
||||
switch ($algo) {
|
||||
@ -115,19 +145,30 @@ class Jwt implements EncryptionInterface
|
||||
return $this->generateRSASignature($input, $key, defined('OPENSSL_ALGO_SHA512') ? OPENSSL_ALGO_SHA512 : 'sha512');
|
||||
|
||||
default:
|
||||
throw new \Exception("Unsupported or invalid signing algorithm.");
|
||||
throw new Exception("Unsupported or invalid signing algorithm.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $input
|
||||
* @param $key
|
||||
* @param string $algo
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
private function generateRSASignature($input, $key, $algo)
|
||||
{
|
||||
if (!openssl_sign($input, $signature, $key, $algo)) {
|
||||
throw new \Exception("Unable to sign data.");
|
||||
throw new Exception("Unable to sign data.");
|
||||
}
|
||||
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
public function urlSafeB64Encode($data)
|
||||
{
|
||||
$b64 = base64_encode($data);
|
||||
@ -138,6 +179,10 @@ class Jwt implements EncryptionInterface
|
||||
return $b64;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $b64
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function urlSafeB64Decode($b64)
|
||||
{
|
||||
$b64 = str_replace(array('-', '_'),
|
||||
@ -158,6 +203,11 @@ class Jwt implements EncryptionInterface
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @return bool
|
||||
*/
|
||||
protected function hash_equals($a, $b)
|
||||
{
|
||||
if (function_exists('hash_equals')) {
|
||||
@ -170,4 +220,4 @@ class Jwt implements EncryptionInterface
|
||||
|
||||
return $diff === 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,29 +6,47 @@ use OAuth2\Storage\AuthorizationCodeInterface;
|
||||
use OAuth2\ResponseType\AccessTokenInterface;
|
||||
use OAuth2\RequestInterface;
|
||||
use OAuth2\ResponseInterface;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class AuthorizationCode implements GrantTypeInterface
|
||||
{
|
||||
/**
|
||||
* @var AuthorizationCodeInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $authCode;
|
||||
|
||||
/**
|
||||
* @param \OAuth2\Storage\AuthorizationCodeInterface $storage REQUIRED Storage class for retrieving authorization code information
|
||||
* @param AuthorizationCodeInterface $storage - REQUIRED Storage class for retrieving authorization code information
|
||||
*/
|
||||
public function __construct(AuthorizationCodeInterface $storage)
|
||||
{
|
||||
$this->storage = $storage;
|
||||
}
|
||||
|
||||
public function getQuerystringIdentifier()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryStringIdentifier()
|
||||
{
|
||||
return 'authorization_code';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the OAuth request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function validateRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (!$request->request('code')) {
|
||||
@ -75,21 +93,45 @@ class AuthorizationCode implements GrantTypeInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientId()
|
||||
{
|
||||
return $this->authCode['client_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scope
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScope()
|
||||
{
|
||||
return isset($this->authCode['scope']) ? $this->authCode['scope'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return isset($this->authCode['user_id']) ? $this->authCode['user_id'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create access token
|
||||
*
|
||||
* @param AccessTokenInterface $accessToken
|
||||
* @param mixed $client_id - client identifier related to the access token.
|
||||
* @param mixed $user_id - user id associated with the access token
|
||||
* @param string $scope - scopes to be stored in space-separated string.
|
||||
* @return array
|
||||
*/
|
||||
public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
|
||||
{
|
||||
$token = $accessToken->createAccessToken($client_id, $user_id, $scope);
|
||||
|
@ -9,12 +9,19 @@ use OAuth2\Storage\ClientCredentialsInterface;
|
||||
/**
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*
|
||||
* @see OAuth2\ClientAssertionType_HttpBasic
|
||||
* @see HttpBasic
|
||||
*/
|
||||
class ClientCredentials extends HttpBasic implements GrantTypeInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $clientData;
|
||||
|
||||
/**
|
||||
* @param ClientCredentialsInterface $storage
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct(ClientCredentialsInterface $storage, array $config = array())
|
||||
{
|
||||
/**
|
||||
@ -27,11 +34,21 @@ class ClientCredentials extends HttpBasic implements GrantTypeInterface
|
||||
parent::__construct($storage, $config);
|
||||
}
|
||||
|
||||
public function getQuerystringIdentifier()
|
||||
/**
|
||||
* Get query string identifier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryStringIdentifier()
|
||||
{
|
||||
return 'client_credentials';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scope
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getScope()
|
||||
{
|
||||
$this->loadClientData();
|
||||
@ -39,6 +56,11 @@ class ClientCredentials extends HttpBasic implements GrantTypeInterface
|
||||
return isset($this->clientData['scope']) ? $this->clientData['scope'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
$this->loadClientData();
|
||||
@ -46,6 +68,15 @@ class ClientCredentials extends HttpBasic implements GrantTypeInterface
|
||||
return isset($this->clientData['user_id']) ? $this->clientData['user_id'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create access token
|
||||
*
|
||||
* @param AccessTokenInterface $accessToken
|
||||
* @param mixed $client_id - client identifier related to the access token.
|
||||
* @param mixed $user_id - user id associated with the access token
|
||||
* @param string $scope - scopes to be stored in space-separated string.
|
||||
* @return array
|
||||
*/
|
||||
public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
|
||||
{
|
||||
/**
|
||||
|
@ -11,10 +11,49 @@ use OAuth2\ResponseInterface;
|
||||
*/
|
||||
interface GrantTypeInterface
|
||||
{
|
||||
public function getQuerystringIdentifier();
|
||||
/**
|
||||
* Get query string identifier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryStringIdentifier();
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return mixed
|
||||
*/
|
||||
public function validateRequest(RequestInterface $request, ResponseInterface $response);
|
||||
|
||||
/**
|
||||
* Get client id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientId();
|
||||
|
||||
/**
|
||||
* Get user id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserId();
|
||||
|
||||
/**
|
||||
* Get scope
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getScope();
|
||||
|
||||
/**
|
||||
* Create access token
|
||||
*
|
||||
* @param AccessTokenInterface $accessToken
|
||||
* @param mixed $client_id - client identifier related to the access token.
|
||||
* @param mixed $user_id - user id associated with the access token
|
||||
* @param string $scope - scopes to be stored in space-separated string.
|
||||
* @return array
|
||||
*/
|
||||
public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope);
|
||||
}
|
||||
|
@ -30,10 +30,12 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
|
||||
/**
|
||||
* Creates an instance of the JWT bearer grant type.
|
||||
*
|
||||
* @param OAuth2\Storage\JWTBearerInterface|JwtBearerInterface $storage A valid storage interface that implements storage hooks for the JWT bearer grant type.
|
||||
* @param string $audience The audience to validate the token against. This is usually the full URI of the OAuth token requests endpoint.
|
||||
* @param EncryptionInterface|OAuth2\Encryption\JWT $jwtUtil OPTONAL The class used to decode, encode and verify JWTs.
|
||||
* @param array $config
|
||||
* @param JwtBearerInterface $storage - A valid storage interface that implements storage hooks for the JWT
|
||||
* bearer grant type.
|
||||
* @param string $audience - The audience to validate the token against. This is usually the full
|
||||
* URI of the OAuth token requests endpoint.
|
||||
* @param EncryptionInterface|JWT $jwtUtil - OPTONAL The class used to decode, encode and verify JWTs.
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct(JwtBearerInterface $storage, $audience, EncryptionInterface $jwtUtil = null, array $config = array())
|
||||
{
|
||||
@ -56,12 +58,11 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
|
||||
/**
|
||||
* Returns the grant_type get parameter to identify the grant type request as JWT bearer authorization grant.
|
||||
*
|
||||
* @return
|
||||
* The string identifier for grant_type.
|
||||
* @return string - The string identifier for grant_type.
|
||||
*
|
||||
* @see OAuth2\GrantType\GrantTypeInterface::getQuerystringIdentifier()
|
||||
* @see GrantTypeInterface::getQueryStringIdentifier()
|
||||
*/
|
||||
public function getQuerystringIdentifier()
|
||||
public function getQueryStringIdentifier()
|
||||
{
|
||||
return 'urn:ietf:params:oauth:grant-type:jwt-bearer';
|
||||
}
|
||||
@ -69,10 +70,9 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
|
||||
/**
|
||||
* Validates the data from the decoded JWT.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the JWT request is valid and can be decoded. Otherwise, FALSE is returned.
|
||||
*
|
||||
* @see OAuth2\GrantType\GrantTypeInterface::getTokenData()
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return bool|mixed|null TRUE if the JWT request is valid and can be decoded. Otherwise, FALSE is returned.@see GrantTypeInterface::getTokenData()
|
||||
*/
|
||||
public function validateRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
@ -196,16 +196,31 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get client id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientId()
|
||||
{
|
||||
return $this->jwt['iss'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return $this->jwt['sub'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scope
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function getScope()
|
||||
{
|
||||
return null;
|
||||
@ -215,7 +230,13 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
|
||||
* Creates an access token that is NOT associated with a refresh token.
|
||||
* If a subject (sub) the name of the user/account we are accessing data on behalf of.
|
||||
*
|
||||
* @see OAuth2\GrantType\GrantTypeInterface::createAccessToken()
|
||||
* @see GrantTypeInterface::createAccessToken()
|
||||
*
|
||||
* @param AccessTokenInterface $accessToken
|
||||
* @param mixed $client_id - client identifier related to the access token.
|
||||
* @param mixed $user_id - user id associated with the access token
|
||||
* @param string $scope - scopes to be stored in space-separated string.
|
||||
* @return array
|
||||
*/
|
||||
public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
|
||||
{
|
||||
|
@ -8,25 +8,34 @@ use OAuth2\RequestInterface;
|
||||
use OAuth2\ResponseInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class RefreshToken implements GrantTypeInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $refreshToken;
|
||||
|
||||
/**
|
||||
* @var RefreshTokenInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @param OAuth2\Storage\RefreshTokenInterface $storage REQUIRED Storage class for retrieving refresh token information
|
||||
* @param array $config OPTIONAL Configuration options for the server
|
||||
* <code>
|
||||
* $config = array(
|
||||
* 'always_issue_new_refresh_token' => true, // whether to issue a new refresh token upon successful token request
|
||||
* 'unset_refresh_token_after_use' => true // whether to unset the refresh token after after using
|
||||
* );
|
||||
* </code>
|
||||
* @param RefreshTokenInterface $storage - REQUIRED Storage class for retrieving refresh token information
|
||||
* @param array $config - OPTIONAL Configuration options for the server
|
||||
* @code
|
||||
* $config = array(
|
||||
* 'always_issue_new_refresh_token' => true, // whether to issue a new refresh token upon successful token request
|
||||
* 'unset_refresh_token_after_use' => true // whether to unset the refresh token after after using
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
public function __construct(RefreshTokenInterface $storage, $config = array())
|
||||
{
|
||||
@ -45,11 +54,21 @@ class RefreshToken implements GrantTypeInterface
|
||||
$this->storage = $storage;
|
||||
}
|
||||
|
||||
public function getQuerystringIdentifier()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryStringIdentifier()
|
||||
{
|
||||
return 'refresh_token';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the OAuth request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return bool|mixed|null
|
||||
*/
|
||||
public function validateRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (!$request->request("refresh_token")) {
|
||||
@ -76,21 +95,45 @@ class RefreshToken implements GrantTypeInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get client id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientId()
|
||||
{
|
||||
return $this->refreshToken['client_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user id
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return isset($this->refreshToken['user_id']) ? $this->refreshToken['user_id'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scope
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getScope()
|
||||
{
|
||||
return isset($this->refreshToken['scope']) ? $this->refreshToken['scope'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create access token
|
||||
*
|
||||
* @param AccessTokenInterface $accessToken
|
||||
* @param mixed $client_id - client identifier related to the access token.
|
||||
* @param mixed $user_id - user id associated with the access token
|
||||
* @param string $scope - scopes to be stored in space-separated string.
|
||||
* @return array
|
||||
*/
|
||||
public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
|
||||
{
|
||||
/*
|
||||
|
@ -6,30 +6,46 @@ use OAuth2\Storage\UserCredentialsInterface;
|
||||
use OAuth2\ResponseType\AccessTokenInterface;
|
||||
use OAuth2\RequestInterface;
|
||||
use OAuth2\ResponseInterface;
|
||||
use LogicException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class UserCredentials implements GrantTypeInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $userInfo;
|
||||
|
||||
/**
|
||||
* @var UserCredentialsInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* @param OAuth2\Storage\UserCredentialsInterface $storage REQUIRED Storage class for retrieving user credentials information
|
||||
* @param UserCredentialsInterface $storage - REQUIRED Storage class for retrieving user credentials information
|
||||
*/
|
||||
public function __construct(UserCredentialsInterface $storage)
|
||||
{
|
||||
$this->storage = $storage;
|
||||
}
|
||||
|
||||
public function getQuerystringIdentifier()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryStringIdentifier()
|
||||
{
|
||||
return 'password';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return bool|mixed|null
|
||||
*
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function validateRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (!$request->request("password") || !$request->request("username")) {
|
||||
@ -61,21 +77,45 @@ class UserCredentials implements GrantTypeInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get client id
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getClientId()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return $this->userInfo['user_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scope
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getScope()
|
||||
{
|
||||
return isset($this->userInfo['scope']) ? $this->userInfo['scope'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create access token
|
||||
*
|
||||
* @param AccessTokenInterface $accessToken
|
||||
* @param mixed $client_id - client identifier related to the access token.
|
||||
* @param mixed $user_id - user id associated with the access token
|
||||
* @param string $scope - scopes to be stored in space-separated string.
|
||||
* @return array
|
||||
*/
|
||||
public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
|
||||
{
|
||||
return $accessToken->createAccessToken($client_id, $user_id, $scope);
|
||||
|
@ -11,8 +11,19 @@ use OAuth2\ResponseInterface;
|
||||
*/
|
||||
class AuthorizeController extends BaseAuthorizeController implements AuthorizeControllerInterface
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $nonce;
|
||||
|
||||
/**
|
||||
* Set not authorized response
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param string $redirect_uri
|
||||
* @param null $user_id
|
||||
*/
|
||||
protected function setNotAuthorizedResponse(RequestInterface $request, ResponseInterface $response, $redirect_uri, $user_id = null)
|
||||
{
|
||||
$prompt = $request->query('prompt', 'consent');
|
||||
@ -32,6 +43,14 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
|
||||
$response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $this->getState(), $error, $error_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO: add dependency injection for the parameters in this method
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param mixed $user_id
|
||||
* @return array
|
||||
*/
|
||||
protected function buildAuthorizeParameters($request, $response, $user_id)
|
||||
{
|
||||
if (!$params = parent::buildAuthorizeParameters($request, $response, $user_id)) {
|
||||
@ -49,6 +68,11 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return bool
|
||||
*/
|
||||
public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (!parent::validateAuthorizeRequest($request, $response)) {
|
||||
@ -69,6 +93,11 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array of valid response types
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getValidResponseTypes()
|
||||
{
|
||||
return array(
|
||||
@ -87,11 +116,8 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
|
||||
* method checks whether OpenID Connect is enabled in the server settings
|
||||
* and whether the openid scope was requested.
|
||||
*
|
||||
* @param $request_scope
|
||||
* A space-separated string of scopes.
|
||||
*
|
||||
* @return
|
||||
* TRUE if an id token is needed, FALSE otherwise.
|
||||
* @param string $request_scope - A space-separated string of scopes.
|
||||
* @return boolean - TRUE if an id token is needed, FALSE otherwise.
|
||||
*/
|
||||
public function needsIdToken($request_scope)
|
||||
{
|
||||
@ -99,6 +125,9 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
|
||||
return $this->scopeUtil->checkScope('openid', $request_scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getNonce()
|
||||
{
|
||||
return $this->nonce;
|
||||
|
@ -5,6 +5,8 @@ namespace OAuth2\OpenID\Controller;
|
||||
interface AuthorizeControllerInterface
|
||||
{
|
||||
const RESPONSE_TYPE_ID_TOKEN = 'id_token';
|
||||
|
||||
const RESPONSE_TYPE_ID_TOKEN_TOKEN = 'id_token token';
|
||||
|
||||
const RESPONSE_TYPE_CODE_ID_TOKEN = 'code id_token';
|
||||
}
|
||||
|
@ -16,30 +16,34 @@ use OAuth2\ResponseInterface;
|
||||
*/
|
||||
class UserInfoController extends ResourceController implements UserInfoControllerInterface
|
||||
{
|
||||
private $token;
|
||||
|
||||
protected $tokenType;
|
||||
protected $tokenStorage;
|
||||
/**
|
||||
* @var UserClaimsInterface
|
||||
*/
|
||||
protected $userClaimsStorage;
|
||||
protected $config;
|
||||
protected $scopeUtil;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param TokenTypeInterface $tokenType
|
||||
* @param AccessTokenInterface $tokenStorage
|
||||
* @param UserClaimsInterface $userClaimsStorage
|
||||
* @param array $config
|
||||
* @param ScopeInterface $scopeUtil
|
||||
*/
|
||||
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, UserClaimsInterface $userClaimsStorage, $config = array(), ScopeInterface $scopeUtil = null)
|
||||
{
|
||||
$this->tokenType = $tokenType;
|
||||
$this->tokenStorage = $tokenStorage;
|
||||
parent::__construct($tokenType, $tokenStorage, $config, $scopeUtil);
|
||||
|
||||
$this->userClaimsStorage = $userClaimsStorage;
|
||||
|
||||
$this->config = array_merge(array(
|
||||
'www_realm' => 'Service',
|
||||
), $config);
|
||||
|
||||
if (is_null($scopeUtil)) {
|
||||
$scopeUtil = new Scope();
|
||||
}
|
||||
$this->scopeUtil = $scopeUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the user info request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return void
|
||||
*/
|
||||
public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (!$this->verifyResourceRequest($request, $response, 'openid')) {
|
||||
@ -55,4 +59,4 @@ class UserInfoController extends ResourceController implements UserInfoControlle
|
||||
);
|
||||
$response->addParameters($claims);
|
||||
}
|
||||
}
|
||||
}
|
@ -9,15 +9,22 @@ use OAuth2\ResponseInterface;
|
||||
* This controller is called when the user claims for OpenID Connect's
|
||||
* UserInfo endpoint should be returned.
|
||||
*
|
||||
* ex:
|
||||
* > $response = new OAuth2\Response();
|
||||
* > $userInfoController->handleUserInfoRequest(
|
||||
* > OAuth2\Request::createFromGlobals(),
|
||||
* > $response;
|
||||
* > $response->send();
|
||||
*
|
||||
* @code
|
||||
* $response = new OAuth2\Response();
|
||||
* $userInfoController->handleUserInfoRequest(
|
||||
* OAuth2\Request::createFromGlobals(),
|
||||
* $response
|
||||
* );
|
||||
* $response->send();
|
||||
* @endcode
|
||||
*/
|
||||
interface UserInfoControllerInterface
|
||||
{
|
||||
/**
|
||||
* Handle user info request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*/
|
||||
public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response);
|
||||
}
|
||||
|
@ -6,11 +6,19 @@ use OAuth2\GrantType\AuthorizationCode as BaseAuthorizationCode;
|
||||
use OAuth2\ResponseType\AccessTokenInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class AuthorizationCode extends BaseAuthorizationCode
|
||||
{
|
||||
/**
|
||||
* Create access token
|
||||
*
|
||||
* @param AccessTokenInterface $accessToken
|
||||
* @param mixed $client_id - client identifier related to the access token.
|
||||
* @param mixed $user_id - user id associated with the access token
|
||||
* @param string $scope - scopes to be stored in space-separated string.
|
||||
* @return array
|
||||
*/
|
||||
public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
|
||||
{
|
||||
$includeRefreshToken = true;
|
||||
|
@ -6,16 +6,26 @@ use OAuth2\ResponseType\AuthorizationCode as BaseAuthorizationCode;
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as AuthorizationCodeStorageInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class AuthorizationCode extends BaseAuthorizationCode implements AuthorizationCodeInterface
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param AuthorizationCodeStorageInterface $storage
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct(AuthorizationCodeStorageInterface $storage, array $config = array())
|
||||
{
|
||||
parent::__construct($storage, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $params
|
||||
* @param null $user_id
|
||||
* @return array
|
||||
*/
|
||||
public function getAuthorizeResponse($params, $user_id = null)
|
||||
{
|
||||
// build the URL to redirect to
|
||||
@ -35,18 +45,14 @@ class AuthorizationCode extends BaseAuthorizationCode implements AuthorizationCo
|
||||
/**
|
||||
* Handle the creation of the authorization code.
|
||||
*
|
||||
* @param $client_id
|
||||
* Client identifier related to the authorization code
|
||||
* @param $user_id
|
||||
* User ID associated with the authorization code
|
||||
* @param $redirect_uri
|
||||
* An absolute URI to which the authorization server will redirect the
|
||||
* user-agent to when the end-user authorization step is completed.
|
||||
* @param $scope
|
||||
* (optional) Scopes to be stored in space-separated string.
|
||||
* @param $id_token
|
||||
* (optional) The OpenID Connect id_token.
|
||||
* @param mixed $client_id - Client identifier related to the authorization code
|
||||
* @param mixed $user_id - User ID associated with the authorization code
|
||||
* @param string $redirect_uri - An absolute URI to which the authorization server will redirect the
|
||||
* user-agent to when the end-user authorization step is completed.
|
||||
* @param string $scope - OPTIONAL Scopes to be stored in space-separated string.
|
||||
* @param string $id_token - OPTIONAL The OpenID Connect id_token.
|
||||
*
|
||||
* @return string
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-4
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
|
@ -5,7 +5,6 @@ namespace OAuth2\OpenID\ResponseType;
|
||||
use OAuth2\ResponseType\AuthorizationCodeInterface as BaseAuthorizationCodeInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface AuthorizationCodeInterface extends BaseAuthorizationCodeInterface
|
||||
@ -13,12 +12,13 @@ interface AuthorizationCodeInterface extends BaseAuthorizationCodeInterface
|
||||
/**
|
||||
* Handle the creation of the authorization code.
|
||||
*
|
||||
* @param $client_id Client identifier related to the authorization code
|
||||
* @param $user_id User ID associated with the authorization code
|
||||
* @param $redirect_uri An absolute URI to which the authorization server will redirect the
|
||||
* user-agent to when the end-user authorization step is completed.
|
||||
* @param $scope OPTIONAL Scopes to be stored in space-separated string.
|
||||
* @param $id_token OPTIONAL The OpenID Connect id_token.
|
||||
* @param mixed $client_id - Client identifier related to the authorization code
|
||||
* @param mixed $user_id - User ID associated with the authorization code
|
||||
* @param string $redirect_uri - An absolute URI to which the authorization server will redirect the
|
||||
* user-agent to when the end-user authorization step is completed.
|
||||
* @param string $scope - OPTIONAL Scopes to be stored in space-separated string.
|
||||
* @param string $id_token - OPTIONAL The OpenID Connect id_token.
|
||||
* @return string
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-4
|
||||
* @ingroup oauth2_section_4
|
||||
|
@ -4,15 +4,31 @@ namespace OAuth2\OpenID\ResponseType;
|
||||
|
||||
class CodeIdToken implements CodeIdTokenInterface
|
||||
{
|
||||
/**
|
||||
* @var AuthorizationCodeInterface
|
||||
*/
|
||||
protected $authCode;
|
||||
|
||||
/**
|
||||
* @var IdTokenInterface
|
||||
*/
|
||||
protected $idToken;
|
||||
|
||||
/**
|
||||
* @param AuthorizationCodeInterface $authCode
|
||||
* @param IdTokenInterface $idToken
|
||||
*/
|
||||
public function __construct(AuthorizationCodeInterface $authCode, IdTokenInterface $idToken)
|
||||
{
|
||||
$this->authCode = $authCode;
|
||||
$this->idToken = $idToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @param mixed $user_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAuthorizeResponse($params, $user_id = null)
|
||||
{
|
||||
$result = $this->authCode->getAuthorizeResponse($params, $user_id);
|
||||
|
@ -6,14 +6,38 @@ use OAuth2\Encryption\EncryptionInterface;
|
||||
use OAuth2\Encryption\Jwt;
|
||||
use OAuth2\Storage\PublicKeyInterface;
|
||||
use OAuth2\OpenID\Storage\UserClaimsInterface;
|
||||
use LogicException;
|
||||
|
||||
class IdToken implements IdTokenInterface
|
||||
{
|
||||
/**
|
||||
* @var UserClaimsInterface
|
||||
*/
|
||||
protected $userClaimsStorage;
|
||||
/**
|
||||
* @var PublicKeyInterface
|
||||
*/
|
||||
protected $publicKeyStorage;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var EncryptionInterface
|
||||
*/
|
||||
protected $encryptionUtil;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param UserClaimsInterface $userClaimsStorage
|
||||
* @param PublicKeyInterface $publicKeyStorage
|
||||
* @param array $config
|
||||
* @param EncryptionInterface $encryptionUtil
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function __construct(UserClaimsInterface $userClaimsStorage, PublicKeyInterface $publicKeyStorage, array $config = array(), EncryptionInterface $encryptionUtil = null)
|
||||
{
|
||||
$this->userClaimsStorage = $userClaimsStorage;
|
||||
@ -24,13 +48,18 @@ class IdToken implements IdTokenInterface
|
||||
$this->encryptionUtil = $encryptionUtil;
|
||||
|
||||
if (!isset($config['issuer'])) {
|
||||
throw new \LogicException('config parameter "issuer" must be set');
|
||||
throw new LogicException('config parameter "issuer" must be set');
|
||||
}
|
||||
$this->config = array_merge(array(
|
||||
'id_lifetime' => 3600,
|
||||
), $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @param null $userInfo
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getAuthorizeResponse($params, $userInfo = null)
|
||||
{
|
||||
// build the URL to redirect to
|
||||
@ -50,6 +79,16 @@ class IdToken implements IdTokenInterface
|
||||
return array($params['redirect_uri'], $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create id token
|
||||
*
|
||||
* @param string $client_id
|
||||
* @param mixed $userInfo
|
||||
* @param mixed $nonce
|
||||
* @param mixed $userClaims
|
||||
* @param mixed $access_token
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function createIdToken($client_id, $userInfo, $nonce = null, $userClaims = null, $access_token = null)
|
||||
{
|
||||
// pull auth_time from user info if supplied
|
||||
@ -79,6 +118,11 @@ class IdToken implements IdTokenInterface
|
||||
return $this->encodeToken($token, $client_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $access_token
|
||||
* @param null $client_id
|
||||
* @return mixed|string
|
||||
*/
|
||||
protected function createAtHash($access_token, $client_id = null)
|
||||
{
|
||||
// maps HS256 and RS256 to sha256, etc.
|
||||
@ -90,6 +134,11 @@ class IdToken implements IdTokenInterface
|
||||
return $this->encryptionUtil->urlSafeB64Encode($at_hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $token
|
||||
* @param null $client_id
|
||||
* @return mixed|string
|
||||
*/
|
||||
protected function encodeToken(array $token, $client_id = null)
|
||||
{
|
||||
$private_key = $this->publicKeyStorage->getPrivateKey($client_id);
|
||||
@ -98,6 +147,11 @@ class IdToken implements IdTokenInterface
|
||||
return $this->encryptionUtil->encode($token, $private_key, $algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $userInfo
|
||||
* @return array
|
||||
* @throws LogicException
|
||||
*/
|
||||
private function getUserIdAndAuthTime($userInfo)
|
||||
{
|
||||
$auth_time = null;
|
||||
@ -105,7 +159,7 @@ class IdToken implements IdTokenInterface
|
||||
// support an array for user_id / auth_time
|
||||
if (is_array($userInfo)) {
|
||||
if (!isset($userInfo['user_id'])) {
|
||||
throw new \LogicException('if $user_id argument is an array, user_id index must be set');
|
||||
throw new LogicException('if $user_id argument is an array, user_id index must be set');
|
||||
}
|
||||
|
||||
$auth_time = isset($userInfo['auth_time']) ? $userInfo['auth_time'] : null;
|
||||
|
@ -15,12 +15,13 @@ interface IdTokenInterface extends ResponseTypeInterface
|
||||
* If the Implicit Flow is used, the token and id_token are generated and
|
||||
* returned together.
|
||||
*
|
||||
* @param string $client_id The client id.
|
||||
* @param string $user_id The user id.
|
||||
* @param string $nonce OPTIONAL The nonce.
|
||||
* @param string $userClaims OPTIONAL Claims about the user.
|
||||
* @param string $access_token OPTIONAL The access token, if known.
|
||||
*
|
||||
* @param string $client_id - The client id.
|
||||
* @param mixed $userInfo - User info
|
||||
* @param string $nonce - OPTIONAL The nonce.
|
||||
* @param string $userClaims - OPTIONAL Claims about the user.
|
||||
* @param string $access_token - OPTIONAL The access token, if known.
|
||||
|
||||
* @internal param string $user_id - The user id.
|
||||
* @return string The ID Token represented as a JSON Web Token (JWT).
|
||||
*
|
||||
* @see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
|
@ -6,15 +6,33 @@ use OAuth2\ResponseType\AccessTokenInterface;
|
||||
|
||||
class IdTokenToken implements IdTokenTokenInterface
|
||||
{
|
||||
/**
|
||||
* @var AccessTokenInterface
|
||||
*/
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* @var IdTokenInterface
|
||||
*/
|
||||
protected $idToken;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param AccessTokenInterface $accessToken
|
||||
* @param IdTokenInterface $idToken
|
||||
*/
|
||||
public function __construct(AccessTokenInterface $accessToken, IdTokenInterface $idToken)
|
||||
{
|
||||
$this->accessToken = $accessToken;
|
||||
$this->idToken = $idToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @param mixed $user_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAuthorizeResponse($params, $user_id = null)
|
||||
{
|
||||
$result = $this->accessToken->getAuthorizeResponse($params, $user_id);
|
||||
|
@ -23,13 +23,13 @@ interface AuthorizationCodeInterface extends BaseAuthorizationCodeInterface
|
||||
*
|
||||
* Required for OAuth2::GRANT_TYPE_AUTH_CODE.
|
||||
*
|
||||
* @param $code authorization code to be stored.
|
||||
* @param $client_id client identifier to be stored.
|
||||
* @param $user_id user identifier to be stored.
|
||||
* @param string $redirect_uri redirect URI(s) to be stored in a space-separated string.
|
||||
* @param int $expires expiration to be stored as a Unix timestamp.
|
||||
* @param string $scope OPTIONAL scopes to be stored in space-separated string.
|
||||
* @param string $id_token OPTIONAL the OpenID Connect id_token.
|
||||
* @param string $code - authorization code to be stored.
|
||||
* @param mixed $client_id - client identifier to be stored.
|
||||
* @param mixed $user_id - user identifier to be stored.
|
||||
* @param string $redirect_uri - redirect URI(s) to be stored in a space-separated string.
|
||||
* @param int $expires - expiration to be stored as a Unix timestamp.
|
||||
* @param string $scope - OPTIONAL scopes to be stored in space-separated string.
|
||||
* @param string $id_token - OPTIONAL the OpenID Connect id_token.
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
|
@ -23,14 +23,11 @@ interface UserClaimsInterface
|
||||
* Groups of claims are returned based on the requested scopes. No group
|
||||
* is required, and no claim is required.
|
||||
*
|
||||
* @param $user_id
|
||||
* The id of the user for which claims should be returned.
|
||||
* @param $scope
|
||||
* The requested scope.
|
||||
* @param mixed $user_id - The id of the user for which claims should be returned.
|
||||
* @param string $scope - The requested scope.
|
||||
* Scopes with matching claims: profile, email, address, phone.
|
||||
*
|
||||
* @return
|
||||
* An array in the claim => value format.
|
||||
* @return array - An array in the claim => value format.
|
||||
*
|
||||
* @see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
|
||||
*/
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace OAuth2;
|
||||
|
||||
use LogicException;
|
||||
|
||||
/**
|
||||
* OAuth2\Request
|
||||
* This class is taken from the Symfony2 Framework and is part of the Symfony package.
|
||||
@ -21,13 +23,14 @@ class Request implements RequestInterface
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $query The GET parameters
|
||||
* @param array $request The POST parameters
|
||||
* @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array $cookies The COOKIE parameters
|
||||
* @param array $files The FILES parameters
|
||||
* @param array $server The SERVER parameters
|
||||
* @param string $content The raw body data
|
||||
* @param array $query - The GET parameters
|
||||
* @param array $request - The POST parameters
|
||||
* @param array $attributes - The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array $cookies - The COOKIE parameters
|
||||
* @param array $files - The FILES parameters
|
||||
* @param array $server - The SERVER parameters
|
||||
* @param string $content - The raw body data
|
||||
* @param array $headers - The headers
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
@ -41,13 +44,14 @@ class Request implements RequestInterface
|
||||
*
|
||||
* This method also re-initializes all properties.
|
||||
*
|
||||
* @param array $query The GET parameters
|
||||
* @param array $request The POST parameters
|
||||
* @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array $cookies The COOKIE parameters
|
||||
* @param array $files The FILES parameters
|
||||
* @param array $server The SERVER parameters
|
||||
* @param string $content The raw body data
|
||||
* @param array $query - The GET parameters
|
||||
* @param array $request - The POST parameters
|
||||
* @param array $attributes - The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array $cookies - The COOKIE parameters
|
||||
* @param array $files - The FILES parameters
|
||||
* @param array $server - The SERVER parameters
|
||||
* @param string $content - The raw body data
|
||||
* @param array $headers - The headers
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
@ -63,21 +67,41 @@ class Request implements RequestInterface
|
||||
$this->headers = is_null($headers) ? $this->getHeadersFromServer($this->server) : $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($name, $default = null)
|
||||
{
|
||||
return isset($this->query[$name]) ? $this->query[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function request($name, $default = null)
|
||||
{
|
||||
return isset($this->request[$name]) ? $this->request[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function server($name, $default = null)
|
||||
{
|
||||
return isset($this->server[$name]) ? $this->server[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function headers($name, $default = null)
|
||||
{
|
||||
$headers = array_change_key_case($this->headers);
|
||||
@ -86,6 +110,9 @@ class Request implements RequestInterface
|
||||
return isset($headers[$name]) ? $headers[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAllQueryParameters()
|
||||
{
|
||||
return $this->query;
|
||||
@ -94,14 +121,15 @@ class Request implements RequestInterface
|
||||
/**
|
||||
* Returns the request body content.
|
||||
*
|
||||
* @param Boolean $asResource If true, a resource will be returned
|
||||
* @param boolean $asResource - If true, a resource will be returned
|
||||
* @return string|resource - The request body content or a resource to read the body stream.
|
||||
*
|
||||
* @return string|resource The request body content or a resource to read the body stream.
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function getContent($asResource = false)
|
||||
{
|
||||
if (false === $this->content || (true === $asResource && null !== $this->content)) {
|
||||
throw new \LogicException('getContent() can only be called once when using the resource return type.');
|
||||
throw new LogicException('getContent() can only be called once when using the resource return type.');
|
||||
}
|
||||
|
||||
if (true === $asResource) {
|
||||
@ -117,6 +145,10 @@ class Request implements RequestInterface
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $server
|
||||
* @return array
|
||||
*/
|
||||
private function getHeadersFromServer($server)
|
||||
{
|
||||
$headers = array();
|
||||
@ -185,13 +217,15 @@ class Request implements RequestInterface
|
||||
/**
|
||||
* Creates a new request with values from PHP's super globals.
|
||||
*
|
||||
* @return Request A new request
|
||||
* @return Request - A new request
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public static function createFromGlobals()
|
||||
{
|
||||
$class = get_called_class();
|
||||
|
||||
/** @var Request $request */
|
||||
$request = new $class($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
|
||||
|
||||
$contentType = $request->server('CONTENT_TYPE', '');
|
||||
|
@ -4,13 +4,36 @@ namespace OAuth2;
|
||||
|
||||
interface RequestInterface
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($name, $default = null);
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function request($name, $default = null);
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function server($name, $default = null);
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function headers($name, $default = null);
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAllQueryParameters();
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace OAuth2;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Class to handle OAuth2 Responses in a graceful way. Use this interface
|
||||
* to output the proper OAuth2 responses.
|
||||
@ -13,12 +15,34 @@ namespace OAuth2;
|
||||
*/
|
||||
class Response implements ResponseInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $statusCode = 200;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $statusText;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $parameters = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $httpHeaders = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $statusTexts = array(
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
@ -63,6 +87,11 @@ class Response implements ResponseInterface
|
||||
505 => 'HTTP Version Not Supported',
|
||||
);
|
||||
|
||||
/**
|
||||
* @param array $parameters
|
||||
* @param int $statusCode
|
||||
* @param array $headers
|
||||
*/
|
||||
public function __construct($parameters = array(), $statusCode = 200, $headers = array())
|
||||
{
|
||||
$this->setParameters($parameters);
|
||||
@ -102,76 +131,128 @@ class Response implements ResponseInterface
|
||||
return sprintf("%s: %s\n", $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $statusCode
|
||||
* @param string $text
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setStatusCode($statusCode, $text = null)
|
||||
{
|
||||
$this->statusCode = (int) $statusCode;
|
||||
if ($this->isInvalid()) {
|
||||
throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $statusCode));
|
||||
throw new InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $statusCode));
|
||||
}
|
||||
|
||||
$this->statusText = false === $text ? '' : (null === $text ? self::$statusTexts[$this->statusCode] : $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStatusText()
|
||||
{
|
||||
return $this->statusText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function setParameters(array $parameters)
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function addParameters(array $parameters)
|
||||
{
|
||||
$this->parameters = array_merge($this->parameters, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParameter($name, $default = null)
|
||||
{
|
||||
return isset($this->parameters[$name]) ? $this->parameters[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
$this->parameters[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $httpHeaders
|
||||
*/
|
||||
public function setHttpHeaders(array $httpHeaders)
|
||||
{
|
||||
$this->httpHeaders = $httpHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setHttpHeader($name, $value)
|
||||
{
|
||||
$this->httpHeaders[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $httpHeaders
|
||||
*/
|
||||
public function addHttpHeaders(array $httpHeaders)
|
||||
{
|
||||
$this->httpHeaders = array_merge($this->httpHeaders, $httpHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getHttpHeaders()
|
||||
{
|
||||
return $this->httpHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getHttpHeader($name, $default = null)
|
||||
{
|
||||
return isset($this->httpHeaders[$name]) ? $this->httpHeaders[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
* @return mixed
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getResponseBody($format = 'json')
|
||||
{
|
||||
switch ($format) {
|
||||
@ -187,10 +268,13 @@ class Response implements ResponseInterface
|
||||
return $xml->asXML();
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('The format %s is not supported', $format));
|
||||
throw new InvalidArgumentException(sprintf('The format %s is not supported', $format));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
*/
|
||||
public function send($format = 'json')
|
||||
{
|
||||
// headers have already been sent by the developer
|
||||
@ -215,6 +299,14 @@ class Response implements ResponseInterface
|
||||
echo $this->getResponseBody($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $statusCode
|
||||
* @param string $error
|
||||
* @param string $errorDescription
|
||||
* @param string $errorUri
|
||||
* @return mixed
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setError($statusCode, $error, $errorDescription = null, $errorUri = null)
|
||||
{
|
||||
$parameters = array(
|
||||
@ -239,14 +331,24 @@ class Response implements ResponseInterface
|
||||
$this->addHttpHeaders($httpHeaders);
|
||||
|
||||
if (!$this->isClientError() && !$this->isServerError()) {
|
||||
throw new \InvalidArgumentException(sprintf('The HTTP status code is not an error ("%s" given).', $statusCode));
|
||||
throw new InvalidArgumentException(sprintf('The HTTP status code is not an error ("%s" given).', $statusCode));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $statusCode
|
||||
* @param string $url
|
||||
* @param string $state
|
||||
* @param string $error
|
||||
* @param string $errorDescription
|
||||
* @param string $errorUri
|
||||
* @return mixed
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setRedirect($statusCode, $url, $state = null, $error = null, $errorDescription = null, $errorUri = null)
|
||||
{
|
||||
if (empty($url)) {
|
||||
throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
|
||||
throw new InvalidArgumentException('Cannot redirect to an empty URL.');
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
@ -271,15 +373,16 @@ class Response implements ResponseInterface
|
||||
$this->addHttpHeaders(array('Location' => $url));
|
||||
|
||||
if (!$this->isRedirection()) {
|
||||
throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $statusCode));
|
||||
throw new InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $statusCode));
|
||||
}
|
||||
}
|
||||
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||
/**
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||
*/
|
||||
public function isInvalid()
|
||||
{
|
||||
@ -336,8 +439,11 @@ class Response implements ResponseInterface
|
||||
return $this->statusCode >= 500 && $this->statusCode < 600;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions from Symfony2 HttpFoundation - output pretty header
|
||||
/**
|
||||
* Function from Symfony2 HttpFoundation - output pretty header
|
||||
*
|
||||
* @param array $headers
|
||||
* @return string
|
||||
*/
|
||||
private function getHttpHeadersAsString($headers)
|
||||
{
|
||||
@ -357,11 +463,23 @@ class Response implements ResponseInterface
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function from Symfony2 HttpFoundation - output pretty header
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
private function beautifyHeaderName($name)
|
||||
{
|
||||
return preg_replace_callback('/\-(.)/', array($this, 'beautifyCallback'), ucfirst($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Function from Symfony2 HttpFoundation - output pretty header
|
||||
*
|
||||
* @param array $match
|
||||
* @return string
|
||||
*/
|
||||
private function beautifyCallback($match)
|
||||
{
|
||||
return '-'.strtoupper($match[1]);
|
||||
|
@ -6,19 +6,48 @@ namespace OAuth2;
|
||||
* Interface which represents an object response. Meant to handle and display the proper OAuth2 Responses
|
||||
* for errors and successes
|
||||
*
|
||||
* @see OAuth2\Response
|
||||
* @see \OAuth2\Response
|
||||
*/
|
||||
interface ResponseInterface
|
||||
{
|
||||
/**
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function addParameters(array $parameters);
|
||||
|
||||
/**
|
||||
* @param array $httpHeaders
|
||||
*/
|
||||
public function addHttpHeaders(array $httpHeaders);
|
||||
|
||||
/**
|
||||
* @param int $statusCode
|
||||
*/
|
||||
public function setStatusCode($statusCode);
|
||||
|
||||
/**
|
||||
* @param int $statusCode
|
||||
* @param string $name
|
||||
* @param string $description
|
||||
* @param string $uri
|
||||
* @return mixed
|
||||
*/
|
||||
public function setError($statusCode, $name, $description = null, $uri = null);
|
||||
|
||||
/**
|
||||
* @param int $statusCode
|
||||
* @param string $url
|
||||
* @param string $state
|
||||
* @param string $error
|
||||
* @param string $errorDescription
|
||||
* @param string $errorUri
|
||||
* @return mixed
|
||||
*/
|
||||
public function setRedirect($statusCode, $url, $state = null, $error = null, $errorDescription = null, $errorUri = null);
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParameter($name);
|
||||
}
|
||||
|
@ -4,28 +4,39 @@ namespace OAuth2\ResponseType;
|
||||
|
||||
use OAuth2\Storage\AccessTokenInterface as AccessTokenStorageInterface;
|
||||
use OAuth2\Storage\RefreshTokenInterface;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class AccessToken implements AccessTokenInterface
|
||||
{
|
||||
/**
|
||||
* @var AccessTokenInterface
|
||||
*/
|
||||
protected $tokenStorage;
|
||||
|
||||
/**
|
||||
* @var RefreshTokenInterface
|
||||
*/
|
||||
protected $refreshStorage;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @param OAuth2\Storage\AccessTokenInterface $tokenStorage REQUIRED Storage class for saving access token information
|
||||
* @param OAuth2\Storage\RefreshTokenInterface $refreshStorage OPTIONAL Storage class for saving refresh token information
|
||||
* @param array $config OPTIONAL Configuration options for the server
|
||||
* <code>
|
||||
* $config = array(
|
||||
* 'token_type' => 'bearer', // token type identifier
|
||||
* 'access_lifetime' => 3600, // time before access token expires
|
||||
* 'refresh_token_lifetime' => 1209600, // time before refresh token expires
|
||||
* );
|
||||
* </endcode>
|
||||
* @param AccessTokenStorageInterface $tokenStorage - REQUIRED Storage class for saving access token information
|
||||
* @param RefreshTokenInterface $refreshStorage - OPTIONAL Storage class for saving refresh token information
|
||||
* @param array $config - OPTIONAL Configuration options for the server
|
||||
* @code
|
||||
* $config = array(
|
||||
* 'token_type' => 'bearer', // token type identifier
|
||||
* 'access_lifetime' => 3600, // time before access token expires
|
||||
* 'refresh_token_lifetime' => 1209600, // time before refresh token expires
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
public function __construct(AccessTokenStorageInterface $tokenStorage, RefreshTokenInterface $refreshStorage = null, array $config = array())
|
||||
{
|
||||
@ -39,6 +50,13 @@ class AccessToken implements AccessTokenInterface
|
||||
), $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authorize response
|
||||
*
|
||||
* @param array $params
|
||||
* @param mixed $user_id
|
||||
* @return array
|
||||
*/
|
||||
public function getAuthorizeResponse($params, $user_id = null)
|
||||
{
|
||||
// build the URL to redirect to
|
||||
@ -64,10 +82,11 @@ class AccessToken implements AccessTokenInterface
|
||||
/**
|
||||
* Handle the creation of access token, also issue refresh token if supported / desirable.
|
||||
*
|
||||
* @param $client_id client identifier related to the access token.
|
||||
* @param $user_id user ID associated with the access token
|
||||
* @param $scope OPTIONAL scopes to be stored in space-separated string.
|
||||
* @param bool $includeRefreshToken if true, a new refresh_token will be added to the response
|
||||
* @param mixed $client_id - client identifier related to the access token.
|
||||
* @param mixed $user_id - user ID associated with the access token
|
||||
* @param string $scope - OPTIONAL scopes to be stored in space-separated string.
|
||||
* @param bool $includeRefreshToken - if true, a new refresh_token will be added to the response
|
||||
* @return array
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-5
|
||||
* @ingroup oauth2_section_5
|
||||
@ -107,13 +126,18 @@ class AccessToken implements AccessTokenInterface
|
||||
* Implementing classes may want to override this function to implement
|
||||
* other access token generation schemes.
|
||||
*
|
||||
* @return
|
||||
* An unique access token.
|
||||
* @return string - A unique access token.
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
protected function generateAccessToken()
|
||||
{
|
||||
if (function_exists('random_bytes')) {
|
||||
$randomData = random_bytes(20);
|
||||
if ($randomData !== false && strlen($randomData) === 20) {
|
||||
return bin2hex($randomData);
|
||||
}
|
||||
}
|
||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||
$randomData = openssl_random_pseudo_bytes(20);
|
||||
if ($randomData !== false && strlen($randomData) === 20) {
|
||||
@ -144,8 +168,7 @@ class AccessToken implements AccessTokenInterface
|
||||
* Implementing classes may want to override this function to implement
|
||||
* other refresh token generation schemes.
|
||||
*
|
||||
* @return
|
||||
* An unique refresh.
|
||||
* @return string - A unique refresh token.
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
* @see OAuth2::generateAccessToken()
|
||||
@ -162,6 +185,7 @@ class AccessToken implements AccessTokenInterface
|
||||
*
|
||||
* @param $token
|
||||
* @param null $tokenTypeHint
|
||||
* @throws RuntimeException
|
||||
* @return boolean
|
||||
*/
|
||||
public function revokeToken($token, $tokenTypeHint = null)
|
||||
@ -174,7 +198,7 @@ class AccessToken implements AccessTokenInterface
|
||||
|
||||
/** @TODO remove in v2 */
|
||||
if (!method_exists($this->tokenStorage, 'unsetAccessToken')) {
|
||||
throw new \RuntimeException(
|
||||
throw new RuntimeException(
|
||||
sprintf('Token storage %s must implement unsetAccessToken method', get_class($this->tokenStorage)
|
||||
));
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace OAuth2\ResponseType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface AccessTokenInterface extends ResponseTypeInterface
|
||||
@ -11,10 +10,10 @@ interface AccessTokenInterface extends ResponseTypeInterface
|
||||
/**
|
||||
* Handle the creation of access token, also issue refresh token if supported / desirable.
|
||||
*
|
||||
* @param $client_id client identifier related to the access token.
|
||||
* @param $user_id user ID associated with the access token
|
||||
* @param $scope OPTONAL scopes to be stored in space-separated string.
|
||||
* @param bool $includeRefreshToken if true, a new refresh_token will be added to the response
|
||||
* @param mixed $client_id - client identifier related to the access token.
|
||||
* @param mixed $user_id - user ID associated with the access token
|
||||
* @param string $scope - OPTONAL scopes to be stored in space-separated string.
|
||||
* @param bool $includeRefreshToken - if true, a new refresh_token will be added to the response
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-5
|
||||
* @ingroup oauth2_section_5
|
||||
@ -31,4 +30,4 @@ interface AccessTokenInterface extends ResponseTypeInterface
|
||||
* @todo v2.0 include this method in interface. Omitted to maintain BC in v1.x
|
||||
*/
|
||||
//public function revokeToken($token, $tokenTypeHint);
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ namespace OAuth2\ResponseType;
|
||||
use OAuth2\Storage\AuthorizationCodeInterface as AuthorizationCodeStorageInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class AuthorizationCode implements AuthorizationCodeInterface
|
||||
@ -85,7 +84,9 @@ class AuthorizationCode implements AuthorizationCodeInterface
|
||||
protected function generateAuthorizationCode()
|
||||
{
|
||||
$tokenLen = 40;
|
||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||
if (function_exists('random_bytes')) {
|
||||
$randomData = random_bytes(100);
|
||||
} elseif (function_exists('openssl_random_pseudo_bytes')) {
|
||||
$randomData = openssl_random_pseudo_bytes(100);
|
||||
} elseif (function_exists('mcrypt_create_iv')) {
|
||||
$randomData = mcrypt_create_iv(100, MCRYPT_DEV_URANDOM);
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace OAuth2\ResponseType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
interface AuthorizationCodeInterface extends ResponseTypeInterface
|
||||
@ -17,11 +16,12 @@ interface AuthorizationCodeInterface extends ResponseTypeInterface
|
||||
/**
|
||||
* Handle the creation of the authorization code.
|
||||
*
|
||||
* @param $client_id client identifier related to the authorization code
|
||||
* @param $user_id user id associated with the authorization code
|
||||
* @param $redirect_uri an absolute URI to which the authorization server will redirect the
|
||||
* user-agent to when the end-user authorization step is completed.
|
||||
* @param $scope OPTIONAL scopes to be stored in space-separated string.
|
||||
* @param mixed $client_id - Client identifier related to the authorization code
|
||||
* @param mixed $user_id - User ID associated with the authorization code
|
||||
* @param string $redirect_uri - An absolute URI to which the authorization server will redirect the
|
||||
* user-agent to when the end-user authorization step is completed.
|
||||
* @param string $scope - OPTIONAL Scopes to be stored in space-separated string.
|
||||
* @return string
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-4
|
||||
* @ingroup oauth2_section_4
|
||||
|
@ -10,7 +10,6 @@ use OAuth2\Storage\PublicKeyInterface;
|
||||
use OAuth2\Storage\Memory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class JwtAccessToken extends AccessToken
|
||||
@ -19,10 +18,13 @@ class JwtAccessToken extends AccessToken
|
||||
protected $encryptionUtil;
|
||||
|
||||
/**
|
||||
* @param $config
|
||||
* - store_encrypted_token_string (bool true)
|
||||
* whether the entire encrypted string is stored,
|
||||
* or just the token ID is stored
|
||||
* @param PublicKeyInterface $publicKeyStorage -
|
||||
* @param AccessTokenStorageInterface $tokenStorage -
|
||||
* @param RefreshTokenInterface $refreshStorage -
|
||||
* @param array $config - array with key store_encrypted_token_string (bool true)
|
||||
* whether the entire encrypted string is stored,
|
||||
* or just the token ID is stored
|
||||
* @param EncryptionInterface $encryptionUtil -
|
||||
*/
|
||||
public function __construct(PublicKeyInterface $publicKeyStorage = null, AccessTokenStorageInterface $tokenStorage = null, RefreshTokenInterface $refreshStorage = null, array $config = array(), EncryptionInterface $encryptionUtil = null)
|
||||
{
|
||||
@ -45,46 +47,31 @@ class JwtAccessToken extends AccessToken
|
||||
/**
|
||||
* Handle the creation of access token, also issue refresh token if supported / desirable.
|
||||
*
|
||||
* @param $client_id
|
||||
* Client identifier related to the access token.
|
||||
* @param $user_id
|
||||
* User ID associated with the access token
|
||||
* @param $scope
|
||||
* (optional) Scopes to be stored in space-separated string.
|
||||
* @param bool $includeRefreshToken
|
||||
* If true, a new refresh_token will be added to the response
|
||||
* @param mixed $client_id - Client identifier related to the access token.
|
||||
* @param mixed $user_id - User ID associated with the access token
|
||||
* @param string $scope - (optional) Scopes to be stored in space-separated string.
|
||||
* @param bool $includeRefreshToken - If true, a new refresh_token will be added to the response
|
||||
* @return array - The access token
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-5
|
||||
* @ingroup oauth2_section_5
|
||||
*/
|
||||
public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true)
|
||||
{
|
||||
// token to encrypt
|
||||
$expires = time() + $this->config['access_lifetime'];
|
||||
$id = $this->generateAccessToken();
|
||||
$jwtAccessToken = array(
|
||||
'id' => $id, // for BC (see #591)
|
||||
'jti' => $id,
|
||||
'iss' => $this->config['issuer'],
|
||||
'aud' => $client_id,
|
||||
'sub' => $user_id,
|
||||
'exp' => $expires,
|
||||
'iat' => time(),
|
||||
'token_type' => $this->config['token_type'],
|
||||
'scope' => $scope
|
||||
);
|
||||
// payload to encrypt
|
||||
$payload = $this->createPayload($client_id, $user_id, $scope);
|
||||
|
||||
/*
|
||||
* Encode the token data into a single access_token string
|
||||
* Encode the payload data into a single JWT access_token string
|
||||
*/
|
||||
$access_token = $this->encodeToken($jwtAccessToken, $client_id);
|
||||
$access_token = $this->encodeToken($payload, $client_id);
|
||||
|
||||
/*
|
||||
* Save the token to a secondary storage. This is implemented on the
|
||||
* OAuth2\Storage\JwtAccessToken side, and will not actually store anything,
|
||||
* if no secondary storage has been supplied
|
||||
*/
|
||||
$token_to_store = $this->config['store_encrypted_token_string'] ? $access_token : $jwtAccessToken['id'];
|
||||
$token_to_store = $this->config['store_encrypted_token_string'] ? $access_token : $payload['id'];
|
||||
$this->tokenStorage->setAccessToken($token_to_store, $client_id, $user_id, $this->config['access_lifetime'] ? time() + $this->config['access_lifetime'] : null, $scope);
|
||||
|
||||
// token to return to the client
|
||||
@ -114,6 +101,11 @@ class JwtAccessToken extends AccessToken
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $token
|
||||
* @param mixed $client_id
|
||||
* @return mixed
|
||||
*/
|
||||
protected function encodeToken(array $token, $client_id = null)
|
||||
{
|
||||
$private_key = $this->publicKeyStorage->getPrivateKey($client_id);
|
||||
@ -121,4 +113,31 @@ class JwtAccessToken extends AccessToken
|
||||
|
||||
return $this->encryptionUtil->encode($token, $private_key, $algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function can be used to create custom JWT payloads
|
||||
*
|
||||
* @param mixed $client_id - Client identifier related to the access token.
|
||||
* @param mixed $user_id - User ID associated with the access token
|
||||
* @param string $scope - (optional) Scopes to be stored in space-separated string.
|
||||
* @return array - The access token
|
||||
*/
|
||||
protected function createPayload($client_id, $user_id, $scope = null)
|
||||
{
|
||||
// token to encrypt
|
||||
$expires = time() + $this->config['access_lifetime'];
|
||||
$id = $this->generateAccessToken();
|
||||
|
||||
return array(
|
||||
'id' => $id, // for BC (see #591)
|
||||
'jti' => $id,
|
||||
'iss' => $this->config['issuer'],
|
||||
'aud' => $client_id,
|
||||
'sub' => $user_id,
|
||||
'exp' => $expires,
|
||||
'iat' => time(),
|
||||
'token_type' => $this->config['token_type'],
|
||||
'scope' => $scope
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -4,5 +4,10 @@ namespace OAuth2\ResponseType;
|
||||
|
||||
interface ResponseTypeInterface
|
||||
{
|
||||
/**
|
||||
* @param array $params
|
||||
* @param mixed $user_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAuthorizeResponse($params, $user_id = null);
|
||||
}
|
||||
|
@ -2,19 +2,23 @@
|
||||
|
||||
namespace OAuth2;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use OAuth2\Storage\Memory;
|
||||
use OAuth2\Storage\ScopeInterface as ScopeStorageInterface;
|
||||
|
||||
/**
|
||||
* @see OAuth2\ScopeInterface
|
||||
* @see ScopeInterface
|
||||
*/
|
||||
class Scope implements ScopeInterface
|
||||
{
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* @param mixed @storage
|
||||
* Either an array of supported scopes, or an instance of OAuth2\Storage\ScopeInterface
|
||||
* Constructor
|
||||
*
|
||||
* @param mixed $storage - Either an array of supported scopes, or an instance of OAuth2\Storage\ScopeInterface
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct($storage = null)
|
||||
{
|
||||
@ -23,7 +27,7 @@ class Scope implements ScopeInterface
|
||||
}
|
||||
|
||||
if (!$storage instanceof ScopeStorageInterface) {
|
||||
throw new \InvalidArgumentException("Argument 1 to OAuth2\Scope must be null, an array, or instance of OAuth2\Storage\ScopeInterface");
|
||||
throw new InvalidArgumentException("Argument 1 to OAuth2\Scope must be null, an array, or instance of OAuth2\Storage\ScopeInterface");
|
||||
}
|
||||
|
||||
$this->storage = $storage;
|
||||
@ -32,12 +36,10 @@ class Scope implements ScopeInterface
|
||||
/**
|
||||
* Check if everything in required scope is contained in available scope.
|
||||
*
|
||||
* @param $required_scope
|
||||
* A space-separated string of scopes.
|
||||
*
|
||||
* @return
|
||||
* TRUE if everything in required scope is contained in available scope,
|
||||
* and FALSE if it isn't.
|
||||
* @param string $required_scope - A space-separated string of scopes.
|
||||
* @param string $available_scope - A space-separated string of scopes.
|
||||
* @return bool - TRUE if everything in required scope is contained in available scope and FALSE
|
||||
* if it isn't.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-7
|
||||
*
|
||||
@ -54,11 +56,8 @@ class Scope implements ScopeInterface
|
||||
/**
|
||||
* Check if the provided scope exists in storage.
|
||||
*
|
||||
* @param $scope
|
||||
* A space-separated string of scopes.
|
||||
*
|
||||
* @return
|
||||
* TRUE if it exists, FALSE otherwise.
|
||||
* @param string $scope - A space-separated string of scopes.
|
||||
* @return bool - TRUE if it exists, FALSE otherwise.
|
||||
*/
|
||||
public function scopeExists($scope)
|
||||
{
|
||||
@ -76,12 +75,20 @@ class Scope implements ScopeInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @return string
|
||||
*/
|
||||
public function getScopeFromRequest(RequestInterface $request)
|
||||
{
|
||||
// "scope" is valid if passed in either POST or QUERY
|
||||
return $request->request('scope', $request->query('scope'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $client_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefaultScope($client_id = null)
|
||||
{
|
||||
return $this->storage->getDefaultScope($client_id);
|
||||
@ -93,8 +100,7 @@ class Scope implements ScopeInterface
|
||||
* In case OpenID Connect is used, these scopes must include:
|
||||
* 'openid', offline_access'.
|
||||
*
|
||||
* @return
|
||||
* An array of reserved scopes.
|
||||
* @return array - An array of reserved scopes.
|
||||
*/
|
||||
public function getReservedScopes()
|
||||
{
|
||||
|
@ -7,19 +7,17 @@ use OAuth2\Storage\ScopeInterface as ScopeStorageInterface;
|
||||
/**
|
||||
* Class to handle scope implementation logic
|
||||
*
|
||||
* @see OAuth2\Storage\ScopeInterface
|
||||
* @see \OAuth2\Storage\ScopeInterface
|
||||
*/
|
||||
interface ScopeInterface extends ScopeStorageInterface
|
||||
{
|
||||
/**
|
||||
* Check if everything in required scope is contained in available scope.
|
||||
*
|
||||
* @param $required_scope
|
||||
* A space-separated string of scopes.
|
||||
*
|
||||
* @return
|
||||
* TRUE if everything in required scope is contained in available scope,
|
||||
* and FALSE if it isn't.
|
||||
* @param string $required_scope - A space-separated string of scopes.
|
||||
* @param string $available_scope - A space-separated string of scopes.
|
||||
* @return boolean - TRUE if everything in required scope is contained in available scope and FALSE
|
||||
* if it isn't.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-7
|
||||
*
|
||||
@ -30,11 +28,8 @@ interface ScopeInterface extends ScopeStorageInterface
|
||||
/**
|
||||
* Return scope info from request
|
||||
*
|
||||
* @param OAuth2\RequestInterface
|
||||
* Request object to check
|
||||
*
|
||||
* @return
|
||||
* string representation of requested scope
|
||||
* @param RequestInterface $request - Request object to check
|
||||
* @return string - representation of requested scope
|
||||
*/
|
||||
public function getScopeFromRequest(RequestInterface $request);
|
||||
}
|
||||
|
@ -30,25 +30,28 @@ use OAuth2\GrantType\UserCredentials;
|
||||
use OAuth2\GrantType\ClientCredentials;
|
||||
use OAuth2\GrantType\RefreshToken;
|
||||
use OAuth2\GrantType\AuthorizationCode;
|
||||
use OAuth2\Storage\ClientCredentialsInterface;
|
||||
use OAuth2\Storage\ClientInterface;
|
||||
use OAuth2\Storage\JwtAccessToken as JwtAccessTokenStorage;
|
||||
use OAuth2\Storage\JwtAccessTokenInterface;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
|
||||
/**
|
||||
* Server class for OAuth2
|
||||
* This class serves as a convience class which wraps the other Controller classes
|
||||
*
|
||||
* @see OAuth2\Controller\ResourceController
|
||||
* @see OAuth2\Controller\AuthorizeController
|
||||
* @see OAuth2\Controller\TokenController
|
||||
* @see \OAuth2\Controller\ResourceController
|
||||
* @see \OAuth2\Controller\AuthorizeController
|
||||
* @see \OAuth2\Controller\TokenController
|
||||
*/
|
||||
class Server implements ResourceControllerInterface,
|
||||
AuthorizeControllerInterface,
|
||||
TokenControllerInterface,
|
||||
UserInfoControllerInterface
|
||||
{
|
||||
// misc properties
|
||||
/**
|
||||
* @var Response
|
||||
* @var ResponseInterface
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
@ -62,7 +65,6 @@ class Server implements ResourceControllerInterface,
|
||||
*/
|
||||
protected $storages;
|
||||
|
||||
// servers
|
||||
/**
|
||||
* @var AuthorizeControllerInterface
|
||||
*/
|
||||
@ -83,17 +85,34 @@ class Server implements ResourceControllerInterface,
|
||||
*/
|
||||
protected $userInfoController;
|
||||
|
||||
// config classes
|
||||
protected $grantTypes;
|
||||
protected $responseTypes;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $grantTypes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $responseTypes = [];
|
||||
|
||||
/**
|
||||
* @var TokenTypeInterface
|
||||
*/
|
||||
protected $tokenType;
|
||||
|
||||
/**
|
||||
* @var ScopeInterface
|
||||
*/
|
||||
protected $scopeUtil;
|
||||
|
||||
/**
|
||||
* @var ClientAssertionTypeInterface
|
||||
*/
|
||||
protected $clientAssertionType;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $storageMap = array(
|
||||
'access_token' => 'OAuth2\Storage\AccessTokenInterface',
|
||||
'authorization_code' => 'OAuth2\Storage\AuthorizationCodeInterface',
|
||||
@ -107,6 +126,9 @@ class Server implements ResourceControllerInterface,
|
||||
'scope' => 'OAuth2\Storage\ScopeInterface',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $responseTypeMap = array(
|
||||
'token' => 'OAuth2\ResponseType\AccessTokenInterface',
|
||||
'code' => 'OAuth2\ResponseType\AuthorizationCodeInterface',
|
||||
@ -116,15 +138,15 @@ class Server implements ResourceControllerInterface,
|
||||
);
|
||||
|
||||
/**
|
||||
* @param mixed $storage (array or OAuth2\Storage) - single object or array of objects implementing the
|
||||
* required storage types (ClientCredentialsInterface and AccessTokenInterface as a minimum)
|
||||
* @param array $config specify a different token lifetime, token header name, etc
|
||||
* @param array $grantTypes An array of OAuth2\GrantType\GrantTypeInterface to use for granting access tokens
|
||||
* @param array $responseTypes Response types to use. array keys should be "code" and and "token" for
|
||||
* Access Token and Authorization Code response types
|
||||
* @param \OAuth2\TokenType\TokenTypeInterface $tokenType The token type object to use. Valid token types are "bearer" and "mac"
|
||||
* @param \OAuth2\ScopeInterface $scopeUtil The scope utility class to use to validate scope
|
||||
* @param \OAuth2\ClientAssertionType\ClientAssertionTypeInterface $clientAssertionType The method in which to verify the client identity. Default is HttpBasic
|
||||
* @param mixed $storage (array or OAuth2\Storage) - single object or array of objects implementing the
|
||||
* required storage types (ClientCredentialsInterface and AccessTokenInterface as a minimum)
|
||||
* @param array $config specify a different token lifetime, token header name, etc
|
||||
* @param array $grantTypes An array of OAuth2\GrantType\GrantTypeInterface to use for granting access tokens
|
||||
* @param array $responseTypes Response types to use. array keys should be "code" and "token" for
|
||||
* Access Token and Authorization Code response types
|
||||
* @param TokenTypeInterface $tokenType The token type object to use. Valid token types are "bearer" and "mac"
|
||||
* @param ScopeInterface $scopeUtil The scope utility class to use to validate scope
|
||||
* @param ClientAssertionTypeInterface $clientAssertionType The method in which to verify the client identity. Default is HttpBasic
|
||||
*
|
||||
* @ingroup oauth2_section_7
|
||||
*/
|
||||
@ -172,6 +194,9 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AuthorizeControllerInterface
|
||||
*/
|
||||
public function getAuthorizeController()
|
||||
{
|
||||
if (is_null($this->authorizeController)) {
|
||||
@ -181,6 +206,9 @@ class Server implements ResourceControllerInterface,
|
||||
return $this->authorizeController;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TokenController
|
||||
*/
|
||||
public function getTokenController()
|
||||
{
|
||||
if (is_null($this->tokenController)) {
|
||||
@ -190,6 +218,9 @@ class Server implements ResourceControllerInterface,
|
||||
return $this->tokenController;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ResourceControllerInterface
|
||||
*/
|
||||
public function getResourceController()
|
||||
{
|
||||
if (is_null($this->resourceController)) {
|
||||
@ -199,6 +230,9 @@ class Server implements ResourceControllerInterface,
|
||||
return $this->resourceController;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UserInfoControllerInterface
|
||||
*/
|
||||
public function getUserInfoController()
|
||||
{
|
||||
if (is_null($this->userInfoController)) {
|
||||
@ -209,8 +243,6 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
|
||||
/**
|
||||
* every getter deserves a setter
|
||||
*
|
||||
* @param AuthorizeControllerInterface $authorizeController
|
||||
*/
|
||||
public function setAuthorizeController(AuthorizeControllerInterface $authorizeController)
|
||||
@ -219,8 +251,6 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
|
||||
/**
|
||||
* every getter deserves a setter
|
||||
*
|
||||
* @param TokenControllerInterface $tokenController
|
||||
*/
|
||||
public function setTokenController(TokenControllerInterface $tokenController)
|
||||
@ -229,8 +259,6 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
|
||||
/**
|
||||
* every getter deserves a setter
|
||||
*
|
||||
* @param ResourceControllerInterface $resourceController
|
||||
*/
|
||||
public function setResourceController(ResourceControllerInterface $resourceController)
|
||||
@ -239,8 +267,6 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
|
||||
/**
|
||||
* every getter deserves a setter
|
||||
*
|
||||
* @param UserInfoControllerInterface $userInfoController
|
||||
*/
|
||||
public function setUserInfoController(UserInfoControllerInterface $userInfoController)
|
||||
@ -252,12 +278,8 @@ class Server implements ResourceControllerInterface,
|
||||
* Return claims about the authenticated end-user.
|
||||
* This would be called from the "/UserInfo" endpoint as defined in the spec.
|
||||
*
|
||||
* @param $request - \OAuth2\RequestInterface
|
||||
* Request object to grant access token
|
||||
*
|
||||
* @param $response - \OAuth2\ResponseInterface
|
||||
* Response object containing error messages (failure) or user claims (success)
|
||||
*
|
||||
* @param RequestInterface $request - Request object to grant access token
|
||||
* @param ResponseInterface $response - Response object containing error messages (failure) or user claims (success)
|
||||
* @return ResponseInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
@ -278,12 +300,8 @@ class Server implements ResourceControllerInterface,
|
||||
* This would be called from the "/token" endpoint as defined in the spec.
|
||||
* Obviously, you can call your endpoint whatever you want.
|
||||
*
|
||||
* @param $request - \OAuth2\RequestInterface
|
||||
* Request object to grant access token
|
||||
*
|
||||
* @param $response - \OAuth2\ResponseInterface
|
||||
* Response object containing error messages (failure) or access token (success)
|
||||
*
|
||||
* @param RequestInterface $request - Request object to grant access token
|
||||
* @param ResponseInterface $response - Response object containing error messages (failure) or access token (success)
|
||||
* @return ResponseInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
@ -303,6 +321,11 @@ class Server implements ResourceControllerInterface,
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request - Request object to grant access token
|
||||
* @param ResponseInterface $response - Response object
|
||||
* @return mixed
|
||||
*/
|
||||
public function grantAccessToken(RequestInterface $request, ResponseInterface $response = null)
|
||||
{
|
||||
$this->response = is_null($response) ? new Response() : $response;
|
||||
@ -336,25 +359,18 @@ class Server implements ResourceControllerInterface,
|
||||
* authorization server should call this function to redirect the user
|
||||
* appropriately.
|
||||
*
|
||||
* @param $request
|
||||
* The request should have the follow parameters set in the querystring:
|
||||
* - response_type: The requested response: an access token, an
|
||||
* authorization code, or both.
|
||||
* @param RequestInterface $request - The request should have the follow parameters set in the querystring:
|
||||
* - response_type: The requested response: an access token, an authorization code, or both.
|
||||
* - client_id: The client identifier as described in Section 2.
|
||||
* - redirect_uri: An absolute URI to which the authorization server
|
||||
* will redirect the user-agent to when the end-user authorization
|
||||
* step is completed.
|
||||
* - scope: (optional) The scope of the resource request expressed as a
|
||||
* list of space-delimited strings.
|
||||
* - state: (optional) An opaque value used by the client to maintain
|
||||
* state between the request and callback.
|
||||
* @param ResponseInterface $response
|
||||
* @param $is_authorized
|
||||
* TRUE or FALSE depending on whether the user authorized the access.
|
||||
* @param $user_id
|
||||
* Identifier of user who authorized the client
|
||||
* - redirect_uri: An absolute URI to which the authorization server will redirect the user-agent to when the
|
||||
* end-user authorization step is completed.
|
||||
* - scope: (optional) The scope of the resource request expressed as a list of space-delimited strings.
|
||||
* - state: (optional) An opaque value used by the client to maintain state between the request and callback.
|
||||
*
|
||||
* @return Response
|
||||
* @param ResponseInterface $response - Response object
|
||||
* @param bool $is_authorized - TRUE or FALSE depending on whether the user authorized the access.
|
||||
* @param mixed $user_id - Identifier of user who authorized the client
|
||||
* @return ResponseInterface
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6749#section-4
|
||||
*
|
||||
@ -371,14 +387,17 @@ class Server implements ResourceControllerInterface,
|
||||
/**
|
||||
* Pull the authorization request data out of the HTTP request.
|
||||
* - The redirect_uri is OPTIONAL as per draft 20. But your implementation can enforce it
|
||||
* by setting $config['enforce_redirect'] to true.
|
||||
* by setting $config['enforce_redirect'] to true.
|
||||
* - The state is OPTIONAL but recommended to enforce CSRF. Draft 21 states, however, that
|
||||
* CSRF protection is MANDATORY. You can enforce this by setting the $config['enforce_state'] to true.
|
||||
* CSRF protection is MANDATORY. You can enforce this by setting the $config['enforce_state'] to true.
|
||||
*
|
||||
* The draft specifies that the parameters should be retrieved from GET, override the Response
|
||||
* object to change this
|
||||
*
|
||||
* @return
|
||||
* @param RequestInterface $request - Request object
|
||||
* @param ResponseInterface $response - Response object
|
||||
* @return bool
|
||||
*
|
||||
* The authorization parameters so the authorization server can prompt
|
||||
* the user for approval if valid.
|
||||
*
|
||||
@ -395,6 +414,12 @@ class Server implements ResourceControllerInterface,
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request - Request object
|
||||
* @param ResponseInterface $response - Response object
|
||||
* @param string $scope - Scope
|
||||
* @return mixed
|
||||
*/
|
||||
public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response = null, $scope = null)
|
||||
{
|
||||
$this->response = is_null($response) ? new Response() : $response;
|
||||
@ -403,6 +428,11 @@ class Server implements ResourceControllerInterface,
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request - Request object
|
||||
* @param ResponseInterface $response - Response object
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAccessTokenData(RequestInterface $request, ResponseInterface $response = null)
|
||||
{
|
||||
$this->response = is_null($response) ? new Response() : $response;
|
||||
@ -411,10 +441,14 @@ class Server implements ResourceControllerInterface,
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GrantTypeInterface $grantType
|
||||
* @param mixed $identifier
|
||||
*/
|
||||
public function addGrantType(GrantTypeInterface $grantType, $identifier = null)
|
||||
{
|
||||
if (!is_string($identifier)) {
|
||||
$identifier = $grantType->getQuerystringIdentifier();
|
||||
$identifier = $grantType->getQueryStringIdentifier();
|
||||
}
|
||||
|
||||
$this->grantTypes[$identifier] = $grantType;
|
||||
@ -428,11 +462,10 @@ class Server implements ResourceControllerInterface,
|
||||
/**
|
||||
* Set a storage object for the server
|
||||
*
|
||||
* @param $storage
|
||||
* An object implementing one of the Storage interfaces
|
||||
* @param $key
|
||||
* If null, the storage is set to the key of each storage interface it implements
|
||||
* @param object $storage - An object implementing one of the Storage interfaces
|
||||
* @param mixed $key - If null, the storage is set to the key of each storage interface it implements
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @see storageMap
|
||||
*/
|
||||
public function addStorage($storage, $key = null)
|
||||
@ -446,11 +479,11 @@ class Server implements ResourceControllerInterface,
|
||||
|
||||
// special logic to handle "client" and "client_credentials" strangeness
|
||||
if ($key === 'client' && !isset($this->storages['client_credentials'])) {
|
||||
if ($storage instanceof \OAuth2\Storage\ClientCredentialsInterface) {
|
||||
if ($storage instanceof ClientCredentialsInterface) {
|
||||
$this->storages['client_credentials'] = $storage;
|
||||
}
|
||||
} elseif ($key === 'client_credentials' && !isset($this->storages['client'])) {
|
||||
if ($storage instanceof \OAuth2\Storage\ClientInterface) {
|
||||
if ($storage instanceof ClientInterface) {
|
||||
$this->storages['client'] = $storage;
|
||||
}
|
||||
}
|
||||
@ -471,6 +504,12 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ResponseTypeInterface $responseType
|
||||
* @param mixed $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function addResponseType(ResponseTypeInterface $responseType, $key = null)
|
||||
{
|
||||
$key = $this->normalizeResponseType($key);
|
||||
@ -497,6 +536,9 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ScopeInterface
|
||||
*/
|
||||
public function getScopeUtil()
|
||||
{
|
||||
if (!$this->scopeUtil) {
|
||||
@ -508,8 +550,6 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
|
||||
/**
|
||||
* every getter deserves a setter
|
||||
*
|
||||
* @param ScopeInterface $scopeUtil
|
||||
*/
|
||||
public function setScopeUtil($scopeUtil)
|
||||
@ -517,6 +557,10 @@ class Server implements ResourceControllerInterface,
|
||||
$this->scopeUtil = $scopeUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AuthorizeControllerInterface
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function createDefaultAuthorizeController()
|
||||
{
|
||||
if (!isset($this->storages['client'])) {
|
||||
@ -541,6 +585,10 @@ class Server implements ResourceControllerInterface,
|
||||
return new AuthorizeController($this->storages['client'], $this->responseTypes, $config, $this->getScopeUtil());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TokenControllerInterface
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function createDefaultTokenController()
|
||||
{
|
||||
if (0 == count($this->grantTypes)) {
|
||||
@ -562,7 +610,7 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
|
||||
if (!isset($this->storages['client'])) {
|
||||
throw new \LogicException('You must supply a storage object implementing OAuth2\Storage\ClientInterface to use the token server');
|
||||
throw new LogicException("You must supply a storage object implementing OAuth2\Storage\ClientInterface to use the token server");
|
||||
}
|
||||
|
||||
$accessTokenResponseType = $this->getAccessTokenResponseType();
|
||||
@ -570,6 +618,10 @@ class Server implements ResourceControllerInterface,
|
||||
return new TokenController($accessTokenResponseType, $this->storages['client'], $this->grantTypes, $this->clientAssertionType, $this->getScopeUtil());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ResourceControllerInterface
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function createDefaultResourceController()
|
||||
{
|
||||
if ($this->config['use_jwt_access_tokens']) {
|
||||
@ -590,6 +642,10 @@ class Server implements ResourceControllerInterface,
|
||||
return new ResourceController($this->tokenType, $this->storages['access_token'], $config, $this->getScopeUtil());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UserInfoControllerInterface
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function createDefaultUserInfoController()
|
||||
{
|
||||
if ($this->config['use_jwt_access_tokens']) {
|
||||
@ -614,6 +670,9 @@ class Server implements ResourceControllerInterface,
|
||||
return new UserInfoController($this->tokenType, $this->storages['access_token'], $this->storages['user_claims'], $config, $this->getScopeUtil());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Bearer
|
||||
*/
|
||||
protected function getDefaultTokenType()
|
||||
{
|
||||
$config = array_intersect_key($this->config, array_flip(explode(' ', 'token_param_name token_bearer_header_name')));
|
||||
@ -621,6 +680,10 @@ class Server implements ResourceControllerInterface,
|
||||
return new Bearer($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function getDefaultResponseTypes()
|
||||
{
|
||||
$responseTypes = array();
|
||||
@ -656,6 +719,10 @@ class Server implements ResourceControllerInterface,
|
||||
return $responseTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function getDefaultGrantTypes()
|
||||
{
|
||||
$grantTypes = array();
|
||||
@ -692,6 +759,9 @@ class Server implements ResourceControllerInterface,
|
||||
return $grantTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AccessToken
|
||||
*/
|
||||
protected function getAccessTokenResponseType()
|
||||
{
|
||||
if (isset($this->responseTypes['token'])) {
|
||||
@ -705,6 +775,9 @@ class Server implements ResourceControllerInterface,
|
||||
return $this->createDefaultAccessTokenResponseType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IdToken
|
||||
*/
|
||||
protected function getIdTokenResponseType()
|
||||
{
|
||||
if (isset($this->responseTypes['id_token'])) {
|
||||
@ -714,6 +787,9 @@ class Server implements ResourceControllerInterface,
|
||||
return $this->createDefaultIdTokenResponseType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IdTokenToken
|
||||
*/
|
||||
protected function getIdTokenTokenResponseType()
|
||||
{
|
||||
if (isset($this->responseTypes['id_token token'])) {
|
||||
@ -725,6 +801,9 @@ class Server implements ResourceControllerInterface,
|
||||
|
||||
/**
|
||||
* For Resource Controller
|
||||
*
|
||||
* @return JwtAccessTokenStorage
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function createDefaultJwtAccessTokenStorage()
|
||||
{
|
||||
@ -741,6 +820,9 @@ class Server implements ResourceControllerInterface,
|
||||
|
||||
/**
|
||||
* For Authorize and Token Controllers
|
||||
*
|
||||
* @return JwtAccessToken
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function createDefaultJwtAccessTokenResponseType()
|
||||
{
|
||||
@ -763,10 +845,14 @@ class Server implements ResourceControllerInterface,
|
||||
return new JwtAccessToken($this->storages['public_key'], $tokenStorage, $refreshStorage, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AccessToken
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function createDefaultAccessTokenResponseType()
|
||||
{
|
||||
if (!isset($this->storages['access_token'])) {
|
||||
throw new \LogicException('You must supply a response type implementing OAuth2\ResponseType\AccessTokenInterface, or a storage object implementing OAuth2\Storage\AccessTokenInterface to use the token server');
|
||||
throw new LogicException("You must supply a response type implementing OAuth2\ResponseType\AccessTokenInterface, or a storage object implementing OAuth2\Storage\AccessTokenInterface to use the token server");
|
||||
}
|
||||
|
||||
$refreshStorage = null;
|
||||
@ -780,13 +866,17 @@ class Server implements ResourceControllerInterface,
|
||||
return new AccessToken($this->storages['access_token'], $refreshStorage, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IdToken
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function createDefaultIdTokenResponseType()
|
||||
{
|
||||
if (!isset($this->storages['user_claims'])) {
|
||||
throw new \LogicException('You must supply a storage object implementing OAuth2\OpenID\Storage\UserClaimsInterface to use openid connect');
|
||||
throw new LogicException("You must supply a storage object implementing OAuth2\OpenID\Storage\UserClaimsInterface to use openid connect");
|
||||
}
|
||||
if (!isset($this->storages['public_key'])) {
|
||||
throw new \LogicException('You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use openid connect');
|
||||
throw new LogicException("You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use openid connect");
|
||||
}
|
||||
|
||||
$config = array_intersect_key($this->config, array_flip(explode(' ', 'issuer id_lifetime')));
|
||||
@ -794,11 +884,17 @@ class Server implements ResourceControllerInterface,
|
||||
return new IdToken($this->storages['user_claims'], $this->storages['public_key'], $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IdTokenToken
|
||||
*/
|
||||
protected function createDefaultIdTokenTokenResponseType()
|
||||
{
|
||||
return new IdTokenToken($this->getAccessTokenResponseType(), $this->getIdTokenResponseType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function validateOpenIdConnect()
|
||||
{
|
||||
$authCodeGrant = $this->getGrantType('authorization_code');
|
||||
@ -807,6 +903,10 @@ class Server implements ResourceControllerInterface,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function normalizeResponseType($name)
|
||||
{
|
||||
// for multiple-valued response types - make them alphabetical
|
||||
@ -819,36 +919,60 @@ class Server implements ResourceControllerInterface,
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getStorages()
|
||||
{
|
||||
return $this->storages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return object|null
|
||||
*/
|
||||
public function getStorage($name)
|
||||
{
|
||||
return isset($this->storages[$name]) ? $this->storages[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getGrantTypes()
|
||||
{
|
||||
return $this->grantTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return object|null
|
||||
*/
|
||||
public function getGrantType($name)
|
||||
{
|
||||
return isset($this->grantTypes[$name]) ? $this->grantTypes[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getResponseTypes()
|
||||
{
|
||||
return $this->responseTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return object|null
|
||||
*/
|
||||
public function getResponseType($name)
|
||||
{
|
||||
// for multiple-valued response types - make them alphabetical
|
||||
@ -857,23 +981,38 @@ class Server implements ResourceControllerInterface,
|
||||
return isset($this->responseTypes[$name]) ? $this->responseTypes[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TokenTypeInterface
|
||||
*/
|
||||
public function getTokenType()
|
||||
{
|
||||
return $this->tokenType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClientAssertionTypeInterface
|
||||
*/
|
||||
public function getClientAssertionType()
|
||||
{
|
||||
return $this->clientAssertionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setConfig($name, $value)
|
||||
{
|
||||
$this->config[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getConfig($name, $default = null)
|
||||
{
|
||||
return isset($this->config[$name]) ? $this->config[$name] : $default;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,17 +15,18 @@ interface AccessTokenInterface
|
||||
*
|
||||
* We need to retrieve access token data as we create and verify tokens.
|
||||
*
|
||||
* @param $oauth_token
|
||||
* oauth_token to be check with.
|
||||
* @param string $oauth_token - oauth_token to be check with.
|
||||
*
|
||||
* @return
|
||||
* An associative array as below, and return NULL if the supplied oauth_token
|
||||
* is invalid:
|
||||
* - expires: Stored expiration in unix timestamp.
|
||||
* - client_id: (optional) Stored client identifier.
|
||||
* - user_id: (optional) Stored user identifier.
|
||||
* - scope: (optional) Stored scope values in space-separated string.
|
||||
* - id_token: (optional) Stored id_token (if "use_openid_connect" is true).
|
||||
* @return array|null - An associative array as below, and return NULL if the supplied oauth_token is invalid:
|
||||
* @code
|
||||
* array(
|
||||
* 'expires' => $expires, // Stored expiration in unix timestamp.
|
||||
* 'client_id' => $client_id, // (optional) Stored client identifier.
|
||||
* 'user_id' => $user_id, // (optional) Stored user identifier.
|
||||
* 'scope' => $scope, // (optional) Stored scope values in space-separated string.
|
||||
* 'id_token' => $id_token // (optional) Stored id_token (if "use_openid_connect" is true).
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup oauth2_section_7
|
||||
*/
|
||||
@ -36,11 +37,11 @@ interface AccessTokenInterface
|
||||
*
|
||||
* We need to store access token data as we create and verify tokens.
|
||||
*
|
||||
* @param $oauth_token oauth_token to be stored.
|
||||
* @param $client_id client identifier to be stored.
|
||||
* @param $user_id user identifier to be stored.
|
||||
* @param int $expires expiration to be stored as a Unix timestamp.
|
||||
* @param string $scope OPTIONAL Scopes to be stored in space-separated string.
|
||||
* @param string $oauth_token - oauth_token to be stored.
|
||||
* @param mixed $client_id - client identifier to be stored.
|
||||
* @param mixed $user_id - user identifier to be stored.
|
||||
* @param int $expires - expiration to be stored as a Unix timestamp.
|
||||
* @param string $scope - OPTIONAL Scopes to be stored in space-separated string.
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
@ -61,4 +62,4 @@ interface AccessTokenInterface
|
||||
* @todo v2.0 include this method in interface. Omitted to maintain BC in v1.x
|
||||
*/
|
||||
//public function unsetAccessToken($access_token);
|
||||
}
|
||||
}
|
@ -59,12 +59,12 @@ interface AuthorizationCodeInterface
|
||||
*
|
||||
* Required for OAuth2::GRANT_TYPE_AUTH_CODE.
|
||||
*
|
||||
* @param string $code Authorization code to be stored.
|
||||
* @param mixed $client_id Client identifier to be stored.
|
||||
* @param mixed $user_id User identifier to be stored.
|
||||
* @param string $redirect_uri Redirect URI(s) to be stored in a space-separated string.
|
||||
* @param int $expires Expiration to be stored as a Unix timestamp.
|
||||
* @param string $scope OPTIONAL Scopes to be stored in space-separated string.
|
||||
* @param string $code - Authorization code to be stored.
|
||||
* @param mixed $client_id - Client identifier to be stored.
|
||||
* @param mixed $user_id - User identifier to be stored.
|
||||
* @param string $redirect_uri - Redirect URI(s) to be stored in a space-separated string.
|
||||
* @param int $expires - Expiration to be stored as a Unix timestamp.
|
||||
* @param string $scope - OPTIONAL Scopes to be stored in space-separated string.
|
||||
*
|
||||
* @ingroup oauth2_section_4
|
||||
*/
|
||||
|
@ -7,24 +7,25 @@ use phpcassa\ColumnSlice;
|
||||
use phpcassa\Connection\ConnectionPool;
|
||||
use OAuth2\OpenID\Storage\UserClaimsInterface;
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Cassandra storage for all storage types
|
||||
*
|
||||
* To use, install "thobbs/phpcassa" via composer
|
||||
* To use, install "thobbs/phpcassa" via composer:
|
||||
* <code>
|
||||
* composer require thobbs/phpcassa:dev-master
|
||||
* composer require thobbs/phpcassa:dev-master
|
||||
* </code>
|
||||
*
|
||||
* Once this is done, instantiate the
|
||||
* Once this is done, instantiate the connection:
|
||||
* <code>
|
||||
* $cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_server', array('127.0.0.1:9160'));
|
||||
* $cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_server', array('127.0.0.1:9160'));
|
||||
* </code>
|
||||
*
|
||||
* Then, register the storage client:
|
||||
* <code>
|
||||
* $storage = new OAuth2\Storage\Cassandra($cassandra);
|
||||
* $storage->setClientDetails($client_id, $client_secret, $redirect_uri);
|
||||
* $storage = new OAuth2\Storage\Cassandra($cassandra);
|
||||
* $storage->setClientDetails($client_id, $client_secret, $redirect_uri);
|
||||
* </code>
|
||||
*
|
||||
* @see test/lib/OAuth2/Storage/Bootstrap::getCassandraStorage
|
||||
@ -43,17 +44,23 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
|
||||
private $cache;
|
||||
|
||||
/* The cassandra client */
|
||||
/**
|
||||
* @var ConnectionPool
|
||||
*/
|
||||
protected $cassandra;
|
||||
|
||||
/* Configuration array */
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Cassandra Storage! uses phpCassa
|
||||
*
|
||||
* @param \phpcassa\ConnectionPool $cassandra
|
||||
* @param array $config
|
||||
* @param ConnectionPool|array $connection
|
||||
* @param array $config
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct($connection = array(), array $config = array())
|
||||
{
|
||||
@ -61,7 +68,7 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
$this->cassandra = $connection;
|
||||
} else {
|
||||
if (!is_array($connection)) {
|
||||
throw new \InvalidArgumentException('First argument to OAuth2\Storage\Cassandra must be an instance of phpcassa\Connection\ConnectionPool or a configuration array');
|
||||
throw new InvalidArgumentException('First argument to OAuth2\Storage\Cassandra must be an instance of phpcassa\Connection\ConnectionPool or a configuration array');
|
||||
}
|
||||
$connection = array_merge(array(
|
||||
'keyspace' => 'oauth2',
|
||||
@ -87,6 +94,10 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
), $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @return bool|mixed
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
if (isset($this->cache[$key])) {
|
||||
@ -104,6 +115,12 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return json_decode($value, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param $value
|
||||
* @param int $expire
|
||||
* @return bool
|
||||
*/
|
||||
protected function setValue($key, $value, $expire = 0)
|
||||
{
|
||||
$this->cache[$key] = $value;
|
||||
@ -131,6 +148,10 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @return bool
|
||||
*/
|
||||
protected function expireValue($key)
|
||||
{
|
||||
unset($this->cache[$key]);
|
||||
@ -151,12 +172,25 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* AuthorizationCodeInterface */
|
||||
/**
|
||||
* @param string $code
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function getAuthorizationCode($code)
|
||||
{
|
||||
return $this->getValue($this->config['code_key'] . $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $authorization_code
|
||||
* @param mixed $client_id
|
||||
* @param mixed $user_id
|
||||
* @param string $redirect_uri
|
||||
* @param int $expires
|
||||
* @param string $scope
|
||||
* @param string $id_token
|
||||
* @return bool
|
||||
*/
|
||||
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
@ -166,6 +200,10 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
* @return bool
|
||||
*/
|
||||
public function expireAuthorizationCode($code)
|
||||
{
|
||||
$key = $this->config['code_key'] . $code;
|
||||
@ -174,7 +212,11 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return $this->expireValue($key);
|
||||
}
|
||||
|
||||
/* UserCredentialsInterface */
|
||||
/**
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
@ -184,7 +226,13 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return false;
|
||||
}
|
||||
|
||||
// plaintext passwords are bad! Override this for your application
|
||||
/**
|
||||
* plaintext passwords are bad! Override this for your application
|
||||
*
|
||||
* @param array $user
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkPassword($user, $password)
|
||||
{
|
||||
return $user['password'] == $this->hashPassword($password);
|
||||
@ -196,11 +244,19 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return sha1($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @return array|bool|false
|
||||
*/
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
return $this->getUser($username);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getUser($username)
|
||||
{
|
||||
if (!$userInfo = $this->getValue($this->config['user_key'] . $username)) {
|
||||
@ -213,6 +269,13 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
), $userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $first_name
|
||||
* @param string $last_name
|
||||
* @return bool
|
||||
*/
|
||||
public function setUser($username, $password, $first_name = null, $last_name = null)
|
||||
{
|
||||
$password = $this->hashPassword($password);
|
||||
@ -223,7 +286,11 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
);
|
||||
}
|
||||
|
||||
/* ClientCredentialsInterface */
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @param string $client_secret
|
||||
* @return bool
|
||||
*/
|
||||
public function checkClientCredentials($client_id, $client_secret = null)
|
||||
{
|
||||
if (!$client = $this->getClientDetails($client_id)) {
|
||||
@ -234,6 +301,10 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
&& $client['client_secret'] == $client_secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $client_id
|
||||
* @return bool
|
||||
*/
|
||||
public function isPublicClient($client_id)
|
||||
{
|
||||
if (!$client = $this->getClientDetails($client_id)) {
|
||||
@ -243,12 +314,24 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return empty($client['client_secret']);
|
||||
}
|
||||
|
||||
/* ClientInterface */
|
||||
/**
|
||||
* @param $client_id
|
||||
* @return array|bool|mixed
|
||||
*/
|
||||
public function getClientDetails($client_id)
|
||||
{
|
||||
return $this->getValue($this->config['client_key'] . $client_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $client_id
|
||||
* @param null $client_secret
|
||||
* @param null $redirect_uri
|
||||
* @param null $grant_types
|
||||
* @param null $scope
|
||||
* @param null $user_id
|
||||
* @return bool
|
||||
*/
|
||||
public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
@ -257,6 +340,11 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $client_id
|
||||
* @param $grant_type
|
||||
* @return bool
|
||||
*/
|
||||
public function checkRestrictedGrantType($client_id, $grant_type)
|
||||
{
|
||||
$details = $this->getClientDetails($client_id);
|
||||
@ -270,12 +358,23 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* RefreshTokenInterface */
|
||||
/**
|
||||
* @param $refresh_token
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function getRefreshToken($refresh_token)
|
||||
{
|
||||
return $this->getValue($this->config['refresh_token_key'] . $refresh_token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $refresh_token
|
||||
* @param $client_id
|
||||
* @param $user_id
|
||||
* @param $expires
|
||||
* @param null $scope
|
||||
* @return bool
|
||||
*/
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
@ -285,17 +384,32 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $refresh_token
|
||||
* @return bool
|
||||
*/
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
return $this->expireValue($this->config['refresh_token_key'] . $refresh_token);
|
||||
}
|
||||
|
||||
/* AccessTokenInterface */
|
||||
/**
|
||||
* @param string $access_token
|
||||
* @return array|bool|mixed|null
|
||||
*/
|
||||
public function getAccessToken($access_token)
|
||||
{
|
||||
return $this->getValue($this->config['access_token_key'].$access_token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $access_token
|
||||
* @param mixed $client_id
|
||||
* @param mixed $user_id
|
||||
* @param int $expires
|
||||
* @param null $scope
|
||||
* @return bool
|
||||
*/
|
||||
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
return $this->setValue(
|
||||
@ -305,12 +419,19 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $access_token
|
||||
* @return bool
|
||||
*/
|
||||
public function unsetAccessToken($access_token)
|
||||
{
|
||||
return $this->expireValue($this->config['access_token_key'] . $access_token);
|
||||
}
|
||||
|
||||
/* ScopeInterface */
|
||||
/**
|
||||
* @param $scope
|
||||
* @return bool
|
||||
*/
|
||||
public function scopeExists($scope)
|
||||
{
|
||||
$scope = explode(' ', $scope);
|
||||
@ -322,6 +443,10 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return (count(array_diff($scope, $supportedScope)) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $client_id
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function getDefaultScope($client_id = null)
|
||||
{
|
||||
if (is_null($client_id) || !$result = $this->getValue($this->config['scope_key'].'default:'.$client_id)) {
|
||||
@ -331,6 +456,13 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $scope
|
||||
* @param null $client_id
|
||||
* @param string $type
|
||||
* @return bool
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setScope($scope, $client_id = null, $type = 'supported')
|
||||
{
|
||||
if (!in_array($type, array('default', 'supported'))) {
|
||||
@ -346,7 +478,11 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return $this->setValue($key, $scope);
|
||||
}
|
||||
|
||||
/*JWTBearerInterface */
|
||||
/**
|
||||
* @param $client_id
|
||||
* @param $subject
|
||||
* @return bool|null
|
||||
*/
|
||||
public function getClientKey($client_id, $subject)
|
||||
{
|
||||
if (!$jwt = $this->getValue($this->config['jwt_key'] . $client_id)) {
|
||||
@ -360,6 +496,12 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $client_id
|
||||
* @param $key
|
||||
* @param null $subject
|
||||
* @return bool
|
||||
*/
|
||||
public function setClientKey($client_id, $key, $subject = null)
|
||||
{
|
||||
return $this->setValue($this->config['jwt_key'] . $client_id, array(
|
||||
@ -368,7 +510,10 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
));
|
||||
}
|
||||
|
||||
/*ScopeInterface */
|
||||
/**
|
||||
* @param $client_id
|
||||
* @return bool|null
|
||||
*/
|
||||
public function getClientScope($client_id)
|
||||
{
|
||||
if (!$clientDetails = $this->getClientDetails($client_id)) {
|
||||
@ -382,19 +527,38 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $client_id
|
||||
* @param $subject
|
||||
* @param $audience
|
||||
* @param $expiration
|
||||
* @param $jti
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs cassandra implementation.
|
||||
throw new \Exception('getJti() for the Cassandra driver is currently unimplemented.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $client_id
|
||||
* @param $subject
|
||||
* @param $audience
|
||||
* @param $expiration
|
||||
* @param $jti
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setJti($client_id, $subject, $audience, $expiration, $jti)
|
||||
{
|
||||
//TODO: Needs cassandra implementation.
|
||||
throw new \Exception('setJti() for the Cassandra driver is currently unimplemented.');
|
||||
}
|
||||
|
||||
/* PublicKeyInterface */
|
||||
/**
|
||||
* @param string $client_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPublicKey($client_id = '')
|
||||
{
|
||||
$public_key = $this->getValue($this->config['public_key_key'] . $client_id);
|
||||
@ -407,6 +571,10 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $client_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPrivateKey($client_id = '')
|
||||
{
|
||||
$public_key = $this->getValue($this->config['public_key_key'] . $client_id);
|
||||
@ -419,6 +587,10 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $client_id
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function getEncryptionAlgorithm($client_id = null)
|
||||
{
|
||||
$public_key = $this->getValue($this->config['public_key_key'] . $client_id);
|
||||
@ -433,7 +605,11 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return 'RS256';
|
||||
}
|
||||
|
||||
/* UserClaimsInterface */
|
||||
/**
|
||||
* @param mixed $user_id
|
||||
* @param string $claims
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getUserClaims($user_id, $claims)
|
||||
{
|
||||
$userDetails = $this->getUserDetails($user_id);
|
||||
@ -460,6 +636,11 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $claim
|
||||
* @param $userDetails
|
||||
* @return array
|
||||
*/
|
||||
protected function getUserClaim($claim, $userDetails)
|
||||
{
|
||||
$userClaims = array();
|
||||
@ -476,5 +657,4 @@ class Cassandra implements AuthorizationCodeInterface,
|
||||
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
2
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/CouchbaseDB.php
vendored
Executable file → Normal file
2
vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/CouchbaseDB.php
vendored
Executable file → Normal file
@ -328,4 +328,4 @@ class CouchbaseDB implements AuthorizationCodeInterface,
|
||||
//TODO: Needs couchbase implementation.
|
||||
throw new \Exception('setJti() for the Couchbase driver is currently unimplemented.');
|
||||
}
|
||||
}
|
||||
}
|
@ -537,4 +537,4 @@ class DynamoDB implements
|
||||
{
|
||||
return null !== $value && '' !== $value;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ use OAuth2\Encryption\EncryptionInterface;
|
||||
use OAuth2\Encryption\Jwt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Brent Shaffer <bshafs at gmail dot com>
|
||||
*/
|
||||
class JwtAccessToken implements JwtAccessTokenInterface
|
||||
@ -85,4 +84,4 @@ class JwtAccessToken implements JwtAccessTokenInterface
|
||||
|
||||
return $tokenData;
|
||||
}
|
||||
}
|
||||
}
|
@ -378,4 +378,4 @@ class Memory implements AuthorizationCodeInterface,
|
||||
|
||||
return 'RS256';
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ namespace OAuth2\Storage;
|
||||
|
||||
use OAuth2\OpenID\Storage\UserClaimsInterface;
|
||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Simple PDO storage for all storage types
|
||||
@ -29,9 +30,22 @@ class Pdo implements
|
||||
UserClaimsInterface,
|
||||
OpenIDAuthorizationCodeInterface
|
||||
{
|
||||
/**
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @param mixed $connection
|
||||
* @param array $config
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct($connection, $config = array())
|
||||
{
|
||||
if (!$connection instanceof \PDO) {
|
||||
@ -70,7 +84,11 @@ class Pdo implements
|
||||
), $config);
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\ClientCredentialsInterface */
|
||||
/**
|
||||
* @param string $client_id
|
||||
* @param null|string $client_secret
|
||||
* @return bool
|
||||
*/
|
||||
public function checkClientCredentials($client_id, $client_secret = null)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
|
||||
@ -81,6 +99,10 @@ class Pdo implements
|
||||
return $result && $result['client_secret'] == $client_secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $client_id
|
||||
* @return bool
|
||||
*/
|
||||
public function isPublicClient($client_id)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
|
||||
@ -93,7 +115,10 @@ class Pdo implements
|
||||
return empty($result['client_secret']);
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\ClientInterface */
|
||||
/**
|
||||
* @param string $client_id
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getClientDetails($client_id)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
|
||||
@ -102,6 +127,15 @@ class Pdo implements
|
||||
return $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $client_id
|
||||
* @param null|string $client_secret
|
||||
* @param null|string $redirect_uri
|
||||
* @param null|array $grant_types
|
||||
* @param null|string $scope
|
||||
* @param null|string $user_id
|
||||
* @return bool
|
||||
*/
|
||||
public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
|
||||
{
|
||||
// if it exists, update it.
|
||||
@ -114,6 +148,11 @@ class Pdo implements
|
||||
return $stmt->execute(compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $client_id
|
||||
* @param $grant_type
|
||||
* @return bool
|
||||
*/
|
||||
public function checkRestrictedGrantType($client_id, $grant_type)
|
||||
{
|
||||
$details = $this->getClientDetails($client_id);
|
||||
@ -127,7 +166,10 @@ class Pdo implements
|
||||
return true;
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\AccessTokenInterface */
|
||||
/**
|
||||
* @param string $access_token
|
||||
* @return array|bool|mixed|null
|
||||
*/
|
||||
public function getAccessToken($access_token)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where access_token = :access_token', $this->config['access_token_table']));
|
||||
@ -141,6 +183,14 @@ class Pdo implements
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $access_token
|
||||
* @param mixed $client_id
|
||||
* @param mixed $user_id
|
||||
* @param int $expires
|
||||
* @param string $scope
|
||||
* @return bool
|
||||
*/
|
||||
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// convert expires to datestring
|
||||
@ -156,6 +206,10 @@ class Pdo implements
|
||||
return $stmt->execute(compact('access_token', 'client_id', 'user_id', 'expires', 'scope'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $access_token
|
||||
* @return bool
|
||||
*/
|
||||
public function unsetAccessToken($access_token)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE access_token = :access_token', $this->config['access_token_table']));
|
||||
@ -166,6 +220,10 @@ class Pdo implements
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\AuthorizationCodeInterface */
|
||||
/**
|
||||
* @param string $code
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAuthorizationCode($code)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * from %s where authorization_code = :code', $this->config['code_table']));
|
||||
@ -179,6 +237,16 @@ class Pdo implements
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
* @param mixed $client_id
|
||||
* @param mixed $user_id
|
||||
* @param string $redirect_uri
|
||||
* @param int $expires
|
||||
* @param string $scope
|
||||
* @param string $id_token
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
if (func_num_args() > 6) {
|
||||
@ -199,6 +267,16 @@ class Pdo implements
|
||||
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
* @param mixed $client_id
|
||||
* @param mixed $user_id
|
||||
* @param string $redirect_uri
|
||||
* @param string $expires
|
||||
* @param string $scope
|
||||
* @param string $id_token
|
||||
* @return bool
|
||||
*/
|
||||
private function setAuthorizationCodeWithIdToken($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
||||
{
|
||||
// convert expires to datestring
|
||||
@ -214,6 +292,10 @@ class Pdo implements
|
||||
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
* @return bool
|
||||
*/
|
||||
public function expireAuthorizationCode($code)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE authorization_code = :code', $this->config['code_table']));
|
||||
@ -221,7 +303,11 @@ class Pdo implements
|
||||
return $stmt->execute(compact('code'));
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\UserCredentialsInterface */
|
||||
/**
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
@ -231,12 +317,20 @@ class Pdo implements
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
return $this->getUser($username);
|
||||
}
|
||||
|
||||
/* UserClaimsInterface */
|
||||
/**
|
||||
* @param mixed $user_id
|
||||
* @param string $claims
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getUserClaims($user_id, $claims)
|
||||
{
|
||||
if (!$userDetails = $this->getUserDetails($user_id)) {
|
||||
@ -262,6 +356,11 @@ class Pdo implements
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $claim
|
||||
* @param array $userDetails
|
||||
* @return array
|
||||
*/
|
||||
protected function getUserClaim($claim, $userDetails)
|
||||
{
|
||||
$userClaims = array();
|
||||
@ -275,7 +374,10 @@ class Pdo implements
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
/* OAuth2\Storage\RefreshTokenInterface */
|
||||
/**
|
||||
* @param string $refresh_token
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function getRefreshToken($refresh_token)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT * FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
|
||||
@ -289,6 +391,14 @@ class Pdo implements
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $refresh_token
|
||||
* @param mixed $client_id
|
||||
* @param mixed $user_id
|
||||
* @param string $expires
|
||||
* @param string $scope
|
||||
* @return bool
|
||||
*/
|
||||
public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// convert expires to datestring
|
||||
@ -299,6 +409,10 @@ class Pdo implements
|
||||
return $stmt->execute(compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $refresh_token
|
||||
* @return bool
|
||||
*/
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
|
||||
@ -308,7 +422,13 @@ class Pdo implements
|
||||
return $stmt->rowCount() > 0;
|
||||
}
|
||||
|
||||
// plaintext passwords are bad! Override this for your application
|
||||
/**
|
||||
* plaintext passwords are bad! Override this for your application
|
||||
*
|
||||
* @param array $user
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkPassword($user, $password)
|
||||
{
|
||||
return $user['password'] == $this->hashPassword($password);
|
||||
@ -320,6 +440,10 @@ class Pdo implements
|
||||
return sha1($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getUser($username)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT * from %s where username=:username', $this->config['user_table']));
|
||||
@ -335,6 +459,15 @@ class Pdo implements
|
||||
), $userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* plaintext passwords are bad! Override this for your application
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $firstName
|
||||
* @param string $lastName
|
||||
* @return bool
|
||||
*/
|
||||
public function setUser($username, $password, $firstName = null, $lastName = null)
|
||||
{
|
||||
// do not store in plaintext
|
||||
@ -350,7 +483,10 @@ class Pdo implements
|
||||
return $stmt->execute(compact('username', 'password', 'firstName', 'lastName'));
|
||||
}
|
||||
|
||||
/* ScopeInterface */
|
||||
/**
|
||||
* @param string $scope
|
||||
* @return bool
|
||||
*/
|
||||
public function scopeExists($scope)
|
||||
{
|
||||
$scope = explode(' ', $scope);
|
||||
@ -365,6 +501,10 @@ class Pdo implements
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @return null|string
|
||||
*/
|
||||
public function getDefaultScope($client_id = null)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('SELECT scope FROM %s WHERE is_default=:is_default', $this->config['scope_table']));
|
||||
@ -381,7 +521,11 @@ class Pdo implements
|
||||
return null;
|
||||
}
|
||||
|
||||
/* JWTBearerInterface */
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @param $subject
|
||||
* @return string
|
||||
*/
|
||||
public function getClientKey($client_id, $subject)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT public_key from %s where client_id=:client_id AND subject=:subject', $this->config['jwt_table']));
|
||||
@ -391,6 +535,10 @@ class Pdo implements
|
||||
return $stmt->fetchColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @return bool|null
|
||||
*/
|
||||
public function getClientScope($client_id)
|
||||
{
|
||||
if (!$clientDetails = $this->getClientDetails($client_id)) {
|
||||
@ -404,6 +552,14 @@ class Pdo implements
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @param $subject
|
||||
* @param $audience
|
||||
* @param $expires
|
||||
* @param $jti
|
||||
* @return array|null
|
||||
*/
|
||||
public function getJti($client_id, $subject, $audience, $expires, $jti)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT * FROM %s WHERE issuer=:client_id AND subject=:subject AND audience=:audience AND expires=:expires AND jti=:jti', $this->config['jti_table']));
|
||||
@ -423,6 +579,14 @@ class Pdo implements
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @param $subject
|
||||
* @param $audience
|
||||
* @param $expires
|
||||
* @param $jti
|
||||
* @return bool
|
||||
*/
|
||||
public function setJti($client_id, $subject, $audience, $expires, $jti)
|
||||
{
|
||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (issuer, subject, audience, expires, jti) VALUES (:client_id, :subject, :audience, :expires, :jti)', $this->config['jti_table']));
|
||||
@ -430,7 +594,10 @@ class Pdo implements
|
||||
return $stmt->execute(compact('client_id', 'subject', 'audience', 'expires', 'jti'));
|
||||
}
|
||||
|
||||
/* PublicKeyInterface */
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPublicKey($client_id = null)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT public_key FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
|
||||
@ -441,6 +608,10 @@ class Pdo implements
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPrivateKey($client_id = null)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT private_key FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
|
||||
@ -451,6 +622,10 @@ class Pdo implements
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @return string
|
||||
*/
|
||||
public function getEncryptionAlgorithm($client_id = null)
|
||||
{
|
||||
$stmt = $this->db->prepare($sql = sprintf('SELECT encryption_algorithm FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
|
||||
@ -467,6 +642,9 @@ class Pdo implements
|
||||
* DDL to create OAuth2 database and tables for PDO storage
|
||||
*
|
||||
* @see https://github.com/dsquier/oauth2-server-php-mysql
|
||||
*
|
||||
* @param string $dbName
|
||||
* @return string
|
||||
*/
|
||||
public function getBuildSql($dbName = 'oauth2_server_php')
|
||||
{
|
||||
@ -481,73 +659,73 @@ class Pdo implements
|
||||
PRIMARY KEY (client_id)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['access_token_table']} (
|
||||
access_token VARCHAR(40) NOT NULL,
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
user_id VARCHAR(80),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
scope VARCHAR(4000),
|
||||
PRIMARY KEY (access_token)
|
||||
);
|
||||
CREATE TABLE {$this->config['access_token_table']} (
|
||||
access_token VARCHAR(40) NOT NULL,
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
user_id VARCHAR(80),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
scope VARCHAR(4000),
|
||||
PRIMARY KEY (access_token)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['code_table']} (
|
||||
authorization_code VARCHAR(40) NOT NULL,
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
user_id VARCHAR(80),
|
||||
redirect_uri VARCHAR(2000),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
scope VARCHAR(4000),
|
||||
id_token VARCHAR(1000),
|
||||
PRIMARY KEY (authorization_code)
|
||||
);
|
||||
CREATE TABLE {$this->config['code_table']} (
|
||||
authorization_code VARCHAR(40) NOT NULL,
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
user_id VARCHAR(80),
|
||||
redirect_uri VARCHAR(2000),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
scope VARCHAR(4000),
|
||||
id_token VARCHAR(1000),
|
||||
PRIMARY KEY (authorization_code)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['refresh_token_table']} (
|
||||
refresh_token VARCHAR(40) NOT NULL,
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
user_id VARCHAR(80),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
scope VARCHAR(4000),
|
||||
PRIMARY KEY (refresh_token)
|
||||
);
|
||||
CREATE TABLE {$this->config['refresh_token_table']} (
|
||||
refresh_token VARCHAR(40) NOT NULL,
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
user_id VARCHAR(80),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
scope VARCHAR(4000),
|
||||
PRIMARY KEY (refresh_token)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['user_table']} (
|
||||
username VARCHAR(80),
|
||||
password VARCHAR(80),
|
||||
first_name VARCHAR(80),
|
||||
last_name VARCHAR(80),
|
||||
email VARCHAR(80),
|
||||
email_verified BOOLEAN,
|
||||
scope VARCHAR(4000)
|
||||
);
|
||||
CREATE TABLE {$this->config['user_table']} (
|
||||
username VARCHAR(80),
|
||||
password VARCHAR(80),
|
||||
first_name VARCHAR(80),
|
||||
last_name VARCHAR(80),
|
||||
email VARCHAR(80),
|
||||
email_verified BOOLEAN,
|
||||
scope VARCHAR(4000)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['scope_table']} (
|
||||
scope VARCHAR(80) NOT NULL,
|
||||
is_default BOOLEAN,
|
||||
PRIMARY KEY (scope)
|
||||
);
|
||||
CREATE TABLE {$this->config['scope_table']} (
|
||||
scope VARCHAR(80) NOT NULL,
|
||||
is_default BOOLEAN,
|
||||
PRIMARY KEY (scope)
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['jwt_table']} (
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
subject VARCHAR(80),
|
||||
public_key VARCHAR(2000) NOT NULL
|
||||
);
|
||||
CREATE TABLE {$this->config['jwt_table']} (
|
||||
client_id VARCHAR(80) NOT NULL,
|
||||
subject VARCHAR(80),
|
||||
public_key VARCHAR(2000) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['jti_table']} (
|
||||
issuer VARCHAR(80) NOT NULL,
|
||||
subject VARCHAR(80),
|
||||
audience VARCHAR(80),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
jti VARCHAR(2000) NOT NULL
|
||||
);
|
||||
CREATE TABLE {$this->config['jti_table']} (
|
||||
issuer VARCHAR(80) NOT NULL,
|
||||
subject VARCHAR(80),
|
||||
audiance VARCHAR(80),
|
||||
expires TIMESTAMP NOT NULL,
|
||||
jti VARCHAR(2000) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE {$this->config['public_key_table']} (
|
||||
client_id VARCHAR(80),
|
||||
public_key VARCHAR(2000),
|
||||
private_key VARCHAR(2000),
|
||||
encryption_algorithm VARCHAR(100) DEFAULT 'RS256'
|
||||
)
|
||||
";
|
||||
CREATE TABLE {$this->config['public_key_table']} (
|
||||
client_id VARCHAR(80),
|
||||
public_key VARCHAR(2000),
|
||||
private_key VARCHAR(2000),
|
||||
encryption_algorithm VARCHAR(100) DEFAULT 'RS256'
|
||||
)
|
||||
";
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,21 @@ namespace OAuth2\Storage;
|
||||
*/
|
||||
interface PublicKeyInterface
|
||||
{
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPublicKey($client_id = null);
|
||||
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPrivateKey($client_id = null);
|
||||
|
||||
/**
|
||||
* @param mixed $client_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getEncryptionAlgorithm($client_id = null);
|
||||
}
|
||||
}
|
@ -37,15 +37,15 @@ interface UserCredentialsInterface
|
||||
public function checkUserCredentials($username, $password);
|
||||
|
||||
/**
|
||||
* @return
|
||||
* ARRAY the associated "user_id" and optional "scope" values
|
||||
* This function MUST return FALSE if the requested user does not exist or is
|
||||
* invalid. "scope" is a space-separated list of restricted scopes.
|
||||
* @param string $username - username to get details for
|
||||
* @return array|false - the associated "user_id" and optional "scope" values
|
||||
* This function MUST return FALSE if the requested user does not exist or is
|
||||
* invalid. "scope" is a space-separated list of restricted scopes.
|
||||
* @code
|
||||
* return array(
|
||||
* "user_id" => USER_ID, // REQUIRED user_id to be stored with the authorization code or access token
|
||||
* "scope" => SCOPE // OPTIONAL space-separated list of restricted scopes
|
||||
* );
|
||||
* return array(
|
||||
* "user_id" => USER_ID, // REQUIRED user_id to be stored with the authorization code or access token
|
||||
* "scope" => SCOPE // OPTIONAL space-separated list of restricted scopes
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
public function getUserDetails($username);
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
namespace OAuth2;
|
||||
|
||||
class AutoloadTest extends \PHPUnit_Framework_TestCase
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AutoloadTest extends TestCase
|
||||
{
|
||||
public function testClassesExist()
|
||||
{
|
||||
|
@ -10,8 +10,9 @@ use OAuth2\GrantType\AuthorizationCode;
|
||||
use OAuth2\Request;
|
||||
use OAuth2\Response;
|
||||
use OAuth2\Request\TestRequest;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AuthorizeControllerTest extends \PHPUnit_Framework_TestCase
|
||||
class AuthorizeControllerTest extends TestCase
|
||||
{
|
||||
public function testNoClientIdResponse()
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user