Migration to CakePHP 2.1.

Most of the functionality migrated, Q&A review required.
pull/61/head
Christophe Vandeplas 2012-03-15 15:06:45 +01:00
parent 6da66f61b6
commit 865a24d0bd
161 changed files with 4999 additions and 4385 deletions

5
.gitignore vendored
View File

@ -1,6 +1,8 @@
/app/tmp
/plugins
/vendors
/lib
/build.properties
/build.xml
/.project
/.settings
/.buildpath
@ -10,3 +12,4 @@
/index.php
/README
/app/tmp/sessions/sess_*
/app/tmp/logs/*.log

View File

@ -2,4 +2,4 @@
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</IfModule>
</IfModule>

View File

@ -1,11 +1,12 @@
<?php
/*DbAcl schema generated on: 2007-11-24 15:11:13 : 1195945453*/
/**
* This is Acl Schema file
*
* Use it to configure database for ACL
*
* PHP versions 4 and 5
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
@ -15,11 +16,11 @@
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.app.config.sql
* @package app.Config.Schema
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/*
*
* Using the Schema command line utility
@ -28,16 +29,16 @@
*/
class DbAclSchema extends CakeSchema {
var $name = 'DbAcl';
public $name = 'DbAcl';
function before($event = array()) {
public function before($event = array()) {
return true;
}
function after($event = array()) {
public function after($event = array()) {
}
var $acos = array(
public $acos = array(
'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
'parent_id' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
'model' => array('type'=>'string', 'null' => true),
@ -48,7 +49,7 @@ class DbAclSchema extends CakeSchema {
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
);
var $aros = array(
public $aros = array(
'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
'parent_id' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
'model' => array('type'=>'string', 'null' => true),
@ -59,7 +60,7 @@ class DbAclSchema extends CakeSchema {
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
);
var $aros_acos = array(
public $aros_acos = array(
'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
'aro_id' => array('type'=>'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
'aco_id' => array('type'=>'integer', 'null' => false, 'length' => 10),

View File

@ -0,0 +1,40 @@
# $Id$
#
# Copyright 2005-2011, Cake Software Foundation, Inc.
#
# Licensed under The MIT License
# Redistributions of files must retain the above copyright notice.
# MIT License (http://www.opensource.org/licenses/mit-license.php)
CREATE TABLE acos (
id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INTEGER(10) DEFAULT NULL,
model VARCHAR(255) DEFAULT '',
foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
alias VARCHAR(255) DEFAULT '',
lft INTEGER(10) DEFAULT NULL,
rght INTEGER(10) DEFAULT NULL,
PRIMARY KEY (id)
);
CREATE TABLE aros_acos (
id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
aro_id INTEGER(10) UNSIGNED NOT NULL,
aco_id INTEGER(10) UNSIGNED NOT NULL,
_create CHAR(2) NOT NULL DEFAULT 0,
_read CHAR(2) NOT NULL DEFAULT 0,
_update CHAR(2) NOT NULL DEFAULT 0,
_delete CHAR(2) NOT NULL DEFAULT 0,
PRIMARY KEY(id)
);
CREATE TABLE aros (
id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INTEGER(10) DEFAULT NULL,
model VARCHAR(255) DEFAULT '',
foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
alias VARCHAR(255) DEFAULT '',
lft INTEGER(10) DEFAULT NULL,
rght INTEGER(10) DEFAULT NULL,
PRIMARY KEY (id)
);

View File

@ -1,11 +1,12 @@
<?php
/*i18n schema generated on: 2007-11-25 07:11:25 : 1196004805*/
/**
* This is i18n Schema file
*
* Use it to configure database for i18n
*
* PHP versions 4 and 5
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
@ -15,11 +16,11 @@
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.app.config.sql
* @package app.Config.Schema
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/*
*
* Using the Schema command line utility
@ -28,16 +29,16 @@
*/
class i18nSchema extends CakeSchema {
var $name = 'i18n';
public $name = 'i18n';
function before($event = array()) {
public function before($event = array()) {
return true;
}
function after($event = array()) {
public function after($event = array()) {
}
var $i18n = array(
public $i18n = array(
'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
'locale' => array('type'=>'string', 'null' => false, 'length' => 6, 'key' => 'index'),
'model' => array('type'=>'string', 'null' => false, 'key' => 'index'),

View File

@ -0,0 +1,26 @@
# $Id$
#
# Copyright 2005-2011, Cake Software Foundation, Inc.
#
# Licensed under The MIT License
# Redistributions of files must retain the above copyright notice.
# MIT License (http://www.opensource.org/licenses/mit-license.php)
CREATE TABLE i18n (
id int(10) NOT NULL auto_increment,
locale varchar(6) NOT NULL,
model varchar(255) NOT NULL,
foreign_key int(10) NOT NULL,
field varchar(255) NOT NULL,
content mediumtext,
PRIMARY KEY (id),
# UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field),
# INDEX I18N_LOCALE_ROW(locale, model, foreign_key),
# INDEX I18N_LOCALE_MODEL(locale, model),
# INDEX I18N_FIELD(model, foreign_key, field),
# INDEX I18N_ROW(model, foreign_key),
INDEX locale (locale),
INDEX model (model),
INDEX row_id (foreign_key),
INDEX field (field)
);

View File

@ -1,11 +1,12 @@
<?php
/*Sessions schema generated on: 2007-11-25 07:11:54 : 1196004714*/
/**
* This is Sessions Schema file
*
* Use it to configure database for Sessions
*
* PHP versions 4 and 5
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
@ -15,11 +16,11 @@
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.app.config.sql
* @package app.Config.Schema
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/*
*
* Using the Schema command line utility
@ -28,16 +29,16 @@
*/
class SessionsSchema extends CakeSchema {
var $name = 'Sessions';
public $name = 'Sessions';
function before($event = array()) {
public function before($event = array()) {
return true;
}
function after($event = array()) {
public function after($event = array()) {
}
var $cake_sessions = array(
public $cake_sessions = array(
'id' => array('type'=>'string', 'null' => false, 'key' => 'primary'),
'data' => array('type'=>'text', 'null' => true, 'default' => NULL),
'expires' => array('type'=>'integer', 'null' => true, 'default' => NULL),

View File

@ -0,0 +1,16 @@
# $Id$
#
# Copyright 2005-2011, Cake Software Foundation, Inc.
# 1785 E. Sahara Avenue, Suite 490-204
# Las Vegas, Nevada 89104
#
# Licensed under The MIT License
# Redistributions of files must retain the above copyright notice.
# MIT License (http://www.opensource.org/licenses/mit-license.php)
CREATE TABLE cake_sessions (
id varchar(255) NOT NULL default '',
data text,
expires int(11) default NULL,
PRIMARY KEY (id)
);

14
app/config/acl.ini.php → app/Config/acl.ini.php Executable file → Normal file
View File

@ -1,12 +1,11 @@
;<?php die() ?>
; SVN FILE: $Id$
;<?php exit() ?>
;/**
; * ACL configuration
; * ACL Configuration
; *
; *
; * PHP versions 4 and 5
; * PHP 5
; *
; * CakePHP(tm) : Rapid Development Framework http://cakephp.org
; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
; * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
; *
; * Licensed under The MIT License
@ -14,8 +13,7 @@
; *
; * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
; * @link http://cakephp.org CakePHP(tm) Project
; * @package cake
; * @subpackage cake.app.config
; * @package app.Config
; * @since CakePHP(tm) v 0.10.0.1076
; * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
; */
@ -67,4 +65,4 @@ allow = aco3, aco4
[groupname-goes-here]
deny = aco5, aco6
allow = aco7, aco8
allow = aco7, aco8

134
app/Config/acl.php Normal file
View File

@ -0,0 +1,134 @@
<?php
/**
* This is the PHP base ACL configuration file.
*
* Use it to configure access control of your Cake application.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 2.1
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Example
* -------
*
* Assumptions:
*
* 1. In your application you created a User model with the following properties:
* username, group_id, password, email, firstname, lastname and so on.
* 2. You configured AuthComponent to authorize actions via
* $this->Auth->authorize = array('Actions' => array('actionPath' => 'controllers/'),...)
*
* Now, when a user (i.e. jeff) authenticates successfully and requests a controller action (i.e. /invoices/delete)
* that is not allowed by default (e.g. via $this->Auth->allow('edit') in the Invoices controller) then AuthComponent
* will ask the configured ACL interface if access is granted. Under the assumptions 1. and 2. this will be
* done via a call to Acl->check() with
*
* array('User' => array('username' => 'jeff', 'group_id' => 4, ...))
*
* as ARO and
*
* '/controllers/invoices/delete'
*
* as ACO.
*
* If the configured map looks like
*
* $config['map'] = array(
* 'User' => 'User/username',
* 'Role' => 'User/group_id',
* );
*
* then PhpAcl will lookup if we defined a role like User/jeff. If that role is not found, PhpAcl will try to
* find a definition for Role/4. If the definition isn't found then a default role (Role/default) will be used to
* check rules for the given ACO. The search can be expanded by defining aliases in the alias configuration.
* E.g. if you want to use a more readable name than Role/4 in your definitions you can define an alias like
*
* $config['alias'] = array(
* 'Role/4' => 'Role/editor',
* );
*
* In the roles configuration you can define roles on the lhs and inherited roles on the rhs:
*
* $config['roles'] = array(
* 'Role/admin' => null,
* 'Role/accountant' => null,
* 'Role/editor' => null,
* 'Role/manager' => 'Role/editor, Role/accountant',
* 'User/jeff' => 'Role/manager',
* );
*
* In this example manager inherits all rules from editor and accountant. Role/admin doesn't inherit from any role.
* Lets define some rules:
*
* $config['rules'] = array(
* 'allow' => array(
* '*' => 'Role/admin',
* 'controllers/users/(dashboard|profile)' => 'Role/default',
* 'controllers/invoices/*' => 'Role/accountant',
* 'controllers/articles/*' => 'Role/editor',
* 'controllers/users/*' => 'Role/manager',
* 'controllers/invoices/delete' => 'Role/manager',
* ),
* 'deny' => array(
* 'controllers/invoices/delete' => 'Role/accountant, User/jeff',
* 'controllers/articles/(delete|publish)' => 'Role/editor',
* ),
* );
*
* Ok, so as jeff inherits from Role/manager he's matched every rule that references User/jeff, Role/manager,
* Role/editor, Role/accountant and Role/default. However, for jeff, rules for User/jeff are more specific than
* rules for Role/manager, rules for Role/manager are more specific than rules for Role/editor and so on.
* This is important when allow and deny rules match for a role. E.g. Role/accountant is allowed
* controllers/invoices/* but at the same time controllers/invoices/delete is denied. But there is a more
* specific rule defined for Role/manager which is allowed controllers/invoices/delete. However, the most specific
* rule denies access to the delete action explicitly for User/jeff, so he'll be denied access to the resource.
*
* If we would remove the role definition for User/jeff, then jeff would be granted access as he would be resolved
* to Role/manager and Role/manager has an allow rule.
*/
/**
* The role map defines how to resolve the user record from your application
* to the roles you defined in the roles configuration.
*/
$config['map'] = array(
'User' => 'User/username',
'Role' => 'User/group_id',
);
/**
* define aliases to map your model information to
* the roles defined in your role configuration.
*/
$config['alias'] = array(
'Role/4' => 'Role/editor',
);
/**
* role configuration
*/
$config['roles'] = array(
'Role/admin' => null,
);
/**
* rule configuration
*/
$config['rules'] = array(
'allow' => array(
'*' => 'Role/admin',
),
'deny' => array(),
);

139
app/Config/bootstrap.php Normal file
View File

@ -0,0 +1,139 @@
<?php
/**
* This file is loaded automatically by the app/webroot/index.php file after core.php
*
* This file should load/create any application wide configuration settings, such as
* Caching, Logging, loading additional configuration files.
*
* You should also use this file to include any files that provide global functions/constants
* that your application uses.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 0.10.8.2117
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Cache Engine Configuration
* Default settings provided below
*
* File storage engine.
*
* Cache::config('default', array(
* 'engine' => 'File', //[required]
* 'duration'=> 3600, //[optional]
* 'probability'=> 100, //[optional]
* 'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path
* 'prefix' => 'cake_', //[optional] prefix every cache file with this string
* 'lock' => false, //[optional] use file locking
* 'serialize' => true, // [optional]
* 'mask' => 0666, // [optional] permission mask to use when creating cache files
* ));
*
* APC (http://pecl.php.net/package/APC)
*
* Cache::config('default', array(
* 'engine' => 'Apc', //[required]
* 'duration'=> 3600, //[optional]
* 'probability'=> 100, //[optional]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
* ));
*
* Xcache (http://xcache.lighttpd.net/)
*
* Cache::config('default', array(
* 'engine' => 'Xcache', //[required]
* 'duration'=> 3600, //[optional]
* 'probability'=> 100, //[optional]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
* 'user' => 'user', //user from xcache.admin.user settings
* 'password' => 'password', //plaintext password (xcache.admin.pass)
* ));
*
* Memcache (http://memcached.org/)
*
* Cache::config('default', array(
* 'engine' => 'Memcache', //[required]
* 'duration'=> 3600, //[optional]
* 'probability'=> 100, //[optional]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
* 'servers' => array(
* '127.0.0.1:11211' // localhost, default port 11211
* ), //[optional]
* 'persistent' => true, // [optional] set this to false for non-persistent connections
* 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
* ));
*
* Wincache (http://php.net/wincache)
*
* Cache::config('default', array(
* 'engine' => 'Wincache', //[required]
* 'duration'=> 3600, //[optional]
* 'probability'=> 100, //[optional]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
* ));
*/
Cache::config('default', array('engine' => 'File'));
//Configure::write('CyDefSIG.baseurl', 'https://sig.cyber-defence.be');
Configure::write('CyDefSIG.baseurl', 'http://localhost:8888');
Configure::write('CyDefSIG.showorg', 'false'); // show the name of the organisation that uploaded the data
Configure::write('CyDefSIG.email', 'no-reply@sig.mil.be'); // email from for all the mails
Configure::write('GnuPG.onlyencrypted', 'true'); // only allow encrypted email, do not allow plaintext mails
Configure::write('GnuPG.email', 'no-reply@sig.mil.be');
Configure::write('GnuPG.password', 'ii3naxoK|o2a');
Configure::write('GnuPG.homedir', '/Users/chri/Documents/Work/Projects/201107-CyDefSIG/.gnupg/');
Configure::write('Recaptcha.publicKey', '6LdzJsYSAAAAAFCn4Ju7pnmKQ8yhiDbXT-b1eJtN');
Configure::write('Recaptcha.privateKey', '6LdzJsYSAAAAAD2IwnWwp16gIclZYVKynhsZEMZh');
/**
* The settings below can be used to set additional paths to models, views and controllers.
*
* App::build(array(
* 'Plugin' => array('/full/path/to/plugins/', '/next/full/path/to/plugins/'),
* 'Model' => array('/full/path/to/models/', '/next/full/path/to/models/'),
* 'View' => array('/full/path/to/views/', '/next/full/path/to/views/'),
* 'Controller' => array('/full/path/to/controllers/', '/next/full/path/to/controllers/'),
* 'Model/Datasource' => array('/full/path/to/datasources/', '/next/full/path/to/datasources/'),
* 'Model/Behavior' => array('/full/path/to/behaviors/', '/next/full/path/to/behaviors/'),
* 'Controller/Component' => array('/full/path/to/components/', '/next/full/path/to/components/'),
* 'View/Helper' => array('/full/path/to/helpers/', '/next/full/path/to/helpers/'),
* 'Vendor' => array('/full/path/to/vendors/', '/next/full/path/to/vendors/'),
* 'Console/Command' => array('/full/path/to/shells/', '/next/full/path/to/shells/'),
* 'Locale' => array('/full/path/to/locale/', '/next/full/path/to/locale/')
* ));
*
*/
/**
* Custom Inflector rules, can be set to correctly pluralize or singularize table, model, controller names or whatever other
* string is passed to the inflection functions
*
* Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
* Inflector::rules('plural', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
*
*/
/**
* Plugins need to be loaded manually, you can either load them one by one or all of them in a single call
* Uncomment one of the lines below, as you need. make sure you read the documentation on CakePlugin to use more
* advanced ways of loading plugins
*
* CakePlugin::loadAll(); // Loads all plugins at once
* CakePlugin::load('DebugKit'); //Loads a single plugin named DebugKit
*
*/

278
app/Config/core.php Normal file
View File

@ -0,0 +1,278 @@
<?php
/**
* This is core configuration file.
*
* Use it to configure core behavior of Cake.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* CakePHP Debug Level:
*
* Production Mode:
* 0: No error messages, errors, or warnings shown. Flash messages redirect.
*
* Development Mode:
* 1: Errors and warnings shown, model caches refreshed, flash messages halted.
* 2: As in 1, but also with full debug messages and SQL output.
*
* In production mode, flash messages redirect after a time interval.
* In development mode, you need to click the flash message to continue.
*/
Configure::write('debug', 2);
/**
* Configure the Error handler used to handle errors for your application. By default
* ErrorHandler::handleError() is used. It will display errors using Debugger, when debug > 0
* and log errors with CakeLog when debug = 0.
*
* Options:
*
* - `handler` - callback - The callback to handle errors. You can set this to any callback type,
* including anonymous functions.
* - `level` - int - The level of errors you are interested in capturing.
* - `trace` - boolean - Include stack traces for errors in log files.
*
* @see ErrorHandler for more information on error handling and configuration.
*/
Configure::write('Error', array(
'handler' => 'ErrorHandler::handleError',
'level' => E_ALL & ~E_DEPRECATED,
'trace' => true
));
/**
* Configure the Exception handler used for uncaught exceptions. By default,
* ErrorHandler::handleException() is used. It will display a HTML page for the exception, and
* while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0,
* framework errors will be coerced into generic HTTP errors.
*
* Options:
*
* - `handler` - callback - The callback to handle exceptions. You can set this to any callback type,
* including anonymous functions.
* - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you
* should place the file for that class in app/Lib/Error. This class needs to implement a render method.
* - `log` - boolean - Should Exceptions be logged?
*
* @see ErrorHandler for more information on exception handling and configuration.
*/
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'ExceptionRenderer',
'log' => true
));
/**
* Application wide charset encoding
*/
Configure::write('App.encoding', 'UTF-8');
/**
* To configure CakePHP *not* to use mod_rewrite and to
* use CakePHP pretty URLs, remove these .htaccess
* files:
*
* /.htaccess
* /app/.htaccess
* /app/webroot/.htaccess
*
* And uncomment the App.baseUrl below:
*/
//Configure::write('App.baseUrl', env('SCRIPT_NAME'));
/**
* Uncomment the define below to use CakePHP prefix routes.
*
* The value of the define determines the names of the routes
* and their associated controller actions:
*
* Set to an array of prefixes you want to use in your application. Use for
* admin or other prefixed routes.
*
* Routing.prefixes = array('admin', 'manager');
*
* Enables:
* `admin_index()` and `/admin/controller/index`
* `manager_index()` and `/manager/controller/index`
*
*/
Configure::write('Routing.prefixes', array('admin'));
/**
* Turn off all caching application-wide.
*
*/
Configure::write('Cache.disable', true);
/**
* Enable cache checking.
*
* If set to true, for view caching you must still use the controller
* public $cacheAction inside your controllers to define caching settings.
* You can either set it controller-wide by setting public $cacheAction = true,
* or in each action using $this->cacheAction = true.
*
*/
//Configure::write('Cache.check', true);
/**
* Defines the default error type when using the log() function. Used for
* differentiating error logging and debugging. Currently PHP supports LOG_DEBUG.
*/
define('LOG_ERROR', 2);
/**
* Session configuration.
*
* Contains an array of settings to use for session configuration. The defaults key is
* used to define a default preset to use for sessions, any settings declared here will override
* the settings of the default config.
*
* ## Options
*
* - `Session.cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'
* - `Session.timeout` - The number of minutes you want sessions to live for. This timeout is handled by CakePHP
* - `Session.cookieTimeout` - The number of minutes you want session cookies to live for.
* - `Session.checkAgent` - Do you want the user agent to be checked when starting sessions? You might want to set the
* value to false, when dealing with older versions of IE, Chrome Frame or certain web-browsing devices and AJAX
* - `Session.defaults` - The default configuration set to use as a basis for your session.
* There are four builtins: php, cake, cache, database.
* - `Session.handler` - Can be used to enable a custom session handler. Expects an array of of callables,
* that can be used with `session_save_handler`. Using this option will automatically add `session.save_handler`
* to the ini array.
* - `Session.autoRegenerate` - Enabling this setting, turns on automatic renewal of sessions, and
* sessionids that change frequently. See CakeSession::$requestCountdown.
* - `Session.ini` - An associative array of additional ini values to set.
*
* The built in defaults are:
*
* - 'php' - Uses settings defined in your php.ini.
* - 'cake' - Saves session files in CakePHP's /tmp directory.
* - 'database' - Uses CakePHP's database sessions.
* - 'cache' - Use the Cache class to save sessions.
*
* To define a custom session handler, save it at /app/Model/Datasource/Session/<name>.php.
* Make sure the class implements `CakeSessionHandlerInterface` and set Session.handler to <name>
*
* To use database sessions, run the app/Config/Schema/sessions.php schema using
* the cake shell command: cake schema create Sessions
*
*/
Configure::write('Session', array(
'defaults' => 'php'
));
/**
* The level of CakePHP security.
*/
Configure::write('Security.level', 'medium');
/**
* A random string used in security hashing methods.
*/
Configure::write('Security.salt', 'Rooraenietu8Eeyo<Qu2eeNfterd-dd+');
/**
* A random numeric string (digits only) used to encrypt/decrypt strings.
*/
Configure::write('Security.cipherSeed', '395786739573056621429506834955');
/**
* Apply timestamps with the last modified time to static assets (js, css, images).
* Will append a querystring parameter containing the time the file was modified. This is
* useful for invalidating browser caches.
*
* Set to `true` to apply timestamps when debug > 0. Set to 'force' to always enable
* timestamping regardless of debug value.
*/
//Configure::write('Asset.timestamp', true);
/**
* Compress CSS output by removing comments, whitespace, repeating tags, etc.
* This requires a/var/cache directory to be writable by the web server for caching.
* and /vendors/csspp/csspp.php
*
* To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use HtmlHelper::css().
*/
//Configure::write('Asset.filter.css', 'css.php');
/**
* Plug in your own custom JavaScript compressor by dropping a script in your webroot to handle the
* output, and setting the config below to the name of the script.
*
* To use, prefix your JavaScript link URLs with '/cjs/' instead of '/js/' or use JavaScriptHelper::link().
*/
//Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php');
/**
* The classname and database used in CakePHP's
* access control lists.
*/
Configure::write('Acl.classname', 'DbAcl');
Configure::write('Acl.database', 'default');
/**
* Uncomment this line and correct your server timezone to fix
* any date & time related errors.
*/
//date_default_timezone_set('UTC');
/**
* Pick the caching engine to use. If APC is enabled use it.
* If running via cli - apc is disabled by default. ensure it's available and enabled in this case
*
* Note: 'default' and other application caches should be configured in app/Config/bootstrap.php.
* Please check the comments in boostrap.php for more info on the cache engines available
* and their setttings.
*/
$engine = 'File';
if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) {
$engine = 'Apc';
}
// In development mode, caches should expire quickly.
$duration = '+999 days';
if (Configure::read('debug') >= 1) {
$duration = '+10 seconds';
}
// Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts.
$prefix = 'myapp_';
/**
* Configure the cache used for general framework caching. Path information,
* object listings, and translation cache files are stored with this configuration.
*/
Cache::config('_cake_core_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_core_',
'path' => CACHE . 'persistent' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration
));
/**
* Configure the cache for model and datasource caches. This cache configuration
* is used to store schema descriptions, and table listings in connections.
*/
Cache::config('_cake_model_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_model_',
'path' => CACHE . 'models' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration
));

17
app/Config/database.php Normal file
View File

@ -0,0 +1,17 @@
<?php
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => '127.0.0.1',
'login' => 'cyberdefence',
'port' => 8889,
'password' => 'PhwaxFJbNhnRGfZ8',
'database' => 'cyberdefence_sig',
'prefix' => '',
//'encoding' => 'utf8',
);
}

12
app/Config/email.php Normal file
View File

@ -0,0 +1,12 @@
<?php
class EmailConfig {
public $default = array(
'transport' => 'Mail',
//'from' => 'you@localhost',
'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
);
}

27
app/config/routes.php → app/Config/routes.php Executable file → Normal file
View File

@ -6,30 +6,35 @@
* Routes are very important mechanism that allows you to freely connect
* different urls to chosen controllers and their actions (functions).
*
* PHP versions 4 and 5
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.app.config
* @package app.Config
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Here, we are connecting '/' (base path) to controller called 'Pages',
* its action called 'display', and we pass a param to select the view file
* to use (in this case, /app/views/pages/home.ctp)...
* to use (in this case, /app/View/Pages/home.ctp)...
*/
// Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
/**
* ...and connect the rest of 'Pages' controller's urls.
*/
// Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/', array('controller' => 'events', 'action' => 'index'));
Router::connect('/', array('controller' => 'events', 'action' => 'index'));
/**
* Load all plugin routes. See the CakePlugin documentation on
* how to customize the loading of plugin routes.
*/
CakePlugin::routes();
/**
* Load the CakePHP default routes. Remove this if you do not want to use
* the built-in default routes.
*/
require CAKE . 'Config' . DS . 'routes.php';

View File

@ -0,0 +1,31 @@
<?php
/**
* AppShell file
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('Shell', 'Console');
/**
* Application Shell
*
* Add your application-wide methods in the class below, your shells
* will inherit them.
*
* @package app.Console.Command
*/
class AppShell extends Shell {
}

View File

0
app/libs/empty → app/Console/Templates/empty Executable file → Normal file
View File

33
app/Console/cake Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
################################################################################
#
# Bake is a shell script for running CakePHP bake script
# PHP 5
#
# CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
# Copyright 2005-2011, Cake Software Foundation, Inc.
#
# Licensed under The MIT License
# Redistributions of files must retain the above copyright notice.
#
# @copyright Copyright 2005-2011, Cake Software Foundation, Inc.
# @link http://cakephp.org CakePHP(tm) Project
# @package app.Console
# @since CakePHP(tm) v 2.0
# @license MIT License (http://www.opensource.org/licenses/mit-license.php)
#
################################################################################
LIB=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && LIB=$LIB/$(basename -- "$0")
while [ -h "$LIB" ]; do
DIR=$(dirname -- "$LIB")
SYM=$(readlink "$LIB")
LIB=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
done
LIB=$(dirname -- "$LIB")/
APP=`pwd`
exec php -q "$LIB"cake.php -working "$APP" "$@"
exit;

32
app/Console/cake.bat Normal file
View File

@ -0,0 +1,32 @@
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: Bake is a shell script for running CakePHP bake script
:: PHP 5
::
:: CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
:: Copyright 2005-2011, Cake Software Foundation, Inc.
::
:: Licensed under The MIT License
:: Redistributions of files must retain the above copyright notice.
::
:: @copyright Copyright 2005-2011, Cake Software Foundation, Inc.
:: @link http://cakephp.org CakePHP(tm) Project
:: @package app.Console
:: @since CakePHP(tm) v 2.0
:: @license MIT License (http://www.opensource.org/licenses/mit-license.php)
::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: In order for this script to work as intended, the cake\console\ folder must be in your PATH
@echo.
@echo off
SET app=%0
SET lib=%~dp0
php -q "%lib%cake.php" -working "%CD% " %*
echo.
exit /B %ERRORLEVEL%

33
app/Console/cake.php Normal file
View File

@ -0,0 +1,33 @@
#!/usr/bin/php -q
<?php
/**
* Command-line code generation utility to automate programmer chores.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc.
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Console
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
$ds = DIRECTORY_SEPARATOR;
$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php';
if (function_exists('ini_set')) {
$root = dirname(dirname(dirname(__FILE__)));
ini_set('include_path', $root . $ds. 'lib' . PATH_SEPARATOR . ini_get('include_path'));
}
if (!include($dispatcher)) {
trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
}
unset($paths, $path, $dispatcher, $root, $ds);
return ShellDispatcher::run($argv);

View File

@ -0,0 +1,107 @@
<?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-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, 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)
*/
App::uses('Controller', 'Controller');
App::uses('Sanitize', '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
*/
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email')
)
),
'loginRedirect' => array('controller' => 'users', 'action' => 'routeafterlogin'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
'authorize' => array('Controller') // Added this line
)
);
public function isAuthorized($user) {
if (isset($user['org']) && $user['org'] === 'admin') {
return true; // admin can access every action
}
elseif ($this->Auth->loggedIn()) {
return true; // logged users
}
return false; // The rest don't
}
function beforeFilter() {
}
/**
* Convert an array to the same array but with the values also as index instead of an interface_exists
*/
function _arrayToValuesIndexArray($old_array) {
$new_array = Array();
foreach ($old_array as $value)
$new_array[$value] = $value;
return $new_array;
}
/**
* checks if the currently logged user is an administrator
*/
public function _isAdmin() {
$user = $this->Auth->user();
if (isset($user['org']) && $user['org'] === 'admin') {
return true;
}
return false;
}
/**
* Refreshes the Auth session with new/updated data
* @return void
*/
function _refreshAuth() {
if (isset($this->User)) {
$user = $this->User->read(false, $this->Auth->user('id'));
} else {
$user= ClassRegistry::init('User')->findById($this->Auth->user('id'));
}
$this->Auth->login($user['User']);
}
}

View File

View File

@ -0,0 +1,808 @@
<?php
App::uses('AppController', 'Controller');
App::uses('Xml', 'Utility');
/**
* Events Controller
*
* @property Event $Event
*/
class EventsController extends AppController {
/**
* Components
*
* @var array
*/
public $components = array('Security', 'Email');
public $paginate = array(
'limit' => 50,
'order' => array(
'Event.date' => 'DESC'
)
);
function beforeFilter() {
$this->Auth->allow('xml');
$this->Auth->allow('nids');
$this->Auth->allow('text');
// These variables are required for every view
$this->set('me', $this->Auth->user());
$this->set('isAdmin', $this->_isAdmin());
}
/**
* index method
*
* @return void
*/
function index() {
// list the events
$this->Event->recursive = 0;
$this->set('events', $this->paginate());
if (!$this->Auth->user('gpgkey')) {
$this->Session->setFlash('No GPG key set in your profile. To receive emails, submit your public key in your profile.');
}
}
/**
* view method
*
* @param string $id
* @return void
*/
public function view($id = null) {
$this->Event->id = $id;
if (!$this->Event->exists()) {
throw new NotFoundException(__('Invalid event'));
}
$this->set('event', $this->Event->read(null, $id));
$this->set('relatedEvents', $this->Event->getRelatedEvents());
$related_signatures = array();
$this->loadModel('Signature');
foreach ($this->Event->data['Signature'] as $signature) {
$related_signatures[$signature['id']] = $this->Signature->getRelatedSignatures($signature);
}
$this->set('relatedSignatures', $related_signatures);
}
/**
* add method
*
* @return void
*/
public function add() {
if ($this->request->is('post')) {
// force check userid and orgname to be from yourself
$this->request->data['Event']['user_id'] = $this->Auth->user('id');
$this->request->data['Event']['org'] = $this->Auth->user('org');
$this->Event->create();
if ($this->Event->save($this->request->data)) {
$this->Session->setFlash(__('The event has been saved'));
$this->redirect(array('action' => 'view', $this->Event->getId()));
} else {
$this->Session->setFlash(__('The event could not be saved. Please, try again.'), 'default', array(), 'error');
}
}
// combobox for risks
$risks = $this->Event->validate['risk']['rule'][1];
$risks = $this->_arrayToValuesIndexArray($risks);
$this->set('risks',compact('risks'));
}
/**
* edit method
*
* @param string $id
* @return void
*/
public function edit($id = null) {
$this->Event->id = $id;
if (!$this->Event->exists()) {
throw new NotFoundException(__('Invalid event'));
}
// only edit own events
$old_event = $this->Event->read(null, $id);
if (!$this->_isAdmin() && $this->Auth->user('org') != $old_event['Event']['org']) {
throw new UnauthorizedException('You are only allowed to edit events of your own organisation.');
}
if ($this->request->is('post') || $this->request->is('put')) {
// always force the user and org, but do not force it for admins
if (!$this->_isAdmin()) {
$this->request->data['Event']['user_id'] = $this->Auth->user('id');
$this->request->data['Event']['org'] = $this->Auth->user('org');
} else {
$this->request->data['Event']['user_id'] = $old_event['Event']['id'];
$this->request->data['Event']['org'] = $old_event['Event']['org'];
}
// we probably also want to remove the alerted flag
$this->request->data['Event']['alerted'] = 0;
// say what fields are to be updated
$fieldList=array('user_id', 'org', 'date', 'risk', 'info', 'alerted');
if ($this->Event->save($this->request->data, true, $fieldList)) {
$this->Session->setFlash(__('The event has been saved'));
$this->redirect(array('action' => 'view', $id));
} else {
$this->Session->setFlash(__('The event could not be saved. Please, try again.'));
}
} else {
$this->request->data = $this->Event->read(null, $id);
}
// combobox for types
$risks = $this->Event->validate['risk']['rule'][1];
$risks = $this->_arrayToValuesIndexArray($risks);
$this->set('risks',compact('risks'));
}
/**
* delete method
*
* @param string $id
* @return void
*/
public function delete($id = null) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->Event->id = $id;
if (!$this->Event->exists()) {
throw new NotFoundException(__('Invalid event'));
}
// only edit own events
$this->Event->read();
if (!$this->_isAdmin() && $this->Auth->user('org') != $this->Event->data['Event']['org']) {
throw new UnauthorizedException('You are only allowed to edit your own events.');
}
if ($this->Event->delete()) {
$this->Session->setFlash(__('Event deleted'));
$this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Event was not deleted'));
$this->redirect(array('action' => 'index'));
}
/**
* Send out an alert email to all the users that wanted to be notified.
* Users with a GPG key will get the mail encrypted, other users will get the mail unencrypted
*/
function alert($id = null) {
$this->Event->id = $id;
if (!$this->Event->exists()) {
throw new NotFoundException(__('Invalid event'));
}
// only allow form submit CSRF protection.
if ($this->request->is('post') || $this->request->is('put')) {
// only allow alert for own events or admins
$this->Event->id = $id;
$this->Event->read();
if (!$this->_isAdmin() && $this->Auth->user('org') != $this->Event->data['Event']['org']) {
throw new UnauthorizedException('You are only allowed to finish events of your own organisation.');
}
// fetch the event and build the body
if (1 == $this->Event->data['Event']['alerted']) {
$this->Session->setFlash(__('Everyone has already been alerted for this event. To alert again, first edit this event.', true), 'default', array(), 'error');
$this->redirect(array('action' => 'view', $id));
}
// The mail body, Sanitize::html() is NOT needed as we are sending plain-text mails.
$body = "";
$appendlen = 20;
$body .= 'URL : '.Configure::read('CyDefSIG.baseurl').'/events/view/'.$this->Event->data['Event']['id']."\n";
$body .= 'Event : '.$this->Event->data['Event']['id']."\n";
$body .= 'Date : '.$this->Event->data['Event']['date']."\n";
if ('true' == Configure::read('CyDefSIG.showorg')) {
$body .= 'Reported by : '.$this->Event->data['Event']['org']."\n";
}
$body .= 'Risk : '.$this->Event->data['Event']['risk']."\n";
$relatedEvents = $this->Event->getRelatedEvents($id);
if (!empty($relatedEvents)) {
foreach ($relatedEvents as $relatedEvent){
$body .= 'Related to : '.Configure::read('CyDefSIG.baseurl').'/events/view/'.$relatedEvent['Event']['id'].' ('.$relatedEvent['Event']['date'].')'."\n" ;
}
}
$body .= 'Info : '."\n";
$body .= $this->Event->data['Event']['info']."\n";
$body .= "\n";
$body .= 'Signatures :'."\n";
$body_temp_other = "";
if (isset($this->Event->data['Signature'])) {
foreach ($this->Event->data['Signature'] as $signature){
$line = '- '.$signature['type'].str_repeat(' ', $appendlen - 2 - strlen( $signature['type'])).': '.$signature['value']."\n";
if ('other' == $signature['type']) // append the 'other' signature types to the bottom.
$body_temp_other .= $line;
else $body .= $line;
}
}
$body .= "\n";
$body .= $body_temp_other; // append the 'other' signature types to the bottom.
// sign the body
require_once 'Crypt/GPG.php';
$gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir')));
$gpg->addSignKey(Configure::read('GnuPG.email'), Configure::read('GnuPG.password'));
$body_signed = $gpg->sign($body, Crypt_GPG::SIGN_MODE_CLEAR);
$this->loadModel('User');
//
// Build a list of the recipients that get a non-encrypted mail
// But only do this if it is allowed in the bootstrap.php file.
//
if ('false' == Configure::read('GnuPG.onlyencrypted')) {
$alert_users = $this->User->find('all', array(
'conditions' => array('User.autoalert' => 1,
'User.gpgkey =' => ""),
'recursive' => 0,
) );
$alert_emails = Array();
foreach ($alert_users as $user) {
$alert_emails[] = $user['User']['email'];
}
// prepare the the unencrypted email
$this->Email->from = Configure::read('CyDefSIG.email');
//$this->Email->to = "CyDefSIG <sig@cyber-defence.be>"; TODO check if it doesn't break things to not set a to , like being spammed away
$this->Email->bcc = $alert_emails;
$this->Email->subject = "[CyDefSIG] Event ".$id." - ".$this->Event->data['Event']['risk']." - TLP Amber";
$this->Email->template = 'body';
$this->Email->sendAs = 'text'; // both text or html
$this->set('body', $body_signed);
// send it
$this->Email->send();
// If you wish to send multiple emails using a loop, you'll need
// to reset the email fields using the reset method of the Email component.
$this->Email->reset();
}
//
// Build a list of the recipients that wish to receive encrypted mails.
//
$alert_users = $this->User->find('all', array(
'conditions' => array( 'User.autoalert' => 1,
'User.gpgkey !=' => ""),
'recursive' => 0,
)
);
// encrypt the mail for each user and send it separately
foreach ($alert_users as $user) {
// send the email
$this->Email->from = Configure::read('CyDefSIG.email');
$this->Email->to = $user['User']['email'];
$this->Email->subject = "[CyDefSIG] Event ".$id." - ".$this->Event->data['Event']['risk']." - TLP Amber";
$this->Email->template = 'body';
$this->Email->sendAs = 'text'; // both text or html
// import the key of the user into the keyring
// this is not really necessary, but it enables us to find
// the correct key-id even if it is not the same as the emailaddress
$key_import_output = $gpg->importKey($user['User']['gpgkey']);
// say what key should be used to encrypt
$gpg = new Crypt_GPG();
$gpg->addEncryptKey($key_import_output['fingerprint']); // use the key that was given in the import
$body_enc_sig = $gpg->encrypt($body_signed, true);
$this->set('body', $body_enc_sig);
$this->Email->send();
// If you wish to send multiple emails using a loop, you'll need
// to reset the email fields using the reset method of the Email component.
$this->Email->reset();
}
// update the DB to set the alerted flag
$this->Event->saveField('alerted', 1);
// redirect to the view event page
$this->Session->setFlash(__('Email sent to all participants.', true));
$this->redirect(array('action' => 'view', $id));
}
}
/**
* Send out an contact email to the person who posted the event.
* Users with a GPG key will get the mail encrypted, other users will get the mail unencrypted
* @todo allow the user to enter a comment in the contact email.
*/
public function contact($id = null) {
$this->Event->id = $id;
if (!$this->Event->exists()) {
throw new NotFoundException(__('Invalid event'));
}
// User has filled in his contact form, send out the email.
if ($this->request->is('post') || $this->request->is('put')) {
$message = $this->request->data['Event']['message'];
if ($this->_sendContactEmail($id, $message)) {
// redirect to the view event page
$this->Session->setFlash(__('Email sent to the reporter.', true));
} else {
$this->Session->setFlash(__('Sending of email failed', true), 'default', array(), 'error');
}
$this->redirect(array('action' => 'view', $id));
}
// User didn't see the contact form yet. Present it to him.
if (empty($this->data)) {
$this->data = $this->Event->read(null, $id);
}
}
/**
*
* Sends out an email with the request to be contacted about a specific event.
* @todo move _sendContactEmail($id, $message) to a better place. (components?)
*
* @param unknown_type $id The id of the event for wich you want to contact the person.
* @param unknown_type $message The custom message that will be appended to the email.
* @return True if success, False if error
*/
private function _sendContactEmail($id, $message) {
// fetch the event
$event = $this->Event->read(null, $id);
$reporter = $event['User']; // email, gpgkey
// The mail body, Sanitize::html() is NOT needed as we are sending plain-text mails.
$body = "";
$body .="Hello, \n";
$body .="\n";
$body .="Someone wants to get in touch with you concerning a CyDefSIG event. \n";
$body .="\n";
$body .="You can reach him at ".$this->Auth->user('email')."\n";
if (!$this->Auth->user('gpgkey'))
$body .="His GPG/PGP key is added as attachment to this email. \n";
$body .="\n";
$body .="He wrote the following message: \n";
$body .=$message."\n";
$body .="\n";
$body .="\n";
$body .="The event is the following: \n";
// print the event in mail-format
// LATER place event-to-email-layout in a function
$appendlen = 20;
$body .= 'URL : '.Configure::read('CyDefSIG.baseurl').'/events/view/'.$event['Event']['id']."\n";
$body .= 'Event : '.$event['Event']['id']."\n";
$body .= 'Date : '.$event['Event']['date']."\n";
if ('true' == Configure::read('CyDefSIG.showorg')) {
$body .= 'Reported by : '.$event['Event']['org']."\n";
}
$body .= 'Risk : '.$event['Event']['risk']."\n";
$relatedEvents = $this->Event->getRelatedEvents($id);
if (!empty($relatedEvents)) {
foreach ($relatedEvents as $relatedEvent){
$body .= 'Related to : '.Configure::read('CyDefSIG.baseurl').'/events/view/'.$relatedEvent['Event']['id'].' ('.$relatedEvent['Event']['date'].')'."\n" ;
}
}
$body .= 'Info : '."\n";
$body .= $event['Event']['info']."\n";
$body .= "\n";
$body .= 'Signatures :'."\n";
$body_temp_other = "";
if (!empty($event['Signature'])) {
foreach ($event['Signature'] as $signature){
$line = '- '.$signature['type'].str_repeat(' ', $appendlen - 2 - strlen( $signature['type'])).': '.$signature['value']."\n";
if ('other' == $signature['type']) // append the 'other' signature types to the bottom.
$body_temp_other .= $line;
else $body .= $line;
}
}
$body .= "\n";
$body .= $body_temp_other; // append the 'other' signature types to the bottom.
// sign the body
require_once 'Crypt/GPG.php';
$gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir')));
$gpg->addSignKey(Configure::read('GnuPG.email'), Configure::read('GnuPG.password'));
$body_signed = $gpg->sign($body, Crypt_GPG::SIGN_MODE_CLEAR);
if (!empty($reporter['gpgkey'])) {
// import the key of the user into the keyring
// this isn't really necessary, but it gives it the fingerprint necessary for the next step
$key_import_output = $gpg->importKey($reporter['gpgkey']);
// say what key should be used to encrypt
$gpg = new Crypt_GPG();
$gpg->addEncryptKey($key_import_output['fingerprint']); // use the key that was given in the import
$body_enc_sig = $gpg->encrypt($body_signed, true);
} else {
$body_enc_sig = $body_signed;
// FIXME should I allow sending unencrypted "contact" mails to people if they didn't import they GPG key?
}
// prepare the email
$this->Email->from = Configure::read('CyDefSIG.email');
$this->Email->to = $reporter['email'];
$this->Email->subject = "[CyDefSIG] Need info about event ".$id." - TLP Amber";
//$this->Email->delivery = 'debug'; // do not really send out mails, only display it on the screen
$this->Email->template = 'body';
$this->Email->sendAs = 'text'; // both text or html
$this->set('body', $body_enc_sig);
// Add the GPG key of the user as attachment
// LATER sign the attached GPG key
if (!empty($me_user['gpgkey'])) {
// save the gpg key to a temporary file
$tmpfname = tempnam(TMP, "GPGkey");
$handle = fopen($tmpfname, "w");
fwrite($handle, $me_user['gpgkey']);
fclose($handle);
// attach it
$this->Email->attachments = array(
'gpgkey.asc' => $tmpfname
);
}
// send it
$result = $this->Email->send();
// remove the temporary gpg file
if (!empty($me_user['gpgkey']))
unlink($tmpfname);
return $result;
}
public function export() {
// Simply display a static view
// generate the list of signature types
$this->loadModel('Signature');
$this->set('sig_types', $this->Signature->validate['type']['rule'][1]);
}
public function xml($key) {
// FIXME implement XML output
// check if the key is valid -> search for users based on key
$this->loadModel('User');
// no input sanitization necessary, it's done by model
$user = $this->User->findByAuthkey($key);
if (empty($user)) {
throw new UnauthorizedException('Incorrect authentication key');
}
// display the full xml
$this->header('Content-Type: text/xml'); // set the content type
$this->layout = 'xml/default';
// $this->header('Content-Disposition: attachment; filename="cydefsig.xml"');
$conditions = array("Event.alerted" => 1);
$fields = array('Event.id', 'Event.date', 'Event.risk', 'Event.info');
if ('true' == Configure::read('CyDefSIG.showorg')) {
$fields[] = 'Event.org';
}
// $this->Event->Behaviors->attach('Containable');
// $contain = array('Signature.id', 'Signature.type', 'Signature.value', 'Signature.to_snort');
$params = array('conditions' => $conditions,
'recursive' => 1,
'fields' => $fields,
// 'contain' => $contain
);
$results = $this->Event->find('all', $params);
/* $xml = Xml::build('<?xml version="1.0" encoding="UTF-8" ?><CyDefSIG></CyDefSIG>'); */
$myXmlOriginal = '<?xml version="1.0"?><root><child>value</child></root>';
$xml = Xml::build($myXmlOriginal);
$xml->root->addChild('young', 'new value');
// foreach ($results as $result) {
// debug($result);
// $xml->CyDefSIG->addChild('f', 'b');
// debug($xml);
// }
// debug($results);
// $xml= Xml::fromArray(array('event' =>$results), array('format' => 'tags', 'return' => 'domdocument'));
// debug($xml->saveXML());
}
public function nids($key) {
// check if the key is valid -> search for users based on key
$this->loadModel('User');
// no input sanitization necessary, it's done by model
$user = $this->User->findByAuthkey($key);
if (empty($user)) {
throw new UnauthorizedException('Incorrect authentication key');
}
// display the full snort rulebase
$this->header('Content-Type: text/plain'); // set the content type
$this->header('Content-Disposition: attachment; filename="cydefsig.rules"');
$this->layout = 'text/default';
$rules= array();
// find events that are finished
$events = $this->Event->findAllByAlerted(1);
$classtype = 'targeted-attack';
foreach ($events as $event) {
# proto src_ip src_port direction dst_ip dst_port msg rule_content tag sid rev
$rule_format_msg = 'msg: "CyDefSIG %s, Event '.$event['Event']['id'].', '.$event['Event']['risk'].'"';
$rule_format_reference = 'reference:url,'.Configure::read('CyDefSIG.baseurl').'/events/view/'.$event['Event']['id'];
$rule_format = 'alert %s %s %s %s %s %s ('.$rule_format_msg.'; %s %s classtype:'.$classtype.'; sid:%d; rev:%d; '.$rule_format_reference.';) ';
$sid = $user['User']['nids_sid']+($event['Event']['id']*100); // LATER this will cause issues with events containing more than 99 signatures
//debug($event);
foreach ($event['Signature'] as $signature) {
if (0 == $signature['to_ids']) continue; // signature is not to be exported to IDS. // LATER filter out to_ids=0 in the query
$sid++;
switch ($signature['type']) {
// LATER test all the snort signatures
// LATER add the tag keyword in the rules to capture network traffic
// LATER sanitize every $signature['value'] to not conflict with snort
case 'ip-dst':
$rules[] = sprintf($rule_format,
'ip', // proto
'$HOME_NET', // src_ip
'any', // src_port
'->', // direction
$signature['value'], // dst_ip
'any', // dst_port
'Outgoing To Bad IP', // msg
'', // rule_content
'', // tag
$sid, // sid
1 // rev
);
break;
case 'ip-src':
$rules[] = sprintf($rule_format,
'ip', // proto
$signature['value'], // src_ip
'any', // src_port
'->', // direction
'$HOME_NET', // dst_ip
'any', // dst_port
'Incoming From Bad IP', // msg
'', // rule_content
'', // tag
$sid, // sid
1 // rev
);
break;
case 'email-src':
$rules[] = sprintf($rule_format,
'tcp', // proto
'$EXTERNAL_NET', // src_ip
'any', // src_port
'<>', // direction
'$SMTP_SERVERS', // dst_ip
'25', // dst_port
'Bad Source Email Address', // msg
'flow:established,to_server; content:"MAIL FROM|3a|"; nocase; content:"'.$signature['value'].'"; nocase;', // rule_content
'tag:session,600,seconds;', // tag
$sid, // sid
1 // rev
);
break;
case 'email-dst':
$rules[] = sprintf($rule_format,
'tcp', // proto
'$EXTERNAL_NET', // src_ip
'any', // src_port
'<>', // direction
'$SMTP_SERVERS', // dst_ip
'25', // dst_port
'Bad Destination Email Address',// msg
'flow:established,to_server; content:"RCPT TO|3a|"; nocase; content:"'.$signature['value'].'"; nocase;', // rule_content
'tag:session,600,seconds;', // tag
$sid, // sid
1 // rev
);
break;
case 'email-subject':
// LATER email-subject rule might not match because of line-wrapping
$rules[] = sprintf($rule_format,
'tcp', // proto
'$EXTERNAL_NET', // src_ip
'any', // src_port
'<>', // direction
'$SMTP_SERVERS', // dst_ip
'25', // dst_port
'Bad Email Subject', // msg
'flow:established,to_server; content:"Subject|3a|"; nocase; content:"'.$signature['value'].'"; nocase;', // rule_content
'tag:session,600,seconds;', // tag
$sid, // sid
1 // rev
);
break;
case 'email-attachment':
// LATER email-attachment rule might not match because of line-wrapping
$rules[] = sprintf($rule_format,
'tcp', // proto
'$EXTERNAL_NET', // src_ip
'any', // src_port
'<>', // direction
'$SMTP_SERVERS', // dst_ip
'25', // dst_port
'Bad Email Attachment', // msg
'flow:established,to_server; content:"Content-Disposition: attachment|3b| filename=|22|"; content:"'.$signature['value'].'|22|";', // rule_content // LATER test and finetune this snort rule https://secure.wikimedia.org/wikipedia/en/wiki/MIME#Content-Disposition
'tag:session,600,seconds;', // tag
$sid, // sid
1 // rev
);
break;
case 'domain':
$rules[] = sprintf($rule_format,
'udp', // proto
'any', // src_ip
'any', // src_port
'->', // direction
'any', // dst_ip
'53', // dst_port
'Lookup Of Bad Domain', // msg
'content:"'.$this->_dnsNameToRawFormat($signature['value']).'"; nocase;', // rule_content
'', // tag
$sid, // sid
1 // rev
);
$sid++;
$rules[] = sprintf($rule_format,
'tcp', // proto
'any', // src_ip
'any', // src_port
'->', // direction
'any', // dst_ip
'53', // dst_port
'Lookup Of Bad Domain', // msg
'content:"'.$this->_dnsNameToRawFormat($signature['value']).'"; nocase;', // rule_content
'', // tag
$sid, // sid
1 // rev
);
$sid++;
//break; // domain should also detect the domain name in a url
case 'url':
$rules[] = sprintf($rule_format,
'tcp', // proto
'$HOME_NET', // src_ip
'any', // src_port
'->', // direction
'$EXTERNAL_NET', // dst_ip
'$HTTP_PORTS', // dst_port
'Outgoing Bad HTTP URL', // msg
'flow:to_server,established; uricontent:"'.$signature['value'].'"; nocase;', // rule_content
'tag:session,600,seconds;', // tag
$sid, // sid
1 // rev
);
break;
case 'user-agent':
$rules[] = "";
// TODO write snort user-agent rule
break;
case 'snort':
$tmp_rule = $signature['value'];
// rebuild the rule by overwriting the different keywords using preg_replace()
// sid - '/sid\s*:\s*[0-9]+\s*;/'
// rev - '/rev\s*:\s*[0-9]+\s*;/'
// classtype - '/classtype:[a-zA-Z_-]+;/'
// msg - '/msg\s*:\s*".*"\s*;/'
// reference - '/reference\s*:\s*.+;/'
$replace_count=array();
$tmp_rule = preg_replace('/sid\s*:\s*[0-9]+\s*;/', 'sid:'.$sid.';', $tmp_rule, -1, $replace_count['sid']);
if (null == $tmp_rule ) break; // don't output the rule on error with the regex
$tmp_rule = preg_replace('/rev\s*:\s*[0-9]+\s*;/', 'rev:1;', $tmp_rule, -1, $replace_count['rev']);
if (null == $tmp_rule ) break; // don't output the rule on error with the regex
$tmp_rule = preg_replace('/classtype:[a-zA-Z_-]+;/', 'classtype:'.$classtype.';', $tmp_rule, -1, $replace_count['classtype']);
if (null == $tmp_rule ) break; // don't output the rule on error with the regex
$tmp_message = sprintf($rule_format_msg, 'snort-rule');
$tmp_rule = preg_replace('/msg\s*:\s*".*"\s*;/', $tmp_message.';', $tmp_rule, -1, $replace_count['msg']);
if (null == $tmp_rule ) break; // don't output the rule on error with the regex
$tmp_rule = preg_replace('/reference\s*:\s*.+;/', $rule_format_reference.';', $tmp_rule, -1, $replace_count['reference']);
if (null == $tmp_rule ) break; // don't output the rule on error with the regex
// some values were not replaced, so we need to add them ourselves, and insert them in the rule
$extra_for_rule="";
if (0 == $replace_count['sid']) {
$extra_for_rule .= 'sid:'.$sid.';';
} if (0 == $replace_count['rev']) {
$extra_for_rule .= 'rev:1;';
} if (0 == $replace_count['classtype']) {
$extra_for_rule .= 'classtype:'.$classtype.';';
} if (0 == $replace_count['msg']) {
$extra_for_rule .= $tmp_message.';';
} if (0 == $replace_count['reference']) {
$extra_for_rule .= $rule_format_reference.';';
}
$tmp_rule = preg_replace('/;\s*\)/', '; '.$extra_for_rule.')', $tmp_rule);
// finally the rule is cleaned up and can be outputed
$rules[] = $tmp_rule;
// TODO test using lots of snort rules.
default:
break;
}
}
}
print ("#<h1>This part is not finished and might be buggy. Please report any issues.</h1>\n");
print "#<pre> \n";
foreach ($rules as $rule)
print $rule."\n";
print "#</pre>\n";
$this->set('rules', $rules);
}
public function text($key, $type="") {
// check if the key is valid -> search for users based on key
$this->loadModel('User');
// no input sanitization necessary, it's done by model
$user = $this->User->findByAuthkey($key);
if (empty($user)) {
throw new UnauthorizedException('Incorrect authentication key');
}
$this->header('Content-Type: text/plain'); // set the content type
$this->layout = 'text/default';
$this->loadModel('Signature');
$params = array(
'conditions' => array('Signature.type' => $type), //array of conditions
'recursive' => 0, //int
'fields' => array('Signature.value'), //array of field names
'order' => array('Signature.value'), //string or array defining order
'group' => array('Signature.value'), //fields to GROUP BY
);
$signatures = $this->Signature->find('all', $params);
$this->set('signatures', $signatures);
}
/**
* // LATER move _dnsNameToRawFormat($name) function to a better place
* Converts a DNS name to a raw format usable in NIDS like Snort.
* example: foobar.com becomes |06|foobar|03|com|00|
* @param string $name dns name to be converted
* @return string raw snort compatible format of the dns name
*/
private function _dnsNameToRawFormat($name) {
$rawName = "";
// explode using the dot
$explodedNames = explode('.', $name);
// for each part
foreach ($explodedNames as $explodedName) {
// count the lenght of the part, and add |length| before
$length = strlen($explodedName);
if ($length > 255) exit('ERROR: dns name is to long for RFC'); // LATER log correctly without dying
$hexLength = dechex($length);
if (1 == strlen($hexLength)) $hexLength = '0'.$hexLength;
$rawName .= '|'.$hexLength.'|'.$explodedName;
}
// put all together
$rawName .= '|00|';
// and append |00| to terminate the name
return $rawName;
}
}

View File

@ -0,0 +1,82 @@
<?php
/**
* Static content controller.
*
* This file will render views from views/pages/
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, 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)
*/
App::uses('AppController', 'Controller');
/**
* Static content controller
*
* Override this controller by placing a copy in controllers directory of an application
*
* @package app.Controller
* @link http://book.cakephp.org/2.0/en/controllers/pages-controller.html
*/
class PagesController extends AppController {
/**
* Controller name
*
* @var string
*/
public $name = 'Pages';
/**
* Default helper
*
* @var array
*/
public $helpers = array('Html', 'Session');
/**
* This controller does not use a model
*
* @var array
*/
public $uses = array();
/**
* Displays a view
*
* @param mixed What page to display
* @return void
*/
public function display() {
$path = func_get_args();
$count = count($path);
if (!$count) {
$this->redirect('/');
}
$page = $subpage = $title_for_layout = null;
if (!empty($path[0])) {
$page = $path[0];
}
if (!empty($path[1])) {
$subpage = $path[1];
}
if (!empty($path[$count - 1])) {
$title_for_layout = Inflector::humanize($path[$count - 1]);
}
$this->set(compact('page', 'subpage', 'title_for_layout'));
$this->render(implode('/', $path));
}
}

View File

@ -0,0 +1,189 @@
<?php
App::uses('AppController', 'Controller');
/**
* Signatures Controller
*
* @property Signature $Signature
*/
class SignaturesController extends AppController {
public $components = array('Security');
function beforeFilter() {
// These variables are required for every view
$this->set('me', $this->Auth->user());
$this->set('isAdmin', $this->_isAdmin());
}
/**
* index method
*
* @return void
*/
public function index() {
$this->Signature->recursive = 0;
$this->set('signatures', $this->paginate());
}
/**
* add method
*
* @return void
*/
public function add($event_id = null) {
if ($this->request->is('post')) {
$this->loadModel('Event');
// only own signatures
$this->Event->recursive = 0;
$event = $this->Event->findById($this->request->data['Signature']['event_id']);
if (!$this->_isAdmin() && $this->Auth->user('org') != $event['Event']['org']) {
throw new UnauthorizedException('You can only add signatures for your own organisation.');
}
// remove the alerted flag from the event
$this->Event->id = $this->request->data['Signature']['event_id'];
$this->Event->saveField('alerted', 0);
//
// multiple signatures in batch import
//
if ($this->data['Signature']['batch_import'] == 1) {
// make array from value field
$signatures = explode("\n", $this->request->data['Signature']['value']);
$fails = ""; // will be used to keep a list of the lines that failed or succeeded
$successes = "";
foreach ($signatures as $key => $signature) {
$signature = trim($signature);
if (strlen($signature) == 0 )
continue; // don't do anything for empty lines
$this->Signature->create();
$this->request->data['Signature']['value'] = $signature; // set the value as the content of the single line
if ($this->Signature->save($this->request->data)) {
$successes .= " ".($key+1);
} else {
$fails .= " ".($key+1);
}
}
// we added all the signatures,
if ($fails) {
// list the ones that failed
$this->Session->setFlash(__('The lines'.$fails.' could not be saved. Please, try again.', true), 'default', array(), 'error');
}
if ($successes) {
// list the ones that succeeded
$this->Session->setFlash(__('The lines'.$successes.' have been saved', true));
}
$this->redirect(array('controller' => 'events', 'action' => 'view', $this->request->data['Signature']['event_id']));
}
else {
//
// single signature
//
// create the signature
$this->Signature->create();
if ($this->Signature->save($this->request->data)) {
// inform the user and redirect
$this->Session->setFlash(__('The signature has been saved'));
$this->redirect(array('controller' => 'events', 'action' => 'view', $this->request->data['Signature']['event_id']));
} else {
$this->Session->setFlash(__('The signature could not be saved. Please, try again.'));
}
}
} else {
// set the event_id in the form
$this->request->data['Signature']['event_id'] = $event_id;
}
// combobox for types
$types = $this->Signature->validate['type']['rule'][1];
$types = $this->_arrayToValuesIndexArray($types);
$this->set('types',compact('types'));
}
/**
* edit method
*
* @param string $id
* @return void
*/
public function edit($id = null) {
$this->Signature->id = $id;
if (!$this->Signature->exists()) {
throw new NotFoundException(__('Invalid signature'));
}
// only own signatures
$this->Signature->read();
if (!$this->_isAdmin() && $this->Auth->user('org') != $this->Signature->data['Event']['org']) {
throw new UnauthorizedException('You can only edit signatures from your own organisation.');
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->Signature->save($this->request->data)) {
$this->Session->setFlash(__('The signature has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The signature could not be saved. Please, try again.'));
}
} else {
$this->request->data = $this->Signature->read(null, $id);
}
}
/**
* delete method
*
* @param string $id
* @return void
*/
public function delete($id = null) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->Signature->id = $id;
if (!$this->Signature->exists()) {
throw new NotFoundException(__('Invalid signature'));
}
// only own signatures
$this->Signature->read();
if (!$this->_isAdmin() && $this->Auth->user('org') != $this->Signature->data['Event']['org']) {
throw new UnauthorizedException('You can only delete signatures from your own organisation.');
}
if ($this->Signature->delete()) {
$this->Session->setFlash(__('Signature deleted'));
} else {
$this->Session->setFlash(__('Signature was not deleted'));
}
$this->redirect($this->referer());
}
public function search() {
if ($this->request->is('post')) {
$keyword = $this->request->data['Signature']['keyword'];
// search the db
$this->Signature->recursive = 0;
$this->paginate = array(
'conditions' => array('Signature.value LIKE' => '%'.$keyword.'%'),
);
$this->set('signatures', $this->paginate());
// set the same view as the index page
$this->render('index');
}
}
}

View File

@ -0,0 +1,309 @@
<?php
App::uses('AppController', 'Controller');
/**
* Users Controller
*
* @property User $User
*/
class UsersController extends AppController {
public $components = array('Security');
function beforeFilter() {
parent::beforeFilter();
// what pages are allowed for everyone
$this->Auth->allow('login', 'logout');
// These variables are required for every view
$this->set('me', $this->Auth->user());
$this->set('isAdmin', $this->_isAdmin());
}
/**
* view method
*
* @param string $id
* @return void
*/
public function view($id = null) {
if ("me" == $id) $id = $this->Auth->user('id');
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
// Only own profile
if ($this->Auth->user('id') != $id) {
throw new ForbiddenException('You are not authorized to access this profile.');
}
$this->set('user', $this->User->read(null, $id));
}
/**
* edit method
*
* @param string $id
* @return void
*/
public function edit($id = null) {
if ("me" == $id) $id = $this->Auth->user('id');
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
// Only own profile
if ($this->Auth->user('id') != $id) {
throw new ForbiddenException('You are not authorized to edit this profile.');
}
if ($this->request->is('post') || $this->request->is('put')) {
// What fields should be saved (allowed to be saved)
$fieldList=array('email', 'autoalert', 'gpgkey', 'nids_sid' );
if ("" != $this->data['User']['password'])
$fieldList[] = 'password';
// Save the data
if ($this->User->save($this->request->data, true ,$fieldList)) {
$this->Session->setFlash(__('The profile has been updated'));
$this->redirect(array('action' => 'view', $id));
} else {
$this->Session->setFlash(__('The profile could not be updated. Please, try again.'));
}
} else {
$this->User->recursive=0;
$this->User->read(null, $id);
$this->User->set('password', '');
$this->request->data = $this->User->data;
}
$this->request->data['User']['org']=$this->Auth->user('org');
}
/**
* delete method
*
* @param string $id
* @return void
*/
public function delete($id = null) {
if ("me" == $id) $id = $this->Auth->user('id');
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
// Only own profile
if ($this->Auth->user('id') != $id) {
throw new ForbiddenException('You are not authorized to delete this profile.');
}
if ($this->User->delete()) {
$this->Session->setFlash(__('User deleted'));
$this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('User was not deleted'));
$this->redirect(array('action' => 'index'));
}
/**
* admin_index method
*
* @return void
*/
public function admin_index() {
$this->User->recursive = 0;
$this->set('users', $this->paginate());
}
/**
* admin_view method
*
* @param string $id
* @return void
*/
public function admin_view($id = null) {
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
$this->set('user', $this->User->read(null, $id));
}
/**
* admin_add method
*
* @return void
*/
public function admin_add() {
if ($this->request->is('post')) {
$this->User->create();
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
}
}
/**
* admin_edit method
*
* @param string $id
* @return void
*/
public function admin_edit($id = null) {
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
} else {
$this->request->data = $this->User->read(null, $id);
}
}
/**
* admin_delete method
*
* @param string $id
* @return void
*/
public function admin_delete($id = null) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->User->delete()) {
$this->Session->setFlash(__('User deleted'));
$this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('User was not deleted'));
$this->redirect(array('action' => 'index'));
}
public function login() {
// FIXME implement authentication brute-force protection
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
public function routeafterlogin() {
// Terms and Conditions Page
if (!$this->Auth->user('termsaccepted')) {
$this->redirect(array('action' => 'terms'));
}
// News page
$new_newsdate = new DateTime("2012-03-15");
$newsdate = new DateTime($this->Auth->user('newsread'));
if ($new_newsdate > $newsdate) {
$this->redirect(array('action' => 'news'));
}
// Events list
$this->redirect(array('controller' => 'events', 'action' => 'index'));
}
public function logout() {
$this->Session->setFlash('Good-Bye');
$this->redirect($this->Auth->logout());
}
public function resetauthkey($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid id for user', true), 'default', array(), 'error');
$this->redirect(array('action'=>'index'));
}
if ('me' == $id ) $id = $this->Auth->user('id');
// only allow reset key for own account, except for admins
if (!$this->_isAdmin() && $id != $this->Auth->user('id')) {
throw new ForbiddenException('Not authorized to reset the key for this user');
}
// reset the key
$this->User->id = $id;
$newkey = $this->User->generateAuthKey();
$this->User->saveField('authkey', $newkey);
$this->Session->setFlash(__('New authkey generated.', true));
$this->redirect($this->referer());
}
public function memberslist() {
$this->loadModel('Signature');
$this->loadModel('Event');
// Orglist
$fields = array('User.org', 'count(User.id) as `num_members`');
$params = array('recursive' => 0,
'fields' => $fields,
'group' => array('User.org'),
'order' => array('User.org'),
);
$orgs = $this->User->find('all', $params);
$this->set('orgs', $orgs);
// $fields = array('User.org', 'count(User.id) as `num_members`', 'count(Event.id) as `num_events`');
// $params = array('recursive' => 0,
// 'fields' => $fields,
// 'group' => array('User.org'),
// 'order' => array('User.org'),
// );
// $orgs = $this->Event->find('all', $params);
// $this->set('orgs', $orgs);
// What org posted what type of signature
// LATER beautify types_histogram
$this->loadModel('Signature');
$fields = array('Event.org', 'Signature.type', 'count(Signature.type) as `num_types`');
$params = array('recursive' => 0,
'fields' => $fields,
'group' => array('Signature.type', 'Event.org'),
'order' => array('Event.org', 'num_types DESC'),
);
$types_histogram = $this->Signature->find('all', $params);
$this->set('types_histogram', $types_histogram);
}
public function terms() {
if ($this->request->is('post') || $this->request->is('put')) {
$this->User->id = $this->Auth->user('id');
$this->User->saveField('termsaccepted', true);
$this->_refreshAuth(); // refresh auth info
$this->Session->setFlash(__('You accepted the Terms and Conditions.'));
$this->redirect(array('action' => 'routeafterlogin'));
}
$this->set('termsaccepted', $this->Auth->user('termsaccepted'));
}
public function news() {
$this->User->id = $this->Auth->user('id');
$this->User->saveField('newsread', date("Y-m-d"));
$this->_refreshAuth(); // refresh auth info
}
}

0
app/models/behaviors/empty → app/Lib/empty Executable file → Normal file
View File

View File

34
app/Model/AppModel.php Normal file
View File

@ -0,0 +1,34 @@
<?php
/**
* Application model for Cake.
*
* This file is application-wide model file. You can put all
* application-wide model-related methods here.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Model
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('Model', 'Model');
/**
* Application model for Cake.
*
* Add your application-wide methods in the class below, your models
* will inherit them.
*
* @package app.Model
*/
class AppModel extends Model {
}

0
app/plugins/empty → app/Model/Behavior/empty Executable file → Normal file
View File

View File

155
app/Model/Event.php Normal file
View File

@ -0,0 +1,155 @@
<?php
App::uses('AppModel', 'Model');
/**
* Event Model
*
* @property User $User
* @property Signature $Signature
*/
class Event extends AppModel {
/**
* Display field
*
* @var string
*/
public $displayField = 'id';
/**
* Validation rules
*
* @var array
*/
public $validate = array(
'org' => array(
'notempty' => array(
'rule' => array('notempty'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'date' => array(
'date' => array(
'rule' => array('date'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'risk' => array(
'rule' => array('inList', array('Undefined', 'Low','Medium','High')),
'message' => 'Options : Undefined, Low, Medium, High',
//'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'info' => array(
'notempty' => array(
'rule' => array('notempty'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'user_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'alerted' => array(
'boolean' => array(
'rule' => array('boolean'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'uuid' => array(
'uuid' => array(
'rule' => array('uuid'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
/**
* belongsTo associations
*
* @var array
*/
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
/**
* hasMany associations
*
* @var array
*/
public $hasMany = array(
'Signature' => array(
'className' => 'Signature',
'foreignKey' => 'event_id',
'dependent' => true, // cascade deletes
'conditions' => '',
'fields' => '',
'order' => 'Signature.type ASC',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
function getRelatedEvents() {
// first get a list of related event_ids
// then do a single query to search for all the events with that id
$relatedEventIds = Array();
foreach ($this->data['Signature'] as $signature ) {
if ($signature['type'] == 'other')
continue; // sigs of type 'other' should not be matched against the others
$conditions = array('Signature.value =' => $signature['value'], 'Signature.type =' => $signature['type']);
$similar_signatures = $this->Signature->find('all',array('conditions' => $conditions));
foreach ($similar_signatures as $similar_signature) {
if ($this->id == $similar_signature['Signature']['event_id'])
continue; // same as this event, not needed in the list
$relatedEventIds[] = $similar_signature['Signature']['event_id'];
}
}
$conditions = array("Event.id" => $relatedEventIds);
$relatedEvents= $this->find('all',
array('conditions' => $conditions,
'recursive' => 0,
'order' => 'Event.date DESC',
'fields' => 'Event.*'
)
);
return $relatedEvents;
}
}

249
app/Model/Signature.php Normal file
View File

@ -0,0 +1,249 @@
<?php
App::uses('AppModel', 'Model');
/**
* Signature Model
*
* @property Event $Event
*/
class Signature extends AppModel {
/**
* Display field
*
* @var string
*/
public $displayField = 'value';
var $order = array("Signature.event_id" => "DESC", "Signature.type" => "ASC");
/**
* Validation rules
*
* @var array
*/
public $validate = array(
'event_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'type' => array(
'rule' => array('inList', array('md5','sha1',
'filename',
'ip-src',
'ip-dst',
'domain',
'email-src',
'email-dst',
'email-subject',
'email-attachment',
'url',
'user-agent',
'regkey',
'AS',
'snort',
'pattern-in-file',
'other')),
'message' => 'Options : md5, sha1, filename, ip, domain, email, url, regkey, AS, other, ...',
//'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'value' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please fill in this field',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'userdefined' => array(
'rule' => array('validateSignatureValue'),
'message' => 'Value not in the right type/format. Please double check the value or select "other" for a type.',
//'allowEmpty' => false,
//'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'to_ids' => array(
'boolean' => array(
'rule' => array('boolean'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'uuid' => array(
'uuid' => array(
'rule' => array('uuid'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
/**
* belongsTo associations
*
* @var array
*/
public $belongsTo = array(
'Event' => array(
'className' => 'Event',
'foreignKey' => 'event_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
function validateSignatureValue ($fields) {
$value = $fields['value'];
$event_id = $this->data['Signature']['event_id'];
$type = $this->data['Signature']['type'];
// check if the signature already exists in the same event
$params = array('recursive' => 0,
'conditions' => array('Signature.event_id' => $event_id,
'Signature.type' => $type,
'Signature.value' => $value),
);
if (0 != $this->find('count', $params) )
return 'Signature already exists for this event.';
// check data validation
switch($this->data['Signature']['type']) {
case 'md5':
if (preg_match("#^[0-9a-f]{32}$#i", $value))
return true;
return 'Checksum has invalid lenght or format. Please double check the value or select "other" for a type.';
break;
case 'sha1':
if (preg_match("#^[0-9a-f]{40}$#i", $value))
return true;
return 'Checksum has invalid lenght or format. Please double check the value or select "other" for a type.';
break;
case 'filename':
// no newline
if (!preg_match("#\n#", $value))
return true;
break;
case 'ip-src':
$parts = explode("/", $value);
// [0] = the ip
// [1] = the network address
if (count($parts) <= 2 ) {
// ipv4 and ipv6 matching
if (filter_var($parts[0],FILTER_VALIDATE_IP)) {
// ip is validated, now check if we have a valid network mask
if (empty($parts[1]))
return true;
else if(is_numeric($parts[1]) && $parts[1] < 129)
return true;
}
}
return 'IP address has invalid format. Please double check the value or select "other" for a type.';
break;
case 'ip-dst':
$parts = explode("/", $value);
// [0] = the ip
// [1] = the network address
if (count($parts) <= 2 ) {
// ipv4 and ipv6 matching
if (filter_var($parts[0],FILTER_VALIDATE_IP)) {
// ip is validated, now check if we have a valid network mask
if (empty($parts[1]))
return true;
else if(is_numeric($parts[1]) && $parts[1] < 129)
return true;
}
}
return 'IP address has invalid format. Please double check the value or select "other" for a type.';
break;
case 'domain':
if(preg_match("#^[A-Z0-9.-]+\.[A-Z]{2,4}$#i", $value))
return true;
return 'Domain name has invalid format. Please double check the value or select "other" for a type.';
break;
case 'email-src':
// we don't use the native function to prevent issues with partial email addresses
if(preg_match("#^[A-Z0-9._%+-]*@[A-Z0-9.-]+\.[A-Z]{2,4}$#i", $value))
return true;
return 'Email address has invalid format. Please double check the value or select "other" for a type.';
break;
case 'email-dst':
// we don't use the native function to prevent issues with partial email addresses
if(preg_match("#^[A-Z0-9._%+-]*@[A-Z0-9.-]+\.[A-Z]{2,4}$#i", $value))
return true;
return 'Email address has invalid format. Please double check the value or select "other" for a type.';
break;
case 'email-subject':
// no newline
if (!preg_match("#\n#", $value))
return true;
break;
case 'email-attachment':
// no newline
if (!preg_match("#\n#", $value))
return true;
break;
case 'url':
// no newline
if (!preg_match("#\n#", $value))
return true;
break;
case 'user-agent':
// no newline
if (!preg_match("#\n#", $value))
return true;
break;
case 'regkey':
// no newline
if (!preg_match("#\n#", $value))
return true;
break;
case 'snort':
// no validation yet. TODO implement data validation on snort signature type
case 'other':
return true;
break;
}
// default action is to return false
return true;
}
function getRelatedSignatures($signature) {
// LATER getRelatedSignatures($signature) this might become a performance bottleneck
$conditions = array('Signature.value =' => $signature['value'],
'Signature.id !=' => $signature['id'],
'Signature.type =' => $signature['type'], );
// $fields = array('Event.*');
$fields = array('Signature.*');
$similar_events = $this->find('all',array('conditions' => $conditions,
'fields' => $fields,
'order' => 'Signature.event_id DESC', )
);
return $similar_events;
}
}

244
app/Model/User.php Normal file
View File

@ -0,0 +1,244 @@
<?php
App::uses('AppModel', 'Model');
App::uses('AuthComponent', 'Controller/Component');
/**
* User Model
*
* @property Group $Group
* @property Event $Event
*/
class User extends AppModel {
/**
* Display field
*
* @var string
*/
public $displayField = 'email';
/**
* Validation rules
*
* @var array
*/
public $validate = array(
'group_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'password' => array(
'minlength' => array(
'rule' => array('minlength', 6),
'message' => 'A password of a minimum length of 6 is required.',
//'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'complexity' => array(
'rule' => array('complexPassword'),
'message' => 'The password must contain at least one upper-case, one lower-case, one (digits or special character).', // TODO password strength requirements
//'allowEmpty' => false,
//'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'org' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please specify the organisation where you are working.',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'email' => array(
'email' => array(
'rule' => array('email'),
'message' => 'Please enter a valid email address.',
//'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'An account with this email address already exists.'
),
),
'autoalert' => array(
'boolean' => array(
'rule' => array('boolean'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'authkey' => array(
'notempty' => array(
'rule' => array('notempty'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'invited_by' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'gpgkey' => array(
'notempty' => array(
'rule' => array('validateGpgkey'),
'message' => 'GPG key not valid, please enter a valid key.',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'nids_sid' => array(
'numeric' => array(
'rule' => array('numeric'),
'message' => 'A SID should be an integer.',
'allowEmpty' => false,
'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'termsaccepted' => array(
'boolean' => array(
'rule' => array('boolean'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'newsread' => array(
'date' => array(
'rule' => array('date'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
/**
* hasMany associations
*
* @var array
*/
public $hasMany = array(
'Event' => array(
'className' => 'Event',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
// var $actsAs = array('Acl' => array('type' => 'requester'));
//
// public function beforeValidate() {
// // Fix issue with an empty password being automagically hashed
// App::import('Core', 'Security'); // not sure whether this is necessary
// if ($this->data['User']['password'] == Security::hash('', null, true)) {
// $this->data['User']['password'] = '';
// }
// return true;
// }
public function beforeSave() {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
/**
* Checks if the GPG key is a valid key
* But also import it in the keychain.
*/
function validateGpgkey($check) {
// LATER first remove the old gpgkey from the keychain
// empty value
if (empty($check['gpgkey']))
return true;
// key is entered
require_once 'Crypt/GPG.php';
$gpg = new Crypt_GPG();
try {
$key_import_output = $gpg->importKey($check['gpgkey']);
if (!empty($key_import_output['fingerprint'])) {
return true;
}
} catch (Exception $e) {
debug($e);
return false;
}
}
function complexPassword($check) {
/*
6 characters minimum
1 or more upper-case letters
1 or more lower-case letters
1 or more digits or special characters
example: "EasyPeasy34"
*/
$value = array_values($check);
$value = $value[0];
return preg_match('/((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/', $value);
}
/**
* Generates an authentication key for each user
*/
function generateAuthKey() {
//$key = sha1(mt_rand(30, 30).time());
$length = 40;
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$char_len = strlen($characters)-1;
$key = '';
for ($p = 0; $p < $length; $p++) {
$key .= $characters[rand(0, $char_len)];
}
return $key;
}
}

0
app/tests/cases/components/empty → app/Plugin/empty Executable file → Normal file
View File

View File

@ -1,21 +1,16 @@
TODOs
-----
Auth
- Use captcha authentication
- cleanup ACL and do it using the CakePHP concept
- password strength requirements
- Prevent bruteforce auth attempts
implement auditing/logging system
- add / edit events and signatures
- failed / success logins (with source IP, headers,...)
Security
- apply CSRF checks on the delete parameters by enabling security modules and rewriting some parts
- force cookie reset after login
@ -26,10 +21,10 @@ Download CyDefSIG using git in the /var/www/ directory.
cd /var/www/
git clone git@code.lab.modiss.be:cydefsig.git
Download and extract CakePHP 1.3 to the web root directory:
Download and extract CakePHP 2.x to the web root directory:
cd /tmp/
wget https://nodeload.github.com/cakephp/cakephp/tarball/1.3
wget https://nodeload.github.com/cakephp/cakephp/tarball/2.1
tar zxvf cakephp-cakephp-<version>.tar.gz
cd cakephp-cakephp-*

View File

@ -0,0 +1,142 @@
<?php
App::uses('EventsController', 'Controller');
/**
* TestEventsController *
*/
class TestEventsController extends EventsController {
/**
* Auto render
*
* @var boolean
*/
public $autoRender = false;
/**
* Redirect action
*
* @param mixed $url
* @param mixed $status
* @param boolean $exit
* @return void
*/
public function redirect($url, $status = null, $exit = true) {
$this->redirectUrl = $url;
}
}
/**
* EventsController Test Case
*
*/
class EventsControllerTestCase extends CakeTestCase {
/**
* Fixtures
*
* @var array
*/
public $fixtures = array('app.event', 'app.user', 'app.group', 'app.signature');
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->Events = new TestEventsController();
$this->Events->constructClasses();
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
unset($this->Events);
parent::tearDown();
}
/**
* testIndex method
*
* @return void
*/
public function testIndex() {
}
/**
* testView method
*
* @return void
*/
public function testView() {
}
/**
* testAdd method
*
* @return void
*/
public function testAdd() {
}
/**
* testEdit method
*
* @return void
*/
public function testEdit() {
}
/**
* testDelete method
*
* @return void
*/
public function testDelete() {
}
/**
* testAdminIndex method
*
* @return void
*/
public function testAdminIndex() {
}
/**
* testAdminView method
*
* @return void
*/
public function testAdminView() {
}
/**
* testAdminAdd method
*
* @return void
*/
public function testAdminAdd() {
}
/**
* testAdminEdit method
*
* @return void
*/
public function testAdminEdit() {
}
/**
* testAdminDelete method
*
* @return void
*/
public function testAdminDelete() {
}
}

View File

@ -0,0 +1,142 @@
<?php
App::uses('SignaturesController', 'Controller');
/**
* TestSignaturesController *
*/
class TestSignaturesController extends SignaturesController {
/**
* Auto render
*
* @var boolean
*/
public $autoRender = false;
/**
* Redirect action
*
* @param mixed $url
* @param mixed $status
* @param boolean $exit
* @return void
*/
public function redirect($url, $status = null, $exit = true) {
$this->redirectUrl = $url;
}
}
/**
* SignaturesController Test Case
*
*/
class SignaturesControllerTestCase extends CakeTestCase {
/**
* Fixtures
*
* @var array
*/
public $fixtures = array('app.signature', 'app.event', 'app.user', 'app.group');
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->Signatures = new TestSignaturesController();
$this->Signatures->constructClasses();
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
unset($this->Signatures);
parent::tearDown();
}
/**
* testIndex method
*
* @return void
*/
public function testIndex() {
}
/**
* testView method
*
* @return void
*/
public function testView() {
}
/**
* testAdd method
*
* @return void
*/
public function testAdd() {
}
/**
* testEdit method
*
* @return void
*/
public function testEdit() {
}
/**
* testDelete method
*
* @return void
*/
public function testDelete() {
}
/**
* testAdminIndex method
*
* @return void
*/
public function testAdminIndex() {
}
/**
* testAdminView method
*
* @return void
*/
public function testAdminView() {
}
/**
* testAdminAdd method
*
* @return void
*/
public function testAdminAdd() {
}
/**
* testAdminEdit method
*
* @return void
*/
public function testAdminEdit() {
}
/**
* testAdminDelete method
*
* @return void
*/
public function testAdminDelete() {
}
}

View File

@ -0,0 +1,142 @@
<?php
App::uses('UsersController', 'Controller');
/**
* TestUsersController *
*/
class TestUsersController extends UsersController {
/**
* Auto render
*
* @var boolean
*/
public $autoRender = false;
/**
* Redirect action
*
* @param mixed $url
* @param mixed $status
* @param boolean $exit
* @return void
*/
public function redirect($url, $status = null, $exit = true) {
$this->redirectUrl = $url;
}
}
/**
* UsersController Test Case
*
*/
class UsersControllerTestCase extends CakeTestCase {
/**
* Fixtures
*
* @var array
*/
public $fixtures = array('app.user', 'app.group', 'app.event', 'app.signature');
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->Users = new TestUsersController();
$this->Users->constructClasses();
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
unset($this->Users);
parent::tearDown();
}
/**
* testIndex method
*
* @return void
*/
public function testIndex() {
}
/**
* testView method
*
* @return void
*/
public function testView() {
}
/**
* testAdd method
*
* @return void
*/
public function testAdd() {
}
/**
* testEdit method
*
* @return void
*/
public function testEdit() {
}
/**
* testDelete method
*
* @return void
*/
public function testDelete() {
}
/**
* testAdminIndex method
*
* @return void
*/
public function testAdminIndex() {
}
/**
* testAdminView method
*
* @return void
*/
public function testAdminView() {
}
/**
* testAdminAdd method
*
* @return void
*/
public function testAdminAdd() {
}
/**
* testAdminEdit method
*
* @return void
*/
public function testAdminEdit() {
}
/**
* testAdminDelete method
*
* @return void
*/
public function testAdminDelete() {
}
}

View File

View File

@ -0,0 +1,37 @@
<?php
App::uses('Event', 'Model');
/**
* Event Test Case
*
*/
class EventTestCase extends CakeTestCase {
/**
* Fixtures
*
* @var array
*/
public $fixtures = array('app.event', 'app.user', 'app.group', 'app.signature');
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->Event = ClassRegistry::init('Event');
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
unset($this->Event);
parent::tearDown();
}
}

View File

@ -0,0 +1,37 @@
<?php
App::uses('Group', 'Model');
/**
* Group Test Case
*
*/
class GroupTestCase extends CakeTestCase {
/**
* Fixtures
*
* @var array
*/
public $fixtures = array('app.group', 'app.user', 'app.event');
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->Group = ClassRegistry::init('Group');
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
unset($this->Group);
parent::tearDown();
}
}

View File

@ -0,0 +1,37 @@
<?php
App::uses('Signature', 'Model');
/**
* Signature Test Case
*
*/
class SignatureTestCase extends CakeTestCase {
/**
* Fixtures
*
* @var array
*/
public $fixtures = array('app.signature', 'app.event');
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->Signature = ClassRegistry::init('Signature');
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
unset($this->Signature);
parent::tearDown();
}
}

View File

@ -0,0 +1,37 @@
<?php
App::uses('User', 'Model');
/**
* User Test Case
*
*/
class UserTestCase extends CakeTestCase {
/**
* Fixtures
*
* @var array
*/
public $fixtures = array('app.user', 'app.group', 'app.event');
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->User = ClassRegistry::init('User');
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
unset($this->User);
parent::tearDown();
}
}

View File

View File

@ -0,0 +1,41 @@
<?php
/**
* EventFixture
*
*/
class EventFixture extends CakeTestFixture {
/**
* Fields
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'org' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'date' => array('type' => 'date', 'null' => false, 'default' => NULL),
'info' => array('type' => 'text', 'null' => false, 'default' => NULL, 'key' => 'index', 'collate' => 'utf8_unicode_ci', 'charset' => 'utf8'),
'user_id' => array('type' => 'integer', 'null' => false, 'default' => NULL),
'alerted' => array('type' => 'boolean', 'null' => false, 'default' => '0'),
'uuid' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 40, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'info' => array('column' => 'info', 'unique' => 0)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
/**
* Records
*
* @var array
*/
public $records = array(
array(
'id' => 1,
'org' => 'Lorem ipsum dolor sit amet',
'date' => '2012-03-13',
'info' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
'user_id' => 1,
'alerted' => 1,
'uuid' => 'Lorem ipsum dolor sit amet'
),
);
}

View File

@ -0,0 +1,31 @@
<?php
/**
* GroupFixture
*
*/
class GroupFixture extends CakeTestFixture {
/**
* Fields
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 100, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
/**
* Records
*
* @var array
*/
public $records = array(
array(
'id' => 1,
'name' => 'Lorem ipsum dolor sit amet'
),
);
}

View File

@ -0,0 +1,39 @@
<?php
/**
* SignatureFixture
*
*/
class SignatureFixture extends CakeTestFixture {
/**
* Fields
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'event_id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'index'),
'type' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 100, 'collate' => 'utf8_unicode_ci', 'charset' => 'utf8'),
'value' => array('type' => 'text', 'null' => false, 'default' => NULL, 'collate' => 'utf8_unicode_ci', 'charset' => 'utf8'),
'to_ids' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
'uuid' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 40, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'event_id' => array('column' => 'event_id', 'unique' => 0)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
/**
* Records
*
* @var array
*/
public $records = array(
array(
'id' => 1,
'event_id' => 1,
'type' => 'Lorem ipsum dolor sit amet',
'value' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
'to_ids' => 1,
'uuid' => 'Lorem ipsum dolor sit amet'
),
);
}

View File

@ -0,0 +1,51 @@
<?php
/**
* UserFixture
*
*/
class UserFixture extends CakeTestFixture {
/**
* Fields
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'group_id' => array('type' => 'integer', 'null' => false, 'default' => NULL),
'password' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 40, 'key' => 'index', 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'org' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'email' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'autoalert' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'authkey' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 40, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'invited_by' => array('type' => 'integer', 'null' => false, 'default' => NULL),
'gpgkey' => array('type' => 'text', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'nids_sid' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 15),
'termsaccepted' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'newsread' => array('type' => 'date', 'null' => false, 'default' => NULL),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'username' => array('column' => 'password', 'unique' => 0)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
/**
* Records
*
* @var array
*/
public $records = array(
array(
'id' => 1,
'group_id' => 1,
'password' => 'Lorem ipsum dolor sit amet',
'org' => 'Lorem ipsum dolor sit amet',
'email' => 'Lorem ipsum dolor sit amet',
'autoalert' => 1,
'authkey' => 'Lorem ipsum dolor sit amet',
'invited_by' => 1,
'gpgkey' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
'nids_sid' => 1,
'termsaccepted' => 1,
'newsread' => '2012-03-13'
),
);
}

0
app/tests/fixtures/empty → app/Test/Fixture/empty Executable file → Normal file
View File

0
app/tests/groups/empty → app/Vendor/empty vendored Executable file → Normal file
View File

View File

View File

@ -0,0 +1,25 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Emails.html
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<?php
$content = explode("\n", $content);
foreach ($content as $line):
echo '<p> ' . $line . "</p>\n";
endforeach;
?>

View File

@ -0,0 +1,19 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Emails.text
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<?php echo $content; ?>

View File

@ -0,0 +1,31 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Errors
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<h2><?php echo $name; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php printf(
__d('cake', 'The requested address %s was not found on this server.'),
"<strong>'{$url}'</strong>"
); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
echo $this->element('exception_stack_trace');
endif;
?>

View File

@ -0,0 +1,28 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Errors
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<h2><?php echo $name; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php echo __d('cake', 'An Internal Error Has Occurred.'); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
echo $this->element('exception_stack_trace');
endif;
?>

View File

@ -3,8 +3,6 @@
<fieldset>
<legend><?php __('Add Event'); ?></legend>
<?php
echo $this->Form->hidden('user_id');
echo $this->Form->hidden('org');
echo $this->Form->input('date');
echo $this->Form->input('risk');
echo $this->Form->input('info');

View File

@ -2,7 +2,7 @@
<?php echo $this->Form->create('Event');?>
<fieldset>
<legend><?php echo 'Contact reporter of event '.$this->Form->value('Event.id'); ?></legend>
<p>You are about to contact the person who reported event <?php echo $this->Form->value('Event.id'); ?>.</br>
<p>You are about to contact the person who reported event <?php echo $this->Form->value('Event.id'); ?>.<br/>
Feel free to add a custom message that will be sent to the reporter. <br/>
Your email address and details about the event will be added automagically to the message.</p>
<?php
@ -13,7 +13,6 @@
</div>
<div class="actions">
<h3><?php __('Actions'); ?></h3>
<ul>
<?php echo $this->element('actions_menu'); ?>

View File

@ -4,8 +4,6 @@
<legend><?php __('Edit Event'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->hidden('user_id');
echo $this->Form->hidden('org');
echo $this->Form->input('date');
echo $this->Form->input('risk');
echo $this->Form->input('info');

View File

@ -9,13 +9,13 @@ You can <?php echo $this->Html->link('reset', array('controller' => 'users', 'ac
<h3>XML Export</h3>
<p>An automatic export of all events and signatures is available under a custom XML format.</p>
<p>You can configure your tools to automatically download the following following file:</p>
<pre>https://sig.cyber-defence.be/events/xml/<?php echo $me['authkey']; ?></pre>
<pre><?php echo Configure::read('CyDefSIG.baseurl');?>/events/xml/<?php echo $me['authkey']; ?></pre>
<p></p>
<h3>NIDS Export</h3>
<p>An automatic export of all network related signatures is available under the Snort rule format. Only signatures marked as <u>to IDS</u> are exported.</p>
<p>You can configure your tools to automatically download the following following file:</p>
<pre>https://sig.cyber-defence.be/events/nids/<?php echo $me['authkey']; ?></pre>
<pre><?php echo Configure::read('CyDefSIG.baseurl');?>/events/nids/<?php echo $me['authkey']; ?></pre>
<p></p>
<h3>Text Export</h3>
@ -23,7 +23,7 @@ You can <?php echo $this->Html->link('reset', array('controller' => 'users', 'ac
<p>You can configure your tools to automatically download the following following files:</p>
<pre>
<?php foreach ($sig_types as $sig_type):?>
https://sig.cyber-defence.be/events/text/<?php echo $me['authkey']; ?>/<?php echo $sig_type."\n";?>
<?php echo Configure::read('CyDefSIG.baseurl');?>/events/text/<?php echo $me['authkey']; ?>/<?php echo $sig_type."\n";?>
<?php endforeach;?>
</pre>
<p></p>

View File

@ -9,33 +9,33 @@
<th><?php echo $this->Paginator->sort('date');?></th>
<th><?php echo $this->Paginator->sort('risk');?></th>
<th><?php echo $this->Paginator->sort('info');?></th>
<th class="actions"><?php __('Actions');?></th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
$i = 0;
foreach ($events as $event):
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
foreach ($events as $event):
// FIXME reactivate the onclick without breaking the delete form submit
?>
<tr<?php echo $class;?> onclick="document.location ='<?php echo $this->Html->url(array('action' => 'view', $event['Event']['id']), true) ;?>';">
<td style="white-space: nowrap"><?php echo $event['Event']['id']; ?>&nbsp;</td>
<!-- <tr onclick="document.location ='<?php echo $this->Html->url(array('action' => 'view', $event['Event']['id']), true) ;?>';" > -->
<tr>
<td style="white-space: nowrap">
<?php echo $this->Html->link($event['Event']['id'], array('controller' => 'events', 'action' => 'view', $event['Event']['id'])); ?>
&nbsp;</td>
<?php if ('true' == Configure::read('CyDefSIG.showorg') || $isAdmin): ?>
<td style="white-space: nowrap"><?php echo Sanitize::html($event['Event']['org']); ?>&nbsp;</td>
<?php endif; ?>
<td style="white-space: nowrap"><?php echo $event['Event']['date']; ?>&nbsp;</td>
<td style="white-space: nowrap"><?php echo $event['Event']['risk']; ?>&nbsp;</td>
<td><?php echo nl2br(Sanitize::html($event['Event']['info'])); ?>&nbsp;</td>
<td class="actions" style="text-align:right;">
<td class="actions">
<?php
if (0 == $event['Event']['alerted'] && ($isAdmin || $event['Event']['org'] == $me['org'])) echo $this->Html->link(__('Finish Edit', true), array('action' => 'alert', $event['Event']['id']), array(), 'Are you sure this event is complete and everyone should be alerted?');
if (0 == $event['Event']['alerted'] && ($isAdmin || $event['Event']['org'] == $me['org']))
echo $this->Form->postLink('Finish Edit', array('action' => 'alert', $event['Event']['id']), null, 'Are you sure this event is complete and everyone should be alerted?');
elseif (0 == $event['Event']['alerted']) echo 'Not finished editing';
?>
<?php
if ($isAdmin || $event['Event']['org'] == $me['org']) {
echo $this->Html->link(__('Edit', true), array('action' => 'edit', $event['Event']['id']));
echo $this->Html->link(__('Delete', true), array('action' => 'delete', $event['Event']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $event['Event']['id']));
echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $event['Event']['id']), null, __('Are you sure you want to delete # %s?', $event['Event']['id']));
}
?>
<?php echo $this->Html->link(__('View', true), array('action' => 'view', $event['Event']['id'])); ?>
@ -46,7 +46,7 @@
<p>
<?php
echo $this->Paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
));
?> </p>
@ -58,7 +58,6 @@
</div>
</div>
<div class="actions">
<h3><?php __('Actions'); ?></h3>
<ul>
<?php echo $this->element('actions_menu'); ?>

View File

@ -3,7 +3,9 @@
<?php if ( 0 == $event['Event']['alerted'] && ($isAdmin || $event['Event']['org'] == $me['org'])):
// only show button if alert has not been sent // LATER show the ALERT button in red-ish
?>
<ul><li><?php echo $this->Html->link(__('Finish Edit', true), array('action' => 'alert', $event['Event']['id']), array(), 'Are you sure this event is complete and everyone should be alerted?'); ?> </li></ul>
<ul><li><?php
echo $this->Form->postLink('Finish Edit', array('action' => 'alert', $event['Event']['id']), null, 'Are you sure this event is complete and everyone should be alerted?');
?> </li></ul>
<?php elseif (0 == $event['Event']['alerted']): ?>
<ul><li>Not finished editing</li></ul>
<?php else: ?>
@ -14,39 +16,39 @@
<h2><?php __('Event');?></h2>
<dl><?php $i = 0; $class = ' class="altrow"';?>
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Id'); ?></dt>
<dd<?php if ($i++ % 2 == 0) echo $class;?>>
<h2>Event</h2>
<dl>
<dt>ID</dt>
<dd>
<?php echo Sanitize::html($event['Event']['id']); ?>
&nbsp;
</dd>
<?php if ('true' == Configure::read('CyDefSIG.showorg') || $isAdmin): ?>
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Org'); ?></dt>
<dd<?php if ($i++ % 2 == 0) echo $class;?>>
<dt>Org</dt>
<dd>
<?php echo Sanitize::html($event['Event']['org']); ?>
&nbsp;
</dd>
<?php endif; ?>
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Date'); ?></dt>
<dd<?php if ($i++ % 2 == 0) echo $class;?>>
<dt>Date</dt>
<dd>
<?php echo Sanitize::html($event['Event']['date']); ?>
&nbsp;
</dd>
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Risk'); ?></dt>
<dd<?php if ($i++ % 2 == 0) echo $class;?>>
<dt>Risk</dt>
<dd>
<?php echo $event['Event']['risk']; ?>
&nbsp;
</dd>
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Info'); ?></dt>
<dd<?php if ($i++ % 2 == 0) echo $class;?>>
<dt>Info</dt>
<dd>
<?php echo nl2br(Sanitize::html($event['Event']['info'])); ?>
&nbsp;
</dd>
</dl>
<?php if (!empty($relatedEvents)):?>
<div class="related">
<h3><?php __('Related Events');?></h3>
<h3>Related Events</h3>
<ul>
<?php foreach ($relatedEvents as $relatedEvent): ?>
<li><?php
@ -58,7 +60,7 @@
<?php endif; ?>
<div class="related">
<h3><?php __('Signatures');?></h3>
<h3>Signatures</h3>
<?php if (!empty($event['Signature'])):?>
<table cellpadding = "0" cellspacing = "0">
<tr>
@ -66,17 +68,12 @@
<th>Value</th>
<th>Related Events</th>
<th>To IDS</th>
<th class="actions">Actions</th>
<th class="actions" style="text-align:right;">Actions</th>
</tr>
<?php
$i = 0;
foreach ($event['Signature'] as $signature):
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
?>
<tr<?php echo $class;?>>
<tr>
<td><?php echo $signature['type'];?></td>
<td><?php echo nl2br(Sanitize::html($signature['value']));?></td>
<td>
@ -94,7 +91,7 @@
<?php
if ($isAdmin || $event['Event']['org'] == $me['org']) {
echo $this->Html->link(__('Edit', true), array('controller' => 'signatures', 'action' => 'edit', $signature['id']));
echo $this->Html->link(__('Delete', true), array('controller' => 'signatures', 'action' => 'delete', $signature['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $signature['id']));
echo $this->Form->postLink(__('Delete'), array('controller' => 'signatures', 'action' => 'delete', $signature['id']), null, __('Are you sure you want to delete this signature?'));
} ?>
</td>
</tr>
@ -104,7 +101,7 @@
<?php if ($isAdmin || $event['Event']['org'] == $me['org']): ?>
<div class="actions">
<ul>
<li><?php echo $this->Html->link(__('New Signature', true), array('controller' => 'signatures', 'action' => 'add', $event['Event']['id']));?> </li>
<li><?php echo $this->Html->link('New Signature', array('controller' => 'signatures', 'action' => 'add', $event['Event']['id']));?> </li>
</ul>
</div>
<?php endif; ?>
@ -113,12 +110,11 @@
</div>
<div class="actions">
<h3><?php __('Actions'); ?></h3>
<ul>
<?php if ($isAdmin || $event['Event']['org'] == $me['org']): ?>
<li><?php echo $this->Html->link(__('New Signature', true), array('controller' => 'signatures', 'action' => 'add', $event['Event']['id']));?> </li>
<li><?php echo $this->Html->link(__('Edit Event', true), array('action' => 'edit', $event['Event']['id'])); ?> </li>
<li><?php echo $this->Html->link(__('Delete Event', true), array('action' => 'delete', $event['Event']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $event['Event']['id'])); ?> </li>
<li><?php echo $this->Form->postLink(__('Delete Event'), array('action' => 'delete', $event['Event']['id']), null, __('Are you sure you want to delete # %s?', $event['Event']['id'])); ?></li>
<li>&nbsp;</li>
<?php endif; ?>
<?php echo $this->element('actions_menu'); ?>

8
app/View/Events/xml.ctp Executable file
View File

@ -0,0 +1,8 @@
<?php
// $xml = Xml::build($events);
//echo $this->Xml->header();
?>
<CyDefSIG>
<?php // echo $this->Xml->serialize($events, array('format' => 'tags')); ?>
<?php // echo Xml::fromArray($events, array('format' => 'tags')); ?>
</CyDefSIG>

View File

@ -0,0 +1,34 @@
<?php
/**
* Application level View Helper
*
* This file is application-wide helper file. You can put all
* application-wide helper-related methods here.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.View.Helper
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('Helper', 'View');
/**
* Application helper
*
* Add your application-wide methods in the class below, your helpers
* will inherit them.
*
* @package app.View.Helper
*/
class AppHelper extends Helper {
}

View File

@ -1,18 +1,17 @@
<?php
/**
*
* PHP versions 4 and 5
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.view.templates.elements.email.html
* @package Cake.View.Layouts.Emails.html
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
@ -20,10 +19,10 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title><?php echo $title_for_layout;?></title>
<title><?php echo $title_for_layout;?></title>
</head>
<body>
<?php echo $content_for_layout;?>
<?php echo $content_for_layout;?>
</body>
</html>
</html>

View File

@ -1,18 +1,17 @@
<?php
/**
*
* PHP versions 4 and 5
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.view.templates.elements.email.text
* @package Cake.View.Layouts.Emails.text
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/

19
app/View/Layouts/ajax.ctp Normal file
View File

@ -0,0 +1,19 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Layouts
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<?php echo $content_for_layout; ?>

View File

@ -1,7 +1,7 @@
<?php
/**
*
* PHP versions 4 and 5
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
@ -11,18 +11,19 @@
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.view.templates.layouts
* @package Cake.View.Layouts
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php echo $this->Html->charset(); ?>
<title>
CyDefSIG -
<?php echo $cakeDescription ?>:
<?php echo $title_for_layout; ?>
</title>
<?php
@ -30,40 +31,25 @@
echo $this->Html->css('cake.generic');
echo $scripts_for_layout;
echo $this->fetch('meta');
echo $this->fetch('css');
echo $this->fetch('script');
?>
</head>
<body>
<div id="container">
<div id="header">
<h1><?php echo $this->Html->link(__('CyDefSIG: Cyber-Defence Signatures: sharing detection patterns', true), array('controller' => 'events', 'action' => 'index')); ?></h1>
<div style="float:right;">
<?php
/* echo $this->Form->create('Signature', array(
'controller' => 'signatures',
'action' => 'search',
'inputDefaults' => array(
'label' => false,
'div' => false,
),
));
echo $this->Form->input('keyword');
echo $this->Form->end(__('Search', true));
*/ ?>
</div>
</div>
<div id="content">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Session->flash('error'); ?>
<?php echo $this->Session->flash('gpg'); ?>
<?php echo $this->Session->flash(); ?>
<?php echo $this->Session->flash('email'); ?>
<?php echo $content_for_layout; ?>
<?php echo $this->fetch('content'); ?>
</div>
<div id="footer">
<h1 style="float:left;">Download: <?php echo $this->Html->link('PGP/GPG key', '/gpg.asc');?></h1>
@ -73,7 +59,5 @@
</div>
</div>
<?php echo $this->element('sql_dump'); ?>
</body>
</html>

View File

@ -0,0 +1,37 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Layouts
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php echo $this->Html->charset(); ?>
<title><?php echo $page_title; ?></title>
<?php if (Configure::read('debug') == 0) { ?>
<meta http-equiv="Refresh" content="<?php echo $pause; ?>;url=<?php echo $url; ?>"/>
<?php } ?>
<style><!--
P { text-align:center; font:bold 1.1em sans-serif }
A { color:#444; text-decoration:none }
A:HOVER { text-decoration: underline; color:#44E }
--></style>
</head>
<body>
<p><a href="<?php echo $url; ?>"><?php echo $message; ?></a></p>
</body>
</html>

View File

@ -0,0 +1,2 @@
<?php echo $scripts_for_layout; ?>
<script type="text/javascript"><?php echo $content_for_layout; ?></script>

View File

@ -0,0 +1,14 @@
<?php
if (!isset($channel)) {
$channel = array();
}
if (!isset($channel['title'])) {
$channel['title'] = $title_for_layout;
}
echo $this->Rss->document(
$this->Rss->channel(
array(), $channel, $content_for_layout
)
);
?>

View File

View File

@ -0,0 +1 @@
<?php echo $content_for_layout; ?>

188
app/View/Pages/home.ctp Normal file
View File

@ -0,0 +1,188 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Pages
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
if (Configure::read('debug') == 0):
throw new NotFoundException();
endif;
App::uses('Debugger', 'Utility');
?>
<iframe src="http://cakephp.org/bake-banner" width="830" height="160" style="overflow:hidden; border:none;">
<p>For updates and important announcements, visit http://cakefest.org</p>
</iframe>
<h2><?php echo __d('cake_dev', 'Release Notes for CakePHP %s.', Configure::version()); ?></h2>
<a href="http://cakephp.org/changelogs/<?php echo Configure::version(); ?>"><?php echo __d('cake_dev', 'Read the changelog'); ?> </a>
<?php
if (Configure::read('debug') > 0):
Debugger::checkSecurityKeys();
endif;
?>
<p id="url-rewriting-warning" style="background-color:#e32; color:#fff;">
<?php echo __d('cake_dev', 'URL rewriting is not properly configured on your server.'); ?>
1) <a target="_blank" href="http://book.cakephp.org/2.0/en/installation/advanced-installation.html#apache-and-mod-rewrite-and-htaccess" style="color:#fff;">Help me configure it</a>
2) <a target="_blank" href="http://book.cakephp.org/2.0/en/development/configuration.html#cakephp-core-configuration" style="color:#fff;">I don't / can't use URL rewriting</a>
</p>
<p>
<?php
if (version_compare(PHP_VERSION, '5.2.8', '>=')):
echo '<span class="notice success">';
echo __d('cake_dev', 'Your version of PHP is 5.2.8 or higher.');
echo '</span>';
else:
echo '<span class="notice">';
echo __d('cake_dev', 'Your version of PHP is too low. You need PHP 5.2.8 or higher to use CakePHP.');
echo '</span>';
endif;
?>
</p>
<p>
<?php
if (is_writable(TMP)):
echo '<span class="notice success">';
echo __d('cake_dev', 'Your tmp directory is writable.');
echo '</span>';
else:
echo '<span class="notice">';
echo __d('cake_dev', 'Your tmp directory is NOT writable.');
echo '</span>';
endif;
?>
</p>
<p>
<?php
$settings = Cache::settings();
if (!empty($settings)):
echo '<span class="notice success">';
echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit APP/Config/core.php ', '<em>'. $settings['engine'] . 'Engine</em>');
echo '</span>';
else:
echo '<span class="notice">';
echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in APP/Config/core.php');
echo '</span>';
endif;
?>
</p>
<p>
<?php
$filePresent = null;
if (file_exists(APP . 'Config' . DS . 'database.php')):
echo '<span class="notice success">';
echo __d('cake_dev', 'Your database configuration file is present.');
$filePresent = true;
echo '</span>';
else:
echo '<span class="notice">';
echo __d('cake_dev', 'Your database configuration file is NOT present.');
echo '<br/>';
echo __d('cake_dev', 'Rename APP/Config/database.php.default to APP/Config/database.php');
echo '</span>';
endif;
?>
</p>
<?php
if (isset($filePresent)):
App::uses('ConnectionManager', 'Model');
try {
$connected = ConnectionManager::getDataSource('default');
} catch (Exception $connectionError) {
$connected = false;
}
?>
<p>
<?php
if ($connected && $connected->isConnected()):
echo '<span class="notice success">';
echo __d('cake_dev', 'Cake is able to connect to the database.');
echo '</span>';
else:
echo '<span class="notice">';
echo __d('cake_dev', 'Cake is NOT able to connect to the database.');
echo '<br /><br />';
echo $connectionError->getMessage();
echo '</span>';
endif;
?>
</p>
<?php endif;?>
<?php
App::uses('Validation', 'Utility');
if (!Validation::alphaNumeric('cakephp')) {
echo '<p><span class="notice">';
echo __d('cake_dev', 'PCRE has not been compiled with Unicode support.');
echo '<br/>';
echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding <code>--enable-unicode-properties</code> when configuring');
echo '</span></p>';
}
?>
<h3><?php echo __d('cake_dev', 'Editing this Page'); ?></h3>
<p>
<?php
echo __d('cake_dev', 'To change the content of this page, create: APP/View/Pages/home.ctp.<br />
To change its layout, create: APP/View/Layouts/default.ctp.<br />
You can also add some CSS styles for your pages at: APP/webroot/css.');
?>
</p>
<h3><?php echo __d('cake_dev', 'Getting Started'); ?></h3>
<p>
<?php
echo $this->Html->link(
sprintf('<strong>%s</strong> %s', __d('cake_dev', 'New'), __d('cake_dev', 'CakePHP 2.0 Docs')),
'http://book.cakephp.org/2.0/en/',
array('target' => '_blank', 'escape' => false)
);
?>
</p>
<p>
<?php
echo $this->Html->link(
__d('cake_dev', 'The 15 min Blog Tutorial'),
'http://book.cakephp.org/2.0/en/tutorials-and-examples/blog/blog.html',
array('target' => '_blank', 'escape' => false)
);
?>
</p>
<h3><?php echo __d('cake_dev', 'More about Cake'); ?></h3>
<p>
<?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
</p>
<p>
<?php echo __d('cake_dev', 'Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.'); ?>
</p>
<ul>
<li><a href="http://cakefoundation.org/"><?php echo __d('cake_dev', 'Cake Software Foundation'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Promoting development related to CakePHP'); ?></li></ul></li>
<li><a href="http://www.cakephp.org"><?php echo __d('cake_dev', 'CakePHP'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'The Rapid Development Framework'); ?></li></ul></li>
<li><a href="http://book.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Documentation'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Your Rapid Development Cookbook'); ?></li></ul></li>
<li><a href="http://api20.cakephp.org"><?php echo __d('cake_dev', 'CakePHP API'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Quick Reference'); ?></li></ul></li>
<li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li>
<li><a href="http://live.cakephp.org"><?php echo __d('cake_dev', 'The Show'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'The Show is a live and archived internet radio broadcast CakePHP-related topics and answer questions live via IRC, Skype, and telephone.'); ?></li></ul></li>
<li><a href="http://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li>
<li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
<ul><li><?php echo __d('cake_dev', 'Live chat about CakePHP'); ?></li></ul></li>
<li><a href="http://github.com/cakephp/"><?php echo __d('cake_dev', 'CakePHP Code'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'For the Development of CakePHP Git repository, Downloads'); ?></li></ul></li>
<li><a href="http://cakephp.lighthouseapp.com/"><?php echo __d('cake_dev', 'CakePHP Lighthouse'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'CakePHP Tickets, Wiki pages, Roadmap'); ?></li></ul></li>
</ul>

View File

View File

@ -1,28 +1,27 @@
<div class="signatures form">
<?php echo $this->Form->create('Signature');?>
<fieldset>
<legend><?php __('Add Signature'); ?></legend>
<legend><?php echo __('Add Signature'); ?></legend>
<?php
echo $this->Form->hidden('event_id');
echo $this->Form->input('type');
echo $this->Form->input('to_ids', array(
'checked' => true,
'after' => ' <i>Is this signature specific enough to be exported to IDS systems?</i>',
'checked' => true,
'after' => ' <i>Is this signature specific enough to be exported to IDS systems?</i>',
));
echo $this->Form->input('value', array(
'error' => array('escape' => false),
'error' => array('escape' => false),
));
echo $this->Form->input('batch_import', array(
'type' => 'checkbox',
'after' => ' <i>When selected each line in the value field will be a signature.</i>',
'type' => 'checkbox',
'after' => ' <i>When selected each line in the value field will be a signature.</i>',
));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit', true));?>
<?php echo $this->Form->end(__('Submit'));?>
</div>
<div class="actions">
<h3><?php __('Actions'); ?></h3>
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
</ul>
</div>

25
app/View/Signatures/edit.ctp Executable file
View File

@ -0,0 +1,25 @@
<div class="signatures form">
<?php echo $this->Form->create('Signature');?>
<fieldset>
<legend><?php echo __('Edit Signature'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('event_id');
echo $this->Form->input('type');
echo $this->Form->input('value');
echo $this->Form->input('to_ids');
echo $this->Form->input('uuid');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $this->Form->value('Signature.id')), null, __('Are you sure you want to delete # %s?', $this->Form->value('Signature.id'))); ?></li>
<li><?php echo $this->Html->link(__('List Signatures'), array('action' => 'index'));?></li>
<li><?php echo $this->Html->link(__('List Events'), array('controller' => 'events', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New Event'), array('controller' => 'events', 'action' => 'add')); ?> </li>
</ul>
</div>

52
app/View/Signatures/index.ctp Executable file
View File

@ -0,0 +1,52 @@
<div class="signatures index">
<h2><?php echo __('Signatures');?></h2>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $this->Paginator->sort('event_id');?></th>
<th><?php echo $this->Paginator->sort('type');?></th>
<th><?php echo $this->Paginator->sort('value');?></th>
<th>To IDS</th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
foreach ($signatures as $signature): ?>
<!-- <tr onclick="document.location ='<?php echo $this->Html->url(array('controller' => 'events', 'action' => 'view', $signature['Signature']['event_id']), true) ; // FIXME activate link onclick ?>';"> -->
<tr>
<td>
<?php echo $this->Html->link($signature['Event']['id'], array('controller' => 'events', 'action' => 'view', $signature['Event']['id'])); ?>
</td>
<td><?php echo h($signature['Signature']['type']); ?>&nbsp;</td>
<td><?php echo nl2br(Sanitize::html($signature['Signature']['value'])); ?>&nbsp;</td>
<td><?php echo $signature['Signature']['to_ids'] ? 'Yes' : 'No'; ?>&nbsp;</td>
<td class="actions"><?php
if ($isAdmin || $signature['Event']['org'] == $me['org']) {
echo $this->Html->link(__('Edit'), array('action' => 'edit', $signature['Signature']['id']));
echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $signature['Signature']['id']), null, __('Are you sure you want to delete this signature?'));
}
echo $this->Html->link(__('View'), array('controller' => 'events', 'action' => 'view', $signature['Signature']['event_id']));
?>
</td>
</tr>
<?php endforeach; ?>
</table>
<p>
<?php
echo $this->Paginator->counter(array(
'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
));
?> </p>
<div class="paging">
<?php
echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
echo $this->Paginator->numbers(array('separator' => ''));
echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
?>
</div>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>

View File

@ -1,7 +1,7 @@
<div class="signatures form">
<?php echo $this->Form->create('Signature');?>
<fieldset>
<legend><?php __('Search Signature'); ?></legend>
<legend><?php echo __('Search Signature'); ?></legend>
<?php
echo $this->Form->input('keyword');
?>
@ -9,7 +9,6 @@
<?php echo $this->Form->end(__('Search', true));?>
</div>
<div class="actions">
<h3><?php __('Actions'); ?></h3>
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>

View File

@ -8,7 +8,7 @@
echo $this->Form->input('password');
echo $this->Form->input('org');
echo $this->Form->input('autoalert');
echo $this->Form->input('snort_sid');
echo $this->Form->input('nids_sid');
echo $this->Form->input('gpgkey');
?>
</fieldset>

View File

@ -0,0 +1,28 @@
<div class="users form">
<?php echo $this->Form->create('User');?>
<fieldset>
<legend><?php echo __('Admin Add User'); ?></legend>
<?php
echo $this->Form->input('password');
echo $this->Form->input('org');
echo $this->Form->input('email');
echo $this->Form->input('autoalert');
echo $this->Form->input('authkey');
echo $this->Form->input('invited_by');
echo $this->Form->input('gpgkey');
echo $this->Form->input('nids_sid');
echo $this->Form->input('termsaccepted');
echo $this->Form->input('newsread');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('List Users'), array('action' => 'index'));?></li>
<li><?php echo $this->Html->link(__('List Events'), array('controller' => 'events', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New Event'), array('controller' => 'events', 'action' => 'add')); ?> </li>
</ul>
</div>

View File

@ -0,0 +1,30 @@
<div class="users form">
<?php echo $this->Form->create('User');?>
<fieldset>
<legend><?php echo __('Admin Edit User'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('password');
echo $this->Form->input('org');
echo $this->Form->input('email');
echo $this->Form->input('autoalert');
echo $this->Form->input('authkey');
echo $this->Form->input('invited_by');
echo $this->Form->input('gpgkey');
echo $this->Form->input('nids_sid');
echo $this->Form->input('termsaccepted');
echo $this->Form->input('newsread');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $this->Form->value('User.id')), null, __('Are you sure you want to delete # %s?', $this->Form->value('User.id'))); ?></li>
<li><?php echo $this->Html->link(__('List Users'), array('action' => 'index'));?></li>
<li><?php echo $this->Html->link(__('List Events'), array('controller' => 'events', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New Event'), array('controller' => 'events', 'action' => 'add')); ?> </li>
</ul>
</div>

View File

@ -0,0 +1,62 @@
<div class="users index">
<h2><?php echo __('Users');?></h2>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $this->Paginator->sort('id');?></th>
<th><?php echo $this->Paginator->sort('password');?></th>
<th><?php echo $this->Paginator->sort('org');?></th>
<th><?php echo $this->Paginator->sort('email');?></th>
<th><?php echo $this->Paginator->sort('autoalert');?></th>
<th><?php echo $this->Paginator->sort('authkey');?></th>
<th><?php echo $this->Paginator->sort('invited_by');?></th>
<th><?php echo $this->Paginator->sort('gpgkey');?></th>
<th><?php echo $this->Paginator->sort('nids_sid');?></th>
<th><?php echo $this->Paginator->sort('termsaccepted');?></th>
<th><?php echo $this->Paginator->sort('newsread');?></th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
foreach ($users as $user): ?>
<tr>
<td><?php echo h($user['User']['id']); ?>&nbsp;</td>
<td><?php echo h($user['User']['password']); ?>&nbsp;</td>
<td><?php echo h($user['User']['org']); ?>&nbsp;</td>
<td><?php echo h($user['User']['email']); ?>&nbsp;</td>
<td><?php echo h($user['User']['autoalert']); ?>&nbsp;</td>
<td><?php echo h($user['User']['authkey']); ?>&nbsp;</td>
<td><?php echo h($user['User']['invited_by']); ?>&nbsp;</td>
<td><?php echo h($user['User']['gpgkey']); ?>&nbsp;</td>
<td><?php echo h($user['User']['nids_sid']); ?>&nbsp;</td>
<td><?php echo h($user['User']['termsaccepted']); ?>&nbsp;</td>
<td><?php echo h($user['User']['newsread']); ?>&nbsp;</td>
<td class="actions">
<?php echo $this->Html->link(__('View'), array('action' => 'view', $user['User']['id'])); ?>
<?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $user['User']['id'])); ?>
<?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $user['User']['id']), null, __('Are you sure you want to delete # %s?', $user['User']['id'])); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<p>
<?php
echo $this->Paginator->counter(array(
'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
));
?> </p>
<div class="paging">
<?php
echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
echo $this->Paginator->numbers(array('separator' => ''));
echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
?>
</div>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('New User'), array('action' => 'add')); ?></li>
<li><?php echo $this->Html->link(__('List Events'), array('controller' => 'events', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New Event'), array('controller' => 'events', 'action' => 'add')); ?> </li>
</ul>
</div>

View File

@ -0,0 +1,117 @@
<div class="users view">
<div class="actions" style="float:right;">
<ul><li><?php echo $this->Html->link(__('Edit Profile', true), array('action' => 'edit', $user['User']['id'])); ?> </li></ul>
</div>
<h2><?php echo __('User');?></h2>
<dl>
<dt><?php echo __('Id'); ?></dt>
<dd>
<?php echo h($user['User']['id']); ?>
&nbsp;
</dd>
<dt><?php echo __('Password'); ?></dt>
<dd>
<?php echo h($user['User']['password']); ?>
&nbsp;
</dd>
<dt><?php echo __('Org'); ?></dt>
<dd>
<?php echo h($user['User']['org']); ?>
&nbsp;
</dd>
<dt><?php echo __('Email'); ?></dt>
<dd>
<?php echo h($user['User']['email']); ?>
&nbsp;
</dd>
<dt><?php echo __('Autoalert'); ?></dt>
<dd>
<?php echo h($user['User']['autoalert']); ?>
&nbsp;
</dd>
<dt><?php echo __('Authkey'); ?></dt>
<dd>
<?php echo h($user['User']['authkey']); ?>
&nbsp;
</dd>
<dt><?php echo __('Invited By'); ?></dt>
<dd>
<?php echo h($user['User']['invited_by']); ?>
&nbsp;
</dd>
<dt><?php echo __('Gpgkey'); ?></dt>
<dd>
<?php echo h($user['User']['gpgkey']); ?>
&nbsp;
</dd>
<dt><?php echo __('Nids Sid'); ?></dt>
<dd>
<?php echo h($user['User']['nids_sid']); ?>
&nbsp;
</dd>
<dt><?php echo __('Termsaccepted'); ?></dt>
<dd>
<?php echo h($user['User']['termsaccepted']); ?>
&nbsp;
</dd>
<dt><?php echo __('Newsread'); ?></dt>
<dd>
<?php echo h($user['User']['newsread']); ?>
&nbsp;
</dd>
</dl>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('Edit User'), array('action' => 'edit', $user['User']['id'])); ?> </li>
<li><?php echo $this->Form->postLink(__('Delete User'), array('action' => 'delete', $user['User']['id']), null, __('Are you sure you want to delete # %s?', $user['User']['id'])); ?> </li>
<li><?php echo $this->Html->link(__('List Users'), array('action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New User'), array('action' => 'add')); ?> </li>
<li><?php echo $this->Html->link(__('List Events'), array('controller' => 'events', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New Event'), array('controller' => 'events', 'action' => 'add')); ?> </li>
</ul>
</div>
<div class="related">
<h3><?php echo __('Related Events');?></h3>
<?php if (!empty($user['Event'])):?>
<table cellpadding = "0" cellspacing = "0">
<tr>
<th><?php echo __('Id'); ?></th>
<th><?php echo __('Org'); ?></th>
<th><?php echo __('Date'); ?></th>
<th><?php echo __('Risk'); ?></th>
<th><?php echo __('Info'); ?></th>
<th><?php echo __('User Id'); ?></th>
<th><?php echo __('Alerted'); ?></th>
<th><?php echo __('Uuid'); ?></th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
$i = 0;
foreach ($user['Event'] as $event): ?>
<tr>
<td><?php echo $event['id'];?></td>
<td><?php echo $event['org'];?></td>
<td><?php echo $event['date'];?></td>
<td><?php echo $event['risk'];?></td>
<td><?php echo $event['info'];?></td>
<td><?php echo $event['user_id'];?></td>
<td><?php echo $event['alerted'];?></td>
<td><?php echo $event['uuid'];?></td>
<td class="actions">
<?php echo $this->Html->link(__('View'), array('controller' => 'events', 'action' => 'view', $event['id'])); ?>
<?php echo $this->Html->link(__('Edit'), array('controller' => 'events', 'action' => 'edit', $event['id'])); ?>
<?php echo $this->Form->postLink(__('Delete'), array('controller' => 'events', 'action' => 'delete', $event['id']), null, __('Are you sure you want to delete # %s?', $event['id'])); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<div class="actions">
<ul>
<li><?php echo $this->Html->link(__('New Event'), array('controller' => 'events', 'action' => 'add'));?> </li>
</ul>
</div>
</div>

View File

@ -4,7 +4,6 @@
<legend><?php __('Edit User'); ?></legend>
<?php
echo $this->Form->input('id');
if ($isAdmin) echo $this->Form->input('group_id');
echo $this->Form->input('email');
echo $this->Form->input('password');
if ($isAdmin) echo $this->Form->input('org');

View File

@ -1,19 +1,14 @@
<div class="users index">
<h2><?php __('Members');?></h2>
<h2>Members</h2>
<table cellpadding="0" cellspacing="0" style="width:300px;">
<tr>
<th>Organisation</th>
<th># of members</th>
</tr>
<?php
$i = 0;
foreach ($orgs as $org):
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
?>
<tr<?php echo $class;?>>
<tr>
<td><?php echo $org['User']['org']; ?>&nbsp;</td>
<td><?php echo $org[0]['num_members']; ?>&nbsp;</td>
@ -30,15 +25,9 @@
<th>Amount</th>
</tr>
<?php
// LATER beautify types_histogram
$i = 0;
foreach ($types_histogram as $item):
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
?>
<tr<?php echo $class;?>>
<tr>
<td><?php echo $item['Event']['org']; ?>&nbsp;</td>
<td><?php echo $item['Signature']['type']; ?>&nbsp;</td>
<td><?php echo $item['0']['num_types']; ?>&nbsp;</td>

View File

@ -1,6 +1,12 @@
<div class="news view">
<h2>News</h2>
<h3>March 2012</h3>
<p><b>Backend rewrite + security</b><br/>
Complete rewrite of the backend code to migrate to CakePHP 2.x (from CakePHP 1.3). <br/>
During this rewrite the code was cleaned up, CSRF protection should now be present on all the important actions.<br/>
Password strength validation, anti-bruteforce has been implemented.<br/>
Some intermittent bugs might have slipped in during the (manual) conversion. Please contact me <a href="mailto:user1088@qet.be">user1088@qet.be</a> to report any issues.
</p>
<p><b>Terms and News</b><br/>
Terms and conditions have been enabled. You should only see this page once.<br/>
When new software updates of CyDefSIG are installed you will see the news page.</p>

View File

@ -43,7 +43,7 @@ holder or other party has been advised of the possibility of such damages.</li>
<?php
if (0 == $termsaccepted) {
if (!isset($termsaccepted)) {
echo $this->Form->create('User');
echo $this->Form->hidden('termsaccepted', array('default'=> '1'));
echo $this->Form->end(__('Accept Terms', true));

58
app/View/Users/view.ctp Executable file
View File

@ -0,0 +1,58 @@
<div class="users view">
<div class="actions" style="float:right;">
<ul><li><?php echo $this->Html->link(__('Edit Profile', true), array('action' => 'edit', $user['User']['id'])); ?> </li></ul>
</div>
<h2><?php echo __('User');?></h2>
<dl>
<dt><?php echo __('Id'); ?></dt>
<dd>
<?php echo h($user['User']['id']); ?>
&nbsp;
</dd>
<dt><?php echo __('Email'); ?></dt>
<dd>
<?php echo h($user['User']['email']); ?>
&nbsp;
</dd>
<dt><?php echo __('Org'); ?></dt>
<dd>
<?php echo h($user['User']['org']); ?>
&nbsp;
</dd>
<dt><?php echo __('Autoalert'); ?></dt>
<dd>
<?php echo h(0 == ($user['User']['autoalert'])) ? 'no' : 'yes'; ?>
&nbsp;
</dd>
<dt><?php echo __('Authkey'); ?></dt>
<dd>
<?php echo h($user['User']['authkey']); ?>
(<?php echo $this->Html->link('reset', array('controller' => 'users', 'action' => 'resetauthkey', $user['User']['id']));?>)
&nbsp;
</dd>
<dt><?php echo __('NIDS Start SID'); ?></dt>
<dd>
<?php echo h($user['User']['nids_sid']); ?>
&nbsp;
</dd>
<dt><?php echo __('Termsaccepted'); ?></dt>
<dd>
<?php echo h((0 == $user['User']['termsaccepted'])? 'no' : 'yes'); ?>
&nbsp;
</dd>
<dt><?php echo __('GPG Key'); ?></dt>
<dd style="font-size: 10px; line-height:100%;">
<code><?php echo nl2br(h($user['User']['gpgkey'])); ?></code>
&nbsp;
</dd>
</dl>
</div>
<div class="actions">
<h3><?php __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('Edit User', true), array('action' => 'edit', $user['User']['id'])); ?> </li>
<li><?php echo $this->Html->link(__('Delete User', true), array('action' => 'delete', $user['User']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $user['User']['id'])); ?> </li>
<li>&nbsp;</li>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>

View File

@ -1,272 +0,0 @@
<?php
App::import('Sanitize');
class AppController extends Controller {
var $components = array('Acl', 'Auth', 'Session');
var $helpers = array('Html', 'Form', 'Session');
// TODO convert things to form submits to prevent CSRF
function beforeFilter() {
//Configure AuthComponent
$this->Auth->authorize = 'actions';
$this->Auth->userModel = 'User';
$this->Auth->fields = array('username' => 'email', 'password' => 'password');
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'routeafterlogin');
$this->Auth->loginRedirect = array('controller' => 'events', 'action' => 'index');
$this->Auth->actionPath = 'controllers/';
$this->Auth->allowedActions = array('build_acl', 'initDB'); // FIXME remove build_acl
}
/**
* Convert an array to the same array but with the values also as index instead of an interface_exists
*/
function _arrayToValuesIndexArray($old_array) {
$new_array = Array();
foreach ($old_array as $value)
$new_array[$value] = $value;
return $new_array;
}
/**
* checks if the currently logged user is an administrator
*/
function isAdmin() {
// TODO group membership should be checked correctly.
// but as quick workaround I check if the group_id = 1 = admin
$user = $this->Auth->user();
if (1 == $user['User']['group_id'])
return true;
else
return false;
}
/**
* These functions will look at every controller in your application.
* It will add any non-private, non Controller methods to the Acl table,
* nicely nested underneath the owning controller. You can add and run this
* in your AppController or any controller for that matter, just be sure to
* remove it before putting your application into production.
* Now run the action in your browser, eg. http://localhost/groups/build_acl,
* This will build your ACO table.
*/
function build_acl() {
if (!Configure::read('debug')) {
return $this->_stop();
}
$log = array();
$aco =& $this->Acl->Aco;
$root = $aco->node('controllers');
if (!$root) {
$aco->create(array('parent_id' => null, 'model' => null, 'alias' => 'controllers'));
$root = $aco->save();
$root['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for controllers';
} else {
$root = $root[0];
}
App::import('Core', 'File');
$Controllers = App::objects('controller');
$appIndex = array_search('App', $Controllers);
if ($appIndex !== false ) {
unset($Controllers[$appIndex]);
}
$baseMethods = get_class_methods('Controller');
$baseMethods[] = 'build_acl';
$Plugins = $this->_getPluginControllerNames();
$Controllers = array_merge($Controllers, $Plugins);
// look at each controller in app/controllers
foreach ($Controllers as $ctrlName) {
$methods = $this->_getClassMethods($this->_getPluginControllerPath($ctrlName));
// Do all Plugins First
if ($this->_isPlugin($ctrlName)){
$pluginNode = $aco->node('controllers/'.$this->_getPluginName($ctrlName));
if (!$pluginNode) {
$aco->create(array('parent_id' => $root['Aco']['id'], 'model' => null, 'alias' => $this->_getPluginName($ctrlName)));
$pluginNode = $aco->save();
$pluginNode['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for ' . $this->_getPluginName($ctrlName) . ' Plugin';
}
}
// find / make controller node
$controllerNode = $aco->node('controllers/'.$ctrlName);
if (!$controllerNode) {
if ($this->_isPlugin($ctrlName)){
$pluginNode = $aco->node('controllers/' . $this->_getPluginName($ctrlName));
$aco->create(array('parent_id' => $pluginNode['0']['Aco']['id'], 'model' => null, 'alias' => $this->_getPluginControllerName($ctrlName)));
$controllerNode = $aco->save();
$controllerNode['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for ' . $this->_getPluginControllerName($ctrlName) . ' ' . $this->_getPluginName($ctrlName) . ' Plugin Controller';
} else {
$aco->create(array('parent_id' => $root['Aco']['id'], 'model' => null, 'alias' => $ctrlName));
$controllerNode = $aco->save();
$controllerNode['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for ' . $ctrlName;
}
} else {
$controllerNode = $controllerNode[0];
}
//clean the methods. to remove those in Controller and private actions.
foreach ($methods as $k => $method) {
if (strpos($method, '_', 0) === 0) {
unset($methods[$k]);
continue;
}
if (in_array($method, $baseMethods)) {
unset($methods[$k]);
continue;
}
$methodNode = $aco->node('controllers/'.$ctrlName.'/'.$method);
if (!$methodNode) {
$aco->create(array('parent_id' => $controllerNode['Aco']['id'], 'model' => null, 'alias' => $method));
$methodNode = $aco->save();
$log[] = 'Created Aco node for '. $method;
}
}
}
if(count($log)>0) {
debug($log);
}
}
function _getClassMethods($ctrlName = null) {
App::import('Controller', $ctrlName);
if (strlen(strstr($ctrlName, '.')) > 0) {
// plugin's controller
$num = strpos($ctrlName, '.');
$ctrlName = substr($ctrlName, $num+1);
}
$ctrlclass = $ctrlName . 'Controller';
$methods = get_class_methods($ctrlclass);
// Add scaffold defaults if scaffolds are being used
$properties = get_class_vars($ctrlclass);
if (array_key_exists('scaffold',$properties)) {
if($properties['scaffold'] == 'admin') {
$methods = array_merge($methods, array('admin_add', 'admin_edit', 'admin_index', 'admin_view', 'admin_delete'));
} else {
$methods = array_merge($methods, array('add', 'edit', 'index', 'view', 'delete'));
}
}
return $methods;
}
function _isPlugin($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) > 1) {
return true;
} else {
return false;
}
}
function _getPluginControllerPath($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) == 2) {
return $arr[0] . '.' . $arr[1];
} else {
return $arr[0];
}
}
function _getPluginName($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) == 2) {
return $arr[0];
} else {
return false;
}
}
function _getPluginControllerName($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) == 2) {
return $arr[1];
} else {
return false;
}
}
/**
* Get the names of the plugin controllers ...
*
* This function will get an array of the plugin controller names, and
* also makes sure the controllers are available for us to get the
* method names by doing an App::import for each plugin controller.
*
* @return array of plugin names.
*
*/
function _getPluginControllerNames() {
App::import('Core', 'File', 'Folder');
$paths = Configure::getInstance();
$folder =& new Folder();
$folder->cd(APP . 'plugins');
// Get the list of plugins
$Plugins = $folder->read();
$Plugins = $Plugins[0];
$arr = array();
// Loop through the plugins
foreach($Plugins as $pluginName) {
// Change directory to the plugin
$didCD = $folder->cd(APP . 'plugins'. DS . $pluginName . DS . 'controllers');
// Get a list of the files that have a file name that ends
// with controller.php
$files = $folder->findRecursive('.*_controller\.php');
// Loop through the controllers we found in the plugins directory
foreach($files as $fileName) {
// Get the base file name
$file = basename($fileName);
// Get the controller name
$file = Inflector::camelize(substr($file, 0, strlen($file)-strlen('_controller.php')));
if (!preg_match('/^'. Inflector::humanize($pluginName). 'App/', $file)) {
if (!App::import('Controller', $pluginName.'.'.$file)) {
debug('Error importing '.$file.' for plugin '.$pluginName);
} else {
/// Now prepend the Plugin name ...
// This is required to allow us to fetch the method names.
$arr[] = Inflector::humanize($pluginName) . "/" . $file;
}
}
}
}
return $arr;
}
}
?>

Some files were not shown because too many files have changed in this diff Show More