2156 api login (#2157)
* error can be due to bad user or password * added login/logout and related private functions * handle case when userLogin fails, current code returns PHP error for and API throw is not called * formatting * converted login params to POST, removed user=&pass= for other APIs * formatting * add auth check back but leave out login/out * fixes to make it work across zmN, postman and curl * added back enabled check
This commit is contained in:
parent
0d75586fac
commit
0ff9002adf
|
@ -27,116 +27,64 @@ App::uses('CrudControllerTrait', 'Crud.Lib');
|
|||
* Add your application-wide methods in the class below, your controllers
|
||||
* will inherit them.
|
||||
*
|
||||
* @package app.Controller
|
||||
* @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
|
||||
* @package app.Controller
|
||||
* @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
|
||||
*/
|
||||
class AppController extends Controller {
|
||||
use CrudControllerTrait;
|
||||
use CrudControllerTrait;
|
||||
|
||||
public $components = [
|
||||
'Session', // We are going to use SessionHelper to check PHP session vars
|
||||
'RequestHandler',
|
||||
'Crud.Crud' => [
|
||||
'actions' => [
|
||||
'index' => 'Crud.Index',
|
||||
'add' => 'Crud.Add',
|
||||
'edit' => 'Crud.Edit',
|
||||
'view' => 'Crud.View',
|
||||
'keyvalue' => 'Crud.List',
|
||||
'category' => 'Crud.Category'
|
||||
],
|
||||
'listeners' => ['Api', 'ApiTransformation']
|
||||
#],
|
||||
public $components = [
|
||||
'Session', // We are going to use SessionHelper to check PHP session vars
|
||||
'RequestHandler',
|
||||
'Crud.Crud' => [
|
||||
'actions' => [
|
||||
'index' => 'Crud.Index',
|
||||
'add' => 'Crud.Add',
|
||||
'edit' => 'Crud.Edit',
|
||||
'view' => 'Crud.View',
|
||||
'keyvalue' => 'Crud.List',
|
||||
'category' => 'Crud.Category'
|
||||
],
|
||||
'listeners' => ['Api', 'ApiTransformation']
|
||||
#],
|
||||
#'DebugKit.Toolbar' => [
|
||||
# 'bootstrap' => true, 'routes' => true
|
||||
]
|
||||
];
|
||||
];
|
||||
|
||||
// Global beforeFilter function
|
||||
//Zoneminder sets the username session variable
|
||||
// to the logged in user. If this variable is set
|
||||
// then you are logged in
|
||||
// its pretty simple to extend this to also check
|
||||
// for role and deny API access in future
|
||||
// Also checking to do this only if ZM_OPT_USE_AUTH is on
|
||||
public function beforeFilter() {
|
||||
$this->loadModel('Config');
|
||||
|
||||
// Global beforeFilter function
|
||||
//Zoneminder sets the username session variable
|
||||
// to the logged in user. If this variable is set
|
||||
// then you are logged in
|
||||
// its pretty simple to extend this to also check
|
||||
// for role and deny API access in future
|
||||
// Also checking to do this only if ZM_OPT_USE_AUTH is on
|
||||
public function beforeFilter() {
|
||||
$this->loadModel('Config');
|
||||
|
||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_API'));
|
||||
$config = $this->Config->find('first', $options);
|
||||
$zmOptApi = $config['Config']['Value'];
|
||||
|
||||
if ($zmOptApi !='1') {
|
||||
if ($zmOptApi !='1') {
|
||||
throw new UnauthorizedException(__('API Disabled'));
|
||||
return;
|
||||
}
|
||||
|
||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH'));
|
||||
$config = $this->Config->find('first', $options);
|
||||
$zmOptAuth = $config['Config']['Value'];
|
||||
|
||||
if ( $zmOptAuth == '1' ) {
|
||||
require_once "../../../includes/auth.php";
|
||||
|
||||
global $user;
|
||||
$user = $this->Session->read('user');
|
||||
|
||||
if ( isset($_REQUEST['user']) and isset($_REQUEST['pass']) ) {
|
||||
$user = userLogin($_REQUEST['user'],$_REQUEST['pass']);
|
||||
if ( !$user ) {
|
||||
throw new UnauthorizedException(__('User not found'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset($_REQUEST['auth']) ) {
|
||||
$user = getAuthUser($_REQUEST['auth']);
|
||||
if ( ! $user ) {
|
||||
throw new UnauthorizedException(__('User not found'));
|
||||
return;
|
||||
}
|
||||
} # end if REQUEST['auth']
|
||||
|
||||
if ( 0 and $user ) {
|
||||
# We have to redo the session variables because cakephp's Session code will overwrite the normal php session
|
||||
# Actually I'm not sure that is true. Getting indeterminate behaviour
|
||||
Logger::Debug("user.Username: " . $this->Session->read('user.Username'));
|
||||
if ( ! $this->Session->Write('user', $user) )
|
||||
$this->log("Error writing session var user");
|
||||
Logger::Debug("user.Username: " . $this->Session->read('user.Username'));
|
||||
if ( ! $this->Session->Write('user.Username', $user['Username']) )
|
||||
$this->log("Error writing session var user.Username");
|
||||
if ( ! $this->Session->Write('password', $user['Password']) )
|
||||
$this->log("Error writing session var user.Username");
|
||||
if ( ! $this->Session->Write('user.Enabled', $user['Enabled']) )
|
||||
$this->log("Error writing session var user.Enabled");
|
||||
if ( ! $this->Session->Write('remoteAddr', $_SERVER['REMOTE_ADDR']) )
|
||||
$this->log("Error writing session var remoteAddr");
|
||||
}
|
||||
|
||||
if ( ! $this->Session->read('user.Username') ) {
|
||||
throw new UnauthorizedException(__('Not Authenticated'));
|
||||
return;
|
||||
} else if ( ! $this->Session->read('user.Enabled') ) {
|
||||
throw new UnauthorizedException(__('User is not enabled'));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->Session->Write('allowedMonitors',$user['MonitorIds']);
|
||||
$this->Session->Write('streamPermission',$user['Stream']);
|
||||
$this->Session->Write('eventPermission',$user['Events']);
|
||||
$this->Session->Write('controlPermission',$user['Control']);
|
||||
$this->Session->Write('systemPermission',$user['System']);
|
||||
$this->Session->Write('monitorPermission',$user['Monitors']);
|
||||
} else {
|
||||
// if auth is not on, you can do everything
|
||||
//$userMonitors = $this->User->find('first', $options);
|
||||
$this->Session->Write('allowedMonitors','');
|
||||
$this->Session->Write('streamPermission','View');
|
||||
$this->Session->Write('eventPermission','Edit');
|
||||
$this->Session->Write('controlPermission','Edit');
|
||||
$this->Session->Write('systemPermission','Edit');
|
||||
$this->Session->Write('monitorPermission','Edit');
|
||||
}
|
||||
// We need to reject methods that are not authenticated
|
||||
// besides login and logout
|
||||
if (strcasecmp($this->params->controller, "host") &&
|
||||
strcasecmp($this->params->action, "login") &&
|
||||
strcasecmp($this->params->action,"logout")) {
|
||||
|
||||
if (!$this->Session->read('user.Username')) {
|
||||
throw new UnauthorizedException(__('Not Authenticated'));
|
||||
return;
|
||||
} else if (!$this->Session->read('user.Enabled')) {
|
||||
throw new UnauthorizedException(__('User is not enabled'));
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} # end function beforeFilter()
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ App::uses('AppController', 'Controller');
|
|||
|
||||
class HostController extends AppController {
|
||||
|
||||
public $components = array('RequestHandler');
|
||||
public $components = array('RequestHandler', 'Session');
|
||||
|
||||
public function daemonCheck($daemon=false, $args=false) {
|
||||
public function daemonCheck($daemon=false, $args=false) {
|
||||
$string = Configure::read('ZM_PATH_BIN').'/zmdc.pl check';
|
||||
if ( $daemon ) {
|
||||
$string .= " $daemon";
|
||||
|
@ -15,27 +15,139 @@ class HostController extends AppController {
|
|||
$result = exec($string);
|
||||
$result = preg_match('/running/', $result);
|
||||
|
||||
$this->set(array(
|
||||
'result' => $result,
|
||||
'_serialize' => array('result')
|
||||
));
|
||||
}
|
||||
$this->set(array(
|
||||
'result' => $result,
|
||||
'_serialize' => array('result')
|
||||
));
|
||||
}
|
||||
|
||||
function getLoad() {
|
||||
$load = sys_getloadavg();
|
||||
function getLoad() {
|
||||
$load = sys_getloadavg();
|
||||
|
||||
$this->set(array(
|
||||
'load' => $load,
|
||||
'_serialize' => array('load')
|
||||
));
|
||||
}
|
||||
$this->set(array(
|
||||
'load' => $load,
|
||||
'_serialize' => array('load')
|
||||
));
|
||||
}
|
||||
|
||||
function getCredentials() {
|
||||
// ignore debug warnings from other functions
|
||||
$this->view='Json';
|
||||
|
||||
|
||||
function login() {
|
||||
|
||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH'));
|
||||
$config = $this->Config->find('first', $options);
|
||||
$zmOptAuth = $config['Config']['Value'];
|
||||
|
||||
if ( $zmOptAuth == '1' ) {
|
||||
require_once "../../../includes/auth.php";
|
||||
|
||||
global $user;
|
||||
$user = $this->Session->read('user');
|
||||
|
||||
|
||||
|
||||
$mUser = $this->request->data('user');
|
||||
$mPassword = $this->request->data('pass');
|
||||
$mAuth = $this->request->data('auth');
|
||||
|
||||
|
||||
if ( $mUser and $mPassword) {
|
||||
$user = userLogin($mUser, $mPassword);
|
||||
if ( !$user ) {
|
||||
throw new UnauthorizedException(__('User not found or incorrect password'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
elseif ( $mAuth ) {
|
||||
$user = getAuthUser($mAuth);
|
||||
if ( ! $user ) {
|
||||
throw new UnauthorizedException(__('User not found or incorrect password'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UnauthorizedException(__('missing credentials'));
|
||||
}
|
||||
|
||||
if ( 0 and $user ) {
|
||||
# We have to redo the session variables because cakephp's Session code will overwrite the normal php session
|
||||
# Actually I'm not sure that is true. Getting indeterminate behaviour
|
||||
Logger::Debug("user.Username: " . $this->Session->read('user.Username'));
|
||||
if ( ! $this->Session->Write('user', $user) )
|
||||
$this->log("Error writing session var user");
|
||||
Logger::Debug("user.Username: " . $this->Session->read('user.Username'));
|
||||
if ( ! $this->Session->Write('user.Username', $user['Username']) )
|
||||
$this->log("Error writing session var user.Username");
|
||||
if ( ! $this->Session->Write('password', $user['Password']) )
|
||||
$this->log("Error writing session var user.Username");
|
||||
if ( ! $this->Session->Write('user.Enabled', $user['Enabled']) )
|
||||
$this->log("Error writing session var user.Enabled");
|
||||
if ( ! $this->Session->Write('remoteAddr', $_SERVER['REMOTE_ADDR']) )
|
||||
$this->log("Error writing session var remoteAddr");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// I don't think this is really needed - the Username part
|
||||
// Enabled check is ok
|
||||
if ( !$user['Username'] ) {
|
||||
throw new UnauthorizedException(__('Not Authenticated'));
|
||||
return;
|
||||
} else if ( !$user['Enabled'] ) {
|
||||
throw new UnauthorizedException(__('User is not enabled'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$this->Session->Write('allowedMonitors',$user['MonitorIds']);
|
||||
$this->Session->Write('streamPermission',$user['Stream']);
|
||||
$this->Session->Write('eventPermission',$user['Events']);
|
||||
$this->Session->Write('controlPermission',$user['Control']);
|
||||
$this->Session->Write('systemPermission',$user['System']);
|
||||
$this->Session->Write('monitorPermission',$user['Monitors']);
|
||||
} else {
|
||||
// if auth is not on, you can do everything
|
||||
//$userMonitors = $this->User->find('first', $options);
|
||||
$this->Session->Write('allowedMonitors','');
|
||||
$this->Session->Write('streamPermission','View');
|
||||
$this->Session->Write('eventPermission','Edit');
|
||||
$this->Session->Write('controlPermission','Edit');
|
||||
$this->Session->Write('systemPermission','Edit');
|
||||
$this->Session->Write('monitorPermission','Edit');
|
||||
}
|
||||
|
||||
|
||||
$cred = $this->_getCredentials();
|
||||
$ver = $this->_getVersion();
|
||||
$this->set(array(
|
||||
'credentials' => $cred[0],
|
||||
'append_password'=>$cred[1],
|
||||
'version' => $ver[0],
|
||||
'apiversion' => $ver[1],
|
||||
'_serialize' => array('credentials',
|
||||
'append_password',
|
||||
'version',
|
||||
'apiversion'
|
||||
)));
|
||||
|
||||
}
|
||||
|
||||
// clears out session
|
||||
function logout() {
|
||||
global $user;
|
||||
$this->Session->Write('user', null);
|
||||
|
||||
$this->set(array(
|
||||
'result' => 'ok',
|
||||
'_serialize' => array('result')
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
private function _getCredentials() {
|
||||
$credentials = '';
|
||||
$appendPassword = 0;
|
||||
|
||||
$this->loadModel('Config');
|
||||
$isZmAuth = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH')))['Config']['Value'];
|
||||
|
||||
|
@ -52,80 +164,90 @@ class HostController extends AppController {
|
|||
$credentials = 'user='.$this->Session->read('user.Username');
|
||||
}
|
||||
}
|
||||
return array($credentials, $appendPassword);
|
||||
|
||||
}
|
||||
|
||||
function getCredentials() {
|
||||
// ignore debug warnings from other functions
|
||||
$this->view='Json';
|
||||
$val = $this->_getCredentials();
|
||||
$this->set(array(
|
||||
'credentials'=> $credentials,
|
||||
'append_password'=>$appendPassword,
|
||||
'credentials'=> $val[0],
|
||||
'append_password'=>$val[1],
|
||||
'_serialize' => array('credentials', 'append_password')
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// If $mid is set, only return disk usage for that monitor
|
||||
// If $mid is set, only return disk usage for that monitor
|
||||
// Else, return an array of total disk usage, and per-monitor
|
||||
// usage.
|
||||
function getDiskPercent($mid = null) {
|
||||
$this->loadModel('Config');
|
||||
$this->loadModel('Monitor');
|
||||
function getDiskPercent($mid = null) {
|
||||
$this->loadModel('Config');
|
||||
$this->loadModel('Monitor');
|
||||
|
||||
// If $mid is passed, see if it is valid
|
||||
if ($mid) {
|
||||
if (!$this->Monitor->exists($mid)) {
|
||||
throw new NotFoundException(__('Invalid monitor'));
|
||||
}
|
||||
}
|
||||
// If $mid is passed, see if it is valid
|
||||
if ($mid) {
|
||||
if (!$this->Monitor->exists($mid)) {
|
||||
throw new NotFoundException(__('Invalid monitor'));
|
||||
}
|
||||
}
|
||||
|
||||
$zm_dir_events = $this->Config->find('list', array(
|
||||
'conditions' => array('Name' => 'ZM_DIR_EVENTS'),
|
||||
'fields' => array('Name', 'Value')
|
||||
));
|
||||
$zm_dir_events = $zm_dir_events['ZM_DIR_EVENTS' ];
|
||||
$zm_dir_events = $this->Config->find('list', array(
|
||||
'conditions' => array('Name' => 'ZM_DIR_EVENTS'),
|
||||
'fields' => array('Name', 'Value')
|
||||
));
|
||||
$zm_dir_events = $zm_dir_events['ZM_DIR_EVENTS' ];
|
||||
|
||||
// Test to see if $zm_dir_events is relative or absolute
|
||||
if ('/' === "" || strrpos($zm_dir_events, '/', -strlen($zm_dir_events)) !== TRUE) {
|
||||
// relative - so add the full path
|
||||
$zm_dir_events = Configure::read('ZM_PATH_WEB') . '/' . $zm_dir_events;
|
||||
}
|
||||
// Test to see if $zm_dir_events is relative or absolute
|
||||
if ('/' === "" || strrpos($zm_dir_events, '/', -strlen($zm_dir_events)) !== TRUE) {
|
||||
// relative - so add the full path
|
||||
$zm_dir_events = Configure::read('ZM_PATH_WEB') . '/' . $zm_dir_events;
|
||||
}
|
||||
|
||||
if ($mid) {
|
||||
// Get disk usage for $mid
|
||||
$usage = shell_exec ("du -sh0 $zm_dir_events/$mid | awk '{print $1}'");
|
||||
} else {
|
||||
$monitors = $this->Monitor->find('all', array(
|
||||
'fields' => array('Id', 'Name', 'WebColour')
|
||||
));
|
||||
$usage = array();
|
||||
if ($mid) {
|
||||
// Get disk usage for $mid
|
||||
$usage = shell_exec ("du -sh0 $zm_dir_events/$mid | awk '{print $1}'");
|
||||
} else {
|
||||
$monitors = $this->Monitor->find('all', array(
|
||||
'fields' => array('Id', 'Name', 'WebColour')
|
||||
));
|
||||
$usage = array();
|
||||
|
||||
// Add each monitor's usage to array
|
||||
foreach ($monitors as $key => $value) {
|
||||
$id = $value['Monitor']['Id'];
|
||||
$name = $value['Monitor']['Name'];
|
||||
$color = $value['Monitor']['WebColour'];
|
||||
// Add each monitor's usage to array
|
||||
foreach ($monitors as $key => $value) {
|
||||
$id = $value['Monitor']['Id'];
|
||||
$name = $value['Monitor']['Name'];
|
||||
$color = $value['Monitor']['WebColour'];
|
||||
|
||||
$space = shell_exec ("du -s0 $zm_dir_events/$id | awk '{print $1}'");
|
||||
if ($space == null) {
|
||||
$space = 0;
|
||||
}
|
||||
$space = $space/1024/1024;
|
||||
$space = shell_exec ("du -s0 $zm_dir_events/$id | awk '{print $1}'");
|
||||
if ($space == null) {
|
||||
$space = 0;
|
||||
}
|
||||
$space = $space/1024/1024;
|
||||
|
||||
$usage[$name] = array(
|
||||
'space' => rtrim($space),
|
||||
'color' => $color
|
||||
);
|
||||
}
|
||||
$usage[$name] = array(
|
||||
'space' => rtrim($space),
|
||||
'color' => $color
|
||||
);
|
||||
}
|
||||
|
||||
// Add total usage to array
|
||||
$space = shell_exec( "df $zm_dir_events |tail -n1 | awk '{print $3 }'");
|
||||
$space = $space/1024/1024;
|
||||
$usage['Total'] = array(
|
||||
'space' => rtrim($space),
|
||||
'color' => '#F7464A'
|
||||
);
|
||||
}
|
||||
// Add total usage to array
|
||||
$space = shell_exec( "df $zm_dir_events |tail -n1 | awk '{print $3 }'");
|
||||
$space = $space/1024/1024;
|
||||
$usage['Total'] = array(
|
||||
'space' => rtrim($space),
|
||||
'color' => '#F7464A'
|
||||
);
|
||||
}
|
||||
|
||||
$this->set(array(
|
||||
'usage' => $usage,
|
||||
'_serialize' => array('usage')
|
||||
));
|
||||
}
|
||||
$this->set(array(
|
||||
'usage' => $usage,
|
||||
'_serialize' => array('usage')
|
||||
));
|
||||
}
|
||||
|
||||
function getTimeZone() {
|
||||
//http://php.net/manual/en/function.date-default-timezone-get.php
|
||||
|
@ -136,18 +258,18 @@ class HostController extends AppController {
|
|||
));
|
||||
}
|
||||
|
||||
function getVersion() {
|
||||
//throw new UnauthorizedException(__('API Disabled'));
|
||||
$version = Configure::read('ZM_VERSION');
|
||||
// not going to use the ZM_API_VERSION
|
||||
// requires recompilation and dependency on ZM upgrade
|
||||
//$apiversion = Configure::read('ZM_API_VERSION');
|
||||
$apiversion = '1.0';
|
||||
private function _getVersion() {
|
||||
$version = Configure::read('ZM_VERSION');
|
||||
$apiversion = '1.0';
|
||||
return array($version, $apiversion);
|
||||
}
|
||||
|
||||
$this->set(array(
|
||||
'version' => $version,
|
||||
'apiversion' => $apiversion,
|
||||
'_serialize' => array('version', 'apiversion')
|
||||
));
|
||||
}
|
||||
function getVersion() {
|
||||
$val = $this->_getVersion();
|
||||
$this->set(array(
|
||||
'version' => $val[0],
|
||||
'apiversion' => $val[1],
|
||||
'_serialize' => array('version', 'apiversion')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ function userLogin($username, $password='', $passwordHashed=false) {
|
|||
}
|
||||
if ( $close_session )
|
||||
session_write_close();
|
||||
return $user;
|
||||
return isset($user) ? $user: null;
|
||||
} # end function userLogin
|
||||
|
||||
function userLogout() {
|
||||
|
|
Loading…
Reference in New Issue