Initial import from local backup (Documents-Playground/pakerpale)
This commit is contained in:
231
application/libraries/Bcrypt.php
Normal file
231
application/libraries/Bcrypt.php
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/**
|
||||
* Name: Bcrypt
|
||||
*
|
||||
* Requirements: PHP5 or above
|
||||
*
|
||||
* @package CodeIgniter-Ion-Auth
|
||||
* @author Ben Edmunds
|
||||
* @link http://github.com/benedmunds/CodeIgniter-Ion-Auth
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Class Bcrypt
|
||||
*/
|
||||
class Bcrypt
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $rounds;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $salt_prefix;
|
||||
|
||||
/**
|
||||
* @var int|string|null
|
||||
*/
|
||||
private $randomState;
|
||||
|
||||
/**
|
||||
* Bcrypt constructor.
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($params = array('rounds' => 7, 'salt_prefix' => '$2y$'))
|
||||
{
|
||||
|
||||
if (CRYPT_BLOWFISH != 1)
|
||||
{
|
||||
throw new Exception("bcrypt not supported in this installation. See http://php.net/crypt");
|
||||
}
|
||||
|
||||
$this->rounds = $params['rounds'];
|
||||
$this->salt_prefix = $params['salt_prefix'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function hash($input)
|
||||
{
|
||||
$hash = crypt($input, $this->getSalt());
|
||||
|
||||
if (strlen($hash) > 13)
|
||||
{
|
||||
return $hash;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
* @param string $existingHash
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function verify($input, $existingHash)
|
||||
{
|
||||
$hash = crypt($input, $existingHash);
|
||||
return $this->hashEquals($existingHash, $hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Polyfill for hash_equals()
|
||||
* Code mainly taken from hash_equals() compat function of CodeIgniter 3
|
||||
*
|
||||
* @param string $known_string
|
||||
* @param string $user_string
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hashEquals($known_string, $user_string)
|
||||
{
|
||||
// For CI3 or PHP >= 5.6
|
||||
if (function_exists('hash_equals'))
|
||||
{
|
||||
return hash_equals($known_string, $user_string);
|
||||
}
|
||||
|
||||
// For CI2 with PHP < 5.6
|
||||
// Code from CI3 https://github.com/bcit-ci/CodeIgniter/blob/develop/system/core/compat/hash.php
|
||||
if (!is_string($known_string))
|
||||
{
|
||||
trigger_error('hash_equals(): Expected known_string to be a string, ' . strtolower(gettype($known_string)) . ' given', E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
else if (!is_string($user_string))
|
||||
{
|
||||
trigger_error('hash_equals(): Expected user_string to be a string, ' . strtolower(gettype($user_string)) . ' given', E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
else if (($length = strlen($known_string)) !== strlen($user_string))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$diff = 0;
|
||||
for ($i = 0; $i < $length; $i++)
|
||||
{
|
||||
$diff |= ord($known_string[$i]) ^ ord($user_string[$i]);
|
||||
}
|
||||
|
||||
return ($diff === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getSalt()
|
||||
{
|
||||
$salt = sprintf($this->salt_prefix . '%02d$', $this->rounds);
|
||||
|
||||
$bytes = $this->getRandomBytes(16);
|
||||
|
||||
$salt .= $this->encodeBytes($bytes);
|
||||
|
||||
return $salt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $count
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getRandomBytes($count)
|
||||
{
|
||||
$bytes = '';
|
||||
|
||||
if (function_exists('openssl_random_pseudo_bytes') &&
|
||||
(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN'))
|
||||
{
|
||||
// OpenSSL slow on Win
|
||||
$bytes = openssl_random_pseudo_bytes($count);
|
||||
}
|
||||
|
||||
if ($bytes === '' && @is_readable('/dev/urandom') &&
|
||||
($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE)
|
||||
{
|
||||
$bytes = fread($hRand, $count);
|
||||
fclose($hRand);
|
||||
}
|
||||
|
||||
if (strlen($bytes) < $count)
|
||||
{
|
||||
$bytes = '';
|
||||
|
||||
if ($this->randomState === NULL)
|
||||
{
|
||||
$this->randomState = microtime();
|
||||
if (function_exists('getmypid'))
|
||||
{
|
||||
$this->randomState .= getmypid();
|
||||
}
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i += 16)
|
||||
{
|
||||
$this->randomState = md5(microtime() . $this->randomState);
|
||||
|
||||
if (PHP_VERSION >= '5')
|
||||
{
|
||||
$bytes .= md5($this->randomState, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
$bytes .= pack('H*', md5($this->randomState));
|
||||
}
|
||||
}
|
||||
|
||||
$bytes = substr($bytes, 0, $count);
|
||||
}
|
||||
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function encodeBytes($input)
|
||||
{
|
||||
// The following is code from the PHP Password Hashing Framework
|
||||
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
$output = '';
|
||||
$i = 0;
|
||||
do
|
||||
{
|
||||
$c1 = ord($input[$i++]);
|
||||
$output .= $itoa64[$c1 >> 2];
|
||||
$c1 = ($c1 & 0x03) << 4;
|
||||
if ($i >= 16)
|
||||
{
|
||||
$output .= $itoa64[$c1];
|
||||
break;
|
||||
}
|
||||
|
||||
$c2 = ord($input[$i++]);
|
||||
$c1 |= $c2 >> 4;
|
||||
$output .= $itoa64[$c1];
|
||||
$c1 = ($c2 & 0x0f) << 2;
|
||||
|
||||
$c2 = ord($input[$i++]);
|
||||
$c1 |= $c2 >> 6;
|
||||
$output .= $itoa64[$c1];
|
||||
$output .= $itoa64[$c2 & 0x3f];
|
||||
} while (1);
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
267
application/libraries/Format.php
Normal file
267
application/libraries/Format.php
Normal file
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
/**
|
||||
* Format class
|
||||
*
|
||||
* Help convert between various formats such as XML, JSON, CSV, etc.
|
||||
*
|
||||
* @author Phil Sturgeon
|
||||
* @license http://philsturgeon.co.uk/code/dbad-license
|
||||
*/
|
||||
class Format {
|
||||
|
||||
// Array to convert
|
||||
protected $_data = array();
|
||||
|
||||
// View filename
|
||||
protected $_from_type = null;
|
||||
|
||||
/**
|
||||
* Returns an instance of the Format object.
|
||||
*
|
||||
* echo $this->format->factory(array('foo' => 'bar'))->to_xml();
|
||||
*
|
||||
* @param mixed general date to be converted
|
||||
* @param string data format the file was provided in
|
||||
* @return Factory
|
||||
*/
|
||||
public function factory($data, $from_type = null)
|
||||
{
|
||||
// Stupid stuff to emulate the "new static()" stuff in this libraries PHP 5.3 equivilent
|
||||
$class = __CLASS__;
|
||||
return new $class($data, $from_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use this directly, call factory()
|
||||
*/
|
||||
public function __construct($data = null, $from_type = null)
|
||||
{
|
||||
get_instance()->load->helper('inflector');
|
||||
|
||||
// If the provided data is already formatted we should probably convert it to an array
|
||||
if ($from_type !== null)
|
||||
{
|
||||
if (method_exists($this, '_from_' . $from_type))
|
||||
{
|
||||
$data = call_user_func(array($this, '_from_' . $from_type), $data);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
throw new Exception('Format class does not support conversion from "' . $from_type . '".');
|
||||
}
|
||||
}
|
||||
|
||||
$this->_data = $data;
|
||||
}
|
||||
|
||||
public function to_data() {
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
// FORMATING OUTPUT ---------------------------------------------------------
|
||||
|
||||
public function to_array($data = null)
|
||||
{
|
||||
// If not just null, but nopthing is provided
|
||||
if ($data === null and ! func_num_args())
|
||||
{
|
||||
$data = $this->_data;
|
||||
}
|
||||
|
||||
$array = array();
|
||||
|
||||
foreach ((array) $data as $key => $value)
|
||||
{
|
||||
if (is_object($value) or is_array($value))
|
||||
{
|
||||
$array[$key] = $this->to_array($value);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$array[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
// Format XML for output
|
||||
public function to_xml($data = null, $structure = null, $basenode = 'xml')
|
||||
{
|
||||
if ($data === null and ! func_num_args())
|
||||
{
|
||||
$data = $this->_data;
|
||||
}
|
||||
|
||||
// turn off compatibility mode as simple xml throws a wobbly if you don't.
|
||||
if (ini_get('zend.ze1_compatibility_mode') == 1)
|
||||
{
|
||||
ini_set('zend.ze1_compatibility_mode', 0);
|
||||
}
|
||||
|
||||
if ($structure === null)
|
||||
{
|
||||
$structure = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$basenode />");
|
||||
}
|
||||
|
||||
// Force it to be something useful
|
||||
if ( ! is_array($data) AND ! is_object($data))
|
||||
{
|
||||
$data = (array) $data;
|
||||
}
|
||||
|
||||
foreach ($data as $key => $value)
|
||||
{
|
||||
// no numeric keys in our xml please!
|
||||
if (is_numeric($key))
|
||||
{
|
||||
// make string key...
|
||||
$key = (singular($basenode) != $basenode) ? singular($basenode) : 'item';
|
||||
}
|
||||
|
||||
// replace anything not alpha numeric
|
||||
$key = preg_replace('/[^a-z_\-0-9]/i', '', $key);
|
||||
|
||||
// if there is another array found recrusively call this function
|
||||
if (is_array($value) || is_object($value))
|
||||
{
|
||||
$node = $structure->addChild($key);
|
||||
|
||||
// recrusive call.
|
||||
$this->to_xml($value, $node, $key);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// add single node.
|
||||
$value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, "UTF-8");
|
||||
|
||||
$structure->addChild($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $structure->asXML();
|
||||
}
|
||||
|
||||
// Format HTML for output
|
||||
public function to_html()
|
||||
{
|
||||
$data = $this->_data;
|
||||
|
||||
// Multi-dimentional array
|
||||
if (isset($data[0]))
|
||||
{
|
||||
$headings = array_keys($data[0]);
|
||||
}
|
||||
|
||||
// Single array
|
||||
else
|
||||
{
|
||||
$headings = array_keys($data);
|
||||
$data = array($data);
|
||||
}
|
||||
|
||||
$ci = get_instance();
|
||||
$ci->load->library('table');
|
||||
|
||||
$ci->table->set_heading($headings);
|
||||
|
||||
foreach ($data as &$row)
|
||||
{
|
||||
$ci->table->add_row($row);
|
||||
}
|
||||
|
||||
return $ci->table->generate();
|
||||
}
|
||||
|
||||
// Format HTML for output
|
||||
public function to_csv()
|
||||
{
|
||||
$data = $this->_data;
|
||||
|
||||
// Multi-dimentional array
|
||||
if (isset($data[0]))
|
||||
{
|
||||
$headings = array_keys($data[0]);
|
||||
}
|
||||
|
||||
// Single array
|
||||
else
|
||||
{
|
||||
$headings = array_keys($data);
|
||||
$data = array($data);
|
||||
}
|
||||
|
||||
$output = implode(',', $headings).PHP_EOL;
|
||||
foreach ($data as &$row)
|
||||
{
|
||||
$output .= '"'.implode('","', $row).'"'.PHP_EOL;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Encode as JSON
|
||||
public function to_json()
|
||||
{
|
||||
return json_encode($this->_data, JSON_NUMERIC_CHECK);
|
||||
}
|
||||
|
||||
// Encode as Serialized array
|
||||
public function to_serialized()
|
||||
{
|
||||
return serialize($this->_data);
|
||||
}
|
||||
|
||||
// Output as a string representing the PHP structure
|
||||
public function to_php()
|
||||
{
|
||||
return var_export($this->_data, TRUE);
|
||||
}
|
||||
|
||||
// Format XML for output
|
||||
protected function _from_xml($string)
|
||||
{
|
||||
return $string ? (array) simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA) : array();
|
||||
}
|
||||
|
||||
// Format HTML for output
|
||||
// This function is DODGY! Not perfect CSV support but works with my REST_Controller
|
||||
protected function _from_csv($string)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
// Splits
|
||||
$rows = explode("\n", trim($string));
|
||||
$headings = explode(',', array_shift($rows));
|
||||
foreach ($rows as $row)
|
||||
{
|
||||
// The substr removes " from start and end
|
||||
$data_fields = explode('","', trim(substr($row, 1, -1)));
|
||||
|
||||
if (count($data_fields) == count($headings))
|
||||
{
|
||||
$data[] = array_combine($headings, $data_fields);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
// Encode as JSON
|
||||
private function _from_json($string)
|
||||
{
|
||||
return json_decode(trim($string));
|
||||
}
|
||||
|
||||
// Encode as Serialized array
|
||||
private function _from_serialize($string)
|
||||
{
|
||||
return unserialize(trim($string));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* End of file format.php */
|
||||
549
application/libraries/Ion_auth.php
Normal file
549
application/libraries/Ion_auth.php
Normal file
@@ -0,0 +1,549 @@
|
||||
<?php
|
||||
/**
|
||||
* Name: Ion Auth
|
||||
* Author: Ben Edmunds
|
||||
* ben.edmunds@gmail.com
|
||||
* @benedmunds
|
||||
*
|
||||
* Added Awesomeness: Phil Sturgeon
|
||||
*
|
||||
* Created: 10.01.2009
|
||||
*
|
||||
* Description: Modified auth system based on redux_auth with extensive customization. This is basically what Redux Auth 2 should be.
|
||||
* Original Author name has been kept but that does not mean that the method has not been modified.
|
||||
*
|
||||
* Requirements: PHP5 or above
|
||||
*
|
||||
* @package CodeIgniter-Ion-Auth
|
||||
* @author Ben Edmunds
|
||||
* @link http://github.com/benedmunds/CodeIgniter-Ion-Auth
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Class Ion_auth
|
||||
*/
|
||||
class Ion_auth
|
||||
{
|
||||
/**
|
||||
* account status ('not_activated', etc ...)
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $status;
|
||||
|
||||
/**
|
||||
* extra where
|
||||
*
|
||||
* @var array
|
||||
**/
|
||||
public $_extra_where = array();
|
||||
|
||||
/**
|
||||
* extra set
|
||||
*
|
||||
* @var array
|
||||
**/
|
||||
public $_extra_set = array();
|
||||
|
||||
/**
|
||||
* caching of users and their groups
|
||||
*
|
||||
* @var array
|
||||
**/
|
||||
public $_cache_user_in_group;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @author Ben
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->config->load('ion_auth', TRUE);
|
||||
$this->load->library(array('email'));
|
||||
$this->lang->load('ion_auth');
|
||||
$this->load->helper(array('cookie', 'language','url'));
|
||||
|
||||
$this->load->library('session');
|
||||
|
||||
$this->load->model('ion_auth_model');
|
||||
|
||||
$this->_cache_user_in_group =& $this->ion_auth_model->_cache_user_in_group;
|
||||
|
||||
$email_config = $this->config->item('email_config', 'ion_auth');
|
||||
|
||||
if ($this->config->item('use_ci_email', 'ion_auth') && isset($email_config) && is_array($email_config))
|
||||
{
|
||||
$this->email->initialize($email_config);
|
||||
}
|
||||
|
||||
$this->ion_auth_model->trigger_events('library_constructor');
|
||||
}
|
||||
|
||||
/**
|
||||
* __call
|
||||
*
|
||||
* Acts as a simple way to call model methods without loads of stupid alias'
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
if (!method_exists( $this->ion_auth_model, $method) )
|
||||
{
|
||||
throw new Exception('Undefined method Ion_auth::' . $method . '() called');
|
||||
}
|
||||
if($method == 'create_user')
|
||||
{
|
||||
return call_user_func_array(array($this, 'register'), $arguments);
|
||||
}
|
||||
if($method=='update_user')
|
||||
{
|
||||
return call_user_func_array(array($this, 'update'), $arguments);
|
||||
}
|
||||
return call_user_func_array( array($this->ion_auth_model, $method), $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* __get
|
||||
*
|
||||
* Enables the use of CI super-global without having to define an extra variable.
|
||||
*
|
||||
* I can't remember where I first saw this, so thank you if you are the original author. -Militis
|
||||
*
|
||||
* @param string $var
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($var)
|
||||
{
|
||||
$CI = & get_instance();
|
||||
return isset($CI->$var) ? $CI->$var : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forgotten password feature
|
||||
*
|
||||
* @param string $identity
|
||||
*
|
||||
* @return array|bool
|
||||
* @author Mathew
|
||||
*/
|
||||
public function forgotten_password($identity)
|
||||
{
|
||||
if ($this->ion_auth_model->forgotten_password($identity))
|
||||
{
|
||||
// Get user information
|
||||
$identifier = $this->ion_auth_model->identity_column; // use model identity column, so it can be overridden in a controller
|
||||
$user = $this->where($identifier, $identity)->where('active', 1)->users()->row();
|
||||
|
||||
if ($user)
|
||||
{
|
||||
$data = array(
|
||||
'identity' => $user->{$this->config->item('identity', 'ion_auth')},
|
||||
'forgotten_password_code' => $user->forgotten_password_code
|
||||
);
|
||||
|
||||
if (!$this->config->item('use_ci_email', 'ion_auth'))
|
||||
{
|
||||
$this->set_message('forgot_password_successful');
|
||||
return $data;
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = $this->load->view($this->config->item('email_templates', 'ion_auth') . $this->config->item('email_forgot_password', 'ion_auth'), $data, TRUE);
|
||||
$this->email->clear();
|
||||
$this->email->from($this->config->item('admin_email', 'ion_auth'), $this->config->item('site_title', 'ion_auth'));
|
||||
$this->email->to($user->email);
|
||||
$this->email->subject($this->config->item('site_title', 'ion_auth') . ' - ' . $this->lang->line('email_forgotten_password_subject'));
|
||||
$this->email->message($message);
|
||||
|
||||
if ($this->email->send())
|
||||
{
|
||||
$this->set_message('forgot_password_successful');
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set_error('forgot_password_unsuccessful');
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set_error('forgot_password_unsuccessful');
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set_error('forgot_password_unsuccessful');
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* forgotten_password_complete
|
||||
*
|
||||
* @param string $code
|
||||
*
|
||||
* @return array|bool
|
||||
* @author Mathew
|
||||
*/
|
||||
public function forgotten_password_complete($code)
|
||||
{
|
||||
$this->ion_auth_model->trigger_events('pre_password_change');
|
||||
|
||||
$identity = $this->config->item('identity', 'ion_auth');
|
||||
$profile = $this->where('forgotten_password_code', $code)->users()->row(); // pass the code to profile
|
||||
|
||||
if (!$profile)
|
||||
{
|
||||
$this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_unsuccessful'));
|
||||
$this->set_error('password_change_unsuccessful');
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$new_password = $this->ion_auth_model->forgotten_password_complete($code, $profile->salt);
|
||||
|
||||
if ($new_password)
|
||||
{
|
||||
$data = array(
|
||||
'identity' => $profile->{$identity},
|
||||
'new_password' => $new_password
|
||||
);
|
||||
if(!$this->config->item('use_ci_email', 'ion_auth'))
|
||||
{
|
||||
$this->set_message('password_change_successful');
|
||||
$this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_successful'));
|
||||
return $data;
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = $this->load->view($this->config->item('email_templates', 'ion_auth').$this->config->item('email_forgot_password_complete', 'ion_auth'), $data, true);
|
||||
|
||||
$this->email->clear();
|
||||
$this->email->from($this->config->item('admin_email', 'ion_auth'), $this->config->item('site_title', 'ion_auth'));
|
||||
$this->email->to($profile->email);
|
||||
$this->email->subject($this->config->item('site_title', 'ion_auth') . ' - ' . $this->lang->line('email_new_password_subject'));
|
||||
$this->email->message($message);
|
||||
|
||||
if ($this->email->send())
|
||||
{
|
||||
$this->set_message('password_change_successful');
|
||||
$this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_successful'));
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set_error('password_change_unsuccessful');
|
||||
$this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_unsuccessful'));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_unsuccessful'));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* forgotten_password_check
|
||||
*
|
||||
* @param string $code
|
||||
*
|
||||
* @return object|bool
|
||||
* @author Michael
|
||||
*/
|
||||
public function forgotten_password_check($code)
|
||||
{
|
||||
$profile = $this->where('forgotten_password_code', $code)->users()->row(); // pass the code to profile
|
||||
|
||||
if (!is_object($profile))
|
||||
{
|
||||
$this->set_error('password_change_unsuccessful');
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->config->item('forgot_password_expiration', 'ion_auth') > 0)
|
||||
{
|
||||
//Make sure it isn't expired
|
||||
$expiration = $this->config->item('forgot_password_expiration', 'ion_auth');
|
||||
if (time() - $profile->forgotten_password_time > $expiration)
|
||||
{
|
||||
//it has expired
|
||||
$this->ion_auth_model->clear_forgotten_password_code($code);
|
||||
$this->set_error('password_change_unsuccessful');
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return $profile;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* register
|
||||
*
|
||||
* @param string $identity
|
||||
* @param string $password
|
||||
* @param string $email
|
||||
* @param array $additional_data
|
||||
* @param array $group_ids
|
||||
*
|
||||
* @return int|array|bool The new user's ID if e-mail activation is disabled or Ion-Auth e-mail activation was
|
||||
* completed; or an array of activation details if CI e-mail validation is enabled; or FALSE
|
||||
* if the operation failed.
|
||||
* @author Mathew
|
||||
*/
|
||||
public function register($identity, $password, $email, $additional_data = array(), $group_ids = array())
|
||||
{
|
||||
$this->ion_auth_model->trigger_events('pre_account_creation');
|
||||
|
||||
$email_activation = $this->config->item('email_activation', 'ion_auth');
|
||||
|
||||
$id = $this->ion_auth_model->register($identity, $password, $email, $additional_data, $group_ids);
|
||||
|
||||
if (!$email_activation)
|
||||
{
|
||||
if ($id !== FALSE)
|
||||
{
|
||||
$this->set_message('account_creation_successful');
|
||||
$this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_successful'));
|
||||
return $id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set_error('account_creation_unsuccessful');
|
||||
$this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_unsuccessful'));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!$id)
|
||||
{
|
||||
$this->set_error('account_creation_unsuccessful');
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// deactivate so the user much follow the activation flow
|
||||
$deactivate = $this->ion_auth_model->deactivate($id);
|
||||
|
||||
// the deactivate method call adds a message, here we need to clear that
|
||||
$this->ion_auth_model->clear_messages();
|
||||
|
||||
|
||||
if (!$deactivate)
|
||||
{
|
||||
$this->set_error('deactivate_unsuccessful');
|
||||
$this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_unsuccessful'));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$activation_code = $this->ion_auth_model->activation_code;
|
||||
$identity = $this->config->item('identity', 'ion_auth');
|
||||
$user = $this->ion_auth_model->user($id)->row();
|
||||
|
||||
$data = array(
|
||||
'identity' => $user->{$identity},
|
||||
'id' => $user->id,
|
||||
'email' => $email,
|
||||
'activation' => $activation_code,
|
||||
);
|
||||
if(!$this->config->item('use_ci_email', 'ion_auth'))
|
||||
{
|
||||
$this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_successful', 'activation_email_successful'));
|
||||
$this->set_message('activation_email_successful');
|
||||
return $data;
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = $this->load->view($this->config->item('email_templates', 'ion_auth').$this->config->item('email_activate', 'ion_auth'), $data, true);
|
||||
|
||||
$this->email->clear();
|
||||
$this->email->from($this->config->item('admin_email', 'ion_auth'), $this->config->item('site_title', 'ion_auth'));
|
||||
$this->email->to($email);
|
||||
$this->email->subject($this->config->item('site_title', 'ion_auth') . ' - ' . $this->lang->line('email_activation_subject'));
|
||||
$this->email->message($message);
|
||||
|
||||
if ($this->email->send() === TRUE)
|
||||
{
|
||||
$this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_successful', 'activation_email_successful'));
|
||||
$this->set_message('activation_email_successful');
|
||||
return $id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_unsuccessful', 'activation_email_unsuccessful'));
|
||||
$this->set_error('activation_email_unsuccessful');
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout
|
||||
*
|
||||
* @return true
|
||||
* @author Mathew
|
||||
**/
|
||||
public function logout()
|
||||
{
|
||||
$this->ion_auth_model->trigger_events('logout');
|
||||
|
||||
$identity = $this->config->item('identity', 'ion_auth');
|
||||
|
||||
if (substr(CI_VERSION, 0, 1) == '2')
|
||||
{
|
||||
$this->session->unset_userdata(array($identity => '', 'id' => '', 'user_id' => ''));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->unset_userdata(array($identity, 'id', 'user_id'));
|
||||
}
|
||||
|
||||
// delete the remember me cookies if they exist
|
||||
if (get_cookie($this->config->item('identity_cookie_name', 'ion_auth')))
|
||||
{
|
||||
delete_cookie($this->config->item('identity_cookie_name', 'ion_auth'));
|
||||
}
|
||||
if (get_cookie($this->config->item('remember_cookie_name', 'ion_auth')))
|
||||
{
|
||||
delete_cookie($this->config->item('remember_cookie_name', 'ion_auth'));
|
||||
}
|
||||
|
||||
// Destroy the session
|
||||
$this->session->sess_destroy();
|
||||
|
||||
//Recreate the session
|
||||
if (substr(CI_VERSION, 0, 1) == '2')
|
||||
{
|
||||
$this->session->sess_create();
|
||||
}
|
||||
else
|
||||
{
|
||||
session_start();
|
||||
$this->session->sess_regenerate(TRUE);
|
||||
}
|
||||
|
||||
$this->set_message('logout_successful');
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto logs-in the user if they are remembered
|
||||
* @return bool Whether the user is logged in
|
||||
* @author Mathew
|
||||
**/
|
||||
public function logged_in()
|
||||
{
|
||||
$this->ion_auth_model->trigger_events('logged_in');
|
||||
|
||||
$recheck = $this->ion_auth_model->recheck_session();
|
||||
|
||||
// auto-login the user if they are remembered
|
||||
if (!$recheck && get_cookie($this->config->item('identity_cookie_name', 'ion_auth')) && get_cookie($this->config->item('remember_cookie_name', 'ion_auth')))
|
||||
{
|
||||
$recheck = $this->ion_auth_model->login_remembered_user();
|
||||
}
|
||||
|
||||
return $recheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null The user's ID from the session user data or NULL if not found
|
||||
* @author jrmadsen67
|
||||
**/
|
||||
public function get_user_id()
|
||||
{
|
||||
$user_id = $this->session->userdata('user_id');
|
||||
if (!empty($user_id))
|
||||
{
|
||||
return $user_id;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string|bool $id
|
||||
*
|
||||
* @return bool Whether the user is an administrator
|
||||
* @author Ben Edmunds
|
||||
*/
|
||||
public function is_admin($id = FALSE)
|
||||
{
|
||||
$this->ion_auth_model->trigger_events('is_admin');
|
||||
|
||||
$admin_group = $this->config->item('admin_group', 'ion_auth');
|
||||
|
||||
return $this->in_group($admin_group, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string|array $check_group group(s) to check
|
||||
* @param int|string|bool $id user id
|
||||
* @param bool $check_all check if all groups is present, or any of the groups
|
||||
*
|
||||
* @return bool Whether the/all user(s) with the given ID(s) is/are in the given group
|
||||
* @author Phil Sturgeon
|
||||
**/
|
||||
public function in_group($check_group, $id = FALSE, $check_all = FALSE)
|
||||
{
|
||||
$this->ion_auth_model->trigger_events('in_group');
|
||||
|
||||
$id || $id = $this->session->userdata('user_id');
|
||||
|
||||
if (!is_array($check_group))
|
||||
{
|
||||
$check_group = array($check_group);
|
||||
}
|
||||
|
||||
if (isset($this->_cache_user_in_group[$id]))
|
||||
{
|
||||
$groups_array = $this->_cache_user_in_group[$id];
|
||||
}
|
||||
else
|
||||
{
|
||||
$users_groups = $this->ion_auth_model->get_users_groups($id)->result();
|
||||
$groups_array = array();
|
||||
foreach ($users_groups as $group)
|
||||
{
|
||||
$groups_array[$group->id] = $group->name;
|
||||
}
|
||||
$this->_cache_user_in_group[$id] = $groups_array;
|
||||
}
|
||||
foreach ($check_group as $key => $value)
|
||||
{
|
||||
$groups = (is_numeric($value)) ? array_keys($groups_array) : $groups_array;
|
||||
|
||||
/**
|
||||
* if !all (default), in_array
|
||||
* if all, !in_array
|
||||
*/
|
||||
if (in_array($value, $groups) xor $check_all)
|
||||
{
|
||||
/**
|
||||
* if !all (default), true
|
||||
* if all, false
|
||||
*/
|
||||
return !$check_all;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if !all (default), false
|
||||
* if all, true
|
||||
*/
|
||||
return $check_all;
|
||||
}
|
||||
|
||||
}
|
||||
733
application/libraries/REST_Controller.php
Normal file
733
application/libraries/REST_Controller.php
Normal file
@@ -0,0 +1,733 @@
|
||||
<?php defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* REST_controller V 2.5.x
|
||||
*
|
||||
* @see https://github.com/philsturgeon/codeigniter-restserver
|
||||
*
|
||||
*/
|
||||
|
||||
class REST_Controller extends CI_Controller
|
||||
{
|
||||
|
||||
protected $rest_format = null; // Set this in a controller to use a default format
|
||||
protected $methods = array(); // contains a list of method properties such as limit, log and level
|
||||
protected $request = null; // Stores accept, language, body, headers, etc
|
||||
protected $response = null; // What is gonna happen in output?
|
||||
public $rest = null; // Stores DB, keys, key level, etc
|
||||
protected $_get_args = array();
|
||||
protected $_post_args = array();
|
||||
protected $_put_args = array();
|
||||
protected $_delete_args = array();
|
||||
protected $_args = array();
|
||||
protected $_allow = true;
|
||||
|
||||
// List all supported methods, the first will be the default format
|
||||
protected $_supported_formats = array(
|
||||
'xml' => 'application/xml',
|
||||
'rawxml' => 'application/xml',
|
||||
'json' => 'application/json',
|
||||
'jsonp' => 'application/javascript',
|
||||
'serialized' => 'application/vnd.php.serialized',
|
||||
'php' => 'text/plain',
|
||||
'html' => 'text/html',
|
||||
'csv' => 'application/csv',
|
||||
);
|
||||
|
||||
// Constructor function
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Lets grab the config and get ready to party
|
||||
$this->load->config('rest');
|
||||
|
||||
if (empty($this->request)) {
|
||||
$this->request = new stdClass;
|
||||
}
|
||||
|
||||
if (empty($this->rest)) {
|
||||
$this->rest = new stdClass;
|
||||
}
|
||||
|
||||
// How is this request being made? POST, DELETE, GET, PUT?
|
||||
$this->request->method = $this->_detect_method();
|
||||
|
||||
// Set up our GET variables
|
||||
$this->_get_args = array_merge($this->_get_args, $this->uri->ruri_to_assoc());
|
||||
|
||||
//$this->load->library('security');
|
||||
|
||||
// This library is bundled with REST_Controller 2.5+, but will eventually be part of CodeIgniter itself
|
||||
$this->load->library('format');
|
||||
|
||||
// Try to find a format for the request (means we have a request body)
|
||||
$this->request->format = $this->_detect_input_format();
|
||||
|
||||
// Some Methods cant have a body
|
||||
$this->request->body = null;
|
||||
|
||||
switch ($this->request->method) {
|
||||
case 'get':
|
||||
// Grab proper GET variables
|
||||
parse_str(parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY), $get);
|
||||
|
||||
// If there are any, populate $this->_get_args
|
||||
empty($get) or $this->_get_args = $get;
|
||||
break;
|
||||
|
||||
case 'post':
|
||||
$this->_post_args = $_POST;
|
||||
|
||||
$this->request->format and $this->request->body = file_get_contents('php://input');
|
||||
break;
|
||||
|
||||
case 'put':
|
||||
// It might be a HTTP body
|
||||
if ($this->request->format) {
|
||||
$this->request->body = file_get_contents('php://input');
|
||||
}
|
||||
|
||||
// If no file type is provided, this is probably just arguments
|
||||
else {
|
||||
parse_str(file_get_contents('php://input'), $this->_put_args);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
// Set up out DELETE variables (which shouldn't really exist, but sssh!)
|
||||
parse_str(file_get_contents('php://input'), $this->_delete_args);
|
||||
break;
|
||||
}
|
||||
|
||||
// Now we know all about our request, let's try and parse the body if it exists
|
||||
if ($this->request->format and $this->request->body) {
|
||||
$this->request->body = $this->format->factory($this->request->body, $this->request->format)->to_data();
|
||||
}
|
||||
|
||||
// Merge both for one mega-args variable
|
||||
$this->_args = array_merge($this->_get_args, $this->_put_args, $this->_post_args, $this->_delete_args);
|
||||
|
||||
// Which format should the data be returned in?
|
||||
if (empty($this->response)) {
|
||||
$this->response = new stdClass;
|
||||
}
|
||||
|
||||
$this->response->format = $this->_detect_output_format();
|
||||
|
||||
// Which format should the data be returned in?
|
||||
$this->response->lang = $this->_detect_lang();
|
||||
|
||||
// Check if there is a specific auth type for the current class/method
|
||||
$this->auth_override = $this->_auth_override_check();
|
||||
|
||||
// When there is no specific override for the current class/method, use the default auth value set in the config
|
||||
if ($this->auth_override !== true) {
|
||||
if ($this->config->item('rest_auth') == 'basic') {
|
||||
$this->_prepare_basic_auth();
|
||||
} elseif ($this->config->item('rest_auth') == 'digest') {
|
||||
$this->_prepare_digest_auth();
|
||||
}
|
||||
}
|
||||
|
||||
// Load DB if its enabled
|
||||
// if (config_item('rest_database_group') AND (config_item('rest_enable_keys') OR config_item('rest_enable_logging')))
|
||||
// {
|
||||
$this->rest->db = $this->load->database(config_item('rest_database_group'), true);
|
||||
// }
|
||||
|
||||
// Checking for keys? GET TO WORK!
|
||||
if (config_item('rest_enable_keys')) {
|
||||
$this->_allow = $this->_detect_api_key();
|
||||
}
|
||||
|
||||
// only allow ajax requests
|
||||
if (!$this->input->is_ajax_request() and config_item('rest_ajax_only')) {
|
||||
$this->response(array('status' => false, 'error' => 'Only AJAX requests are accepted.'), 505);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remap
|
||||
*
|
||||
* Requests are not made to methods directly The request will be for an "object".
|
||||
* this simply maps the object and method to the correct Controller method.
|
||||
*/
|
||||
public function _remap($object_called, $arguments)
|
||||
{
|
||||
$pattern = '/^(.*)\.(' . implode('|', array_keys($this->_supported_formats)) . ')$/';
|
||||
if (preg_match($pattern, $object_called, $matches)) {
|
||||
$object_called = $matches[1];
|
||||
}
|
||||
|
||||
$controller_method = $object_called . '_' . $this->request->method;
|
||||
|
||||
// Do we want to log this method (if allowed by config)?
|
||||
$log_method = !(isset($this->methods[$controller_method]['log']) and $this->methods[$controller_method]['log'] == false);
|
||||
|
||||
// Use keys for this method?
|
||||
$use_key = !(isset($this->methods[$controller_method]['key']) and $this->methods[$controller_method]['key'] == false);
|
||||
|
||||
// Get that useless shitty key out of here
|
||||
if (config_item('rest_enable_keys') and $use_key and $this->_allow === false) {
|
||||
if (config_item('rest_enable_logging') and $log_method) {
|
||||
$this->_log_request();
|
||||
}
|
||||
|
||||
$this->response(array('status' => false, 'error' => 'Invalid API Key.'), 403);
|
||||
}
|
||||
|
||||
// Sure it exists, but can they do anything with it?
|
||||
if (!method_exists($this, $controller_method)) {
|
||||
$this->response(array('status' => false, 'error' => 'Unknown method.'), 404);
|
||||
}
|
||||
|
||||
// Doing key related stuff? Can only do it if they have a key right?
|
||||
if (config_item('rest_enable_keys') and !empty($this->rest->key)) {
|
||||
// Check the limit
|
||||
if (config_item('rest_enable_limits') and !$this->_check_limit($controller_method)) {
|
||||
$this->response(array('status' => false, 'error' => 'This API key has reached the hourly limit for this method.'), 401);
|
||||
}
|
||||
|
||||
// If no level is set use 0, they probably aren't using permissions
|
||||
$level = isset($this->methods[$controller_method]['level']) ? $this->methods[$controller_method]['level'] : 0;
|
||||
|
||||
// If no level is set, or it is lower than/equal to the key's level
|
||||
$authorized = $level <= $this->rest->level;
|
||||
|
||||
// IM TELLIN!
|
||||
if (config_item('rest_enable_logging') and $log_method) {
|
||||
$this->_log_request($authorized);
|
||||
}
|
||||
|
||||
// They don't have good enough perms
|
||||
$authorized or $this->response(array('status' => false, 'error' => 'This API key does not have enough permissions.'), 401);
|
||||
}
|
||||
|
||||
// No key stuff, but record that stuff is happening
|
||||
else if (config_item('rest_enable_logging') and $log_method) {
|
||||
$this->_log_request($authorized = true);
|
||||
}
|
||||
|
||||
// And...... GO!
|
||||
call_user_func_array(array($this, $controller_method), $arguments);
|
||||
}
|
||||
|
||||
/*
|
||||
* response
|
||||
*
|
||||
* Takes pure data and optionally a status code, then creates the response
|
||||
*/
|
||||
public function response($data = array(), $http_code = null)
|
||||
{
|
||||
// If data is empty and not code provide, error and bail
|
||||
if (empty($data) && $http_code === null) {
|
||||
$http_code = 404;
|
||||
}
|
||||
|
||||
// Otherwise (if no data but 200 provided) or some data, carry on camping!
|
||||
else {
|
||||
is_numeric($http_code) or $http_code = 200;
|
||||
|
||||
// If the format method exists, call and return the output in that format
|
||||
if (method_exists($this, '_format_' . $this->response->format)) {
|
||||
// Set the correct format header
|
||||
header('Content-Type: ' . $this->_supported_formats[$this->response->format]);
|
||||
|
||||
$output = $this->{'_format_' . $this->response->format}($data);
|
||||
}
|
||||
|
||||
// If the format method exists, call and return the output in that format
|
||||
elseif (method_exists($this->format, 'to_' . $this->response->format)) {
|
||||
// Set the correct format header
|
||||
header('Content-Type: ' . $this->_supported_formats[$this->response->format]);
|
||||
|
||||
$output = $this->format->factory($data)->{'to_' . $this->response->format}();
|
||||
}
|
||||
|
||||
// Format not supported, output directly
|
||||
else {
|
||||
$output = $data;
|
||||
}
|
||||
}
|
||||
|
||||
header('HTTP/1.1: ' . $http_code);
|
||||
header('Status: ' . $http_code);
|
||||
header('Content-Length: ' . strlen($output));
|
||||
|
||||
exit($output);
|
||||
}
|
||||
|
||||
protected function res($code = 200, $message = 'Success', $data = null)
|
||||
{
|
||||
$this->response(array('code' => $code, 'message' => $message, 'data' => $data), 200);
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect input format
|
||||
*
|
||||
* Detect which format the HTTP Body is provided in
|
||||
*/
|
||||
protected function _detect_input_format()
|
||||
{
|
||||
if ($this->input->server('CONTENT_TYPE')) {
|
||||
// Check all formats against the HTTP_ACCEPT header
|
||||
foreach ($this->_supported_formats as $format => $mime) {
|
||||
if (strpos($match = $this->input->server('CONTENT_TYPE'), ';')) {
|
||||
$match = current(explode(';', $match));
|
||||
}
|
||||
|
||||
if ($match == $mime) {
|
||||
return $format;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect format
|
||||
*
|
||||
* Detect which format should be used to output the data
|
||||
*/
|
||||
protected function _detect_output_format()
|
||||
{
|
||||
$pattern = '/\.(' . implode('|', array_keys($this->_supported_formats)) . ')$/';
|
||||
|
||||
// Check if a file extension is used
|
||||
if (preg_match($pattern, $this->uri->uri_string(), $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
// Check if a file extension is used
|
||||
elseif ($this->_get_args and !is_array(end($this->_get_args)) and preg_match($pattern, end($this->_get_args), $matches)) {
|
||||
// The key of the last argument
|
||||
$last_key = end(array_keys($this->_get_args));
|
||||
|
||||
// Remove the extension from arguments too
|
||||
$this->_get_args[$last_key] = preg_replace($pattern, '', $this->_get_args[$last_key]);
|
||||
$this->_args[$last_key] = preg_replace($pattern, '', $this->_args[$last_key]);
|
||||
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
// A format has been passed as an argument in the URL and it is supported
|
||||
if (isset($this->_get_args['format']) and array_key_exists($this->_get_args['format'], $this->_supported_formats)) {
|
||||
return $this->_get_args['format'];
|
||||
}
|
||||
|
||||
// Otherwise, check the HTTP_ACCEPT (if it exists and we are allowed)
|
||||
if ($this->config->item('rest_ignore_http_accept') === false and $this->input->server('HTTP_ACCEPT')) {
|
||||
// Check all formats against the HTTP_ACCEPT header
|
||||
foreach (array_keys($this->_supported_formats) as $format) {
|
||||
// Has this format been requested?
|
||||
if (strpos($this->input->server('HTTP_ACCEPT'), $format) !== false) {
|
||||
// If not HTML or XML assume its right and send it on its way
|
||||
if ($format != 'html' and $format != 'xml') {
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
// HTML or XML have shown up as a match
|
||||
else {
|
||||
// If it is truely HTML, it wont want any XML
|
||||
if ($format == 'html' and strpos($this->input->server('HTTP_ACCEPT'), 'xml') === false) {
|
||||
return $format;
|
||||
}
|
||||
|
||||
// If it is truely XML, it wont want any HTML
|
||||
elseif ($format == 'xml' and strpos($this->input->server('HTTP_ACCEPT'), 'html') === false) {
|
||||
return $format;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End HTTP_ACCEPT checking
|
||||
|
||||
// Well, none of that has worked! Let's see if the controller has a default
|
||||
if (!empty($this->rest_format)) {
|
||||
return $this->rest_format;
|
||||
}
|
||||
|
||||
// Just use the default format
|
||||
return config_item('rest_default_format');
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect method
|
||||
*
|
||||
* Detect which method (POST, PUT, GET, DELETE) is being used
|
||||
*/
|
||||
|
||||
protected function _detect_method()
|
||||
{
|
||||
$method = strtolower($this->input->server('REQUEST_METHOD'));
|
||||
|
||||
if ($this->config->item('enable_emulate_request') && $this->input->post('_method')) {
|
||||
$method = $this->input->post('_method');
|
||||
}
|
||||
|
||||
if (in_array($method, array('get', 'delete', 'post', 'put'))) {
|
||||
return $method;
|
||||
}
|
||||
|
||||
return 'get';
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect API Key
|
||||
*
|
||||
* See if the user has provided an API key
|
||||
*/
|
||||
|
||||
protected function _detect_api_key()
|
||||
{
|
||||
|
||||
// Get the api key name variable set in the rest config file
|
||||
$api_key_variable = config_item('rest_key_name');
|
||||
|
||||
// Work out the name of the SERVER entry based on config
|
||||
$key_name = 'HTTP_' . strtoupper(str_replace('-', '_', $api_key_variable));
|
||||
|
||||
$this->rest->key = null;
|
||||
$this->rest->level = null;
|
||||
$this->rest->ignore_limits = false;
|
||||
|
||||
// Find the key from server or arguments
|
||||
if ($key = isset($this->_args[$api_key_variable]) ? $this->_args[$api_key_variable] : $this->input->server($key_name)) {
|
||||
if (!$row = $this->rest->db->where('key', $key)->get(config_item('rest_keys_table'))->row()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->rest->key = $row->key;
|
||||
|
||||
isset($row->level) and $this->rest->level = $row->level;
|
||||
isset($row->ignore_limits) and $this->rest->ignore_limits = $row->ignore_limits;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// No key has been sent
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect language(s)
|
||||
*
|
||||
* What language do they want it in?
|
||||
*/
|
||||
|
||||
protected function _detect_lang()
|
||||
{
|
||||
if (!$lang = $this->input->server('HTTP_ACCEPT_LANGUAGE')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// They might have sent a few, make it an array
|
||||
if (strpos($lang, ',') !== false) {
|
||||
$langs = explode(',', $lang);
|
||||
|
||||
$return_langs = array();
|
||||
$i = 1;
|
||||
foreach ($langs as $lang) {
|
||||
// Remove weight and strip space
|
||||
list($lang) = explode(';', $lang);
|
||||
$return_langs[] = trim($lang);
|
||||
}
|
||||
|
||||
return $return_langs;
|
||||
}
|
||||
|
||||
// Nope, just return the string
|
||||
return $lang;
|
||||
}
|
||||
|
||||
/*
|
||||
* Log request
|
||||
*
|
||||
* Record the entry for awesomeness purposes
|
||||
*/
|
||||
|
||||
protected function _log_request($authorized = false)
|
||||
{
|
||||
return $this->rest->db->insert(config_item('rest_logs_table'), array(
|
||||
'uri' => $this->uri->uri_string(),
|
||||
'method' => $this->request->method,
|
||||
'params' => serialize($this->_args),
|
||||
'api_key' => isset($this->rest->key) ? $this->rest->key : '',
|
||||
'ip_address' => $this->input->ip_address(),
|
||||
'time' => function_exists('now') ? now() : time(),
|
||||
'authorized' => $authorized,
|
||||
));
|
||||
}
|
||||
|
||||
/*
|
||||
* Log request
|
||||
*
|
||||
* Record the entry for awesomeness purposes
|
||||
*/
|
||||
|
||||
protected function _check_limit($controller_method)
|
||||
{
|
||||
// They are special, or it might not even have a limit
|
||||
if (!empty($this->rest->ignore_limits) or !isset($this->methods[$controller_method]['limit'])) {
|
||||
// On your way sonny-jim.
|
||||
return true;
|
||||
}
|
||||
|
||||
// How many times can you get to this method an hour?
|
||||
$limit = $this->methods[$controller_method]['limit'];
|
||||
|
||||
// Get data on a keys usage
|
||||
$result = $this->rest->db
|
||||
->where('uri', $this->uri->uri_string())
|
||||
->where('api_key', $this->rest->key)
|
||||
->get(config_item('rest_limits_table'))
|
||||
->row();
|
||||
|
||||
// No calls yet, or been an hour since they called
|
||||
if (!$result or $result->hour_started < time() - (60 * 60)) {
|
||||
// Right, set one up from scratch
|
||||
$this->rest->db->insert(config_item('rest_limits_table'), array(
|
||||
'uri' => $this->uri->uri_string(),
|
||||
'api_key' => isset($this->rest->key) ? $this->rest->key : '',
|
||||
'count' => 1,
|
||||
'hour_started' => time(),
|
||||
));
|
||||
}
|
||||
|
||||
// They have called within the hour, so lets update
|
||||
else {
|
||||
// Your luck is out, you've called too many times!
|
||||
if ($result->count >= $limit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->rest->db
|
||||
->where('uri', $this->uri->uri_string())
|
||||
->where('api_key', $this->rest->key)
|
||||
->set('count', 'count + 1', false)
|
||||
->update(config_item('rest_limits_table'));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* Auth override check
|
||||
*
|
||||
* Check if there is a specific auth type set for the current class/method being called
|
||||
*/
|
||||
|
||||
protected function _auth_override_check()
|
||||
{
|
||||
|
||||
// Assign the class/method auth type override array from the config
|
||||
$this->overrides_array = $this->config->item('auth_override_class_method');
|
||||
|
||||
// Check to see if the override array is even populated, otherwise return false
|
||||
if (empty($this->overrides_array)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check to see if there's an override value set for the current class/method being called
|
||||
if (empty($this->overrides_array[$this->router->class][$this->router->method])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// None auth override found, prepare nothing but send back a true override flag
|
||||
if ($this->overrides_array[$this->router->class][$this->router->method] == 'none') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Basic auth override found, prepare basic
|
||||
if ($this->overrides_array[$this->router->class][$this->router->method] == 'basic') {
|
||||
$this->_prepare_basic_auth();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Digest auth override found, prepare digest
|
||||
if ($this->overrides_array[$this->router->class][$this->router->method] == 'digest') {
|
||||
$this->_prepare_digest_auth();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return false when there is an override value set but it doesn't match 'basic', 'digest', or 'none'. (the value was misspelled)
|
||||
return false;
|
||||
}
|
||||
|
||||
// INPUT FUNCTION --------------------------------------------------------------
|
||||
|
||||
public function get($key = null, $xss_clean = true)
|
||||
{
|
||||
if ($key === null) {
|
||||
return $this->_get_args;
|
||||
}
|
||||
|
||||
return array_key_exists($key, $this->_get_args) ? $this->_xss_clean($this->_get_args[$key], $xss_clean) : false;
|
||||
}
|
||||
|
||||
public function post($key = null, $xss_clean = true)
|
||||
{
|
||||
if ($key === null) {
|
||||
return $this->_post_args;
|
||||
}
|
||||
|
||||
return $this->input->post($key, $xss_clean);
|
||||
}
|
||||
|
||||
public function put($key = null, $xss_clean = true)
|
||||
{
|
||||
if ($key === null) {
|
||||
return $this->_put_args;
|
||||
}
|
||||
|
||||
return array_key_exists($key, $this->_put_args) ? $this->_xss_clean($this->_put_args[$key], $xss_clean) : false;
|
||||
}
|
||||
|
||||
public function delete($key = null, $xss_clean = true)
|
||||
{
|
||||
if ($key === null) {
|
||||
return $this->_delete_args;
|
||||
}
|
||||
|
||||
return array_key_exists($key, $this->_delete_args) ? $this->_xss_clean($this->_delete_args[$key], $xss_clean) : false;
|
||||
}
|
||||
|
||||
protected function _xss_clean($val, $bool)
|
||||
{
|
||||
if (CI_VERSION < 2) {
|
||||
return $bool ? $this->input->xss_clean($val) : $val;
|
||||
} else {
|
||||
return $bool ? $this->security->xss_clean($val) : $val;
|
||||
}
|
||||
}
|
||||
|
||||
public function validation_errors()
|
||||
{
|
||||
$string = strip_tags($this->form_validation->error_string());
|
||||
|
||||
return explode("\n", trim($string, "\n"));
|
||||
}
|
||||
|
||||
// SECURITY FUNCTIONS ---------------------------------------------------------
|
||||
|
||||
protected function _check_login($username = '', $password = null)
|
||||
{
|
||||
if (empty($username)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$valid_logins = &$this->config->item('rest_valid_logins');
|
||||
|
||||
if (!array_key_exists($username, $valid_logins)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If actually NULL (not empty string) then do not check it
|
||||
if ($password !== null and $valid_logins[$username] != $password) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function _prepare_basic_auth()
|
||||
{
|
||||
$username = null;
|
||||
$password = null;
|
||||
|
||||
// mod_php
|
||||
if ($this->input->server('PHP_AUTH_USER')) {
|
||||
$username = $this->input->server('PHP_AUTH_USER');
|
||||
$password = $this->input->server('PHP_AUTH_PW');
|
||||
}
|
||||
|
||||
// most other servers
|
||||
elseif ($this->input->server('HTTP_AUTHENTICATION')) {
|
||||
if (strpos(strtolower($this->input->server('HTTP_AUTHENTICATION')), 'basic') === 0) {
|
||||
list($username, $password) = explode(':', base64_decode(substr($this->input->server('HTTP_AUTHORIZATION'), 6)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->_check_login($username, $password)) {
|
||||
$this->_force_login();
|
||||
}
|
||||
}
|
||||
|
||||
protected function _prepare_digest_auth()
|
||||
{
|
||||
$uniqid = uniqid(""); // Empty argument for backward compatibility
|
||||
// We need to test which server authentication variable to use
|
||||
// because the PHP ISAPI module in IIS acts different from CGI
|
||||
if ($this->input->server('PHP_AUTH_DIGEST')) {
|
||||
$digest_string = $this->input->server('PHP_AUTH_DIGEST');
|
||||
} elseif ($this->input->server('HTTP_AUTHORIZATION')) {
|
||||
$digest_string = $this->input->server('HTTP_AUTHORIZATION');
|
||||
} else {
|
||||
$digest_string = "";
|
||||
}
|
||||
|
||||
/* The $_SESSION['error_prompted'] variabile is used to ask
|
||||
the password again if none given or if the user enters
|
||||
a wrong auth. informations. */
|
||||
if (empty($digest_string)) {
|
||||
$this->_force_login($uniqid);
|
||||
}
|
||||
|
||||
// We need to retrieve authentication informations from the $auth_data variable
|
||||
preg_match_all('@(username|nonce|uri|nc|cnonce|qop|response)=[\'"]?([^\'",]+)@', $digest_string, $matches);
|
||||
$digest = array_combine($matches[1], $matches[2]);
|
||||
|
||||
if (!array_key_exists('username', $digest) or !$this->_check_login($digest['username'])) {
|
||||
$this->_force_login($uniqid);
|
||||
}
|
||||
|
||||
$valid_logins = &$this->config->item('rest_valid_logins');
|
||||
$valid_pass = $valid_logins[$digest['username']];
|
||||
|
||||
// This is the valid response expected
|
||||
$A1 = md5($digest['username'] . ':' . $this->config->item('rest_realm') . ':' . $valid_pass);
|
||||
$A2 = md5(strtoupper($this->request->method) . ':' . $digest['uri']);
|
||||
$valid_response = md5($A1 . ':' . $digest['nonce'] . ':' . $digest['nc'] . ':' . $digest['cnonce'] . ':' . $digest['qop'] . ':' . $A2);
|
||||
|
||||
if ($digest['response'] != $valid_response) {
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
protected function _force_login($nonce = '')
|
||||
{
|
||||
if ($this->config->item('rest_auth') == 'basic') {
|
||||
header('WWW-Authenticate: Basic realm="' . $this->config->item('rest_realm') . '"');
|
||||
} elseif ($this->config->item('rest_auth') == 'digest') {
|
||||
header('WWW-Authenticate: Digest realm="' . $this->config->item('rest_realm') . '" qop="auth" nonce="' . $nonce . '" opaque="' . md5($this->config->item('rest_realm')) . '"');
|
||||
}
|
||||
|
||||
$this->response(array('status' => false, 'error' => 'Not authorized'), 401);
|
||||
}
|
||||
|
||||
// Force it into an array
|
||||
protected function _force_loopable($data)
|
||||
{
|
||||
// Force it to be something useful
|
||||
if (!is_array($data) and !is_object($data)) {
|
||||
$data = (array) $data;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
// FORMATING FUNCTIONS ---------------------------------------------------------
|
||||
|
||||
// Many of these have been moved to the Format class for better separation, but these methods will be checked too
|
||||
|
||||
// Encode as JSONP
|
||||
protected function _format_jsonp($data = array())
|
||||
{
|
||||
return $this->get('callback') . '(' . json_encode($data) . ')';
|
||||
}
|
||||
}
|
||||
62
application/libraries/RadioService.php
Normal file
62
application/libraries/RadioService.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
class RadioService
|
||||
{
|
||||
|
||||
private $CI;
|
||||
|
||||
const TOKEN_MAXAGE = 3600;
|
||||
|
||||
const APP_ID = 75;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->CI = &get_instance();
|
||||
}
|
||||
|
||||
public function getAppId($appId = null) {
|
||||
return $appId ? $appId : self::APP_ID;
|
||||
}
|
||||
|
||||
public function checkToken()
|
||||
{
|
||||
$key = $this->CI->input->server('HTTP_ACCESS_TOKEN');
|
||||
$key = $this->CI->rest->db->where('key', $key)->get(config_item('rest_keys_table'));
|
||||
if ($key->num_rows() == 0) {
|
||||
return 401;
|
||||
} else if ($key->row()->date_created < time() - self::TOKEN_MAXAGE) {
|
||||
return 402;
|
||||
}
|
||||
}
|
||||
|
||||
public function getSchedule($categoryId, $day)
|
||||
{
|
||||
$this->CI->load->model('station_schedule_model');
|
||||
return $this->CI->station_schedule_model->findSchedulesByCategoryIdAndDayName($categoryId, $day)->result();
|
||||
}
|
||||
|
||||
public function getApp($appId)
|
||||
{
|
||||
$this->CI->load->model('app_model');
|
||||
$app = $this->CI->app_model->findByAppId($appId)->row();
|
||||
$customInfos = unserialize($app->customInfo);
|
||||
$app->customInfo = array();
|
||||
for ($i = 0; $i < count($customInfos['link']); $i++) {
|
||||
foreach ($customInfos as $field => $values) {
|
||||
$app->customInfo[$i][$field] = $values[$i];
|
||||
}
|
||||
}
|
||||
$app->customInfo = array_filter($app->customInfo, function ($info) {
|
||||
return count(array_filter(array_values($info)));
|
||||
});
|
||||
return $app;
|
||||
}
|
||||
|
||||
public function getCategory($appId)
|
||||
{
|
||||
$this->CI->load->model('category_model');
|
||||
$categories = $this->CI->category_model->findCategoriesByAppId($appId)->result();
|
||||
return $categories;
|
||||
}
|
||||
}
|
||||
10
application/libraries/index.html
Normal file
10
application/libraries/index.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user