MISP/app/Controller/AppController.php

507 lines
17 KiB
PHP
Raw Normal View History

<?php
/**
* Application level Controller
*
* This file is application-wide controller file. You can put all
* application-wide controller-related methods here.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Controller
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
// TODO GPG encryption has issues when keys are expired
App::uses('Controller', 'Controller');
App::uses('File', 'Utility');
/**
* Application Controller
*
* 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
2012-12-18 17:44:07 +01:00
*
* @throws ForbiddenException // TODO Exception
*/
class AppController extends Controller {
2012-03-26 19:56:44 +02:00
public $defaultModel = '';
public $debugMode = false;
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$name = get_class($this);
$name = str_replace('sController', '', $name);
$name = str_replace('Controller', '', $name);
$this->defaultModel = $name;
}
public $components = array(
'Session',
'Auth' => array(
'className' => 'SecureAuth',
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email')
)
),
'authError' => 'Unauthorised access.',
'loginRedirect' => array('controller' => 'users', 'action' => 'routeafterlogin'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
//'authorize' => array('Controller', // Added this line
//'Actions' => array('actionPath' => 'controllers')) // TODO ACL, 4: tell actionPath
2013-11-06 10:52:18 +01:00
),
);
public function beforeFilter() {
// REST authentication
if ($this->_isRest() || $this->isJson()) {
// disable CSRF for REST access
if (array_key_exists('Security', $this->components))
$this->Security->csrfCheck = false;
// Authenticate user with authkey in Authorization HTTP header
if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
$user = $this->checkAuthUser($_SERVER['HTTP_AUTHORIZATION']);
if ($user) {
// User found in the db, add the user info to the session
$this->Session->renew();
$this->Session->write(AuthComponent::$sessionKey, $user['User']);
}
else {
// User not authenticated correctly
// reset the session information
$this->Session->destroy();
throw new ForbiddenException('The authentication key provided cannot be used for syncing.');
}
}
}
// user must accept terms
//
if ($this->Session->check('Auth.User') && !$this->Auth->user('termsaccepted') && (!in_array($this->request->here, array('/users/terms', '/users/logout', '/users/login')))) {
$this->redirect(array('controller' => 'users', 'action' => 'terms', 'admin' => false));
}
if ($this->Session->check('Auth.User') && $this->Auth->user('change_pw') && (!in_array($this->request->here, array('/users/terms', '/users/change_pw', '/users/logout', '/users/login')))) {
$this->redirect(array('controller' => 'users', 'action' => 'change_pw', 'admin' => false));
}
// We don't want to run these role checks before the user is logged in, but we want them available for every view once the user is logged on
// instead of using checkAction(), like we normally do from controllers when trying to find out about a permission flag, we can use getActions()
// getActions returns all the flags in a single SQL query
if ($this->Auth->user()) {
$role = $this->getActions();
$this->set('me', $this->Auth->user());
$this->set('isAdmin', $role['perm_admin']);
$this->set('isSiteAdmin', $role['perm_site_admin']);
$this->set('isAclAdd', $role['perm_add']);
$this->set('isAclModify', $role['perm_modify']);
$this->set('isAclModifyOrg', $role['perm_modify_org']);
$this->set('isAclPublish', $role['perm_publish']);
$this->set('isAclSync', $role['perm_sync']);
$this->set('isAclAdmin', $role['perm_admin']);
$this->set('isAclAudit', $role['perm_audit']);
$this->set('isAclAuth', $role['perm_auth']);
$this->set('isAclRegexp', $role['perm_regexp_access']);
$this->userRole = $role;
} else {
2013-06-03 16:37:13 +02:00
$this->set('me', false);
$this->set('isAdmin', false);
$this->set('isSiteAdmin', false);
$this->set('isAclAdd', false);
$this->set('isAclModify', false);
$this->set('isAclModifyOrg', false);
$this->set('isAclPublish', false);
$this->set('isAclSync', false);
$this->set('isAclAdmin', false);
$this->set('isAclAudit', false);
$this->set('isAclAuth', false);
$this->set('isAclRegexp', false);
}
if (Configure::read('debug') > 0) {
$this->debugMode = 'debugOn';
} else {
$this->debugMode = 'debugOff';
}
$this->set('debugMode', $this->debugMode);
}
public $userRole = null;
public function isJson(){
return $this->request->header('Accept') === 'application/json';
}
2012-10-25 15:16:19 +02:00
//public function blackhole($type) {
// // handle errors.
// throw new Exception(__d('cake_dev', 'The request has been black-holed'));
// //throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
//}
protected function _isRest() {
return (isset($this->RequestHandler) && ($this->RequestHandler->isXml() || $this->isJson()));
}
/**
* Convert an array to the same array but with the values also as index instead of an interface_exists
*/
protected function _arrayToValuesIndexArray($oldArray) {
$newArray = Array();
foreach ($oldArray as $value)
$newArray[$value] = $value;
return $newArray;
}
/**
* checks if the currently logged user is an administrator (an admin that can manage the users and events of his own organisation)
*/
protected function _isAdmin() {
$org = $this->Auth->user('org');
if ($this->userRole['perm_site_admin'] || $this->userRole['perm_admin']) {
return true;
}
return false;
}
/**
* checks if the currently logged user is a site administrator (an admin that can manage any user or event on the instance and create / edit the roles).
*/
protected function _isSiteAdmin() {
return $this->userRole['perm_site_admin'];
}
protected function _checkOrg() {
return $this->Auth->user('org');
}
/**
* Refreshes the Auth session with new/updated data
* @return void
*/
protected function _refreshAuth() {
2013-06-08 11:31:22 +02:00
$this->loadModel('User');
$this->User->recursive = -1;
$user = $this->User->findById($this->Auth->user('id'));
$this->Auth->login($user['User']);
}
2013-11-06 10:52:18 +01:00
public function queuegenerateCorrelation() {
if (!$this->_isSiteAdmin()) throw new NotFoundException();
2013-11-06 10:52:18 +01:00
CakeResque::enqueue(
'default',
'AdminShell',
array('jobGenerateCorrelation')
);
$this->Session->setFlash('Job queued.');
$this->redirect(array('controller' => 'pages', 'action' => 'display', 'administration'));
}
public function generateCorrelation() {
2013-11-06 10:52:18 +01:00
$this->loadModel('Correlation');
$this->Correlation->deleteAll(array('id !=' => ''), false);
$this->loadModel('Attribute');
$fields = array('Attribute.id', 'Attribute.event_id', 'Attribute.distribution', 'Attribute.type', 'Attribute.category', 'Attribute.value1', 'Attribute.value2');
2013-11-06 10:52:18 +01:00
// get all attributes..
$attributes = $this->Attribute->find('all', array('recursive' => -1, 'fields' => $fields));
2013-11-06 10:52:18 +01:00
// for all attributes..
foreach ($attributes as $attribute) {
$this->Attribute->__afterSaveCorrelation($attribute['Attribute']);
}
}
/*public function generateCorrelation() {
if (!self::_isSiteAdmin()) throw new NotFoundException();
$this->loadModel('Correlation');
$this->Correlation->deleteAll(array('id !=' => ''), false);
$this->loadModel('Attribute');
$fields = array('Attribute.id', 'Attribute.event_id', 'Attribute.distribution', 'Attribute.cluster', 'Event.date', 'Event.org');
// get all attributes..
$attributes = $this->Attribute->find('all', array('recursive' => -1));
// for all attributes..
foreach ($attributes as $attribute) {
$this->Attribute->__afterSaveCorrelation($attribute['Attribute']);
}
$this->Session->setFlash(__('All done.'));
$this->redirect(array('controller' => 'events', 'action' => 'index', 'admin' => false));
2013-11-06 10:52:18 +01:00
}*/
public function generateLocked() {
if (!self::_isSiteAdmin()) throw new NotFoundException();
$this->loadModel('User');
$this->User->recursive = -1;
$localOrgs = array();
$conditions = array();
$orgs = $this->User->find('all', array('fields' => array('DISTINCT org')));
foreach ($orgs as $k => $org) {
$orgs[$k]['User']['count'] = $this->User->find('count', array(
'conditions' => array(
'org =' => $orgs[$k]['User']['org'],
)));
if ($orgs[$k]['User']['count'] > 1) {
$localOrgs[] = $orgs[$k]['User']['org'];
$conditions['AND'][] = array('orgc !=' => $orgs[$k]['User']['org']);
} else if ($orgs[$k]['User']['count'] == 1) {
// If we only have a single user for an org, check if that user is a sync user. If not, then it is a valid local org and the events created by him/her should be unlocked.
$this->User->recursive = 1;
$user = ($this->User->find('first', array(
'fields' => array('id', 'role_id'),
'conditions' => array('org' => $org['User']['org']),
'contain' => array('Role' => array(
'fields' => array('id', 'perm_sync'),
))
)));
if (!$user['Role']['perm_sync']) {
$conditions['AND'][] = array('orgc !=' => $orgs[$k]['User']['org']);
}
}
}
// Don't lock stuff that's already locked
$conditions['AND'][] = array('locked !=' => true);
$this->loadModel('Event');
$this->Event->recursive = -1;
$toBeUpdated = $this->Event->find('count', array(
'conditions' => $conditions
));
$this->Event->updateAll(
array('Event.locked' => 1),
$conditions
);
$this->Session->setFlash('Events updated, '. $toBeUpdated . ' record(s) altered.');
$this->redirect(array('controller' => 'pages', 'action' => 'display', 'administration'));
}
/**
*
* @param $action
* @return boolean
*/
// pass an action to this method for it to check the active user's access to the action
public function checkAction($action = 'perm_sync') {
$this->loadModel('Role');
$this->Role->recursive = -1;
$role = $this->Role->findById($this->Auth->user('role_id'));
if ($role['Role'][$action]) return true;
return false;
}
// returns the role of the currently authenticated user as an array, used to set the permission variables for views in the AppController's beforeFilter() method
public function getActions() {
$this->loadModel('Role');
$this->Role->recursive = -1;
$role = $this->Role->findById($this->Auth->user('role_id'));
return $role['Role'];
}
/**
*
* @param unknown $authkey
* @return boolean or user array
*/
public function checkAuthUser($authkey) {
$this->loadModel('User');
$this->User->recursive = -1;
$user = $this->User->findByAuthkey($authkey);
if (isset($user['User'])) {
$this->loadModel('Role');
$this->Role->recursive = -1;
$role = $this->Role->findById($user['User']['role_id']);
$user['User']['siteAdmin'] = false;
if ($role['Role']['perm_site_admin']) $user['User']['siteAdmin'] = true;
if ($role['Role']['perm_auth']) {
return $user;
}
}
return false;
}
public function generatePrivate() {
$this->generatePrivateForAttributes();
$this->generatePrivateForEvents();
}
public function generatePrivateForAttributes() {
if (!self::_isSiteAdmin()) throw new NotFoundException();
$this->loadModel('Attribute');
$attributes = $this->Attribute->find('all', array('recursive' => 0));
foreach ($attributes as $attribute) {
if ($attribute['Attribute']['private']) {
$attribute['Attribute']['private'] = true;
$attribute['Attribute']['cluster'] = false;
$attribute['Attribute']['communitie'] = false;
} else {
$attribute['Attribute']['private'] = false;
$attribute['Attribute']['cluster'] = false;
$attribute['Attribute']['communitie'] = false;
}
$this->Attribute->save($attribute);
}
}
public function generatePrivateForEvents() {
if (!self::_isSiteAdmin()) throw new NotFoundException();
$this->loadModel('Event');
$events = $this->Event->find('all', array('recursive' => 0));
foreach ($events as $event) {
if ($event['Event']['private']) {
$event['Event']['private'] = true;
$event['Event']['cluster'] = false;
$event['Event']['communitie'] = false;
} else {
$event['Event']['private'] = false;
$event['Event']['cluster'] = false;
$event['Event']['communitie'] = false;
}
$event['Event']['orgc'] = $event['Event']['org'];
$event['Event']['dist_change'] = 0;
$event['Event']['analysis'] = 2;
$this->Event->save($event);
}
}
public function generateCount() {
if (!self::_isSiteAdmin()) throw new NotFoundException();
// do one SQL query with the counts
// loop over events, update in db
$this->loadModel('Attribute');
$events = $this->Attribute->query('SELECT event_id, count(event_id) as attribute_count FROM attributes GROUP BY event_id');
foreach ($events as $event) {
$this->Event->read(null, $event['attributes']['event_id']);
$this->Event->set('attribute_count', $event[0]['attribute_count']);
$this->Event->save();
}
2013-07-12 15:35:00 +02:00
$this->Session->setFlash(__('All done. attribute_count generated from scratch.'));
$this->redirect(array('controller' => 'pages', 'action' => 'display', 'administration'));
}
/**
* CakePHP returns false if filesize is 0 at lib/cake/Utility/File.php:384
*/
public function checkEmpty($fileP = '/var/www/cydefsig/app/files/test') {
// Check if there were problems with the file upload
// only keep the last part of the filename, this should prevent directory attacks
$filename = basename($fileP);
$tmpfile = new File($fileP);
debug($fileP);
debug($tmpfile);
debug($tmpfile->size());
debug($tmpfile->md5());
debug(md5_file($fileP));
$md5 = !$tmpfile->size() ? md5_file($fileP) : $tmpfile->md5();
debug($md5);
}
/**
* generateAllFor<FieldName>
2012-12-18 17:44:07 +01:00
*
* @throws NotFoundException // TODO Exception
**/
public function generateAllFor($field) {
if (!self::_isSiteAdmin()) throw new NotFoundException();
// contain the newValue and oldValue
2012-12-18 17:44:07 +01:00
$methodArgs = $this->params['pass'];
// use call_user_func_array() to pass the newValue and oldValue
2012-12-18 17:44:07 +01:00
$success = call_user_func_array(array($this->{$this->defaultModel}, 'generateAllFor' . $field), $methodArgs);
// give feedback
$this->set('succes', $success);
$this->render('succes');
}
public function call($method, $dummySecond) {
$this->__call($method, $dummySecond);
}
2012-12-18 17:44:07 +01:00
public function __call($method, $dummySecond) {
$args = $this->params['pass']; // TODO this is naughty
if (strpos($method, 'generateAllFor') === 0) {
// massage the args
2012-12-18 17:44:07 +01:00
$methodArgs = $args;
$methodArgs[0] = str_replace('generateAllFor', '', $method); // TODO
//array_unshift($methodArgs, str_replace('generateAllFor', '', $method));
// do the actual call
2012-12-18 17:44:07 +01:00
return call_user_func_array(array($this, 'generateAllFor'), $methodArgs);
}
//if (strpos($method, 'findBy') === 0) {
// //debug(true);debug(tru);
//}
return false;
}
public function reportValidationIssuesEvents() {
// search for validation problems in the events
if (!self::_isSiteAdmin()) throw new NotFoundException();
print ("<h2>Listing invalid event validations</h2>");
$this->loadModel('Event');
2013-06-19 14:51:58 +02:00
// first remove executing some Behaviors because of Noud's crappy code
$this->Event->Behaviors->detach('Regexp');
// get all events..
2013-06-19 14:51:58 +02:00
$events = $this->Event->find('all', array('recursive' => -1));
// for all events..
foreach ($events as $event) {
$this->Event->set($event);
if ($this->Event->validates()) {
// validates
} else {
$errors = $this->Event->validationErrors;
print ("<h3>Validation errors for event: " . $event['Event']['id'] . "</h3><pre>");
print_r($errors);
print ("</pre><p>Event details:</p><pre>");
print_r($event);
print ("</pre><br/>");
}
}
}
public function reportValidationIssuesAttributes() {
2013-06-19 14:51:58 +02:00
// TODO improve performance of this function by eliminating the additional SQL query per attribute
// search for validation problems in the attributes
if (!self::_isSiteAdmin()) throw new NotFoundException();
print ("<h2>Listing invalid attribute validations</h2>");
$this->loadModel('Attribute');
2013-06-19 14:51:58 +02:00
// for efficiency reasons remove the unique requirement
$this->Attribute->validator()->remove('value', 'unique');
// get all attributes..
2013-06-19 14:51:58 +02:00
$attributes = $this->Attribute->find('all', array('recursive' => -1));
// for all attributes..
foreach ($attributes as $attribute) {
$this->Attribute->set($attribute);
if ($this->Attribute->validates()) {
// validates
} else {
$errors = $this->Attribute->validationErrors;
print ("<h3>Validation errors for attribute: " . $attribute['Attribute']['id'] . "</h3><pre>");
print_r($errors['value'][0]);
print ("</pre><p>Attribute details:</p><pre>");
print($attribute['Attribute']['event_id']."\n");
print($attribute['Attribute']['category']."\n");
print($attribute['Attribute']['type']."\n");
print($attribute['Attribute']['value']."\n");
print ("</pre><br/>");
}
}
}
}