Skip to content

Commit e45aade

Browse files
2 parents de9720d + f76bd59 commit e45aade

File tree

5 files changed

+182
-20
lines changed

5 files changed

+182
-20
lines changed

application/config/rest.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
| If 'rest_auth' is 'session' then set 'auth_source' to the name of the session variable to check for.
9898
|
9999
*/
100+
101+
//change this to '' for wildcard unit test
100102
$config['auth_source'] = 'ldap';
101103

102104
/*
@@ -130,15 +132,20 @@
130132
| $config['auth_override_class_method']['deals']['view'] = 'none';
131133
| $config['auth_override_class_method']['deals']['insert'] = 'digest';
132134
| $config['auth_override_class_method']['accounts']['user'] = 'basic';
135+
| $config['auth_override_class_method']['dashboard']['*'] = 'none|digest|basic';
133136
|
134-
| Here 'deals' and 'accounts' are controller names, 'view', 'insert' and 'user' are methods within. (NOTE: leave off the '_get' or '_post' from the end of the method name)
137+
| Here 'deals', 'accounts' and 'dashboard' are controller names, 'view', 'insert' and 'user' are methods within. An asterisk may also be used to specify an authentication method for an entire classes methods. Ex: $config['auth_override_class_method']['dashboard']['*'] = 'basic'; (NOTE: leave off the '_get' or '_post' from the end of the method name)
135138
| Acceptable values are; 'none', 'digest' and 'basic'.
136139
|
137140
*/
138141
// $config['auth_override_class_method']['deals']['view'] = 'none';
139142
// $config['auth_override_class_method']['deals']['insert'] = 'digest';
140143
// $config['auth_override_class_method']['accounts']['user'] = 'basic';
144+
// $config['auth_override_class_method']['dashboard']['*'] = 'basic';
145+
141146

147+
//---Uncomment list line for the wildard unit test
148+
//$config['auth_override_class_method']['wildcard_test_cases']['*'] = 'basic';
142149
/*
143150
|--------------------------------------------------------------------------
144151
| REST Login usernames
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php defined('BASEPATH') OR exit('No direct script access allowed');
2+
3+
/**
4+
* Example
5+
*
6+
* This is a test for the wildcard .
7+
*
8+
* @package CodeIgniter
9+
* @subpackage Rest Server
10+
* @category Controller
11+
* @author Allen Taylor
12+
* @link http://philsturgeon.co.uk/code/
13+
*/
14+
15+
// This can be removed if you use __autoload() in config.php OR use Modular Extensions
16+
17+
/*
18+
In order for this test to work you will need to change the auth_source option in the rest.php config file to '' and uncomment this line $config['auth_override_class_method']['wildcard_test_cases']['*'] = 'basic'; in the file as well. Once these are uncommented the tests will work.
19+
*/
20+
require APPPATH.'/libraries/REST_Controller.php';
21+
class Wildcard_test_cases extends REST_Controller{
22+
function __construct(){
23+
parent::__construct();
24+
//set config for test
25+
$this->config->load('rest');
26+
$this->config->set_item('rest_auth', 'none');//turn on rest auth
27+
$this->config->set_item('auth_source', '');//use config array for authentication
28+
$this->config->set_item('auth_override_class_method', array('wildcard_test_cases' => array('*' => 'basic')));
29+
$this->load->helper('url');
30+
}
31+
32+
33+
function digest_get(){
34+
$this->response("welcome", 200);
35+
}
36+
}
37+
?>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php defined('BASEPATH') OR exit('No direct script access allowed');
2+
3+
/**
4+
* Example
5+
*
6+
* This is a test for the wildcard. Wildcard allows you to specify an authentication type rule for an entire controller. Example would be $config['auth_override_class_method']['wildcard_test_cases']['*'] = 'basic'; This sets the authentication method for the Wildcard_test_harness controller to basic.
7+
*
8+
* @package CodeIgniter
9+
* @subpackage Rest Server
10+
* @category Controller
11+
* @author Allen Taylor
12+
* @link http://philsturgeon.co.uk/code/
13+
*/
14+
15+
// This can be removed if you use __autoload() in config.php OR use Modular Extensions
16+
17+
/*
18+
In order for this test to work you will need to change the auth_source option in the rest.php config file to '' and uncomment this line $config['auth_override_class_method']['wildcard_test_cases']['*'] = 'basic'; in the file as well. Once these are uncommented the tests will work.
19+
*/
20+
class Wildcard_test_harness extends CI_Controller
21+
{
22+
function __construct(){
23+
parent::__construct();
24+
$this->load->library('unit_test');
25+
$this->load->helper('url');
26+
}
27+
28+
//curl interface functions
29+
private function makeRequest($url, $cred = '', $curlopts = array()){
30+
$ch = curl_init($url);
31+
$items = array(
32+
CURLOPT_URL => $url,
33+
CURLOPT_USERPWD => $cred
34+
);
35+
foreach($curlopts as $opt => $value)
36+
$items[$opt] = $value;
37+
curl_setopt_array($ch, $items);
38+
ob_start();
39+
$response = curl_exec($ch);
40+
$contents = ob_get_contents();
41+
ob_end_clean();
42+
$info = curl_getinfo($ch);
43+
44+
$errno = curl_errno($ch);
45+
$error = curl_error($ch);
46+
curl_close($ch);
47+
return array('response' => $response, 'contents' => $contents, 'errno' => $errno, 'error' => $error, 'info' => $info);//return
48+
}
49+
50+
/*
51+
These two test cases will test if the authentication is working for the wildcard method. The curl requests may not work if you do not have an .htaccess file with mod rewrite in the same directory as your index.php file. If you don't have that file you can add it or change the url below to the one that includes index.php.
52+
*/
53+
function index(){
54+
55+
//not authorized
56+
//no htaccess: $test = $this->makeRequest(base_url() . 'index.php/unit_tests/wildcard_test_cases/digest', '');
57+
$test = $this->makeRequest(base_url() . 'unit_tests/wildcard_test_cases/digest', '');
58+
// print_r($test);
59+
$this->unit->run($test['info']['http_code'], '401', 'Not Authorized test (No credentials provided)');
60+
//no htaccess: $test = $this->makeRequest(base_url() . 'index.php/unit_tests/wildcard_test_cases/digest', 'admin:1234');
61+
$test = $this->makeRequest(base_url() . 'unit_tests/wildcard_test_cases/digest', 'admin:1234');
62+
//print_r($test);
63+
$this->unit->run($test['info']['http_code'], '200', 'Authorized, credentials given');
64+
echo $this->unit->report();
65+
}
66+
}
67+
?>

application/libraries/Format.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,22 @@ public function to_json()
227227
$callback = isset($_GET['callback']) ? $_GET['callback'] : '';
228228
if ($callback === '')
229229
{
230-
return json_encode($this->_data);
230+
return json_encode($this->_data);
231+
232+
/* Had to take out this code, it doesn't work on Objects.
233+
$str = $this->_data;
234+
array_walk_recursive($str, function(&$item, $key)
235+
{
236+
if(!mb_detect_encoding($item, 'utf-8', true))
237+
{
238+
$item = utf8_encode($item);
239+
}
240+
});
241+
242+
return json_encode($str);
243+
*/
231244
}
245+
232246
// we only honour jsonp callback which are valid javascript identifiers
233247
else if (preg_match('/^[a-z_\$][a-z0-9\$_]*(\.[a-z_\$][a-z0-9\$_]*)*$/i', $callback))
234248
{

application/libraries/REST_Controller.php

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ public function __construct()
206206
$this->load->library('format');
207207

208208
// init objects
209-
$this->request = new stdClass();
210209
$this->response = new stdClass();
211210
$this->rest = new stdClass();
212211

@@ -250,13 +249,13 @@ public function __construct()
250249
}
251250

252251
// Merge both for one mega-args variable
253-
$this->_args = array_merge($this->_get_args,
254-
$this->_options_args,
255-
$this->_patch_args,
256-
$this->_head_args ,
257-
$this->_put_args,
258-
$this->_post_args,
259-
$this->_delete_args,
252+
$this->_args = array_merge($this->_get_args,
253+
$this->_options_args,
254+
$this->_patch_args,
255+
$this->_head_args ,
256+
$this->_put_args,
257+
$this->_post_args,
258+
$this->_delete_args,
260259
$this->{'_'.$this->request->method.'_args'}
261260
);
262261

@@ -285,9 +284,10 @@ public function __construct()
285284
// Check if there is a specific auth type for the current class/method
286285
// _auth_override_check could exit so we need $this->rest->db initialized before
287286
$this->auth_override = $this->_auth_override_check();
288-
287+
289288
// Checking for keys? GET TO WorK!
290-
if (config_item('rest_enable_keys')) {
289+
// Skip keys test for $config['auth_override_class_method']['class'['method'] = 'none'
290+
if (config_item('rest_enable_keys') and $this->auth_override !== true) {
291291
$this->_allow = $this->_detect_api_key();
292292
}
293293

@@ -298,7 +298,7 @@ public function __construct()
298298
}
299299

300300
// When there is no specific override for the current class/method, use the default auth value set in the config
301-
if ($this->auth_override !== true && $this->_allow === false) {
301+
if ($this->auth_override !== true && !(config_item('rest_enable_keys') && $this->_allow === true)) {
302302
$rest_auth = strtolower($this->config->item('rest_auth'));
303303
switch ($rest_auth) {
304304
case 'basic':
@@ -509,7 +509,7 @@ public function response($data = null, $http_code = null, $continue = false)
509509
echo($output);
510510
ob_end_flush();
511511
ob_flush();
512-
flush();
512+
flush();
513513
}else{
514514
exit($output);
515515
}
@@ -852,6 +852,36 @@ protected function _auth_override_check()
852852
return false;
853853
}
854854

855+
// check for wildcard flag for rules for classes
856+
if(!empty($this->overrides_array[$this->router->class]['*'])){//check for class overides
857+
// None auth override found, prepare nothing but send back a true override flag
858+
if ($this->overrides_array[$this->router->class]['*'] == 'none')
859+
{
860+
return true;
861+
}
862+
863+
// Basic auth override found, prepare basic
864+
if ($this->overrides_array[$this->router->class]['*'] == 'basic')
865+
{
866+
$this->_prepare_basic_auth();
867+
return true;
868+
}
869+
870+
// Digest auth override found, prepare digest
871+
if ($this->overrides_array[$this->router->class]['*'] == 'digest')
872+
{
873+
$this->_prepare_digest_auth();
874+
return true;
875+
}
876+
877+
// Whitelist auth override found, check client's ip against config whitelist
878+
if ($this->overrides_array[$this->router->class]['*'] == 'whitelist')
879+
{
880+
$this->_check_whitelist_auth();
881+
return true;
882+
}
883+
}
884+
855885
// Check to see if there's an override value set for the current class/method being called
856886
if (empty($this->overrides_array[$this->router->class][$this->router->method])) {
857887
return false;
@@ -1164,7 +1194,7 @@ protected function _perform_ldap_auth($username = '', $password = null)
11641194

11651195
log_message('debug', 'Setting timeout to ' . $ldaptimeout . ' seconds');
11661196

1167-
ldap_set_option($ldapconn, LDAP_OPT_NETWorK_TIMEOUT, $ldaptimeout);
1197+
ldap_set_option($ldapconn, LDAP_OPT_NETWORK_TIMEOUT, $ldaptimeout);
11681198

11691199
log_message('debug', 'LDAP Auth: Binding to ' . $ldaphost . ' with dn ' . $ldaprdn);
11701200

@@ -1252,7 +1282,11 @@ protected function _perform_library_auth($username = '', $password = null)
12521282
return false;
12531283
}
12541284

1255-
$this->load->library($auth_library_class);
1285+
if (!is_callable(array($this->$auth_library_class, $auth_library_function))) {
1286+
1287+
$this->load->library($auth_library_class);
1288+
1289+
}
12561290

12571291
return $this->$auth_library_class->$auth_library_function($username, $password);
12581292
}
@@ -1264,12 +1298,16 @@ protected function _perform_library_auth($username = '', $password = null)
12641298
* @param string $password The user's password
12651299
* @return boolean
12661300
*/
1267-
protected function _check_login($username = '', $password = null)
1301+
protected function _check_login($username = '', $password = false)
12681302
{
12691303
if (empty($username)) {
12701304
return false;
12711305
}
12721306

1307+
if ($password === false) {
1308+
return false;
1309+
}
1310+
12731311
$auth_source = strtolower($this->config->item('auth_source'));
12741312

12751313
if ($auth_source == 'ldap') {
@@ -1286,12 +1324,11 @@ protected function _check_login($username = '', $password = null)
12861324

12871325
$valid_logins = $this->config->item('rest_valid_logins');
12881326

1289-
if ( ! array_key_exists($username, $valid_logins)) {
1327+
if (!array_key_exists($username, $valid_logins)) {
12901328
return false;
12911329
}
12921330

1293-
// If actually null (not empty string) then do not check it
1294-
if ($password === null and $valid_logins[$username] != $password) {
1331+
if ($valid_logins[$username] != $password) {
12951332
return false;
12961333
}
12971334

0 commit comments

Comments
 (0)