Merge branch 'master' of ssh://misp.ncirc.nato.int/home/git/cydefsig.git

pull/63/head
noud 2012-10-22 15:14:33 +02:00
commit e300ab7ffa
89 changed files with 6174 additions and 137 deletions

2
.gitignore vendored
View File

@ -13,3 +13,5 @@
/app/tmp/cache/views/myapp*
/app/files/*
/app/webroot/img/logo.png
/app/Config/bootstrap.php
/app/Config/database.php

45
app/Config/Schema/db_group.php Executable file
View File

@ -0,0 +1,45 @@
<?php
class DbGroupSchema extends CakeSchema {
public $name = 'DbGroup';
public function before($event = array()) {
return true;
}
public function after($event = array()) {
if (isset($event['create'])) {
switch ($event['create']) {
case 'groups':
// populate groups
// $groups = ClassRegistry::init('Group');
// $groups->create();
// $groups->save(array('Group' => array('name' => 'malware analyst', 'perm_add' => true, 'perm_modify' => true, 'perm_publish' => false, 'perm_full' => false)));
// $groups->create();
// $groups->save(array('Group' => array('name' => 'admin', 'perm_add' => true, 'perm_modify' => true, 'perm_publish' => true, 'perm_full' => true)));
// $groups->create();
// $groups->save(array('Group' => array('name' => 'IDS analyst', 'perm_add' => true, 'perm_modify' => true, 'perm_publish' => true, 'perm_full' => false)));
// $groups->create();
// $groups->save(array('Group' => array('name' => 'guest', 'perm_add' => false, 'perm_modify' => false, 'perm_publish' => false, 'perm_full' => false)));
// populate Users.group_id
// $users = ClassRegistry::init('User');
// $user = $users->read(null, '1');
// $users->saveField('group_id', '2'); // $user['User']['group_id'] = '2';
break;
}
}
}
public $groups = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 100, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
'perm_add' => array('type' => 'boolean', 'null' => true, 'default' => NULL),
'perm_modify' => array('type' => 'boolean', 'null' => true, 'default' => NULL),
'perm_publish' => array('type' => 'boolean', 'null' => true, 'default' => NULL),
'perm_full' => array('type' => 'boolean', 'null' => true, 'default' => NULL),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'InnoDB')
);
}

31
app/Config/Schema/db_group.sql Executable file
View File

@ -0,0 +1,31 @@
-- ACL, group table
-- works in conjunction with: CakePHP AclComponent
CREATE TABLE groups (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
perm_add boolean,
perm_modify boolean,
perm_publish boolean,
perm_full boolean,
created DATETIME,
modified DATETIME
);
-- ALTER TABLE users ADD COLUMN group_id INT(11);
-- data of Groups
-- INSERT INTO groups (name,perm_add,perm_modify,perm_publish,perm_full) VALUES ('malware analyst',true,true,false,false);
-- INSERT INTO groups (name,perm_add,perm_modify,perm_publish,perm_full) VALUES ('admin',true,true,true,true);
-- INSERT INTO groups (name,perm_add,perm_modify,perm_publish,perm_full) VALUES ('IDS analyst',true,true,true,false);
-- INSERT INTO groups (name,perm_add,perm_modify,perm_publish,perm_full) VALUES ('guest',false,false,false,false);
-- CakePHP AclComponent acor & aros tables
-- aros table (should be auto generated on group create)
-- INSERT INTO aros (model,foreign_key,lft,rght) VALUES ('Group',1,1,2);
-- INSERT INTO aros (model,foreign_key,lft,rght) VALUES ('Group',2,3,4);
-- INSERT INTO aros (model,foreign_key,lft,rght) VALUES ('Group',3,5,6);
-- INSERT INTO aros (model,foreign_key,lft,rght) VALUES ('Group',4,7,8);
-- aros_acos

28
app/Config/Schema/db_log.php Executable file
View File

@ -0,0 +1,28 @@
<?php
class DbLogSchema extends CakeSchema {
public $name = 'DbLog';
public function before($event = array()) {
return true;
}
public function after($event = array()) {
}
public $logs = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'title' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
'model' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 20, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'model_id' => array('type' => 'integer', 'null' => true, 'default' => NULL),
'action' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 20, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'user_id' => array('type' => 'integer', 'null' => true, 'default' => NULL),
'change' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'email' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'org' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'description' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
}

21
app/Config/Schema/db_log.sql Executable file
View File

@ -0,0 +1,21 @@
-- Audit, log table
-- works in conjunction with:
-- https://github.com/alkemann/CakePHP-Assets/wiki
-- also described at:
-- http://bakery.cakephp.org/articles/alkemann/2008/10/21/logablebehavior
DROP TABLE logs;
CREATE TABLE logs (
id int(11) NOT NULL AUTO_INCREMENT,
title varchar(255),
created DATETIME,
description varchar(255),
model varchar(20),
model_id int(11),
action varchar(20),
user_id int(11),
`change` varchar(255),
email varchar(255),
org varchar(255) COLLATE utf8_bin,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=2 ;

View File

@ -0,0 +1,81 @@
<?php
class AppSchema extends CakeSchema {
public $file = 'schema_0.2.2.1.php';
public function before($event = array()) {
return true;
}
public function after($event = array()) {
if (isset($event['update'])) {
switch ($event['update']) {
case 'users':
// TDDO Schema,Users.group_id is not here
break;
}
}
}
public $attributes = 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'),
'category' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'value1' => array('type' => 'text', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'to_ids' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
'uuid' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 40, 'key' => 'index', 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'revision' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 10),
'private' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'value2' => array('type' => 'text', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'event_id' => array('column' => 'event_id', 'unique' => 0), 'uuid' => array('column' => 'uuid', 'unique' => 0)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
public $bruteforces = array(
'ip' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'username' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'expire' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
'indexes' => array(),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
public $events = 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, 'key' => 'index', 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'private' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'published' => array('type' => 'boolean', 'null' => false, 'default' => '0'),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'uuid' => array('column' => 'uuid', 'unique' => 0), 'info' => array('column' => 'info', 'unique' => 0)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
public $servers = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'url' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'authkey' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 40, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'org' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'push' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'pull' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'lastfetchedid' => array('type' => 'integer', 'null' => false, 'default' => NULL),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
public $users = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'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),
'group_id' => array('type' => 'integer', 'null' => true, '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')
);
}

View File

@ -1,6 +1,8 @@
<?php
<?php
class AppSchema extends CakeSchema {
public $file = 'schema_0.2.2.php';
public function before($event = array()) {
return true;
}

View File

@ -0,0 +1,101 @@
<?php
class AppSchema extends CakeSchema {
public $file = 'schema_0.2.3.php';
public function before($event = array()) {
return true;
}
public function after($event = array()) {
}
public $attributes = 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'),
'category' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'value1' => array('type' => 'text', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'to_ids' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
'uuid' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 40, 'key' => 'index', 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'revision' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => 10),
'private' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'value2' => array('type' => 'text', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'event_id' => array('column' => 'event_id', 'unique' => 0), 'uuid' => array('column' => 'uuid', 'unique' => 0)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
public $bruteforces = array(
'ip' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'username' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'expire' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
'indexes' => array(),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
public $events = 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, 'key' => 'index', 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'private' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'published' => array('type' => 'boolean', 'null' => false, 'default' => '0'),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'uuid' => array('column' => 'uuid', 'unique' => 0), 'info' => array('column' => 'info', 'unique' => 0)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
public $groups = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 100, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
'perm_add' => array('type' => 'boolean', 'null' => true, 'default' => NULL),
'perm_modify' => array('type' => 'boolean', 'null' => true, 'default' => NULL),
'perm_publish' => array('type' => 'boolean', 'null' => true, 'default' => NULL),
'perm_full' => array('type' => 'boolean', 'null' => true, 'default' => NULL),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'InnoDB')
);
public $logs = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'title' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
'model' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 20, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'model_id' => array('type' => 'integer', 'null' => true, 'default' => NULL),
'action' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 20, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'user_id' => array('type' => 'integer', 'null' => true, 'default' => NULL),
'change' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'email' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'org' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'description' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
public $servers = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'url' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'authkey' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 40, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'org' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
'push' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'pull' => array('type' => 'boolean', 'null' => false, 'default' => NULL),
'lastfetchedid' => array('type' => 'integer', 'null' => false, 'default' => NULL),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_bin', 'engine' => 'MyISAM')
);
public $users = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
'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),
'group_id' => array('type' => 'integer', 'null' => true, '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')
);
}

View File

@ -111,6 +111,10 @@ Configure::write('CyDefSIG.logo', 'orgs/MIL.be.png'); // used in Events::ind
Configure::write('CyDefSIG.showorg', 'true'); // show the name/flag of the organisation that uploaded the data
Configure::write('CyDefSIG.showowner', 'false'); // show the email of the owner that uploaded the data
Configure::write('CyDefSIG.sync', 'false'); // enable features related to syncing with other CyDefSIG instances
Configure::write('CyDefSIG.private', 'true'); // respect private to org or server.
if ('true' == Configure::read('CyDefSIG.private')) {
Configure::write('CyDefSIG.sync', 'true');
}
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
@ -183,6 +187,12 @@ Configure::write('CyDefSIG.correlation', 'sql'); // correlation between a
*
*/
CakePlugin::load('AclExtras');
CakePlugin::load('SysLog');
CakePlugin::load('Assets'); // having Logable
CakePlugin::load('SysLogLogable');
CakePlugin::load('MagicTools'); // having OrphansProtectable
/**
* You can attach event listeners to the request lifecyle as Dispatcher Filter . By Default CakePHP bundles two filters:

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

@ -27,8 +27,10 @@
*/
Router::connect('/', array('controller' => 'events', 'action' => 'index'));
// admin pagination
// admin Paginator
Router::connect('/users/admin_index/*', array('controller' => 'users', 'action' => 'index', 'admin' => true));
Router::connect('/groups/admin_index/*', array('controller' => 'groups', 'action' => 'index', 'admin' => true));
Router::connect('/logs/admin_index/*', array('controller' => 'logs', 'action' => 'index', 'admin' => true));
// Activate REST
Router::mapResources(array('events'));

View File

@ -0,0 +1,12 @@
<?php
class Populate023Shell extends AppShell {
public $tasks = array('Groups', 'GroupToAroAco', 'GroupId');
public function main() {
// perform tasks
sleep(30);
$this->Groups->execute();
$this->GroupId->execute('2');
$this->GroupToAroAco->execute();
}
}

View File

@ -0,0 +1,14 @@
<?php
App::import('Controller', 'Users');
class GroupIdTask extends Shell {
var $uses = array('User');
var $Users;
public function execute($fk = '1') {
$this->Users = new UsersController();
$this->Users->constructClasses();
$this->Users->setgroupid($fk);
}
}

View File

@ -0,0 +1,18 @@
<?php
App::import('Controller', 'Groups');
class GroupToAroAcoTask extends Shell {
var $uses = array('Group');
var $Groups;
public function execute() {
$this->Groups = new GroupsController();
$this->Groups->constructClasses();
$groups = $this->Group->find('all');
foreach ($groups as $group) {
$this->Groups->saveAcl(array('model' => 'Group', 'foreign_key' => $group['Group']['id']), $group['Group']['perm_add'], $group['Group']['perm_modify'], $group['Group']['perm_publish']);
}
}
}

View File

@ -0,0 +1,24 @@
<?php
App::import('Controller', 'Groups');
class GroupsTask extends Shell {
var $uses = array('Group');
var $Groups;
public function execute() {
$this->Groups = new GroupsController();
$this->Groups->constructClasses();
$groups = ClassRegistry::init('Group');
$groups->create();
$groups->save(array('Group' => array('name' => 'malware analyst', 'perm_add' => true, 'perm_modify' => true, 'perm_publish' => false, 'perm_full' => false)));
$groups->create();
$groups->save(array('Group' => array('name' => 'admin', 'perm_add' => true, 'perm_modify' => true, 'perm_publish' => true, 'perm_full' => true)));
$groups->create();
$groups->save(array('Group' => array('name' => 'IDS analyst', 'perm_add' => true, 'perm_modify' => true, 'perm_publish' => true, 'perm_full' => false)));
$groups->create();
$groups->save(array('Group' => array('name' => 'guest', 'perm_add' => false, 'perm_modify' => false, 'perm_publish' => false, 'perm_full' => false)));
}
}

0
app/Console/cake Normal file → Executable file
View File

View File

@ -0,0 +1,12 @@
#!/bin/sh
# degrate 0.2.3 to 0.2.2
# step into project and ..
PRJCT=/var/www/cydefsig/app
cd ${PRJCT}
# update Schema, remove Users.group_id
./Console/cake schema update -s 0.2.2
exit 0;

View File

@ -0,0 +1,29 @@
#!/bin/sh
# migrate 0.2.2 to 0.2.3
# DataBase migrate, Audit and Access Control granulation
# step into project and ..
PRJCT=/var/www/cydefsig/app
cd ${PRJCT}
# create ACL tables
./Console/cake schema create DbAcl
# populate ACL acos
./Console/cake acl create aco root controllers
./Console/cake AclExtras.AclExtras aco_sync
# update Schema, add Users.group_id
./Console/cake schema update -s 0.2.2.1
# create Log table
./Console/cake schema create DbLog
# create Groups, populate ACL aros and Users.group_id
./Console/cake schema create DbGroup
# populate 0.2.3
./Console/cake populate0_2_3
exit 0;

12
app/Console/shell/rights.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/sh
USER=noud
chown -R ${USER}:www-data /var/www/cydefsig
chmod -R 750 /var/www/cydefsig
chmod -R g+s /var/www/cydefsig
cd /var/www/cydefsig/app/
chmod -R g+w tmp
chmod -R g+w files
exit 0

View File

@ -24,7 +24,6 @@
App::uses('Controller', 'Controller');
App::uses('Sanitize', 'Utility');
/**
* Application Controller
*
@ -37,6 +36,7 @@ App::uses('Sanitize', 'Utility');
class AppController extends Controller {
public $components = array(
'Acl', // TODO XXX remove
'Session',
'Auth' => array(
'className' => 'SecureAuth',
@ -48,8 +48,9 @@ class AppController extends Controller {
'authError' => 'Did you really think you are allowed to see that?',
'loginRedirect' => array('controller' => 'users', 'action' => 'routeafterlogin'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
'authorize' => array('Controller') // Added this line
)
'authorize' => array('Controller', // Added this line
'Actions' => array('actionPath' => 'controllers')) // TODO ACL, 4: tell actionPath
)
);
public function isAuthorized($user) {
@ -94,6 +95,11 @@ class AppController extends Controller {
// These variables are required for every view
$this->set('me', $this->Auth->user());
$this->set('isAdmin', $this->_isAdmin());
// TODO ACL: 5: from Controller to Views
$this->set('isAclAdd', $this->checkAcl('add'));
$this->set('isAclModify', $this->checkAcl('edit'));
$this->set('isAclPublish', $this->checkAcl('publish'));
}
public function blackhole($type) {
@ -316,7 +322,7 @@ class AppController extends Controller {
$this->loadModel('Correlation');
$this->loadModel('Attribute');
$fields = array('Attribute.id', 'Attribute.event_id', 'Event.date');
$fields = array('Attribute.id', 'Attribute.event_id', 'Attribute.private', 'Event.date', 'Event.org');
// get all attributes..
$attributes = $this->Attribute->find('all',array('recursive' => 0));
// for all attributes..
@ -337,4 +343,52 @@ class AppController extends Controller {
//}
}
}
/**
* TODO ACL, 6b: check on Group and per Model (not used)
*/
public function checkAccess() {
$aco = ucfirst($this->params['controller']);
$user = ClassRegistry::init('User')->findById($this->Auth->user('id'));
return $this->Acl->check($user, 'controllers/' . $aco, '*');
}
/**
* TODO ACL, 6: check on Group and any Model
*/
public function checkAcl($action) {
$aco = 'Events'; // TODO ACL was 'Attributes'
$user = ClassRegistry::init('User')->findById($this->Auth->user('id'));
// TODO ACL, CHECK, below if indicates some wrong: Fatal error: Call to a member function check() on a non-object in /var/www/cydefsig/app/Controller/AppController.php on line 289
if ($this->Acl) {
return $this->Acl->check($user, 'controllers/' . $aco . '/' . $action, '*');
} else {
return true;
}
}
public function generatePrivate() {
if (!self::_isAdmin()) throw new NotFoundException();
$this->loadModel('Correlation');
$this->loadModel('Attribute');
$attributes = $this->Attribute->find('all',array('recursive' => 0));
foreach ($attributes as $attribute) {
if ($attribute['Attribute']['private']) {
$attribute['Attribute']['private'] = false;
$attribute['Attribute']['pull'] = true;
}
$this->Attribute->save($attribute);
}
$this->loadModel('Event');
$events = $this->Event->find('all',array('recursive' => 0));
foreach ($events as $event) {
if ($event['Event']['private']) {
$event['Event']['private'] = false;
$event['Event']['pull'] = true;
}
$this->Event->save($event);
}
}
}

82
app/Controller/AttributesController.php Normal file → Executable file
View File

@ -10,7 +10,7 @@ App::uses('File', 'Utility');
*/
class AttributesController extends AppController {
public $components = array('Security', 'RequestHandler');
public $components = array('Acl', 'Security', 'RequestHandler'); // XXX ACL component
public $paginate = array(
'limit' => 60,
@ -41,6 +41,31 @@ class AttributesController extends AppController {
$this->params->addParams(array('pass' => array($id))); // FIXME find better way to change id variable if uuid is found. params->url and params->here is not modified accordingly now
}
}
// do not show private to other groups
if ('true' == Configure::read('CyDefSIG.private')) {
// if not admin or own org, check private as well..
if (!$this->_IsAdmin()) {
$this->paginate = Set::merge($this->paginate,array(
'conditions' =>
array("OR" => array(
array('Event.org =' => $this->Auth->user('org')),
array("AND" => array('Event.org !=' => $this->Auth->user('org')), array('Event.private !=' => 1), array('Attribute.private !=' => 1)))),
)
);
}
}
// do not show cluster outside server
if ('true' == Configure::read('CyDefSIG.private')) {
if ($this->_isRest()) {
$this->paginate = Set::merge($this->paginate,array(
'conditions' =>
array("AND" => array('Event.cluster !=' => true),array('Attribute.cluster !=' => true)),
//array("AND" => array(array('Event.private !=' => 2))),
));
}
}
}
public function isAuthorized($user) {
@ -49,7 +74,7 @@ class AttributesController extends AppController {
return true;
}
// Only on own attributes for these actions
if (in_array($this->action, array('edit', 'delete'))) {
if (in_array($this->action, array('delete'))) { // TODO ACL, removed 'edit' override
$attributeid = $this->request->params['pass'][0];
return $this->Attribute->isOwnedByOrg($attributeid, $this->Auth->user('org'));
}
@ -114,6 +139,9 @@ class AttributesController extends AppController {
$this->Attribute->create();
$this->request->data['Attribute']['value'] = $attribute; // set the value as the content of the single line
if ('true' == Configure::read('CyDefSIG.private')) {
$this->request->data = $this->Attribute->massageData(&$this->request->data);
}
if ($this->Attribute->save($this->request->data)) {
$successes .= " " . ($key + 1);
} else {
@ -140,6 +168,10 @@ class AttributesController extends AppController {
// create the attribute
$this->Attribute->create();
if ('true' == Configure::read('CyDefSIG.private')) {
$this->request->data = $this->Attribute->massageData(&$this->request->data);
}
if ($this->Attribute->save($this->request->data)) {
// inform the user and redirect
$this->Session->setFlash(__('The attribute has been saved'));
@ -162,6 +194,12 @@ class AttributesController extends AppController {
$categories = $this->_arrayToValuesIndexArray($categories);
$this->set('categories',compact('categories'));
if ('true' == Configure::read('CyDefSIG.private')) {
$sharings = array('Org', 'Server', 'Pull only', 'All');
$sharings = $this->_arrayToValuesIndexArray($sharings);
$this->set('sharings',compact('sharings'));
}
$this->set('attrDescriptions', $this->Attribute->fieldDescriptions);
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
@ -183,6 +221,7 @@ class AttributesController extends AppController {
} elseif ('malware-sample' == $this->Attribute->data['Attribute']['type']) {
$filenameHash = explode('|', $this->Attribute->data['Attribute']['value']);
$filename = $filenameHash[0];
$filename = substr($filenameHash[0], strrpos($filenameHash[0], '\\'));
$fileExt = "zip";
} else {
throw new NotFoundException(__('Attribute not an attachment or malware-sample'));
@ -191,10 +230,10 @@ class AttributesController extends AppController {
$this->viewClass = 'Media';
$params = array(
'id' => $file->path,
'name' => $filename,
'name' => $filename,
'extension' => $fileExt,
'download' => true,
'path' => DS
'path' => DS
);
$this->set($params);
}
@ -241,6 +280,9 @@ class AttributesController extends AppController {
}
$this->request->data['Attribute']['uuid'] = String::uuid();
$this->request->data['Attribute']['batch_import'] = 0;
if ('true' == Configure::read('CyDefSIG.private')) {
$this->request->data = $this->Attribute->massageData(&$this->request->data);
}
if ($this->Attribute->save($this->request->data)) {
// attribute saved correctly in the db
@ -329,6 +371,12 @@ class AttributesController extends AppController {
$this->set('zippedDefinitions', $this->Attribute->zippedDefinitions);
$this->set('uploadDefinitions', $this->Attribute->uploadDefinitions);
if ('true' == Configure::read('CyDefSIG.private')) {
$sharings = array('Org', 'Server', 'Pull only', 'All');
$sharings = $this->_arrayToValuesIndexArray($sharings);
$this->set('sharings',compact('sharings'));
}
}
/**
@ -358,8 +406,12 @@ class AttributesController extends AppController {
}
if ($this->request->is('post') || $this->request->is('put')) {
if ('true' == Configure::read('CyDefSIG.private')) {
$this->request->data = $this->Attribute->massageData(&$this->request->data);
}
// say what fields are to be updated
$fieldList = array('category', 'type', 'value1', 'value2', 'to_ids', 'private');
$fieldList = array('category', 'type', 'value1', 'value2', 'to_ids', 'private', 'cluster', 'pull');
if ($this->Attribute->save($this->request->data)) {
$this->Session->setFlash(__('The attribute has been saved'));
@ -385,6 +437,12 @@ class AttributesController extends AppController {
$categories = $this->_arrayToValuesIndexArray($categories);
$this->set('categories',compact('categories'));
if ('true' == Configure::read('CyDefSIG.private')) {
$sharings = array('Org', 'Server', 'Pull only', 'All');
$sharings = $this->_arrayToValuesIndexArray($sharings);
$this->set('sharings',compact('sharings'));
}
$this->set('attrDescriptions', $this->Attribute->fieldDescriptions);
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
@ -492,6 +550,20 @@ class AttributesController extends AppController {
$this->paginate = array(
'conditions' => $conditions
);
if ('true' == Configure::read('CyDefSIG.private')) {
if (!$this->_IsAdmin()) {
// merge in private conditions
$this->paginate = Set::merge($this->paginate,array(
'conditions' =>
array("OR" => array(
array('Event.org =' => $this->Auth->user('org')),
array("AND" => array('Event.org !=' => $this->Auth->user('org')), array('Event.private !=' => 1), array('Attribute.private !=' => 1)))),
)
);
}
}
$this->set('attributes', $this->paginate());
// and store into session

367
app/Controller/EventsController.php Normal file → Executable file
View File

@ -15,6 +15,7 @@ class EventsController extends AppController {
* @var array
*/
public $components = array(
'Acl', // XXX ACL component
'Security',
'Email',
'RequestHandler',
@ -43,6 +44,13 @@ class EventsController extends AppController {
$this->Auth->allow('dot');
// TODO Audit, activate logable in a Controller
if (count($this->uses) && $this->{$this->modelClass}->Behaviors->attached('SysLogLogable')) {
$this->{$this->modelClass}->setUserData($this->activeUser);
}
// TODO ACL, if on ent/attr level, $this->set('isAcl', $this->checkAccess());
// convert uuid to id if present in the url, and overwrite id field
if (isset($this->params->query['uuid'])) {
$params = array(
@ -56,6 +64,30 @@ class EventsController extends AppController {
$this->params->addParams(array('pass' => array($id))); // FIXME find better way to change id variable if uuid is found. params->url and params->here is not modified accordingly now
}
}
// do not show private to other groups
if ('true' == Configure::read('CyDefSIG.private')) {
// if not admin or own org, check private as well..
if (!$this->_IsAdmin()) {
$this->paginate = Set::merge($this->paginate,array(
'conditions' =>
array("OR" => array(
array('Event.org =' => $this->Auth->user('org')),
array("AND" => array('Event.org !=' => $this->Auth->user('org')), array('Event.private !=' => 1)))),
));
}
}
// do not show cluster outside server
if ('true' == Configure::read('CyDefSIG.private')) {
if ($this->_isRest()) {
$this->paginate = Set::merge($this->paginate,array(
'conditions' =>
array(array('Event.cluster !=' => true)),
//array("AND" => array(array('Event.private !=' => 2))),
));
}
}
}
public function isAuthorized($user) {
@ -64,7 +96,7 @@ class EventsController extends AppController {
return true;
}
// Only on own events for these actions
if (in_array($this->action, array('edit', 'delete', 'alert', 'publish'))) {
if (in_array($this->action, array('alert'))) { // TODO ACL, CHECK, remove overruling 'edit', 'delete' and 'publish'
$eventid = $this->request->params['pass'][0];
return $this->Event->isOwnedByOrg($eventid, $this->Auth->user('org'));
}
@ -102,21 +134,44 @@ class EventsController extends AppController {
}
$this->Event->read(null, $id);
if ('true' == Configure::read('CyDefSIG.private')) {
if (!$this->_IsAdmin()) {
// check for non-private and re-read
if ($this->Event->data['Event']['org'] != $this->Auth->user('org')) {
$this->Event->hasMany['Attribute']['conditions'] = array('Attribute.private !=' => 1);
$this->Event->read(null, $id);
}
// check private
if (($this->Event->data['Event']['private']) && ($this->Event->data['Event']['org'] != $this->Auth->user('org'))) {
$this->Session->setFlash('Invalid event.');
$this->redirect(array('controller' => 'users', 'action' => 'terms'));
}
}
}
$relatedAttributes = array();
$this->loadModel('Attribute');
if ('db' == Configure::read('CyDefSIG.correlation')) {
$this->loadModel('Correlation');
$fields = array('Correlation.event_id', 'Correlation.attribute_id', 'Correlation.date');
$fields2 = array('Correlation.1_attribute_id','Correlation.event_id', 'Correlation.attribute_id', 'Correlation.date');
$fields2 = array('Correlation.1_attribute_id','Correlation.event_id', 'Correlation.attribute_id', 'Correlation.date', 'Correlation.private', 'Correlation.org');
$relatedAttributes2 = array();
$relatedAttributes2 = $this->Correlation->find('all',array(
'fields' => $fields2,
'conditions' => array(
'OR' => array(
'Correlation.1_event_id' => $id
)
),
'recursive' => 0));
if ('true' == Configure::read('CyDefSIG.private')) {
$conditionsCorrelation =
array('AND' => array('Correlation.1_event_id' => $id,),
array("OR" => array(
array('Correlation.org =' => $this->Event->data['Event']['org']),
array("AND" => array('Correlation.org !=' => $this->Event->data['Event']['org']), array('Correlation.private !=' => 1)))));
} else {
$conditionsCorrelation =
array('AND' => array('Correlation.1_event_id' => $id,));
}
$relatedAttributes2 = $this->Correlation->find('all',array(
'fields' => $fields2,
'conditions' => $conditionsCorrelation,
'recursive' => 0));
if (empty($relatedAttributes2)) {
$relatedEvents = null;
} else {
@ -223,19 +278,44 @@ class EventsController extends AppController {
*/
public function add() {
if ($this->request->is('post')) {
if ($this->_add($this->request->data, $this->Auth, $this->_isRest(),'')) {
if ($this->_isRest()) {
// REST users want to see the newly created event
$this->view($this->Event->getId());
$this->render('view');
// TODO or massageData here
if ('true' == Configure::read('CyDefSIG.private')) {
$this->request->data = $this->Event->massageData(&$this->request->data);
}
if (!empty($this->data)) {
if (isset($this->data['Event']['submittedfile'])) {
App::uses('File', 'Utility');
$file = new File($this->data['Event']['submittedfile']['name']);
$ext = $file->ext();
} else {
// redirect to the view of the newly created event
$this->Session->setFlash(__('The event has been saved'));
$this->redirect(array('action' => 'view', $this->Event->getId()));
$ext = '';
}
if (isset($this->data['Event']['submittedfile']) && $ext != 'zip' && $this->data['Event']['submittedfile']['size'] > 0 &&
is_uploaded_file($this->data['Event']['submittedfile']['tmp_name'])) {
//return false;
$this->Session->setFlash('You may only upload GFI Sandbox zip files.');
} else {
// TODO or massageData here
if ($this->_add($this->request->data, $this->Auth, $this->_isRest(),'')) {
if ($this->_isRest()) {
// REST users want to see the newly created event
$this->view($this->Event->getId());
$this->render('view');
} else {
// TODO now save uploaded attributes using $this->Event->getId() ..
$this->addGfiZip($this->Event->getId());
// redirect to the view of the newly created event
$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');
// TODO return error if REST
}
}
} else {
$this->Session->setFlash(__('The event could not be saved. Please, try again.'), 'default', array(), 'error');
// TODO return error if REST
}
}
// combobox for risks
@ -243,6 +323,12 @@ class EventsController extends AppController {
$risks = $this->_arrayToValuesIndexArray($risks);
$this->set('risks',compact('risks'));
if ('true' == Configure::read('CyDefSIG.private')) {
$sharings = array('Org', 'Server', 'Pull only', 'All');
$sharings = $this->_arrayToValuesIndexArray($sharings);
$this->set('sharings',compact('sharings'));
}
$this->set('eventDescriptions', $this->Event->fieldDescriptions);
}
@ -296,9 +382,14 @@ class EventsController extends AppController {
}
$fieldList = array(
'Event' => array('org', 'date', 'risk', 'info', 'user_id', 'published', 'uuid', 'private'),
'Attribute' => array('event_id', 'category', 'type', 'value', 'value1', 'value2', 'to_ids', 'uuid', 'revision', 'private')
'Event' => array('org', 'date', 'risk', 'info', 'user_id', 'published', 'uuid', 'private', 'cluster', 'pull'),
'Attribute' => array('event_id', 'category', 'type', 'value', 'value1', 'value2', 'to_ids', 'uuid', 'revision', 'private', 'cluster', 'pull')
);
if ('true' == Configure::read('CyDefSIG.private')) {
$data = $this->Event->massageData(&$data);
}
// this saveAssociated() function will save not only the event, but also the attributes
// from the attributes attachments are also saved to the disk thanks to the afterSave() fonction of Attribute
if ($this->Event->saveAssociated($data, array('validate' => true, 'fieldList' => $fieldList))) {
@ -364,7 +455,7 @@ class EventsController extends AppController {
}
// say what fields are to be updated
$fieldList = array('date', 'risk', 'info', 'published', 'private');
$fieldList = array('date', 'risk', 'info', 'published', 'private', 'cluster', 'pull');
// always force the org, but do not force it for admins
if ($this->_isAdmin()) {
// set the same org as existed before
@ -374,6 +465,10 @@ class EventsController extends AppController {
// we probably also want to remove the published flag
$this->request->data['Event']['published'] = 0;
if ('true' == Configure::read('CyDefSIG.private')) {
$this->request->data = $this->Event->massageData(&$this->request->data);
}
if ($this->Event->save($this->request->data, true, $fieldList)) {
$this->Session->setFlash(__('The event has been saved'));
$this->redirect(array('action' => 'view', $id));
@ -389,7 +484,14 @@ class EventsController extends AppController {
$risks = $this->_arrayToValuesIndexArray($risks);
$this->set('risks',compact('risks'));
if ('true' == Configure::read('CyDefSIG.private')) {
$sharings = array('Org', 'Server', 'Pull only', 'All');
$sharings = $this->_arrayToValuesIndexArray($sharings);
$this->set('sharings', compact('sharings'));
}
$this->set('eventDescriptions', $this->Event->fieldDescriptions);
$this->set('privateDefinitions', $this->Event->privateDefinitions);
}
/**
@ -564,13 +666,13 @@ class EventsController extends AppController {
// The mail body, h() is NOT needed as we are sending plain-text mails.
$body = "";
$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";
$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";
$body .= 'Risk : ' . $event['Event']['risk'] . "\n";
$relatedEvents = $this->Event->getRelatedEvents($id);
if (!empty($relatedEvents)) {
foreach ($relatedEvents as &$relatedEvent) {
@ -586,7 +688,7 @@ class EventsController extends AppController {
if (isset($event['Attribute'])) {
foreach ($event['Attribute'] as &$attribute) {
$line = '- ' . $attribute['type'] . str_repeat(' ', $appendlen - 2 - strlen( $attribute['type'])) . ': ' . $attribute['value'] . "\n";
$line = '- ' . $attribute['type'] . str_repeat(' ', $appendlen - 2 - strlen($attribute['type'])) . ': ' . $attribute['value'] . "\n";
if ('other' == $attribute['type']) // append the 'other' attribute types to the bottom.
$bodyTempOther .= $line;
else $body .= $line;
@ -613,7 +715,7 @@ class EventsController extends AppController {
'conditions' => array('User.autoalert' => 1,
'User.gpgkey =' => ""),
'recursive' => 0,
) );
));
$alertEmails = Array();
foreach ($alertUsers as &$user) {
$alertEmails[] = $user['User']['email'];
@ -624,7 +726,7 @@ class EventsController extends AppController {
$this->Email->bcc = $alertEmails;
$this->Email->subject = "[" . Configure::read('CyDefSIG.name') . "] Event " . $id . " - " . $event['Event']['risk'] . " - TLP Amber";
$this->Email->template = 'body';
$this->Email->sendAs = 'text'; // both text or html
$this->Email->sendAs = 'text'; // both text or html
$this->set('body', $bodySigned);
// send it
$this->Email->send();
@ -649,7 +751,7 @@ class EventsController extends AppController {
$this->Email->to = $user['User']['email'];
$this->Email->subject = "[" . Configure::read('CyDefSIG.name') . "] Event " . $id . " - " . $event['Event']['risk'] . " - TLP Amber";
$this->Email->template = 'body';
$this->Email->sendAs = 'text'; // both text or html
$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
@ -1101,4 +1203,205 @@ class EventsController extends AppController {
// debug($gv);
// $gv->image();
//}
public function getName($id = null) {
$events = $this->Event->find('first', array(
'conditions' => array('Event.id' => $id)
));
$name = $events['Event']['info'];
return $name;
}
public function addGfiZip($id) {
if (!empty($this->data) && $this->data['Event']['submittedfile']['size'] > 0 &&
is_uploaded_file($this->data['Event']['submittedfile']['tmp_name'])) {
$zipData = fread(fopen($this->data['Event']['submittedfile']['tmp_name'], "r"),
$this->data['Event']['submittedfile']['size']);
// write
$rootDir = APP . "files" . DS . $id . DS;
App::uses('Folder', 'Utility');
$dir = new Folder($rootDir, true);
$destpath = $rootDir;
$file = new File ($destpath);
$zipfile = new File ($destpath . DS . $this->data['Event']['submittedfile']['name']);
$result = $zipfile->write($zipData);
if (!$result) $this->Session->setFlash(__('Problem with writing the zip file. Please report to administrator.'));
// extract zip..
$execRetval = '';
exec("unzip " . $zipfile->path . ' -d "' . addslashes($rootDir) . '"', $execOutput, $execRetval);
$execOutput = array();
if ($execRetval != 0) { // not EXIT_SUCCESS
// do some?
}
// now open the xml..
$xml = $rootDir . DS . 'Analysis' . DS . 'analysis.xml';
$fileData = fread(fopen($xml, "r"), $this->data['Event']['submittedfile']['size']);
// read XML
$this->readGfiXML($fileData, $id);
}
}
public function readGfiXML($data, $id) {
$this->loadModel('Attribute');
// import XML class
App::uses('Xml', 'Utility');
// now parse it
$parsedXml =& Xml::build($data, array('return' => 'simplexml'));
// xpath..
//Payload delivery -- malware-sample
$results = $parsedXml->xpath('/analysis');
foreach ($results as $result) {
foreach ($result[0]->attributes() as $key => $val) {
if ((string)$key == 'filename') $realFileName = (string)$val;
}
}
$realMalware = $realFileName;
$rootDir = APP . "files" . DS . $id . DS;
$malware = $rootDir . DS . 'sample';
$this->Event->Attribute->uploadAttachment($malware, $realFileName, true, $id);
//Network activity -- .pcap
$realFileName = 'analysis.pcap';
$rootDir = APP . "files" . DS . $id . DS;
$malware = $rootDir . DS . 'Analysis' . DS . 'analysis.pcap';
$this->Event->Attribute->uploadAttachment($malware, $realFileName, false, $id, 'Network activity');
//Artifacts dropped -- filename|md5
$files = array();
// TODO what about stored_modified_file ??
$results = $parsedXml->xpath('/analysis/processes/process/stored_files/stored_created_file');
foreach ($results as $result) {
$arrayItemKey = '';
$arrayItemValue = '';
foreach ($result[0]->attributes() as $key => $val) {
if ($key == 'filename') $arrayItemKey = (string)$val;
if ($key == 'md5') $arrayItemValue = (string)$val;
}
$files[$arrayItemKey] = $arrayItemValue;
}
//$files = array_unique($files);
// write content..
foreach ($files as $key => $val) {
$keyName = $key;
// replace Windows Environment Variables
$keyName = str_replace('C:\Users\John', '%UserProfile%', $keyName);
$keyName = str_replace('C:\Documents and Settings\James Cocks', '%UserProfile%', $keyName);
$keyName = str_replace('C:\DOCUME~1\JAMESC~1', '%UserProfile%', $keyName);
$keyName = str_replace('C:\Documents and Settings\All Users', '%AllUsersProfile%', $keyName);
if (!strpos($key, $realMalware)) {
$itsType = 'malware-sample';
} else {
$itsType = 'filename|md5';
}
// the actual files..
// seek $val in dirs and add..
$ext = substr($key, strrpos($key, '.'));
$actualFileName = $val . $ext;
$actualFileNameBase = str_replace('\\', '/', $key);
$actualFileNameArray[] = basename($actualFileNameBase);
$realFileName = end(explode('\\', $key));
// have the filename, now look at parents parent for the process number
$express = "/analysis/processes/process/stored_files/stored_created_file[@md5='" . $val . "']/../..";
$results = $parsedXml->xpath($express);
foreach ($results as $result) {
foreach ($result[0]->attributes() as $key => $val) {
if ((string)$key == 'index') $index = (string)$val;
}
}
$actualFile = $rootDir . DS . 'Analysis' . DS . 'proc_' . $index . DS . 'modified_files' . DS . $actualFileName;
$extraPath = 'Analysis' . DS . 'proc_' . $index . DS . 'modified_files' . DS;
$file = new File($actualFile);
if ($file->exists()) { // TODO put in array for test later
$this->Event->Attribute->uploadAttachment($actualFile, $realFileName, true, $id, null, $extraPath, $keyName); // TODO was false
}
}
//Network activity -- ip-dst
$ips = array();
$results = $parsedXml->xpath('/analysis/processes/process/networkpacket_section/connect_to_computer');
foreach ($results as $result) {
foreach ($result[0]->attributes() as $key => $val) {
if ($key == 'remote_ip') $ips[] = (string)$val;
}
}
// write content..
foreach ($ips as $ip) {
// add attribute..
$this->Attribute->read(null, 1);
$this->Attribute->save(array(
'event_id' => $id,
'category' => 'Network activity',
'type' => 'ip-dst',
'value' => $ip,
'to_ids' => false));
}
// Persistence mechanism -- regkey|value
$regs = array();
$results = $parsedXml->xpath('/analysis/processes/process/registry_section/set_value');
foreach ($results as $result) {
$arrayItemKey = '';
$arrayItemValue = '';
foreach ($result[0]->attributes() as $key => $val) {
if ($key == 'key_name') $arrayItemKey = (string)$val;
if ($key == 'data') $arrayItemValue = (string)$val;
}
$arrayItemKey = preg_replace('@\\\REGISTRY\\\USER\\\S(-[0-9]{1}){2}-[0-9]{2}(-[0-9]{10}){2}-[0-9]{9}-[0-9]{4}@','HKEY_CURRENT_USER',$arrayItemKey);
$regs[$arrayItemKey] = str_replace('(UNICODE_0x00000000)', '', $arrayItemValue);
}
//$regs = array_unique($regs);
// write content..
foreach ($regs as $key => $val) {
// add attribute..
$this->Attribute->read(null, 1);
if ($val == '[binary_data]') {
$itsCategory = 'Persistence mechanism';
$itsType = 'regkey';
$itsValue = $key;
} else {
if ($this->strposarray($val,$actualFileNameArray)) {
$itsCategory = 'Persistence mechanism';
$itsType = 'regkey|value';
$itsValue = $key . '|' . $val;
} else {
// replace Windows Environment Variables
$val = str_replace('C:\Users\John', '%UserProfile%', $val);
$val = str_replace('C:\Documents and Settings\James Cocks', '%UserProfile%', $val);
$val = str_replace('C:\DOCUME~1\JAMESC~1', '%UserProfile%', $val);
$val = str_replace('C:\Documents and Settings\All Users', '%AllUsersProfile%', $val);
$itsCategory = 'Artifacts dropped'; // Persistence mechanism
$itsType = 'regkey|value';
$itsValue = $key . '|' . $val;
}
}
$this->Attribute->save(array(
'event_id' => $id,
'category' => $itsCategory, // 'Persistence mechanism'
'type' => $itsType,
'value' => $itsValue,
'to_ids' => false));
}
}
public function strposarray($string, $array) {
$toReturn = false;
foreach ($array as $item) {
if (strpos($string,$item)) {
$toReturn = true;
}
}
return $toReturn;
}
}

View File

@ -0,0 +1,178 @@
<?php
App::uses('AppController', 'Controller');
/**
* Groups Controller
*
* @property Group $Group
*/
class GroupsController extends AppController {
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers/Groups')
)
),
'Session'
);
//public $components = array('Security');
public $paginate = array(
'limit' => 60,
'order' => array(
'Group.name' => 'ASC'
)
);
function beforeFilter() {
parent::beforeFilter();
}
/**
* view method
*
* @param string $id
* @return void
*/
public function view($id = null) {
$this->Group->id = $id;
if (!$this->Group->exists()) {
throw new NotFoundException(__('Invalid group'));
}
$this->set('group', $this->Group->read(null, $id));
}
/**
* admin_index method
*
* @return void
*/
public function admin_index() {
$this->Group->recursive = 0;
$this->set('groups', $this->paginate());
}
/**
* admin_view method
*
* @param string $id
* @return void
*/
public function admin_view($id = null) {
$this->Group->id = $id;
if (!$this->Group->exists()) {
throw new NotFoundException(__('Invalid group'));
}
$this->set('group', $this->Group->read(null, $id));
}
/**
* admin_add method
*
* @return void
*/
public function admin_add() {
if ($this->request->is('post')) {
$this->Group->create();
if ($this->Group->save($this->request->data)) {
$this->saveAcl($this->Group, $this->data['Group']['perm_add'], $this->data['Group']['perm_modify'], $this->data['Group']['perm_publish']); // save to ACL as well
$this->Session->setFlash(__('The group has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The group could not be saved. Please, try again.'));
}
} else {
// generate auth key for a new user
//$newkey = $this->Group->generateAuthKey(); // TODO generateAuthKey?
//$this->set('authkey', $newkey);
}
}
/**
* admin_edit method
*
* @param string $id
* @return void
*/
public function admin_edit($id = null) {
$this->Group->id = $id;
if (!$this->Group->exists()) {
throw new NotFoundException(__('Invalid group'));
}
if ($this->request->is('post') || $this->request->is('put')) {
$fields = array();
foreach (array_keys($this->request->data['Group']) as $field) {
if($field != 'password') array_push($fields, $field);
}
if ("" != $this->request->data['Group']['password'])
$fields[] = 'password';
if ($this->Group->save($this->request->data, true, $fields)) {
$this->saveAcl($this->Group, $this->data['Group']['perm_add'], $this->data['Group']['perm_modify'], $this->data['Group']['perm_publish']); // save to ACL as well
$this->Session->setFlash(__('The group has been saved'));
$this->_refreshAuth(); // in case we modify ourselves
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The group could not be saved. Please, try again.'));
}
} else {
$this->Group->recursive=0;
$this->Group->read(null, $id);
//$this->Group->set('password', ''); // TODO set password?
$this->request->data = $this->Group->data;
}
}
/**
* admin_delete method
*
* @param string $id
* @return void
*/
public function admin_delete($id = null) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->Group->id = $id;
if (!$this->Group->exists()) {
throw new NotFoundException(__('Invalid group'));
}
if ($this->Group->delete(null, false)) {
$this->Session->setFlash(__('Group deleted'));
$this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Group was not deleted'));
$this->redirect(array('action' => 'index'));
}
/**
* saveAcl method
*
* @param string $id
* @return void
*/
public function saveAcl($group, $permAdd = false, $permModify = false, $permPublish = false) {
// this all could need some 'if-changed then do'
if ($permAdd) {
$this->Acl->allow($group, 'controllers/Events/add');
$this->Acl->allow($group, 'controllers/Attributes/add');
} else {
$this->Acl->deny($group, 'controllers/Events/add');
$this->Acl->deny($group, 'controllers/Attributes/add');
}
if ($permModify) {
$this->Acl->allow($group, 'controllers/Events/edit');
$this->Acl->allow($group, 'controllers/Attributes/edit');
} else {
$this->Acl->deny($group, 'controllers/Events/edit');
$this->Acl->deny($group, 'controllers/Attributes/edit');
}
if ($permPublish) {
$this->Acl->allow($group, 'controllers/Events/publish');
} else {
$this->Acl->deny($group, 'controllers/Events/publish');
}
}
}

112
app/Controller/LogsController.php Executable file
View File

@ -0,0 +1,112 @@
<?php
App::uses('AppController', 'Controller');
/**
* Logs Controller
*
* @property Log $Log
*/
class LogsController extends AppController {
public $components = array('Security', 'RequestHandler');
// public $components = array('Security');
public $paginate = array(
'limit' => 60,
'order' => array(
'Log.id' => 'DESC'
)
);
public $helpers = array('Js' => array('Jquery'));
function beforeFilter() {
parent::beforeFilter();
// permit reuse of CSRF tokens on the search page.
if ('search' == $this->request->params['action']) {
$this->Security->csrfUseOnce = false;
}
}
public function isAuthorized($user) {
// Admins can access everything
if (parent::isAuthorized($user)) {
return true;
}
// the other pages are allowed by logged in users
return true;
}
/**
* admin_index method
*
* @return void
*/
public function admin_index() {
$this->Log->recursive = 0;
$this->set('logs', $this->paginate());
}
/**
* admin_view method
*
* @param string $id
* @return void
*/
public function admin_view($id = null) {
$this->Log->id = $id;
if (!$this->Log->exists()) {
throw new NotFoundException(__('Invalid log'));
}
$this->set('log', $this->Log->read(null, $id));
}
public function search() {
$this->admin_search();
}
public function admin_search() {
$this->set('actionDefinitions', $this->Log->actionDefinitions);
if ($this->request->is('post')) {
$email = $this->request->data['Log']['email'];
$org = $this->request->data['Log']['org'];
$action = $this->request->data['Log']['action'];
$title = $this->request->data['Log']['title'];
$change = $this->request->data['Log']['change'];
// search the db
$conditions = array();
if($email) {
$conditions['Log.email LIKE'] = '%'.$email.'%';
}
if($org) {
$conditions['Log.org LIKE'] = '%'.$org.'%';
}
if($action != 'ALL') {
$conditions['Log.action ='] = $action;
}
if($title) {
$conditions['Log.title LIKE'] = '%'.$title.'%';
}
if($change) {
$conditions['Log.change LIKE'] = '%'.$change.'%';
}
$this->Log->recursive = 0;
$this->paginate = array(
'conditions' => $conditions
);
$this->set('logs', $this->paginate());
// set the same view as the index page
$this->render('index');
} else {
// no search keyword is given, show the search form
// combobox for actions
$actions = array('ALL');
$actions = array_merge($actions, $this->Log->validate['action']['rule'][1]);
$actions = $this->_arrayToValuesIndexArray($actions);
$this->set('actions',compact('actions'));
}
}
}

10
app/Controller/ServersController.php Executable file → Normal file
View File

@ -9,7 +9,7 @@ App::uses('Xml', 'Utility');
*/
class ServersController extends AppController {
public $components = array('Security' ,'RequestHandler');
public $components = array('Acl' ,'Security' ,'RequestHandler'); // XXX ACL component
public $paginate = array(
'limit' => 60,
@ -283,9 +283,15 @@ class ServersController extends AppController {
// increment lastid based on the highest ID seen
$this->Server->saveField('lastpushedid', $lastpushedid);
}
$this->set('successes', $successes);
$this->set('fails', $fails);
}
public function getName($id = null) {
$servers = $this->Server->find('first', array(
'conditions' => array('Server.id' => $id)
));
$name = $servers['Server']['url'];
return $name;
}
}

119
app/Controller/UsersController.php Normal file → Executable file
View File

@ -9,7 +9,7 @@ class UsersController extends AppController {
public $newkey;
public $components = array('Security');
public $components = array('Acl','Security'); // TODO ACL, components
public $paginate = array(
'limit' => 60,
@ -94,6 +94,9 @@ class UsersController extends AppController {
$this->request->data = $this->User->data;
}
$this->request->data['User']['org'] = $this->Auth->user('org');
// XXX ACL groups
$groups = $this->User->Group->find('list');
$this->set(compact('groups'));
}
/**
@ -171,6 +174,9 @@ class UsersController extends AppController {
$this->newkey = $this->User->generateAuthKey();
$this->set('authkey', $this->newkey);
}
// XXX ACL groups
$groups = $this->User->Group->find('list');
$this->set(compact('groups'));
}
/**
@ -190,9 +196,48 @@ class UsersController extends AppController {
foreach (array_keys($this->request->data['User']) as $field) {
if($field != 'password') array_push($fields, $field);
}
// TODO Audit, extraLog, fields get orig
$fieldsOldValues = array();
foreach ($fields as $field) {
if($field != 'confirm_password') array_push($fieldsOldValues, $this->User->field($field));
else array_push($fieldsOldValues, $this->User->field('password'));
}
// TODO Audit, extraLog, fields get orig END
if ("" != $this->request->data['User']['password'])
$fields[] = 'password';
if ($this->User->save($this->request->data, true, $fields)) {
// TODO Audit, extraLog, fields compare
// newValues to array
$fieldsNewValues = array();
foreach ($fields as $field) {
if ($field != 'confirm_password') {
$newValue = $this->data['User'][$field];
if (gettype($newValue) == 'array') {
$newValueStr = '';
$cP = 0;
foreach ($newValue as $newValuePart) {
if ($cP < 2) $newValueStr .= '-' . $newValuePart;
else $newValueStr = $newValuePart . $newValueStr;
$cP++;
}
array_push($fieldsNewValues, $newValueStr);
}
else array_push($fieldsNewValues, $newValue);
}
else array_push($fieldsNewValues, $this->data['User']['password']);
}
// compare
$fieldsResultStr = '';
$c = 0;
foreach ($fields as $field) {
if (isset($fieldsOldValues[$c]) && $fieldsOldValues[$c] != $fieldsNewValues[$c]) {
if($field != 'confirm_password') $fieldsResultStr = $fieldsResultStr . ', ' . $field . ' (' . $fieldsOldValues[$c] . ') => (' . $fieldsNewValues[$c] . ')';
}
$c++;
}
$fieldsResultStr = substr($fieldsResultStr, 2);
$this->extraLog("edit", "user", $fieldsResultStr); // TODO Audit, check: modify User
// TODO Audit, extraLog, fields compare END
$this->Session->setFlash(__('The user has been saved'));
$this->_refreshAuth(); // in case we modify ourselves
$this->redirect(array('action' => 'index'));
@ -206,6 +251,13 @@ class UsersController extends AppController {
$this->request->data = $this->User->data;
}
// TODO ACL CLEANUP combobox for orgs
$orgIds = array('ADMIN', 'NCIRC', 'Other MOD');
$orgIds = $this->_arrayToValuesIndexArray($orgIds);
$this->set('orgIds', compact('orgIds'));
// XXX ACL, Groups in Users
$groups = $this->User->Group->find('list');
$this->set(compact('groups'));
}
/**
@ -234,6 +286,7 @@ class UsersController extends AppController {
public function login() {
if ($this->Auth->login()) {
$this->extraLog("login"); // TODO Audit, extraLog, check: customLog i.s.o. extraLog, no auth user?: $this->User->customLog('login', $this->Auth->user('id'), array('title' => '','user_id' => $this->Auth->user('id'),'email' => $this->Auth->user('email'),'org' => 'IN2'));
$this->redirect($this->Auth->redirect());
} else {
// don't display authError before first login attempt
@ -253,7 +306,7 @@ class UsersController extends AppController {
}
// News page
$newNewsdate = new DateTime("2012-03-27");
$newNewsdate = new DateTime("2012-03-27"); // TODO general, fixed odd date??
$newsdate = new DateTime($this->Auth->user('newsread'));
if ($newNewsdate > $newsdate) {
$this->redirect(array('action' => 'news'));
@ -264,6 +317,7 @@ class UsersController extends AppController {
}
public function logout() {
$this->extraLog("logout"); // TODO Audit, extraLog, check: customLog i.s.o. extraLog, $this->User->customLog('logout', $this->Auth->user('id'), array());
$this->Session->setFlash('Good-Bye');
$this->redirect($this->Auth->logout());
}
@ -360,4 +414,65 @@ class UsersController extends AppController {
$this->_refreshAuth(); // refresh auth info
}
public function extraLog($action = null, $description = null, $fieldsResult = null) { // TODO move audit to AuditsController?
// new data
$userId = $this->Auth->user('id');
$model = 'User';
$modelId = $this->Auth->user('id');
if ($action == 'login') {
$description = "User (" . $this->Auth->user('id') . "): " . $this->data['User']['email'];
} elseif ($action == 'logout') {
$description = "User (" . $this->Auth->user('id') . "): " . $this->Auth->user('email');
} else { // edit
$description = "User (" . $this->User->id . "): " . $this->data['User']['email'];
}
// query
$this->Log = ClassRegistry::init('Log');
$this->Log->create();
$this->Log->save(array(
'org' => $this->Auth->user('org'),
'email' => $this->Auth->user('email'),
'action' => $action,
'title' => $description,
'change' => $fieldsResult));
// write to syslogd as well
App::import('Lib', 'SysLog.SysLog');
$syslog = new SysLog();
if ($fieldsResult) $syslog->write('notice', $description . ' -- ' . $action . ' -- ' . $fieldsResult);
else $syslog->write('notice', $description . ' -- ' . $action);
}
/**
* Used for fields_before and fields for audit
*
* @param $array
*/
public function arrayCopy(array $array) {
$result = array();
foreach ($array as $key => $val) {
if (is_array( $val)) {
$result[$key] = arrayCopy($val);
} elseif (is_object($val)) {
$result[$key] = clone $val;
} else {
$result[$key] = $val;
}
}
return $result;
}
public function setgroupid($fk = '2') {
$params = array(
'conditions' => array('User.group_id' => ''),
'recursive' => 0,
'fields' => array('User.id'),
);
$users = $this->User->find('all', $params);
foreach ($users as $user) {
$this->User->id = $user['User']['id'];
$this->User->saveField('group_id', $fk);
}
}
}

View File

@ -5,6 +5,11 @@ CREATE TABLE `correlations` (
`1_attribute_id` int(11) NOT NULL,
`event_id` int(11) NOT NULL,
`attribute_id` int(11) NOT NULL,
`date` date NOT NULL,
`org` varchar(255) COLLATE utf8_bin NOT NULL,
`private` tinyint(1) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=118 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-- ALTER TABLE `correlations` ADD private tinyint(1) NOT NULL;
-- ALTER TABLE `correlations` ADD org varchar(255) COLLATE utf8_bin NOT NULL;

8
app/MYSQL.private.sql Normal file
View File

@ -0,0 +1,8 @@
ALTER TABLE `events` ADD `cluster` tinyint(1) NOT NULL;
ALTER TABLE `attributes` ADD `cluster` tinyint(1) NOT NULL;
ALTER TABLE `events` ADD `pull` tinyint(1) NOT NULL;
ALTER TABLE `attributes` ADD `pull` tinyint(1) NOT NULL;
ALTER TABLE `correlations` ADD private tinyint(1) NOT NULL;
ALTER TABLE `correlations` ADD org varchar(255) COLLATE utf8_bin NOT NULL;

View File

@ -21,6 +21,7 @@
*/
App::uses('Model', 'Model');
App::uses('LogableBehavior', 'Assets.models/behaviors');
/**
* Application model for Cake.

View File

@ -1,4 +1,5 @@
<?php
App::uses('AppModel', 'Model');
App::uses('Folder', 'Utility');
App::uses('File', 'Utility');
@ -10,6 +11,16 @@ App::uses('File', 'Utility');
*/
class Attribute extends AppModel {
public $combinedKeys = array('event_id', 'category', 'type');
public $name = 'Attribute'; // TODO general
public $actsAs = array('SysLogLogable.SysLogLogable' => array( // TODO Audit, logable
'userModel' => 'User',
'userKey' => 'user_id',
'change' => 'full'
));
/**
* Display field
*
@ -17,24 +28,30 @@ class Attribute extends AppModel {
*/
public $displayField = 'value';
/**
* Virtual field
*
* @var array
*/
public $virtualFields = array(
'value' => 'IF (Attribute.value2="", Attribute.value1, CONCAT(Attribute.value1, "|", Attribute.value2))',
'category_order' => 'IF (Attribute.category="Internal reference", "a",
IF (Attribute.category="Antivirus detection", "b",
IF (Attribute.category="Payload delivery", "c",
IF (Attribute.category="Payload installation", "d",
IF (Attribute.category="Artifacts dropped", "e",
IF (Attribute.category="Persistence mechanism", "f",
IF (Attribute.category="Network activity", "g",
IF (Attribute.category="Payload type", "h",
IF (Attribute.category="Attribution", "i",
IF (Attribute.category="External analysis", "j", "k"))))))))))'); // TODO hardcoded
IF (Attribute.category="Antivirus detection", "b",
IF (Attribute.category="Payload delivery", "c",
IF (Attribute.category="Payload installation", "d",
IF (Attribute.category="Artifacts dropped", "e",
IF (Attribute.category="Persistence mechanism", "f",
IF (Attribute.category="Network activity", "g",
IF (Attribute.category="Payload type", "h",
IF (Attribute.category="Attribution", "i",
IF (Attribute.category="External analysis", "j", "k"))))))))))'
); // TODO hardcoded
/**
* Description field
* Field Descriptions
* explanations of certain fields to be used in various views
*
* @var array
* @public array
*/
public $fieldDescriptions = array(
'signature' => array('desc' => 'Is this attribute eligible to automatically create an IDS signature (network IDS or host IDS) out of it ?'),
@ -143,7 +160,7 @@ IF (Attribute.category="External analysis", "j", "k"))))))))))'); // TODO hardc
)
);
public $order = array("Attribute.event_id" => "DESC", "Attribute.type" => "ASC");
public $order = array("Attribute.event_id" => "DESC", "Attribute.type" => "ASC");
/**
* Validation rules
@ -257,6 +274,52 @@ IF (Attribute.category="External analysis", "j", "k"))))))))))'); // TODO hardc
),
);
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
if ('true' == Configure::read('CyDefSIG.private')) {
$this->virtualFields = Set::merge($this->virtualFields,array(
'sharing' => 'IF (Attribute.private=true, "Org", IF (Attribute.cluster=true, "Server", IF (Attribute.pull=true, "Pull only", "All")))',
));
$this->fieldDescriptions = Set::merge($this->fieldDescriptions,array(
'sharing' => array('desc' => 'This field tells how and if the attribute should be shared with other CyDefSIG users'),
));
$this->validate = Set::merge($this->validate,array(
'cluster' => 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
),
),
'pull' => 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
),
),
'sharing' => array(
'rule' => array('inList', array('Org', 'Server', 'Pull only')),
//'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
/**
@ -345,6 +408,32 @@ IF (Attribute.category="External analysis", "j", "k"))))))))))'); // TODO hardc
}
}
public function massageData(&$data) {
switch ($data['Attribute']['sharing']) {
case 'Org':
$data['Attribute']['private'] = true;
$data['Attribute']['cluster'] = false;
$data['Attribute']['pull'] = false;
break;
case 'Server':
$data['Attribute']['private'] = false;
$data['Attribute']['cluster'] = true;
$data['Attribute']['pull'] = false;
break;
case 'Pull only':
$data['Attribute']['private'] = false;
$data['Attribute']['cluster'] = false;
$data['Attribute']['pull'] = true;
break;
case 'All':
$data['Attribute']['private'] = false;
$data['Attribute']['cluster'] = false;
$data['Attribute']['pull'] = false;
break;
}
return $data;
}
public function beforeValidate() {
// remove leading and trailing blanks
$this->data['Attribute']['value'] = trim($this->data['Attribute']['value']);
@ -682,10 +771,70 @@ IF (Attribute.category="External analysis", "j", "k"))))))))))'); // TODO hardc
}
}
/**
* add_attachment method
*
* @return void
*/
public function uploadAttachment($fileP, $realFileName, $malware, $eventId = null, $category = null, $extraPath = '', $fullFileName = '') {
// Check if there were problems with the file upload
// only keep the last part of the filename, this should prevent directory attacks
$filename = basename($fileP);
$tmpfile = new File($fileP);
// save the file-info in the database
$this->create();
$this->data['Attribute']['event_id'] = $eventId;
if ($malware) {
$this->data['Attribute']['category'] = $category ? $category : "Payload delivery";
$this->data['Attribute']['type'] = "malware-sample";
$this->data['Attribute']['value'] = $fullFileName ? $fullFileName . '|' . $tmpfile->md5() : $filename . '|' . $tmpfile->md5(); // TODO gives problems with bigger files
$this->data['Attribute']['to_ids'] = 1; // LATER let user choose to send this to IDS
} else {
$this->data['Attribute']['category'] = $category ? $category : "Artifacts dropped";
$this->data['Attribute']['type'] = "attachment";
$this->data['Attribute']['value'] = $fullFileName ? $fullFileName : $realFileName;
$this->data['Attribute']['to_ids'] = 0;
}
if ($this->save($this->data)) {
// attribute saved correctly in the db
} else {
// do some?
}
// no errors in file upload, entry already in db, now move the file where needed and zip it if required.
// no sanitization is required on the filename, path or type as we save
// create directory structure
$rootDir = APP . DS . "files" . DS . $eventId;
$dir = new Folder($rootDir, true);
// move the file to the correct location
$destpath = $rootDir . DS . $this->getId(); // id of the new attribute in the database
$file = new File ($destpath);
$zipfile = new File ($destpath . '.zip');
$fileInZip = new File($rootDir . DS . $extraPath . $filename); // FIXME do sanitization of the filename
// zip and password protect the malware files
if ($malware) {
// TODO check if CakePHP has no easy/safe wrapper to execute commands
$execRetval = '';
$execOutput = array();
exec("zip -j -P infected " . $zipfile->path . ' "' . addslashes($fileInZip->path) . '"', $execOutput, $execRetval);
if ($execRetval != 0) { // not EXIT_SUCCESS
// do some?
};
$fileInZip->delete(); // delete the original not-zipped-file
rename($zipfile->path, $file->path); // rename the .zip to .nothing
} else {
$fileAttach = new File($fileP);
rename($fileAttach->path, $file->path);
}
}
private function __afterSaveCorrelation($attribute) {
$this->__beforeDeleteCorrelation($attribute);
// re-add
$this->setRelatedAttributes($attribute, array('Attribute.id', 'Attribute.event_id', 'Event.date'));
$this->setRelatedAttributes($attribute, array('Attribute.id', 'Attribute.event_id', 'Attribute.private', 'Event.date', 'Event.org'));
}
private function __beforeDeleteCorrelation($attribute) {
@ -741,7 +890,7 @@ IF (Attribute.category="External analysis", "j", "k"))))))))))'); // TODO hardc
$params = array(
'conditions' => array('Event.id' => $relatedAttribute['Attribute']['event_id']),
'recursive' => 0,
'fields' => array('Event.date')
'fields' => array('Event.date', 'Event.org')
);
$eventDate = $this->Event->find('first', $params);
$this->Correlation = ClassRegistry::init('Correlation');
@ -750,6 +899,8 @@ IF (Attribute.category="External analysis", "j", "k"))))))))))'); // TODO hardc
'Correlation' => array(
'1_event_id' => $attribute['event_id'], '1_attribute_id' => $attribute['id'],
'event_id' => $relatedAttribute['Attribute']['event_id'], 'attribute_id' => $relatedAttribute['Attribute']['id'],
'org' => $eventDate['Event']['org'],
'private' => $relatedAttribute['Attribute']['private'],
'date' => $eventDate['Event']['date']))
);
}

128
app/Model/Event.php Executable file → Normal file
View File

@ -8,6 +8,14 @@ App::uses('AppModel', 'Model');
*/
class Event extends AppModel {
public $name = 'Event'; // TODO general
public $actsAs = array('SysLogLogable.SysLogLogable' => array( // TODO Audit, logable
'userModel' => 'User',
'userKey' => 'user_id',
'change' => 'full'
));
/**
* Display field
*
@ -15,6 +23,8 @@ class Event extends AppModel {
*/
public $displayField = 'id';
public $virtualFields = array();
/**
* Description field
*
@ -23,7 +33,8 @@ class Event extends AppModel {
public $fieldDescriptions = array(
'risk' => array('desc' => 'Risk levels: *low* means mass-malware, *medium* means APT malware, *high* means sophisticated APT malware or 0-day attack', 'formdesc' => 'Risk levels:<br/>low: mass-malware<br/>medium: APT malware<br/>high: sophisticated APT malware or 0-day attack'),
'private' => array('desc' => 'This field tells if the event should be shared with other CyDefSIG servers'),
'classification' => array('desc' => 'Set the Traffic Light Protocol classification. <ol><li><em>TLP:AMBER</em>- Share only within the organization on a need-to-know basis</li><li><em>TLP:GREEN:NeedToKnow</em>- Share within your constituency on the need-to-know basis.</li><li><em>TLP:GREEN</em>- Share within your constituency.</li></ol>')
'classification' => array('desc' => 'Set the Traffic Light Protocol classification. <ol><li><em>TLP:AMBER</em>- Share only within the organization on a need-to-know basis</li><li><em>TLP:GREEN:NeedToKnow</em>- Share within your constituency on the need-to-know basis.</li><li><em>TLP:GREEN</em>- Share within your constituency.</li></ol>'),
'submittedfile' => array('desc' => 'GFI sandbox: export upload', 'formdesc' => 'GFI sandbox:<br/>export upload'),
);
/**
@ -80,6 +91,16 @@ class Event extends AppModel {
//'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
),
),
'published' => array(
'boolean' => array(
'rule' => array('boolean'),
@ -120,6 +141,52 @@ class Event extends AppModel {
//),
);
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
if ('true' == Configure::read('CyDefSIG.private')) {
$this->virtualFields = Set::merge($this->virtualFields,array(
'sharing' => 'IF (Event.private=true, "Org", IF (Event.cluster=true, "Server", IF (Event.pull=true, "Pull only", "All")))',
));
$this->fieldDescriptions = Set::merge($this->fieldDescriptions,array(
'sharing' => array('desc' => 'This field tells how and if the event should be shared with other CyDefSIG users'),
));
$this->validate = Set::merge($this->validate,array(
'cluster' => 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
),
),
'pull' => 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
),
),
'sharing' => array(
'rule' => array('inList', array('Org', 'Server', 'Pull only')),
//'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
/**
@ -165,13 +232,67 @@ class Event extends AppModel {
)
);
public function beforeDelete() {
// delete event from the disk
$this->read(); // first read the event from the db
// FIXME secure this filesystem access/delete by not allowing to change directories or go outside of the directory container.
// only delete the file if it exists
$filepath = APP . "files" . DS . $this->data['Event']['id'];
App::uses('Folder', 'Utility');
$file = new Folder ($filepath);
if (is_dir($filepath)) {
if (!$this->destroyDir($filepath)) {
throw new InternalErrorException('Delete of event file directory failed. Please report to administrator.');
}
}
}
public function destroyDir($dir) {
if (!is_dir($dir) || is_link($dir)) return unlink($dir);
foreach (scandir($dir) as $file) {
if ($file == '.' || $file == '..') continue;
if (!$this->destroyDir($dir . DS . $file)) {
chmod($dir . DS . $file, 0777);
if (!$this->destroyDir($dir . DS . $file)) return false;
};
}
return rmdir($dir);
}
public function beforeValidate() {
parent::beforeValidate();
// generate UUID if it doesn't exist
if (empty($this->data['Event']['uuid'])) {
$this->data['Event']['uuid'] = String::uuid();
}
}
public function massageData(&$data) {
switch ($data['Event']['sharing']) {
case 'Org':
$data['Event']['private'] = true;
$data['Event']['cluster'] = false;
$data['Event']['pull'] = false;
break;
case 'Server':
$data['Event']['private'] = false;
$data['Event']['cluster'] = true;
$data['Event']['pull'] = false;
break;
case 'Pull only':
$data['Event']['private'] = false;
$data['Event']['cluster'] = false;
$data['Event']['pull'] = true;
break;
case 'All':
$data['Event']['private'] = false;
$data['Event']['cluster'] = false;
$data['Event']['pull'] = false;
break;
}
return $data;
}
public function isOwnedByOrg($eventid, $org) {
return $this->field('id', array('id' => $eventid, 'org' => $org)) === $eventid;
}
@ -239,9 +360,12 @@ class Event extends AppModel {
* @return bool true if success, error message if failed
*/
public function uploadEventToServer($event, $server, $HttpSocket=null) {
if (true == $event['Event']['private']) { // never upload private events
if (('true' != Configure::read('CyDefSIG.private')) && (true == $event['Event']['private'])) { // never upload private events
return "Event is private and non exportable";
}
if (('true' == Configure::read('CyDefSIG.private')) && (true == $event['Event']['pull'])) {
return "Event is pull only and non exportable";
}
$url = $server['Server']['url'];
$authkey = $server['Server']['authkey'];

62
app/Model/Group.php Executable file
View File

@ -0,0 +1,62 @@
<?php
App::uses('AppModel', 'Model');
/**
* Group Model
*
* @property User $User
*/
class Group extends AppModel {
/**
* Validation rules
*
* @var array
*/
public $validate = array(
'name' => 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
),
),
);
/**
* hasMany associations
*
* @var array
*/
public $hasMany = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'group_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
/**
* TODO ACL: 1: be requester to CakePHP ACL system
*
* @var unknown_type
*/
public $actsAs = array('Acl' => array('type' => 'requester'), 'MagicTools.OrphansProtectable');
/**
* TODO ACL: 2: hook Group into CakePHP ACL system (so link to aros)
*/
public function parentNode() {
return null;
}
}

31
app/Model/Log.php Executable file
View File

@ -0,0 +1,31 @@
<?php
App::uses('AppModel', 'Model');
/**
* Log Model
*
*/
class Log extends AppModel {
public $validate = array(
'action' => array(
'rule' => array('inList', array(
'login',
'logout',
'add',
'edit',
'delete',
'publish' // FIXME remove this once all attributes have a category. Otherwise sigs without category are not shown in the list
)),
'message' => 'Options : ...'
)
);
public $actionDefinitions = array(
'login' => array('desc' => 'Login action', 'formdesc' => "Login action"),
'logout' => array('desc' => 'Logout action', 'formdesc' => "Logout action"),
'add' => array('desc' => 'Add action', 'formdesc' => "Add action"),
'edit' => array('desc' => 'Edit action', 'formdesc' => "Edit action"),
'delete' => array('desc' => 'Delete action', 'formdesc' => "Delete action"),
'publish' => array('desc' => "Publish action", 'formdesc' => "Publish action")
);
}

10
app/Model/Server.php Normal file → Executable file
View File

@ -6,6 +6,14 @@ App::uses('AppModel', 'Model');
*/
class Server extends AppModel {
public $name = 'Server'; // TODO general
public $actsAs = array('SysLogLogable.SysLogLogable' => array( // TODO Audit, logable, check: 'userModel' and 'userKey' can be removed given default
'userModel' => 'User',
'userKey' => 'user_id',
'change' => 'full'
));
/**
* Display field
*
@ -94,4 +102,4 @@ class Server extends AppModel {
public function isOwnedByOrg($serverid, $org) {
return $this->field('id', array('id' => $serverid, 'org' => $org)) === $serverid;
}
}
}

View File

@ -17,6 +17,14 @@ class User extends AppModel {
*/
public $displayField = 'email';
public $orgField = 'org'; // TODO Audit, LogableBehaviour + org
/**
* Model Name
*
* @var string
*/
public $name = 'User'; // TODO general
/**
* Validation rules
*
@ -69,6 +77,16 @@ class User extends AppModel {
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'org_id' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please specify the organisation ID where you are working.', // TODO ACL, org_id in Users
//'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'),
@ -162,6 +180,21 @@ class User extends AppModel {
//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(
'Group' => array(
'className' => 'Group',
'foreignKey' => 'group_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
/**
* hasMany associations
*
@ -183,6 +216,38 @@ class User extends AppModel {
)
);
/**
* TODO ACL: 1: be requester to CakePHP ACL system
*/
public $actsAs = array('Acl' => array('type' => 'requester', 'enabled' => false)); // TODO ACL, + 'enabled' => false
/**
* TODO ACL: 2: hook User into CakePHP ACL system (so link to aros)
*/
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
if (isset($this->data['User']['group_id'])) {
$groupId = $this->data['User']['group_id'];
} else {
$groupId = $this->field('group_id');
}
if (!$groupId) {
return null;
} else {
return array('Group' => array('id' => $groupId));
}
}
/**
* TODO ACL: 3: rights on Groups: http://stackoverflow.com/questions/6154285/aros-table-in-cakephp-is-still-including-users-even-after-bindnode
*/
public function bindNode($user) {
// return array('model' => 'Group', 'foreign_key' => $user['User']['group_id']);
return array('Group' => array('id' => $user['User']['group_id']));
}
public function beforeSave() {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);

View File

@ -0,0 +1,125 @@
<?php
/**
* Prevents a record from being deleted when deletion would result in orphaned related records; if deletion is prevented, an explanatory error message is stored in the model's attribute $deletionError.
*
* Example: A user has written many posts. Now somebody tries to delete the user - which would result in orphaned posts with no user! So this behavior prevents deletion of the user.
*
* Notice: This behavior has only an effect when 'dependent' is set to false (otherwise the records are all deleted anyway and no orphans would be left behind).
*
* @author Joshua Muheim (Incense.ch)
* @copyright Joshua Muheim, 2011
* @package magic_tools
* @subpackage behaviors
*/
App::import('core', 'ModelBehavior');
class OrphansProtectableBehavior extends ModelBehavior {
/**
* Prepares the behavior.
*
* @param $model Model
* @param $settings array
*/
function setup(&$Model, $settings) {
$Model->_deletionError = null; // Stores the deletion error message
$Model->orphansProtectableOptions = array_merge(array(
'listPossibleOrphans' => true,
'htmlError' => false
), $settings);
}
/**
* Checks if there would be orphaned record left behind after deletion of this record; if so, deletion is prevented.
*
* @param $model Model
* @param $cascade boolean
* @return boolean
*/
function beforeDelete(&$Model, $cascade) {
if($cascade) return true;
return !$Model->wouldLeaveOrphanedRecordsBehind();
}
/**
* Checks if deletion of this record would leave orphaned associated records behind.
*
* @param $model Model
* @return boolean
*/
function wouldLeaveOrphanedRecordsBehind(&$Model) {
$possibleOrphans = array();
foreach($Model->hasMany as $model => $settings) {
// Is relationship is dependent?
if($settings['dependent']){ // Yes! Possible orphans are deleted, too!
// Do nothing
} else { // No! Possible orphans should be protected!
// Is there a possible orphan for this relation?
$Model->{$model}->recursive = -1;
$objects = $Model->{$model}->find('all', array('conditions' => array($settings['className'].'.'.$settings['foreignKey'] => $Model->id), 'order' => 'id asc'));
if(count($objects) > 0) { // Yes, there is at least one possible orphan!
$objectIds = array();
foreach($objects as $object) {
$objectIds[] = $object[$model]['id'];
}
$possibleOrphans[$model] = $objectIds;
}
}
}
// Would orphans be left behind?
if(count($possibleOrphans) > 0) { // Yes! Create deletion error message!
$Model->_deletionError = $Model->createDeletionError($possibleOrphans);
return true;
} else { // No!
return false;
}
}
/**
* Returns the deletion error message (if there is one).
*
* @param $model Model
* @return string
*/
function getDeletionError(&$Model) {
return $Model->_deletionError;
}
/**
* Creates the deletion error message and returns it.
*
* @param $model Model
* @param $possibleOrphans array
* @return string
*/
function createDeletionError(&$Model, $possibleOrphans) {
$errorParts = array();
foreach($possibleOrphans as $model => $ids) {
$count = count($ids);
$modelName = $count > 1 ? Inflector::pluralize($model) : $model;
$errorParts[] = $count.' '.__($modelName, true).' (ID: '.$Model->createDeletionErrorIds($model, $ids).')';
}
return __('it has the following dependent items', true).': '.implode($errorParts, ', ');
}
/**
* Creates a string containing HTML-links to comma separated IDs of the potentially orphaned records of the specified model.
*
* @param $model Model
* @param $orphanModel string
* @param $ids array
* @return string
*/
function createDeletionErrorIds(&$Model, $orphanModel, $ids) {
$messageParts = array();
if($Model->orphansProtectableOptions['htmlError']) {
foreach($ids as $id) {
$messageParts[] = '<a href="'.Inflector::pluralize(strtolower($orphanModel)).'/view/'.$id.'">'.$id.'</a>'; // TODO: Noch unschön! --zivi-muh
}
} else {
$messageParts = $ids;
}
return implode($messageParts, ', ');
}
}
?>

View File

@ -0,0 +1,220 @@
<?php
App::import('Lib', 'SysLog.SysLog'); // Audit, syslogd, extra
App::import('Controller', 'EventsController');
App::import('Controller', 'ServersController');
class SysLogLogableBehavior extends LogableBehavior {
function afterSave(&$Model, $created) {
if (!$this->settings[$Model->alias]['enabled']) {
return true;
}
if (isset($this->settings[$Model->alias]['skip']['add']) && $this->settings[$Model->alias]['skip']['add'] && $created) {
return true;
} elseif (isset($this->settings[$Model->alias]['skip']['edit']) && $this->settings[$Model->alias]['skip']['edit'] && !$created) {
return true;
}
$keys = array_keys($Model->data[$Model->alias]);
$diff = array_diff($keys, $this->settings[$Model->alias]['ignore']);
if (sizeof($diff) == 0 && empty($Model->logableAction)) {
return false;
}
if ($Model->id) {
$id = $Model->id;
} elseif ($Model->insertId) {
$id = $Model->insertId;
}
if (isset($this->schema[$this->settings[$Model->alias]['foreignKey']])) {
$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $id;
}
if (isset($this->schema['description'])) {
$logData['Log']['description'] = $Model->alias . ' ';
if (isset($Model->data[$Model->alias][$Model->displayField]) && $Model->displayField != $Model->primaryKey) {
$logData['Log']['description'] .= '"' . $Model->data[$Model->alias][$Model->displayField] . '" ';
}
if ($this->settings[$Model->alias]['description_ids']) {
$logData['Log']['description'] .= '(' . $id . ') ';
}
if ($created) {
$logData['Log']['description'] .= __('added', TRUE);
} else {
$logData['Log']['description'] .= __('updated', TRUE);
}
}
if (isset($this->schema['action'])) {
if ($created) {
$logData['Log']['action'] = 'add';
} else {
$logData['Log']['action'] = 'edit';
}
}
if (isset($this->schema['change'])) {
$logData['Log']['change'] = '';
$db_fields = array_keys($Model->schema());
$changed_fields = array();
foreach ( $Model->data[$Model->alias] as $key => $value ) {
if (isset($Model->data[$Model->alias][$Model->primaryKey]) && !empty($this->old) && isset($this->old[$Model->alias][$key])) {
$old = $this->old[$Model->alias][$key];
} else {
$old = '';
}
// TODO Audit, removed 'revision' as well
if ($key != 'revision' && $key != 'modified' && !in_array($key, $this->settings[$Model->alias]['ignore']) && $value != $old && in_array($key, $db_fields)) {
if ($this->settings[$Model->alias]['change'] == 'full') {
$changed_fields[] = $key . ' (' . $old . ') => (' . $value . ')';
} else if ($this->settings[$Model->alias]['change'] == 'serialize') {
$changed_fields[$key] = array(
'old' => $old,
'value' => $value);
} else {
$changed_fields[] = $key;
}
}
}
$changes = sizeof($changed_fields);
if ($changes == 0) {
return true;
}
if ($this->settings[$Model->alias]['change'] == 'serialize') {
$logData['Log']['change'] = serialize($changed_fields);
} else {
$logData['Log']['change'] = implode(', ', $changed_fields);
}
$logData['Log']['changes'] = $changes;
}
$this->_saveLog($Model, $logData);
}
function _saveLog(&$Model, $logData, $title = null) {
if ($title !== NULL) {
$logData['Log']['title'] = $title;
} elseif ($Model->displayField == $Model->primaryKey) {
$logData['Log']['title'] = $Model->alias . ' (' . $Model->id . ')';
} elseif (isset($Model->data[$Model->alias][$Model->displayField])) {
$logData['Log']['title'] = $Model->data[$Model->alias][$Model->displayField];
} else {
$logData['Log']['title'] = $Model->field($Model->displayField);
}
if (isset($this->schema[$this->settings[$Model->alias]['classField']])) {
// by miha nahtigal
$logData['Log'][$this->settings[$Model->alias]['classField']] = $Model->name;
}
if (isset($this->schema[$this->settings[$Model->alias]['foreignKey']]) && !isset($logData['Log'][$this->settings[$Model->alias]['foreignKey']])) {
if ($Model->id) {
$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $Model->id;
} elseif ($Model->insertId) {
$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $Model->insertId;
}
}
if (!isset($this->schema['action'])) {
unset($logData['Log']['action']);
} elseif (isset($Model->logableAction) && !empty($Model->logableAction)) {
$logData['Log']['action'] = implode(',', $Model->logableAction); // . ' ' . $logData['Log']['action'];
unset($Model->logableAction);
}
if (isset($this->schema['version_id']) && isset($Model->version_id)) {
$logData['Log']['version_id'] = $Model->version_id;
unset($Model->version_id);
}
if (isset($this->schema['ip']) && $this->userIP) {
$logData['Log']['ip'] = $this->userIP;
}
if (isset($this->schema[$this->settings[$Model->alias]['userKey']]) && $this->user) {
$logData['Log'][$this->settings[$Model->alias]['userKey']] = $this->user[$this->UserModel->alias][$this->UserModel->primaryKey];
}
if (isset($this->schema['description'])) {
if ($this->user && $this->UserModel) {
$logData['Log']['description'] .= ' by ' . $this->settings[$Model->alias]['userModel'] . ' "' . $this->user[$this->UserModel->alias][$this->UserModel->displayField] . '"';
if ($this->settings[$Model->alias]['description_ids']) {
$logData['Log']['description'] .= ' (' . $this->user[$this->UserModel->alias][$this->UserModel->primaryKey] . ')';
}
} else {
// UserModel is active, but the data hasnt been set. Assume system action.
$logData['Log']['description'] .= ' by System';
}
$logData['Log']['description'] .= '.';
}
if (isset($this->schema['email'])) { // TODO Audit, LogableBehevior email
if ($this->user && $this->UserModel) {
$logData['Log']['email'] = $this->user[$this->UserModel->alias][$this->UserModel->displayField];
} else {
// UserModel is active, but the data hasnt been set. Assume system action.
$logData['Log']['email'] = 'SYS';
}
}
if (isset($this->schema['org'])) { // TODO Audit, LogableBehevior org CHECK!!!
if ($this->user && $this->UserModel) {
$logData['Log']['org'] = $this->user[$this->UserModel->alias][$this->UserModel->orgField];
} else {
// UserModel is active, but the data hasnt been set. Assume system action.
$logData['Log']['org'] = 'SYS';
}
}
if (isset($this->schema['title'])) { // TODO LogableBehevior title
if ($this->user && $this->UserModel) { // $Model->data[$Model->alias][$Model->displayField]
switch ($Model->alias) {
case "User": // TODO Audit, not used here but done in UsersController
$title = 'User ('. $Model->data[$Model->alias]['id'].') '. $Model->data[$Model->alias]['email'];
break;
case "Event":
$this->Events = new EventsController();
$this->Events->constructClasses();
$title = 'Event ('. $Model->data[$Model->alias]['id'].'): '.$this->Events->getName($Model->data[$Model->alias]['id']);
$logData['Log']['title'] = $title;
break;
case "Attribute":
if (isset($Model->combinedKeys)) {
if (is_array($Model->combinedKeys)) {
$title = 'Attribute ('. $Model->data[$Model->alias]['id'].') '.'from Event ('. $Model->data[$Model->alias]['event_id'].'): '. $Model->data[$Model->alias][$Model->combinedKeys[1]].'/'. $Model->data[$Model->alias][$Model->combinedKeys[2]].' '. $Model->data[$Model->alias]['value1'];
$logData['Log']['title'] = $title;
}
}
break;
case "Server":
$this->Servers = new ServersController();
$this->Servers->constructClasses();
$title = 'Server ('. $Model->data[$Model->alias]['id'].'): '. $this->Servers->getName($Model->data[$Model->alias]['id']);
$logData['Log']['title'] = $title;
break;
default:
if (isset($Model->combinedKeys)) {
if (is_array($Model->combinedKeys)) {
$title = '';
foreach ($Model->combinedKeys as $combinedKey) {
$title .= '/'. $Model->data[$Model->alias][$combinedKey];
}
$title = substr($title ,1);
$logData['Log']['title'] = $title;
}
}
}
}
}
$this->Log->create($logData);
$this->Log->save(null, array(
'validate' => false,
'callbacks' => false));
// write to syslogd as well
$syslog = new SysLog();
if (isset($logData['Log']['change'])) {
$syslog->write('notice', $logData['Log']['description'].' -- '.$logData['Log']['change']);
} else {
$syslog->write('notice', $logData['Log']['description']);
}
}
}

View File

@ -1,14 +1,25 @@
TODOs
TODOs v0.2.2 to v0.2.3
-----
DB Update
- UpdateShell with in/out
Auth
- Prevent bruteforce auth attempts
implement auditing/logging system
- add / edit events and signatures
- failed / success logins (with source IP, headers,...)
Acl
- inactive buttons
- must be non-clickable.
- JavaScript include.
- DOM read and disable button_offXX.
- clean-up to first cut.
- saveAcl, from GroupsController to AppController and inherit to *Controllers.
auditing/logging system
- logins
- add source IP (headers,...);
- failed logins.
Security
- force cookie reset after login
@ -18,7 +29,7 @@ INSTALLATION INSTRUCTIONS
-------------------------
Install the following libraries:
apt-get install zip
apt-get install pear
apt-get install php-pear
pear install Crypt_GPG # need version >1.3.0
pear install Net_GeoIP
# ideally make sure geoip database is updated using crontab
@ -80,6 +91,17 @@ Don't forget to change the email, password and authentication key after installa
UPDATE INSTRUCTIONS
-------------------
To be sure, dump your database before updating.
CyDefSIG from 0.2.2 to 0.2.3 needs a database migration and population.
This is done executing /var/www/cydefsig/app/Console/shell/migrate-0.2.2-0.2.3.sh
and answer (y)es to all the questions asked.
Recommended patches
-------------------
By default CakePHP exposes his name and version in email headers. Apply a patch to remove this behavior.

34
app/README.ubuntu.txt Executable file
View File

@ -0,0 +1,34 @@
INSTALLATION INSTRUCTIONS
-------------------------
If on Ubuntu, besides the DocumentRoot,
you have to change the AllowOverride from None to All as well.
DocumentRoot /var/www/cydefsig/app/webroot/
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
Find the original below, for reference.
DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
Now /etc/init.d/apache2 restart
and you are done, and now able to use the application.

View File

@ -14,9 +14,15 @@ echo $this->Form->input('type', array(
'empty' => '(first choose category)'
));
if ('true' == Configure::read('CyDefSIG.sync')) {
echo $this->Form->input('private', array(
'before' => $this->Html->div('forminfo', isset($attrDescriptions['private']['formdesc']) ? $attrDescriptions['private']['formdesc'] : $attrDescriptions['private']['desc']),
));
if ('true' == Configure::read('CyDefSIG.private')) {
echo $this->Form->input('sharing', array('label' => 'Private',
'before' => $this->Html->div('forminfo', isset($attrDescriptions['sharing']['formdesc']) ? $attrDescriptions['sharing']['formdesc'] : $attrDescriptions['sharing']['desc']),
));
} else {
echo $this->Form->input('private', array(
'before' => $this->Html->div('forminfo', isset($attrDescriptions['private']['formdesc']) ? $attrDescriptions['private']['formdesc'] : $attrDescriptions['private']['desc']),
));
}
}
echo $this->Form->input('to_ids', array(
'checked' => true,

View File

@ -14,8 +14,13 @@ echo $this->Form->input('malware', array(
'after' => '<br>Tick this box to neutralize the sample. Every malware sample will be zipped with the password "infected"',
));
if ('true' == Configure::read('CyDefSIG.sync')) {
echo $this->Form->input('private', array(
if ('true' == Configure::read('CyDefSIG.private')) {
echo $this->Form->input('sharing', array('label' => 'Private',
'before' => $this->Html->div('forminfo', isset($attrDescriptions['sharing']['formdesc']) ? $attrDescriptions['sharing']['formdesc'] : $attrDescriptions['sharing']['desc']),));
} else {
echo $this->Form->input('private', array(
'before' => $this->Html->div('forminfo', isset($attrDescriptions['private']['formdesc']) ? $attrDescriptions['private']['formdesc'] : $attrDescriptions['private']['desc']),));
}
}
// link an onchange event to the form elements
$this->Js->get('#AttributeType')->event('change', 'showFormInfo("#AttributeType")');

View File

@ -1,3 +1,7 @@
<?php
$buttonModifyStatus = $isAclModify ? 'button_on':'button_off';
$buttonCounter = 0;
?>
<div class="attributes form">
<?php echo $this->Form->create('Attribute');?>
<fieldset>
@ -12,9 +16,15 @@ if ($attachment) {
echo $this->Form->input('type', array('between' => $this->Html->div('forminfo', '', array('id' => 'AttributeTypeDiv'))));
}
if ('true' == Configure::read('CyDefSIG.sync')) {
echo $this->Form->input('private', array(
'before' => $this->Html->div('forminfo', isset($attrDescriptions['private']['formdesc']) ? $attrDescriptions['private']['formdesc'] : $attrDescriptions['private']['desc']),
));
if ('true' == Configure::read('CyDefSIG.private')) {
echo $this->Form->input('sharing', array('label' => 'Private',
'before' => $this->Html->div('forminfo', isset($attrDescriptions['sharing']['formdesc']) ? $attrDescriptions['sharing']['formdesc'] : $attrDescriptions['sharing']['desc']),
));
} else {
echo $this->Form->input('private', array(
'before' => $this->Html->div('forminfo', isset($attrDescriptions['private']['formdesc']) ? $attrDescriptions['private']['formdesc'] : $attrDescriptions['private']['desc']),
));
}
}
echo $this->Form->input('to_ids', array(
'before' => $this->Html->div('forminfo', isset($attrDescriptions['signature']['formdesc']) ? $attrDescriptions['signature']['formdesc'] : $attrDescriptions['signature']['desc']),
@ -38,7 +48,10 @@ $this->Js->get('#AttributeType')->event('change', 'showFormInfo("#AttributeType"
</div>
<div class="actions">
<ul>
<li><?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $this->Form->value('Attribute.id')), null, __('Are you sure you want to delete # %s?', $this->Form->value('Attribute.id'))); ?></li>
<li><?php
$attribute = ClassRegistry::init('Attribute')->findById($this->Form->value('Attribute.id')); // TODO ACL $attribute??
if ($isAclModify || $attribute['Event']['user_id'] == $me['id']) echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $this->Form->value('Attribute.id')), null, __('Are you sure you want to delete # %s?', $this->Form->value('Attribute.id')));
else echo $this->Html->link(__('Delete'), array('action' => 'delete', $this->Form->value('Attribute.id')), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus)); ?></li>
<li>&nbsp;</li>
<?php echo $this->element('actions_menu'); ?>
</ul>
@ -95,8 +108,8 @@ function showFormInfo(id) {
// LATER use nice animations
//$(idDiv).hide('fast');
// change the content
var value = $(id).val(); // get the selected value
$(idDiv).html(formInfoValues[value]); // search in a lookup table
var value = $(id).val(); // get the selected value
$(idDiv).html(formInfoValues[value]); // search in a lookup table
// show it again
$(idDiv).fadeIn('slow');
@ -111,4 +124,12 @@ formCategoryChanged("#AttributeCategory");
$('#AttributeType').val(type_value);
</script>
<?php echo $this->Js->writeBuffer(); // Write cached scripts
<?php echo $this->Js->writeBuffer(); // Write cached scripts ?>
<!--?php $javascript->link('deactivateButtons.js', false); ?-->
<!--script type="text/javascript" src="deactivateButtons.js"></script-->
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
</script>
<?php echo $this->Js->writeBuffer(); // Write cached scripts

View File

@ -1,3 +1,7 @@
<?php
$buttonModifyStatus = $isAclModify ? 'button_on':'button_off';
$buttonCounter = 0;
?>
<div class="attributes index">
<h2><?php echo __('Attributes');?></h2>
<table cellpadding="0" cellspacing="0">
@ -37,8 +41,9 @@ if ('attachment' == $attribute['Attribute']['type'] || 'malware-sample' == $attr
<?php echo $attribute['Attribute']['to_ids'] ? 'Yes' : 'No'; ?>&nbsp;</td>
<td class="actions"><?php
if ($isAdmin || $attribute['Event']['org'] == $me['org']) {
echo $this->Html->link(__('Edit'), array('action' => 'edit', $attribute['Attribute']['id']));
echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $attribute['Attribute']['id']), null, __('Are you sure you want to delete this attribute?'));
echo $this->Html->link(__('Edit'), array('action' => 'edit', $attribute['Attribute']['id']), $isAclModify || ($attribute['Event']['user_id'] == $me['id']) ? null : array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus));
if ($isAclModify || $attribute['Event']['user_id'] == $me['id']) echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $attribute['Attribute']['id']), null, __('Are you sure you want to delete this attribute?'));
else echo $this->Html->link(__('Delete'), array('action' => 'delete', $attribute['Attribute']['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus));
}
echo $this->Html->link(__('View'), array('controller' => 'events', 'action' => 'view', $attribute['Attribute']['event_id']));
?>
@ -65,4 +70,401 @@ echo $this->Html->link(__('View'), array('controller' => 'events', 'action' => '
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
</div>
<!--?php $javascript->link('deactivateButtons.js', false); ?-->
<!--script type="text/javascript" src="deactivateButtons.js"></script-->
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
$('#button_off0').click(function() {
return false;
});
$('#button_off1').click(function() {
return false;
});
$('#button_off2').click(function() {
return false;
});
$('#button_off3').click(function() {
return false;
});
$('#button_off4').click(function() {
return false;
});
$('#button_off5').click(function() {
return false;
});
$('#button_off6').click(function() {
return false;
});
$('#button_off7').click(function() {
return false;
});
$('#button_off8').click(function() {
return false;
});
$('#button_off9').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off11').click(function() {
return false;
});
$('#button_off12').click(function() {
return false;
});
$('#button_off13').click(function() {
return false;
});
$('#button_off14').click(function() {
return false;
});
$('#button_off15').click(function() {
return false;
});
$('#button_off16').click(function() {
return false;
});
$('#button_off17').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off19').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off21').click(function() {
return false;
});
$('#button_off22').click(function() {
return false;
});
$('#button_off23').click(function() {
return false;
});
$('#button_off24').click(function() {
return false;
});
$('#button_off25').click(function() {
return false;
});
$('#button_off26').click(function() {
return false;
});
$('#button_off27').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off29').click(function() {
return false;
});
$('#button_off30').click(function() {
return false;
});
$('#button_off31').click(function() {
return false;
});
$('#button_off32').click(function() {
return false;
});
$('#button_off33').click(function() {
return false;
});
$('#button_off34').click(function() {
return false;
});
$('#button_off35').click(function() {
return false;
});
$('#button_off36').click(function() {
return false;
});
$('#button_off37').click(function() {
return false;
});
$('#button_off30').click(function() {
return false;
});
$('#button_off39').click(function() {
return false;
});
$('#button_off40').click(function() {
return false;
});
$('#button_off41').click(function() {
return false;
});
$('#button_off42').click(function() {
return false;
});
$('#button_off43').click(function() {
return false;
});
$('#button_off44').click(function() {
return false;
});
$('#button_off45').click(function() {
return false;
});
$('#button_off46').click(function() {
return false;
});
$('#button_off47').click(function() {
return false;
});
$('#button_off40').click(function() {
return false;
});
$('#button_off49').click(function() {
return false;
});
$('#button_off50').click(function() {
return false;
});
$('#button_off51').click(function() {
return false;
});
$('#button_off52').click(function() {
return false;
});
$('#button_off53').click(function() {
return false;
});
$('#button_off54').click(function() {
return false;
});
$('#button_off55').click(function() {
return false;
});
$('#button_off56').click(function() {
return false;
});
$('#button_off57').click(function() {
return false;
});
$('#button_off50').click(function() {
return false;
});
$('#button_off59').click(function() {
return false;
});
$('#button_off60').click(function() {
return false;
});
$('#button_off61').click(function() {
return false;
});
$('#button_off62').click(function() {
return false;
});
$('#button_off63').click(function() {
return false;
});
$('#button_off64').click(function() {
return false;
});
$('#button_off65').click(function() {
return false;
});
$('#button_off66').click(function() {
return false;
});
$('#button_off67').click(function() {
return false;
});
$('#button_off60').click(function() {
return false;
});
$('#button_off69').click(function() {
return false;
});
$('#button_off70').click(function() {
return false;
});
$('#button_off71').click(function() {
return false;
});
$('#button_off72').click(function() {
return false;
});
$('#button_off73').click(function() {
return false;
});
$('#button_off74').click(function() {
return false;
});
$('#button_off75').click(function() {
return false;
});
$('#button_off76').click(function() {
return false;
});
$('#button_off77').click(function() {
return false;
});
$('#button_off70').click(function() {
return false;
});
$('#button_off79').click(function() {
return false;
});
$('#button_off80').click(function() {
return false;
});
$('#button_off81').click(function() {
return false;
});
$('#button_off82').click(function() {
return false;
});
$('#button_off83').click(function() {
return false;
});
$('#button_off84').click(function() {
return false;
});
$('#button_off85').click(function() {
return false;
});
$('#button_off86').click(function() {
return false;
});
$('#button_off87').click(function() {
return false;
});
$('#button_off80').click(function() {
return false;
});
$('#button_off89').click(function() {
return false;
});
$('#button_off90').click(function() {
return false;
});
$('#button_off91').click(function() {
return false;
});
$('#button_off92').click(function() {
return false;
});
$('#button_off93').click(function() {
return false;
});
$('#button_off94').click(function() {
return false;
});
$('#button_off95').click(function() {
return false;
});
$('#button_off96').click(function() {
return false;
});
$('#button_off97').click(function() {
return false;
});
$('#button_off90').click(function() {
return false;
});
$('#button_off99').click(function() {
return false;
});
$('#button_off100').click(function() {
return false;
});
$('#button_off101').click(function() {
return false;
});
$('#button_off102').click(function() {
return false;
});
$('#button_off103').click(function() {
return false;
});
$('#button_off104').click(function() {
return false;
});
$('#button_off105').click(function() {
return false;
});
$('#button_off106').click(function() {
return false;
});
$('#button_off107').click(function() {
return false;
});
$('#button_off100').click(function() {
return false;
});
$('#button_off109').click(function() {
return false;
});
$('#button_off110').click(function() {
return false;
});
$('#button_off111').click(function() {
return false;
});
$('#button_off112').click(function() {
return false;
});
$('#button_off113').click(function() {
return false;
});
$('#button_off114').click(function() {
return false;
});
$('#button_off115').click(function() {
return false;
});
$('#button_off116').click(function() {
return false;
});
$('#button_off117').click(function() {
return false;
});
$('#button_off110').click(function() {
return false;
});
$('#button_off119').click(function() {
return false;
});
$('#button_off120').click(function() {
return false;
});
$('#button_off121').click(function() {
return false;
});
$('#button_off122').click(function() {
return false;
});
$('#button_off123').click(function() {
return false;
});
$('#button_off124').click(function() {
return false;
});
$('#button_off125').click(function() {
return false;
});
$('#button_off126').click(function() {
return false;
});
$('#button_off127').click(function() {
return false;
});
$('#button_off120').click(function() {
return false;
});
$('#button_off129').click(function() {
return false;
});
</script>

View File

@ -10,6 +10,10 @@ foreach ($attributes as $key => $attribute) {
if ('true' != Configure::read('CyDefSIG.sync')) {
unset($attributes[$key]['private']);
}
if ('true' == Configure::read('CyDefSIG.private')) {
unset($attributes[$key]['sharing']);
unset($attributes[$key]['cluster']);
}
}

View File

@ -1,4 +1,5 @@
<li><?php echo $this->Html->link(__('New Event', true), array('controller' => 'events', 'action' => 'add')); ?></li>
<?php $buttonAddStatus = $isAclAdd ? 'button_on':'button_off'; ?>
<li><?php echo $this->Html->link(__('New Event', true), array('controller' => 'events', 'action' => 'add'), array('id' => $buttonAddStatus,'class' => $buttonAddStatus)); ?></li>
<li><?php echo $this->Html->link(__('List Events', true), array('controller' => 'events', 'action' => 'index')); ?></li>
<li><?php echo $this->Html->link(__('List Attributes', true), array('controller' => 'attributes', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('Search Attributes', true), array('controller' => 'attributes', 'action' => 'search')); ?> </li>
@ -25,4 +26,10 @@
<li>&nbsp;</li>
<li><?php echo $this->Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add', 'admin' => true)); ?> </li>
<li><?php echo $this->Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index', 'admin' => true)); ?> </li>
<li><?php echo $this->Html->link(__('New Group', true), array('controller' => 'groups', 'action' => 'add', 'admin' => true)); ?> </li>
<li><?php echo $this->Html->link(__('List Groups', true), array('controller' => 'groups', 'action' => 'index', 'admin' => true)); ?> </li>
<li>&nbsp;</li>
<h3><?php echo __('Audit'); ?></h3>
<li><?php echo $this->Html->link(__('List Logs', true), array('controller' => 'logs', 'action' => 'index', 'admin' => true)); ?> </li>
<li><?php echo $this->Html->link(__('Search Logs', true), array('controller' => 'logs', 'action' => 'admin_search', 'admin' => true)); ?> </li>
<?php endif;

View File

@ -1,16 +1,26 @@
<div class="events form">
<?php echo $this->Form->create('Event');?>
<?php echo $this->Form->create('Event', array('type' => 'file'));?>
<fieldset>
<legend><?php echo __('Add Event'); ?></legend>
<?php
echo $this->Form->input('date');
if ('true' == Configure::read('CyDefSIG.sync')) {
echo $this->Form->input('private', array(
'before' => $this->Html->div('forminfo', isset($eventDescriptions['private']['formdesc']) ? $eventDescriptions['private']['formdesc'] : $eventDescriptions['private']['desc']),));
if ('true' == Configure::read('CyDefSIG.private')) {
echo $this->Form->input('sharing', array('label' => 'Private',
'before' => $this->Html->div('forminfo', isset($eventDescriptions['sharing']['formdesc']) ? $eventDescriptions['sharing']['formdesc'] : $eventDescriptions['sharing']['desc']),));
} else {
echo $this->Form->input('private', array(
'before' => $this->Html->div('forminfo', isset($eventDescriptions['private']['formdesc']) ? $eventDescriptions['private']['formdesc'] : $eventDescriptions['private']['desc']),));
}
}
echo $this->Form->input('risk', array(
'before' => $this->Html->div('forminfo', isset($eventDescriptions['risk']['formdesc']) ? $eventDescriptions['risk']['formdesc'] : $eventDescriptions['risk']['desc'])));
echo $this->Form->input('info');
echo $this->Form->input('Event.submittedfile', array(
'label' => '<b>GFI sandbox</b>',
'between' => '<br />',
'type' => 'file',
'before' => $this->Html->div('forminfo', isset($eventDescriptions['submittedfile']['formdesc']) ? $eventDescriptions['submittedfile']['formdesc'] : $eventDescriptions['submittedfile']['desc'])));
?>
</fieldset>
@ -21,4 +31,4 @@ echo $this->Form->input('info');
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
</div>

View File

@ -8,8 +8,13 @@ echo $this->Form->input('date');
echo $this->Form->input('risk', array(
'before' => $this->Html->div('forminfo', isset($eventDescriptions['risk']['formdesc']) ? $eventDescriptions['risk']['formdesc'] : $eventDescriptions['risk']['desc'])));
if ('true' == Configure::read('CyDefSIG.sync')) {
echo $this->Form->input('private', array(
'before' => $this->Html->div('forminfo', isset($eventDescriptions['private']['formdesc']) ? $eventDescriptions['private']['formdesc'] : $eventDescriptions['private']['desc']),));
if ('true' == Configure::read('CyDefSIG.private')) {
echo $this->Form->input('sharing', array('label' => 'Private',
'before' => $this->Html->div('forminfo', isset($eventDescriptions['sharing']['formdesc']) ? $eventDescriptions['sharing']['formdesc'] : $eventDescriptions['sharing']['desc']),));
} else {
echo $this->Form->input('private', array(
'before' => $this->Html->div('forminfo', isset($eventDescriptions['private']['formdesc']) ? $eventDescriptions['private']['formdesc'] : $eventDescriptions['private']['desc']),));
}
}
echo $this->Form->input('info');
?>

View File

@ -1,3 +1,9 @@
<?php
$buttonAddStatus = $isAclAdd ? 'button_on':'button_off';
$buttonModifyStatus = $isAclModify ? 'button_on':'button_off';
$buttonPublishStatus = $isAclPublish ? 'button_on':'button_off';
$buttonCounter = 0;
?>
<div class="events index">
<h2>Events</h2>
<table cellpadding="0" cellspacing="0">
@ -51,13 +57,15 @@
<td class="actions">
<?php
if (0 == $event['Event']['published'] && ($isAdmin || $event['Event']['org'] == $me['org']))
echo $this->Form->postLink('Publish Event', array('action' => 'alert', $event['Event']['id']), null, 'Are you sure this event is complete and everyone should be informed?');
if ($isAclPublish || $event['Event']['user_id'] == $me['id']) echo $this->Form->postLink('Publish Event', array('action' => 'alert', $event['Event']['id']), array('action' => 'alert', $event['Event']['id']), 'Are you sure this event is complete and everyone should be informed?');
else echo $this->Html->link('Publish Event', array('id' => $buttonPublishStatus . $buttonCounter++, 'class' => $buttonPublishStatus, 'action' => 'alert', $event['Event']['id']), array('id' => $buttonPublishStatus . $buttonCounter++, 'class' => $buttonPublishStatus, 'action' => 'alert', $event['Event']['id']));
elseif (0 == $event['Event']['published']) echo 'Not published';
?>
<?php
if ($isAdmin || $event['Event']['org'] == $me['org']) {
echo $this->Html->link(__('Edit', true), array('action' => 'edit', $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']));
echo $this->Html->link(__('Edit', true), array('action' => 'edit', $event['Event']['id']), $isAclModify || ($event['Event']['user_id'] == $me['id']) ? null : array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus));
if ($isAclModify || $event['Event']['user_id'] == $me['id']) echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $event['Event']['id']), null, __('Are you sure you want to delete # %s?', $event['Event']['id']));
else echo $this->Html->link(__('Delete'), array('action' => 'delete', $event['Event']['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus));
}
?>
<?php echo $this->Html->link(__('View', true), array('controller' => 'events', 'action' => 'view', $event['Event']['id'])); ?>
@ -85,3 +93,580 @@ if ($isAdmin || $event['Event']['org'] == $me['org']) {
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
<!--?php $javascript->link('deactivateButtons.js', false); ?-->
<!--script type="text/javascript" src="deactivateButtons.js"></script-->
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
$('#button_off0').click(function() {
return false;
});
$('#button_off1').click(function() {
return false;
});
$('#button_off2').click(function() {
return false;
});
$('#button_off3').click(function() {
return false;
});
$('#button_off4').click(function() {
return false;
});
$('#button_off5').click(function() {
return false;
});
$('#button_off6').click(function() {
return false;
});
$('#button_off7').click(function() {
return false;
});
$('#button_off8').click(function() {
return false;
});
$('#button_off9').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off11').click(function() {
return false;
});
$('#button_off12').click(function() {
return false;
});
$('#button_off13').click(function() {
return false;
});
$('#button_off14').click(function() {
return false;
});
$('#button_off15').click(function() {
return false;
});
$('#button_off16').click(function() {
return false;
});
$('#button_off17').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off19').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off21').click(function() {
return false;
});
$('#button_off22').click(function() {
return false;
});
$('#button_off23').click(function() {
return false;
});
$('#button_off24').click(function() {
return false;
});
$('#button_off25').click(function() {
return false;
});
$('#button_off26').click(function() {
return false;
});
$('#button_off27').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off29').click(function() {
return false;
});
$('#button_off30').click(function() {
return false;
});
$('#button_off31').click(function() {
return false;
});
$('#button_off32').click(function() {
return false;
});
$('#button_off33').click(function() {
return false;
});
$('#button_off34').click(function() {
return false;
});
$('#button_off35').click(function() {
return false;
});
$('#button_off36').click(function() {
return false;
});
$('#button_off37').click(function() {
return false;
});
$('#button_off30').click(function() {
return false;
});
$('#button_off39').click(function() {
return false;
});
$('#button_off40').click(function() {
return false;
});
$('#button_off41').click(function() {
return false;
});
$('#button_off42').click(function() {
return false;
});
$('#button_off43').click(function() {
return false;
});
$('#button_off44').click(function() {
return false;
});
$('#button_off45').click(function() {
return false;
});
$('#button_off46').click(function() {
return false;
});
$('#button_off47').click(function() {
return false;
});
$('#button_off40').click(function() {
return false;
});
$('#button_off49').click(function() {
return false;
});
$('#button_off50').click(function() {
return false;
});
$('#button_off51').click(function() {
return false;
});only in
$('#button_off52').click(function() {
return false;
});
$('#button_off53').click(function() {
return false;
});
$('#button_off54').click(function() {
return false;
});
$('#button_off55').click(function() {
return false;
});
$('#button_off56').click(function() {
return false;
});
$('#button_off57').click(function() {
return false;
});
$('#button_off50').click(function() {
return false;
});
$('#button_off59').click(function() {
return false;
});
$('#button_off60').click(function() {
return false;
});
$('#button_off61').click(function() {
return false;
});
$('#button_off62').click(function() {
return false;
});
$('#button_off63').click(function() {
return false;
});
$('#button_off64').click(function() {
return false;
});
$('#button_off65').click(function() {
return false;
});
$('#button_off66').click(function() {
return false;
});
$('#button_off67').click(function() {
return false;
});
$('#button_off60').click(function() {
return false;
});
$('#button_off69').click(function() {
return false;
});
$('#button_off70').click(function() {
return false;
});
$('#button_off71').click(function() {
return false;
});
$('#button_off72').click(function() {
return false;
});
$('#button_off73').click(function() {
return false;
});
$('#button_off74').click(function() {
return false;
});
$('#button_off75').click(function() {
return false;
});
$('#button_off76').click(function() {
return false;
});
$('#button_off77').click(function() {
return false;
});
$('#button_off70').click(function() {
return false;
});
$('#button_off79').click(function() {
return false;
});
$('#button_off80').click(function() {
return false;
});
$('#button_off81').click(function() {
return false;
});
$('#button_off82').click(function() {
return false;
});
$('#button_off83').click(function() {
return false;
});
$('#button_off84').click(function() {
return false;
});
$('#button_off85').click(function() {
return false;
});
$('#button_off86').click(function() {
return false;
});
$('#button_off87').click(function() {
return false;
});
$('#button_off80').click(function() {
return false;
});
$('#button_off89').click(function() {
return false;
});
$('#button_off90').click(function() {
return false;
});
$('#button_off91').click(function() {
return false;
});
$('#button_off92').click(function() {
return false;
});
$('#button_off93').click(function() {
return false;
});
$('#button_off94').click(function() {
return false;
});
$('#button_off95').click(function() {
return false;
});
$('#button_off96').click(function() {
return false;
});
$('#button_off97').click(function() {
return false;
});
$('#button_off90').click(function() {
return false;
});
$('#button_off99').click(function() {
return false;
});
$('#button_off100').click(function() {
return false;
});
$('#button_off101').click(function() {
return false;
});
$('#button_off102').click(function() {
return false;
});
$('#button_off103').click(function() {
return false;
});
$('#button_off104').click(function() {
return false;
});
$('#button_off105').click(function() {
return false;
});
$('#button_off106').click(function() {
return false;
});
$('#button_off107').click(function() {
return false;
});
$('#button_off100').click(function() {
return false;
});
$('#button_off109').click(function() {
return false;
});
$('#button_off110').click(function() {
return false;
});
$('#button_off111').click(function() {
return false;
});
$('#button_off112').click(function() {
return false;
});
$('#button_off113').click(function() {
return false;
});
$('#button_off114').click(function() {
return false;
});
$('#button_off115').click(function() {
return false;
});
$('#button_off116').click(function() {
return false;
});
$('#button_off117').click(function() {
return false;
});
$('#button_off110').click(function() {
return false;
});
$('#button_off119').click(function() {
return false;
});
$('#button_off120').click(function() {
return false;
});
$('#button_off121').click(function() {
return false;
});
$('#button_off122').click(function() {
return false;
});
$('#button_off123').click(function() {
return false;
});
$('#button_off124').click(function() {
return false;
});
$('#button_off125').click(function() {
return false;
});
$('#button_off126').click(function() {
return false;
});
$('#button_off127').click(function() {
return false;
});
$('#button_off120').click(function() {
return false;
});
$('#button_off129').click(function() {
return false;
});
$('#button_off130').click(function() {
return false;
});
$('#button_off131').click(function() {
return false;
});
$('#button_off132').click(function() {
return false;
});
$('#button_off133').click(function() {
return false;
});
$('#button_off134').click(function() {
return false;
});
$('#button_off135').click(function() {
return false;
});
$('#button_off136').click(function() {
return false;
});
$('#button_off137').click(function() {
return false;
});
$('#button_off130').click(function() {
return false;
});
$('#button_off139').click(function() {
return false;
});
$('#button_off140').click(function() {
return false;
});
$('#button_off141').click(function() {
return false;
});
$('#button_off142').click(function() {
return false;
});
$('#button_off143').click(function() {
return false;
});
$('#button_off144').click(function() {
return false;
});
$('#button_off145').click(function() {
return false;
});
$('#button_off146').click(function() {
return false;
});
$('#button_off147').click(function() {
return false;
});
$('#button_off140').click(function() {
return false;
});
$('#button_off149').click(function() {
return false;
});
$('#button_off150').click(function() {
return false;
});
$('#button_off151').click(function() {
return false;
});
$('#button_off152').click(function() {
return false;
});
$('#button_off153').click(function() {
return false;
});
$('#button_off154').click(function() {
return false;
});
$('#button_off155').click(function() {
return false;
});
$('#button_off156').click(function() {
return false;
});
$('#button_off157').click(function() {
return false;
});
$('#button_off150').click(function() {
return false;
});
$('#button_off159').click(function() {
return false;
});
$('#button_off160').click(function() {
return false;
});
$('#button_off161').click(function() {
return false;
});
$('#button_off162').click(function() {
return false;
});
$('#button_off163').click(function() {
return false;
});
$('#button_off164').click(function() {
return false;
});
$('#button_off165').click(function() {
return false;
});
$('#button_off166').click(function() {
return false;
});
$('#button_off167').click(function() {
return false;
});
$('#button_off160').click(function() {
return false;
});
$('#button_off169').click(function() {
return false;
});
$('#button_off170').click(function() {
return false;
});
$('#button_off171').click(function() {
return false;
});
$('#button_off172').click(function() {
return false;
});
$('#button_off173').click(function() {
return false;
});
$('#button_off174').click(function() {
return false;
});
$('#button_off175').click(function() {
return false;
});
$('#button_off176').click(function() {
return false;
});
$('#button_off177').click(function() {
return false;
});
$('#button_off170').click(function() {
return false;
});
$('#button_off179').click(function() {
return false;
});
$('#button_off180').click(function() {
return false;
});
$('#button_off181').click(function() {
return false;
});
$('#button_off182').click(function() {
return false;
});
$('#button_off183').click(function() {
return false;
});
$('#button_off184').click(function() {
return false;
});
$('#button_off185').click(function() {
return false;
});
$('#button_off186').click(function() {
return false;
});
$('#button_off187').click(function() {
return false;
});
$('#button_off180').click(function() {
return false;
});
$('#button_off189').click(function() {
return false;
});
</script>

View File

@ -1,11 +1,24 @@
<?php
$buttonAddStatus = $isAclAdd || $event['Event']['user_id'] == $me['id'] ? 'button_on':'button_off';
$mayModify = $isAclModify || $event['Event']['user_id'] == $me['id'];
$buttonModifyStatus = $mayModify ? 'button_on':'button_off';
$mayPublish = $isAclPublish || $event['Event']['user_id'] == $me['id'];
$buttonPublishStatus = $mayPublish ? 'button_on':'button_off';
$buttonCounter = 0;
?>
<div class="events view">
<div class="actions" style="float:right;">
<?php if ( 0 == $event['Event']['published'] && ($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
if ($mayPublish) {
echo $this->Form->postLink('Publish Event', array('action' => 'alert', $event['Event']['id']), null, 'Are you sure this event is complete and everyone should be informed?');
echo $this->Form->postLink('Publish (no email)', array('action' => 'publish', $event['Event']['id']), null, 'Publish but do NOT send alert email? Only for minor changes!');
} else {
echo $this->Html->link('Publish Event', array('action' => 'alert', $event['Event']['id']), array('id' => $buttonPublishStatus . $buttonCounter++, 'class' => $buttonPublishStatus));
echo $this->Html->link('Publish (no email)', array('action' => 'publish', $event['Event']['id']), array('id' => $buttonPublishStatus . $buttonCounter++, 'class' => $buttonPublishStatus));
}
?> </li></ul>
<?php elseif (0 == $event['Event']['published']): ?>
<ul><li>Not published</li></ul>
@ -50,12 +63,20 @@
&nbsp;
</dd>
<?php if ('true' == Configure::read('CyDefSIG.sync')): ?>
<?php if ('true' == Configure::read('CyDefSIG.private')): ?>
<dt>Private</dt>
<dd>
<?php echo ($event['Event']['sharing'] == 'All') ? 'upload Event and all Attributes except those marked as to keep in Org or Server.' : (($event['Event']['sharing'] == 'Server') ? 'Server, Only show Event or any Attributes to Server members.' : (($event['Event']['sharing'] == 'Pull only') ? 'Pull only, Do not show Event or any Attributes, but do Pull this Event or Attribute.': 'Org, Only show Event or any Attributes to Org members.')); ?>
&nbsp;
</dd>
<?php else: ?>
<dt>Private</dt>
<dd>
<?php echo ($event['Event']['private'])? 'Yes, never upload Event or any Attributes.' : 'No, upload Event and all Attributes except those marked as Private.'; ?>
&nbsp;
</dd>
<?php endif; ?>
<?php endif; ?>
<!-- dt>UUID</dt>
<dd>
<?php echo $event['Event']['uuid']; ?>
@ -97,30 +118,35 @@
<?php if ($isAdmin || $event['Event']['org'] == $me['org']): ?>
<th class="actions">Actions</th>
<?php endif;?>
</tr>
<?php
</tr><?php
foreach ($categories as $category):
$first = 1;
foreach ($event['Attribute'] as $attribute):
if ($attribute['category'] != $category) continue;
if($attribute['category'] != $category) continue;
?>
<tr>
<td class="short" title="<?php if ('' != $attribute['category']) echo $categoryDefinitions[$attribute['category']]['desc'];?>">
<?php if ($first) {
<td class="short" title="<?php if('' != $attribute['category']) echo $categoryDefinitions[$attribute['category']]['desc'];?>"><?php
if ($first) {
if ('' == $attribute['category']) echo '(no category)';
echo $attribute['category'];
} else {
echo '&nbsp;';
}
?></td>
<td class="short" title="<?php echo $typeDefinitions[$attribute['type']]['desc'];?>">
<?php echo $attribute['type'];?></td>
?></td>
<td class="short" title="<?php echo $typeDefinitions[$attribute['type']]['desc'];?>"><?php echo $attribute['type'];?></td>
<td><?php
$sigDisplay = nl2br(h($attribute['value']));
if ('attachment' == $attribute['type'] ||
'malware-sample' == $attribute['type'] ) {
$filenameHash = explode('|', h($attribute['value']));
echo $this->Html->link($filenameHash[0], array('controller' => 'attributes', 'action' => 'download', $attribute['id']));
if (strrpos($filenameHash[0], '\\')) {
$filepath = substr($filenameHash[0], 0, strrpos($filenameHash[0], '\\'));
$filename = substr($filenameHash[0], strrpos($filenameHash[0], '\\'));
echo $filepath;
echo $this->Html->link($filename, array('controller' => 'attributes', 'action' => 'download', $attribute['id']));
} else {
echo $this->Html->link($filenameHash[0], array('controller' => 'attributes', 'action' => 'download', $attribute['id']));
}
if (isset($filenameHash[1])) echo ' | ' . $filenameHash[1];
} elseif (strpos($attribute['type'], '|') !== false) {
$filenameHash = explode('|', h($attribute['value']));
@ -133,9 +159,9 @@ if ('attachment' == $attribute['type'] ||
} else {
echo $sigDisplay;
}
?></td>
?></td>
<td class="short" style="text-align: center;">
<?php
<?php
$first = 0;
if (isset($relatedAttributes[$attribute['id']]) && (null != $relatedAttributes[$attribute['id']])) {
foreach ($relatedAttributes[$attribute['id']] as $relatedAttribute) {
@ -143,17 +169,26 @@ if (isset($relatedAttributes[$attribute['id']]) && (null != $relatedAttributes[$
echo ' ';
}
}
?>&nbsp;
?>&nbsp;
</td>
<td class="short" style="text-align: center;"><?php echo $attribute['to_ids'] ? 'Yes' : 'No';?></td>
<?php if ('true' == Configure::read('CyDefSIG.sync')): ?>
<?php if ('true' == Configure::read('CyDefSIG.private')): ?>
<td class="short" style="text-align: center;"><?php echo $attribute['sharing'] == 'Org' ? 'Organization' : ($attribute['sharing'] == 'Server' ? 'Server' : ($attribute['sharing'] == 'Pull only' ? 'Pull only' : 'All'));?></td>
<?php else:?>
<td class="short" style="text-align: center;"><?php echo $attribute['private'] ? 'Private' : '&nbsp;';?></td>
<?php endif;?>
<?php endif;?>
<?php if ($isAdmin || $event['Event']['org'] == $me['org']): ?>
<td class="actions">
<?php
echo $this->Html->link(__('Edit', true), array('controller' => 'attributes', 'action' => 'edit', $attribute['id']));
echo $this->Form->postLink(__('Delete'), array('controller' => 'attributes', 'action' => 'delete', $attribute['id']), null, __('Are you sure you want to delete this attribute?'));
if ($isAclModify) {
echo $this->Html->link(__('Edit', true), array('controller' => 'attributes', 'action' => 'edit', $attribute['id']));
echo $this->Form->postLink(__('Delete'), array('controller' => 'attributes', 'action' => 'delete', $attribute['id']), null, __('Are you sure you want to delete this attribute?'));
} else {
echo $this->Html->link(__('Edit', true), array('controller' => 'attributes', 'action' => 'edit', $attribute['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus));
echo $this->Html->link(__('Delete'), array('controller' => 'attributes', 'action' => 'delete', $attribute['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus));
}
?>
</td>
<?php endif;?>
@ -165,8 +200,8 @@ if (isset($relatedAttributes[$attribute['id']]) && (null != $relatedAttributes[$
<?php if ($isAdmin || $event['Event']['org'] == $me['org']): ?>
<div class="actions">
<ul>
<li><?php echo $this->Html->link('Add Attribute', array('controller' => 'attributes', 'action' => 'add', $event['Event']['id']));?> </li>
<li><?php echo $this->Html->link('Add Attachment', array('controller' => 'attributes', 'action' => 'add_attachment', $event['Event']['id']));?> </li>
<li><?php echo $this->Html->link('Add Attribute', array('controller' => 'attributes', 'action' => 'add', $event['Event']['id']), array('id' => $buttonAddStatus . $buttonCounter++, 'class' => $buttonAddStatus));?> </li>
<li><?php echo $this->Html->link('Add Attachment', array('controller' => 'attributes', 'action' => 'add_attachment', $event['Event']['id']), array('id' => $buttonAddStatus . $buttonCounter++, 'class' => $buttonAddStatus));?> </li>
</ul>
</div>
<?php endif; ?>
@ -177,12 +212,143 @@ if (isset($relatedAttributes[$attribute['id']]) && (null != $relatedAttributes[$
<div class="actions">
<ul>
<?php if ($isAdmin || $event['Event']['org'] == $me['org']): ?>
<li><?php echo $this->Html->link(__('Add Attribute', true), array('controller' => 'attributes', 'action' => 'add', $event['Event']['id']));?> </li>
<li><?php echo $this->Html->link(__('Add Attachment', true), array('controller' => 'attributes', 'action' => 'add_attachment', $event['Event']['id']));?> </li>
<li><?php echo $this->Html->link(__('Edit Event', true), array('action' => 'edit', $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><?php echo $this->Html->link(__('Add Attribute', true), array('controller' => 'attributes', 'action' => 'add', $event['Event']['id']), array('id' => $buttonAddStatus . $buttonCounter++, 'class' => $buttonAddStatus));?> </li>
<li><?php echo $this->Html->link(__('Add Attachment', true), array('controller' => 'attributes', 'action' => 'add_attachment', $event['Event']['id']), array('id' => $buttonAddStatus . $buttonCounter++,'class' => $buttonAddStatus));?> </li>
<li><?php echo $this->Html->link(__('Edit Event', true), array('action' => 'edit', $event['Event']['id']), array('id' => $buttonModifyStatus . $buttonCounter++,'class' => $buttonModifyStatus)); ?> </li>
<li><?php
if ($mayModify) echo $this->Form->postLink(__('Delete Event'), array('action' => 'delete', $event['Event']['id']), null, __('Are you sure you want to delete # %s?', $event['Event']['id']));
else echo $this->Html->link(__('Delete Event'), array('action' => 'delete', $event['Event']['id']), array('id' => $buttonModifyStatus . $buttonCounter++,'class' => $buttonModifyStatus));
?></li>
<li>&nbsp;</li>
<?php endif; ?>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
<!--?php $javascript->link('deactivateButtons.js', false); ?-->
<!--script type="text/javascript" src="deactivateButtons.js"></script-->
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
$('#button_off0').click(function() {
return false;
});
$('#button_off1').click(function() {
return false;
});
$('#button_off2').click(function() {
return false;
});
$('#button_off3').click(function() {
return false;
});
$('#button_off4').click(function() {
return false;
});
$('#button_off5').click(function() {
return false;
});
$('#button_off6').click(function() {
return false;
});
$('#button_off7').click(function() {
return false;
});
$('#button_off8').click(function() {
return false;
});
$('#button_off9').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off11').click(function() {
return false;
});
$('#button_off12').click(function() {
return false;
});
$('#button_off13').click(function() {
return false;
});
$('#button_off14').click(function() {
return false;
});
$('#button_off15').click(function() {
return false;
});
$('#button_off16').click(function() {
return false;
});
$('#button_off17').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off19').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off21').click(function() {
return false;
});
$('#button_off22').click(function() {
return false;
});
$('#button_off23').click(function() {
return false;
});
$('#button_off24').click(function() {
return false;
});
$('#button_off25').click(function() {
return false;
});
$('#button_off26').click(function() {
return false;
});
$('#button_off27').click(function() {
return false;
});
$('#button_off28').click(function() {
return false;
});
$('#button_off29').click(function() {
return false;
});
$('#button_off30').click(function() {
return false;
});
$('#button_off31').click(function() {
return false;
});
$('#button_off32').click(function() {
return false;
});
$('#button_off33').click(function() {
return false;
});
$('#button_off34').click(function() {
return false;
});
$('#button_off35').click(function() {
return false;
});
$('#button_off36').click(function() {
return false;
});
$('#button_off37').click(function() {
return false;
});
$('#button_off38').click(function() {
return false;
});
$('#button_off39').click(function() {
return false;
});
</script>

View File

@ -11,6 +11,10 @@ foreach ($events as $key => $event) {
if ('true' != Configure::read('CyDefSIG.sync')) {
unset($events[$key]['private']);
}
if ('true' == Configure::read('CyDefSIG.private')) {
unset($events[$key]['cluster']);
unset($events[$key]['sharing']);
}
// hide the org field is we are not in showorg mode
if ('true' != Configure::read('CyDefSIG.showorg') && !$isAdmin) {
unset($events[$key]['org']);

View File

@ -9,8 +9,18 @@ unset($event['Attribute']);
foreach ($event['Event']['Attribute'] as $key => $value) {
unset($event['Event']['Attribute'][$key]['value1']);
unset($event['Event']['Attribute'][$key]['value2']);
unset($event['Event']['Attribute'][$key]['category_order']);
}
// hide the share fields is we are not in private mode
if ('true' == Configure::read('CyDefSIG.private')) {
unset($event['Event']['cluster']);
unset($event['Event']['sharing']);
foreach ($event['Event']['Attribute'] as $key => $value) {
unset($event['Event']['Attribute'][$key]['cluster']);
unset($event['Event']['Attribute'][$key]['sharing']);
}
}
// hide the private fields is we are not in sync mode
if ('true' != Configure::read('CyDefSIG.sync')) {
unset($event['Event']['private']);

19
app/View/Groups/add.ctp Executable file
View File

@ -0,0 +1,19 @@
<div class="groups form">
<?php echo $this->Form->create('Group');?>
<fieldset>
<legend><?php echo __('Add Group'); ?></legend>
<?php
echo $this->Form->input('name');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('List Groups'), array('action' => 'index'));?></li>
<li><?php echo $this->Html->link(__('List Users'), array('controller' => 'users', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New User'), array('controller' => 'users', 'action' => 'add')); ?> </li>
</ul>
</div>

19
app/View/Groups/admin_add.ctp Executable file
View File

@ -0,0 +1,19 @@
<div class="groups form">
<?php echo $this->Form->create('Group');?>
<fieldset>
<legend><?php echo __('Admin Add Group'); ?></legend>
<?php
echo $this->Form->input('name');
echo $this->Form->input('perm_add');
echo $this->Form->input('perm_modify');
echo $this->Form->input('perm_publish');
echo $this->Form->input('perm_full');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>
<div class="actions">
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>

23
app/View/Groups/admin_edit.ctp Executable file
View File

@ -0,0 +1,23 @@
<div class="groups form">
<?php echo $this->Form->create('Group');?>
<fieldset>
<legend><?php echo __('Admin Edit Group'); ?></legend>
<?php
echo $this->Form->input('name');?>
<fieldset>
<legend><?php echo __('Permission'); ?></legend>
<?php
echo $this->Form->input('perm_add', array( 'label' => 'add'));
echo $this->Form->input('perm_modify', array( 'label' => 'modify'));
echo $this->Form->input('perm_publish', array( 'label' => 'publish'));
echo $this->Form->input('perm_full', array( 'label' => 'full'));
?>
</fieldset>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>
<div class="actions">
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>

88
app/View/Groups/admin_index.ctp Executable file
View File

@ -0,0 +1,88 @@
<div class="groups index">
<h2><?php echo __('Groups');?></h2>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $this->Paginator->sort('id');?></th>
<th><?php echo $this->Paginator->sort('name');?></th>
<th><?php echo $this->Paginator->sort('add');?></th>
<th><?php echo $this->Paginator->sort('modify');?></th>
<th><?php echo $this->Paginator->sort('publish');?></th>
<th><?php echo $this->Paginator->sort('full');?></th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
foreach ($groups as $group): ?>
<tr>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $group['Group']['id']), true) ;?>';">
<?php echo h($group['Group']['id']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $group['Group']['id']), true) ;?>';">
<?php echo h($group['Group']['name']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $group['Group']['id']), true) ;?>';">
<?php echo h($group['Group']['perm_add']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $group['Group']['id']), true) ;?>';">
<?php echo h($group['Group']['perm_modify']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $group['Group']['id']), true) ;?>';">
<?php echo h($group['Group']['perm_publish']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $group['Group']['id']), true) ;?>';">
<?php echo h($group['Group']['perm_full']); ?>&nbsp;</td>
<td class="actions">
<?php echo $this->Html->link(__('View'), array('admin' => true, 'action' => 'view', $group['Group']['id'])); ?>
<?php echo $this->Html->link(__('Edit'), array('admin' => true, 'action' => 'edit', $group['Group']['id'])); ?>
<?php echo $this->Form->postLink(__('Delete'), array('admin' => true, 'action' => 'delete', $group['Group']['id']), null, __('Are you sure you want to delete # %s?', $group['Group']['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">
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
$('#button_off0').click(function() {
return false;
});
$('#button_off1').click(function() {
return false;
});
$('#button_off2').click(function() {
return false;
});
$('#button_off3').click(function() {
return false;
});
$('#button_off4').click(function() {
return false;
});
$('#button_off5').click(function() {
return false;
});
$('#button_off6').click(function() {
return false;
});
$('#button_off7').click(function() {
return false;
});
$('#button_off8').click(function() {
return false;
});
</script>

47
app/View/Groups/admin_view.ctp Executable file
View File

@ -0,0 +1,47 @@
<div class="groups view">
<!--div class="actions" style="float:right;">
<ul><li><?php echo $this->Html->link(__('Edit Profile', true), array('admin' => true, 'action' => 'edit', $group['Group']['id'])); ?> </li></ul>
</div-->
<h2><?php echo __('Group');?></h2>
<dl>
<dt><?php echo __('Id'); ?></dt>
<dd>
<?php echo h($group['Group']['id']); ?>
&nbsp;
</dd>
<dt><?php echo __('Group'); ?></dt>
<dd>
<?php echo h($group['Group']['name']); ?>
&nbsp;
</dd>
<dt><?php echo __('Add'); ?></dt>
<dd>
<?php echo h($group['Group']['perm_add']); ?>
&nbsp;
</dd>
<dt><?php echo __('Modify'); ?></dt>
<dd>
<?php echo h($group['Group']['perm_modify']); ?>
&nbsp;
</dd>
<dt><?php echo __('Publish'); ?></dt>
<dd>
<?php echo h($group['Group']['perm_publish']); ?>
&nbsp;
</dd>
<dt><?php echo __('Full'); ?></dt>
<dd>
<?php echo h($group['Group']['perm_full']); ?>
&nbsp;
</dd>
</dl>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('Edit Group'), array('admin' => true, 'action' => 'edit', $group['Group']['id'])); ?> </li>
<li><?php echo $this->Form->postLink(__('Delete Group'), array('admin' => true, 'action' => 'delete', $group['Group']['id']), null, __('Are you sure you want to delete # %s?', $group['Group']['id'])); ?> </li>
<li><?php echo $this->Html->link(__('List Groups'), array('admin' => true, 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New Group'), array('admin' => true, 'action' => 'add')); ?> </li>
</ul>
</div>

21
app/View/Groups/edit.ctp Executable file
View File

@ -0,0 +1,21 @@
<div class="groups form">
<?php echo $this->Form->create('Group');?>
<fieldset>
<legend><?php echo __('Edit Group'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('name');
?>
</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('Group.id')), null, __('Are you sure you want to delete # %s?', $this->Form->value('Group.id'))); ?></li>
<li><?php echo $this->Html->link(__('List Groups'), array('action' => 'index'));?></li>
<li><?php echo $this->Html->link(__('List Users'), array('controller' => 'users', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New User'), array('controller' => 'users', 'action' => 'add')); ?> </li>
</ul>
</div>

48
app/View/Groups/index.ctp Executable file
View File

@ -0,0 +1,48 @@
<div class="groups index">
<h2><?php echo __('Groups');?></h2>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $this->Paginator->sort('id');?></th>
<th><?php echo $this->Paginator->sort('name');?></th>
<th><?php echo $this->Paginator->sort('created');?></th>
<th><?php echo $this->Paginator->sort('modified');?></th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
foreach ($groups as $group): ?>
<tr>
<td><?php echo h($group['Group']['id']); ?>&nbsp;</td>
<td><?php echo h($group['Group']['name']); ?>&nbsp;</td>
<td><?php echo h($group['Group']['created']); ?>&nbsp;</td>
<td><?php echo h($group['Group']['modified']); ?>&nbsp;</td>
<td class="actions">
<?php echo $this->Html->link(__('View'), array('action' => 'view', $group['Group']['id'])); ?>
<?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $group['Group']['id'])); ?>
<?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $group['Group']['id']), null, __('Are you sure you want to delete # %s?', $group['Group']['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 Group'), array('action' => 'add')); ?></li>
<li><?php echo $this->Html->link(__('List Users'), array('controller' => 'users', 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New User'), array('controller' => 'users', 'action' => 'add')); ?> </li>
</ul>
</div>

40
app/View/Groups/view.ctp Executable file
View File

@ -0,0 +1,40 @@
<div class="groups view">
<h2><?php echo __('Group');?></h2>
<dl>
<dt><?php echo __('Id'); ?></dt>
<dd>
<?php echo h($group['Group']['id']); ?>
&nbsp;
</dd>
<dt><?php echo __('Name'); ?></dt>
<dd>
<?php echo h($group['Group']['name']); ?>
&nbsp;
</dd>
<dt><?php echo __('Add'); ?></dt>
<dd>
<?php echo h($group['Group']['perm_add']); ?>
&nbsp;
</dd>
<dt><?php echo __('Modify'); ?></dt>
<dd>
<?php echo h($group['Group']['perm_modify']); ?>
&nbsp;
</dd>
<dt><?php echo __('Publish'); ?></dt>
<dd>
<?php echo h($group['Group']['perm_publish']); ?>
&nbsp;
</dd>
<dt><?php echo __('Full'); ?></dt>
<dd>
<?php echo h($group['Group']['perm_full']); ?>
&nbsp;
</dd>
</dl>
</div>
<div class="actions">
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>

2
app/View/Layouts/default.ctp Normal file → Executable file
View File

@ -37,6 +37,8 @@
echo $this->Html->script('jquery-1.8.2.min'); // Include jQuery library
?>
<!--?php echo $scripts_for_layout; ?-->
</head>
<body>
<div id="container">

59
app/View/Logs/admin_index.ctp Executable file
View File

@ -0,0 +1,59 @@
<div class="logs index">
<h2><?php echo __('Logs');?></h2>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $this->Paginator->sort('id');?></th>
<!--th><?php echo $this->Paginator->sort('user_id');?></th-->
<th><?php echo $this->Paginator->sort('email');?></th>
<th><?php echo $this->Paginator->sort('org');?></th>
<th><?php echo $this->Paginator->sort('created');?></th>
<th><?php echo $this->Paginator->sort('action');?></th>
<th><?php echo $this->Paginator->sort('title');?></th>
<th><?php echo $this->Paginator->sort('change');?></th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
foreach ($logs as $log): ?>
<tr>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['id']); ?>&nbsp;</td>
<!--td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['user_id']); ?>&nbsp;</td-->
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['email']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['org']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['created']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['action']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['title']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['change']); ?>&nbsp;</td>
<td class="actions">
<?php echo $this->Html->link(__('View'), array('admin' => true, 'action' => 'view', $log['Log']['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">
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>

53
app/View/Logs/admin_search.ctp Executable file
View File

@ -0,0 +1,53 @@
<div class="logs form">
<?php echo $this->Form->create('Log');?>
<fieldset>
<legend><?php echo __('Search Log'); ?></legend>
<?php
echo $this->Form->input('email', array( 'label' => 'Email'));
echo $this->Form->input('org', array( 'label' => 'Org'));
echo $this->Form->input('action', array('between' => $this->Html->div('forminfo', '', array('id'=> 'LogActionDiv'))));
echo $this->Form->input('title', array( 'label' => 'Title'));
echo $this->Form->input('change', array( 'label' => 'Change'));
?>
</fieldset>
<?php echo $this->Form->end(__('Search', true));?>
</div>
<div class="actions">
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
<script type="text/javascript">
var formInfoValues = new Array();
<?php
foreach ($actionDefinitions as $action => $def) {
$info = isset($def['formdesc']) ? $def['formdesc'] : $def['desc'];
echo "formInfoValues['$action'] = \"$info\";\n";
}
$this->Js->get('#LogAction')->event('change', 'showFormInfo("#LogAction")');
?>
formInfoValues['ALL'] = '';
function showFormInfo(id) {
idDiv = id+'Div';
// LATER use nice animations
//$(idDiv).hide('fast');
// change the content
var value = $(id).val(); // get the selected value
$(idDiv).html(formInfoValues[value]); // search in a lookup table
// show it again
$(idDiv).fadeIn('slow');
}
// hide the formInfo things
$('#LogActionDiv').hide();
</script>
<?php echo $this->Js->writeBuffer(); // Write cached scripts ?>

54
app/View/Logs/admin_view.ctp Executable file
View File

@ -0,0 +1,54 @@
<div class="logs view">
<!--div class="actions" style="float:right;">
<ul><li><?php echo $this->Html->link(__('Edit Profile', true), array('admin' => true, 'action' => 'edit', $log['Log']['id'])); ?> </li></ul>
</div-->
<h2><?php echo __('Log');?></h2>
<dl>
<dt><?php echo __('Id'); ?></dt>
<dd>
<?php echo h($log['Log']['id']); ?>
&nbsp;
</dd>
<!--dt><?php echo __('User'); ?></dt>
<dd>
<?php echo h($log['Log']['user_id']); ?>
&nbsp;
</dd-->
<dt><?php echo __('Org'); ?></dt>
<dd>
<?php echo h($log['Log']['org']); ?>
&nbsp;
</dd>
<dt><?php echo __('Email'); ?></dt>
<dd>
<?php echo h($log['Log']['email']); ?>
&nbsp;
</dd>
<dt><?php echo __('Date'); ?></dt>
<dd>
<?php echo h($log['Log']['created']); ?>
&nbsp;
</dd>
<dt><?php echo __('Action'); ?></dt>
<dd>
<?php echo h($log['Log']['action']); ?>
&nbsp;
</dd>
<dt><?php echo __('Title'); ?></dt>
<dd>
<?php echo h($log['Log']['title']); ?>
&nbsp;
</dd>
<dt><?php echo __('Change'); ?></dt>
<dd>
<?php echo h($log['Log']['change']); ?>
&nbsp;
</dd>
</dl>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('List Logs'), array('admin' => true, 'action' => 'index')); ?> </li>
</ul>
</div>

59
app/View/Logs/index.ctp Executable file
View File

@ -0,0 +1,59 @@
<div class="logs index">
<h2><?php echo __('Logs');?></h2>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $this->Paginator->sort('id');?></th>
<!--th><?php echo $this->Paginator->sort('user_id');?></th-->
<th><?php echo $this->Paginator->sort('email');?></th>
<th><?php echo $this->Paginator->sort('org');?></th>
<th><?php echo $this->Paginator->sort('created');?></th>
<th><?php echo $this->Paginator->sort('action');?></th>
<th><?php echo $this->Paginator->sort('title');?></th>
<th><?php echo $this->Paginator->sort('change');?></th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
foreach ($logs as $log): ?>
<tr>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['id']); ?>&nbsp;</td>
<!--td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['user_id']); ?>&nbsp;</td-->
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['email']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['org']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['created']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['action']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['title']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $log['Log']['id']), true) ;?>';">
<?php echo h($log['Log']['change']); ?>&nbsp;</td>
<td class="actions">
<?php echo $this->Html->link(__('View'), array('admin' => true, 'action' => 'view', $log['Log']['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">
<ul>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>

409
app/View/Servers/index.ctp Normal file → Executable file
View File

@ -1,3 +1,10 @@
<?php
$mayAdd = $isAclAdd;
$buttonAddStatus = $mayAdd ? 'button_on':'button_off';
$mayModify = $isAclModify;
$buttonModifyStatus = $mayModify ? 'button_on':'button_off';
$buttonCounter = 0;
?>
<div class="servers index">
<h2><?php echo __('Servers');?></h2>
<table cellpadding="0" cellspacing="0">
@ -26,8 +33,9 @@
<td class="short"><?php echo $server['Server']['lastpulledid']; ?></td>
<td class="short"><?php echo $server['Server']['lastpushedid']; ?></td>
<td class="actions">
<?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $server['Server']['id'])); ?>
<?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $server['Server']['id']), null, __('Are you sure you want to delete # %s?', $server['Server']['id'])); ?>
<?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $server['Server']['id']), $isAclModify || ($server['Server']['org'] == $me['org']) ? null : array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus)); ?>
<?php if ($mayModify || $server['Server']['org'] == $me['org']) echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $server['Server']['id']), null, __('Are you sure you want to delete # %s?', $server['Server']['id']));
else echo $this->Html->link(__('Delete'), array('action' => 'delete', $server['Server']['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus)); ?>
<?php // if ($server['Server']['pull']) echo $this->Form->postLink(__('Pull'), array('action' => 'pull', $server['Server']['id']) ); ?>
<?php // if ($server['Server']['push']) echo $this->Form->postLink(__('Push'), array('action' => 'push', $server['Server']['id']) ); ?>
@ -56,9 +64,404 @@
</div>
<div class="actions">
<ul>
<li><?php echo $this->Html->link(__('New Server'), array('controller' => 'servers', 'action' => 'add')); ?></li>
<li><?php echo $this->Html->link(__('New Server'), array('controller' => 'servers', 'action' => 'add'), array('id' => $buttonAddStatus . $buttonCounter++, 'class' => $buttonAddStatus)); ?></li>
<li><?php echo $this->Html->link(__('List Servers'), array('controller' => 'servers', 'action' => 'index'));?></li>
<li>&nbsp;</li>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
$('#button_off0').click(function() {
return false;
});
$('#button_off1').click(function() {
return false;
});
$('#button_off2').click(function() {
return false;
});
$('#button_off3').click(function() {
return false;
});
$('#button_off4').click(function() {
return false;
});
$('#button_off5').click(function() {
return false;
});
$('#button_off6').click(function() {
return false;
});
$('#button_off7').click(function() {
return false;
});
$('#button_off8').click(function() {
return false;
});
$('#button_off9').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off11').click(function() {
return false;
});
$('#button_off12').click(function() {
return false;
});
$('#button_off13').click(function() {
return false;
});
$('#button_off14').click(function() {
return false;
});
$('#button_off15').click(function() {
return false;
});
$('#button_off16').click(function() {
return false;
});
$('#button_off17').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off19').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off21').click(function() {
return false;
});
$('#button_off22').click(function() {
return false;
});
$('#button_off23').click(function() {
return false;
});
$('#button_off24').click(function() {
return false;
});
$('#button_off25').click(function() {
return false;
});
$('#button_off26').click(function() {
return false;
});
$('#button_off27').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off29').click(function() {
return false;
});
$('#button_off30').click(function() {
return false;
});
$('#button_off31').click(function() {
return false;
});
$('#button_off32').click(function() {
return false;
});
$('#button_off33').click(function() {
return false;
});
$('#button_off34').click(function() {
return false;
});
$('#button_off35').click(function() {
return false;
});
$('#button_off36').click(function() {
return false;
});
$('#button_off37').click(function() {
return false;
});
$('#button_off30').click(function() {
return false;
});
$('#button_off39').click(function() {
return false;
});
$('#button_off40').click(function() {
return false;
});
$('#button_off41').click(function() {
return false;
});
$('#button_off42').click(function() {
return false;
});
$('#button_off43').click(function() {
return false;
});
$('#button_off44').click(function() {
return false;
});
$('#button_off45').click(function() {
return false;
});
$('#button_off46').click(function() {
return false;
});
$('#button_off47').click(function() {
return false;
});
$('#button_off40').click(function() {
return false;
});
$('#button_off49').click(function() {
return false;
});
$('#button_off50').click(function() {
return false;
});
$('#button_off51').click(function() {
return false;
});
$('#button_off52').click(function() {
return false;
});
$('#button_off53').click(function() {
return false;
});
$('#button_off54').click(function() {
return false;
});
$('#button_off55').click(function() {
return false;
});
$('#button_off56').click(function() {
return false;
});
$('#button_off57').click(function() {
return false;
});
$('#button_off50').click(function() {
return false;
});
$('#button_off59').click(function() {
return false;
});
$('#button_off60').click(function() {
return false;
});
$('#button_off61').click(function() {
return false;
});
$('#button_off62').click(function() {
return false;
});
$('#button_off63').click(function() {
return false;
});
$('#button_off64').click(function() {
return false;
});
$('#button_off65').click(function() {
return false;
});
$('#button_off66').click(function() {
return false;
});
$('#button_off67').click(function() {
return false;
});
$('#button_off60').click(function() {
return false;
});
$('#button_off69').click(function() {
return false;
});
$('#button_off70').click(function() {
return false;
});
$('#button_off71').click(function() {
return false;
});
$('#button_off72').click(function() {
return false;
});
$('#button_off73').click(function() {
return false;
});
$('#button_off74').click(function() {
return false;
});
$('#button_off75').click(function() {
return false;
});
$('#button_off76').click(function() {
return false;
});
$('#button_off77').click(function() {
return false;
});
$('#button_off70').click(function() {
return false;
});
$('#button_off79').click(function() {
return false;
});
$('#button_off80').click(function() {
return false;
});
$('#button_off81').click(function() {
return false;
});
$('#button_off82').click(function() {
return false;
});
$('#button_off83').click(function() {
return false;
});
$('#button_off84').click(function() {
return false;
});
$('#button_off85').click(function() {
return false;
});
$('#button_off86').click(function() {
return false;
});
$('#button_off87').click(function() {
return false;
});
$('#button_off80').click(function() {
return false;
});
$('#button_off89').click(function() {
return false;
});
$('#button_off90').click(function() {
return false;
});
$('#button_off91').click(function() {
return false;
});
$('#button_off92').click(function() {
return false;
});
$('#button_off93').click(function() {
return false;
});
$('#button_off94').click(function() {
return false;
});
$('#button_off95').click(function() {
return false;
});
$('#button_off96').click(function() {
return false;
});
$('#button_off97').click(function() {
return false;
});
$('#button_off90').click(function() {
return false;
});
$('#button_off99').click(function() {
return false;
});
$('#button_off100').click(function() {
return false;
});
$('#button_off101').click(function() {
return false;
});
$('#button_off102').click(function() {
return false;
});
$('#button_off103').click(function() {
return false;
});
$('#button_off104').click(function() {
return false;
});
$('#button_off105').click(function() {
return false;
});
$('#button_off106').click(function() {
return false;
});
$('#button_off107').click(function() {
return false;
});
$('#button_off100').click(function() {
return false;
});
$('#button_off109').click(function() {
return false;
});
$('#button_off110').click(function() {
return false;
});
$('#button_off111').click(function() {
return false;
});
$('#button_off112').click(function() {
return false;
});
$('#button_off113').click(function() {
return false;
});
$('#button_off114').click(function() {
return false;
});
$('#button_off115').click(function() {
return false;
});
$('#button_off116').click(function() {
return false;
});
$('#button_off117').click(function() {
return false;
});
$('#button_off110').click(function() {
return false;
});
$('#button_off119').click(function() {
return false;
});
$('#button_off120').click(function() {
return false;
});
$('#button_off121').click(function() {
return false;
});
$('#button_off122').click(function() {
return false;
});
$('#button_off123').click(function() {
return false;
});
$('#button_off124').click(function() {
return false;
});
$('#button_off125').click(function() {
return false;
});
$('#button_off126').click(function() {
return false;
});
$('#button_off127').click(function() {
return false;
});
$('#button_off120').click(function() {
return false;
});
$('#button_off129').click(function() {
return false;
});
</script>

1
app/View/Users/admin_add.ctp Normal file → Executable file
View File

@ -7,6 +7,7 @@
echo $this->Form->input('password');
echo $this->Form->input('confirm_password', array('type' => 'password', 'div' => array('class' => 'input password required')));
echo $this->Form->input('org');
echo $this->Form->input('group_id');
echo $this->Form->input('autoalert');
echo $this->Form->input('authkey', array('value' => $authkey));
echo $this->Form->input('nids_sid');

1
app/View/Users/admin_edit.ctp Normal file → Executable file
View File

@ -7,6 +7,7 @@
echo $this->Form->input('password');
echo $this->Form->input('confirm_password', array('type' => 'password', 'div' => array('class' => 'input password required')));
echo $this->Form->input('org');
echo $this->Form->input('group_id'); // TODO ACL, User edit group_id.
echo $this->Form->input('autoalert');
echo $this->Form->input('authkey');
echo $this->Form->input('nids_sid');

410
app/View/Users/admin_index.ctp Normal file → Executable file
View File

@ -1,9 +1,16 @@
<?php
$buttonAddStatus = $isAclAdd ? 'button_on':'button_off';
$buttonModifyStatus = $isAclModify ? 'button_on':'button_off';
$buttonPublishStatus = $isAclPublish ? 'button_on':'button_off';
$buttonCounter = 0;
?>
<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('org');?></th>
<th><?php echo $this->Paginator->sort('group_id');?></th>
<th><?php echo $this->Paginator->sort('email');?></th>
<th><?php echo $this->Paginator->sort('autoalert');?></th>
<th><?php echo $this->Paginator->sort('gpgkey');?></th>
@ -20,6 +27,8 @@
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $user['User']['id']), true);?>';">
<?php echo h($user['User']['org']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $user['User']['id']), true);?>';">
<?php echo $this->Html->link($user['Group']['name'], array('controller' => 'groups', 'action' => 'view', $user['Group']['id'])); ?></td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $user['User']['id']), true);?>';">
<?php echo h($user['User']['email']); ?>&nbsp;</td>
<td class="short" onclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $user['User']['id']), true);?>';">
<?php echo $user['User']['autoalert']? 'Yes' : 'No'; ?>&nbsp;</td>
@ -33,8 +42,10 @@
<?php echo h($user['User']['newsread']); ?>&nbsp;</td>
<td class="actions">
<?php echo $this->Html->link(__('View'), array('admin' => true, 'action' => 'view', $user['User']['id'])); ?>
<?php echo $this->Html->link(__('Edit'), array('admin' => true, 'action' => 'edit', $user['User']['id'])); ?>
<?php echo $this->Form->postLink(__('Delete'), array('admin' => true, 'action' => 'delete', $user['User']['id']), null, __('Are you sure you want to delete # %s?', $user['User']['id'])); ?>
<?php echo $this->Html->link(__('Edit'), array('admin' => true, 'action' => 'edit', $user['User']['id']), $isAclModify || ($user['User']['org'] == $me['org']) ? null : array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus)); ?>
<?php if ($isAclModify || $user['User']['org'] == $me['org']) echo $this->Form->postLink(__('Delete'), array('admin' => true, 'action' => 'delete', $user['User']['id']), null, __('Are you sure you want to delete # %s?', $user['User']['id']));
else echo $this->Html->link(__('Delete'), array('admin' => true, 'action' => 'delete', $user['User']['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus));
?>
</td>
</tr>
<?php endforeach; ?>
@ -59,3 +70,398 @@
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
$('#button_off0').click(function() {
return false;
});
$('#button_off1').click(function() {
return false;
});
$('#button_off2').click(function() {
return false;
});
$('#button_off3').click(function() {
return false;
});
$('#button_off4').click(function() {
return false;
});
$('#button_off5').click(function() {
return false;
});
$('#button_off6').click(function() {
return false;
});
$('#button_off7').click(function() {
return false;
});
$('#button_off8').click(function() {
return false;
});
$('#button_off9').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off11').click(function() {
return false;
});
$('#button_off12').click(function() {
return false;
});
$('#button_off13').click(function() {
return false;
});
$('#button_off14').click(function() {
return false;
});
$('#button_off15').click(function() {
return false;
});
$('#button_off16').click(function() {
return false;
});
$('#button_off17').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off19').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off21').click(function() {
return false;
});
$('#button_off22').click(function() {
return false;
});
$('#button_off23').click(function() {
return false;
});
$('#button_off24').click(function() {
return false;
});
$('#button_off25').click(function() {
return false;
});
$('#button_off26').click(function() {
return false;
});
$('#button_off27').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off29').click(function() {
return false;
});
$('#button_off30').click(function() {
return false;
});
$('#button_off31').click(function() {
return false;
});
$('#button_off32').click(function() {
return false;
});
$('#button_off33').click(function() {
return false;
});
$('#button_off34').click(function() {
return false;
});
$('#button_off35').click(function() {
return false;
});
$('#button_off36').click(function() {
return false;
});
$('#button_off37').click(function() {
return false;
});
$('#button_off30').click(function() {
return false;
});
$('#button_off39').click(function() {
return false;
});
$('#button_off40').click(function() {
return false;
});
$('#button_off41').click(function() {
return false;
});
$('#button_off42').click(function() {
return false;
});
$('#button_off43').click(function() {
return false;
});
$('#button_off44').click(function() {
return false;
});
$('#button_off45').click(function() {
return false;
});
$('#button_off46').click(function() {
return false;
});
$('#button_off47').click(function() {
return false;
});
$('#button_off40').click(function() {
return false;
});
$('#button_off49').click(function() {
return false;
});
$('#button_off50').click(function() {
return false;
});
$('#button_off51').click(function() {
return false;
});
$('#button_off52').click(function() {
return false;
});
$('#button_off53').click(function() {
return false;
});
$('#button_off54').click(function() {
return false;
});
$('#button_off55').click(function() {
return false;
});
$('#button_off56').click(function() {
return false;
});
$('#button_off57').click(function() {
return false;
});
$('#button_off50').click(function() {
return false;
});
$('#button_off59').click(function() {
return false;
});
$('#button_off60').click(function() {
return false;
});
$('#button_off61').click(function() {
return false;
});
$('#button_off62').click(function() {
return false;
});
$('#button_off63').click(function() {
return false;
});
$('#button_off64').click(function() {
return false;
});
$('#button_off65').click(function() {
return false;
});
$('#button_off66').click(function() {
return false;
});
$('#button_off67').click(function() {
return false;
});
$('#button_off60').click(function() {
return false;
});
$('#button_off69').click(function() {
return false;
});
$('#button_off70').click(function() {
return false;
});
$('#button_off71').click(function() {
return false;
});
$('#button_off72').click(function() {
return false;
});
$('#button_off73').click(function() {
return false;
});
$('#button_off74').click(function() {
return false;
});
$('#button_off75').click(function() {
return false;
});
$('#button_off76').click(function() {
return false;
});
$('#button_off77').click(function() {
return false;
});
$('#button_off70').click(function() {
return false;
});
$('#button_off79').click(function() {
return false;
});
$('#button_off80').click(function() {
return false;
});
$('#button_off81').click(function() {
return false;
});
$('#button_off82').click(function() {
return false;
});
$('#button_off83').click(function() {
return false;
});
$('#button_off84').click(function() {
return false;
});
$('#button_off85').click(function() {
return false;
});
$('#button_off86').click(function() {
return false;
});
$('#button_off87').click(function() {
return false;
});
$('#button_off80').click(function() {
return false;
});
$('#button_off89').click(function() {
return false;
});
$('#button_off90').click(function() {
return false;
});
$('#button_off91').click(function() {
return false;
});
$('#button_off92').click(function() {
return false;
});
$('#button_off93').click(function() {
return false;
});
$('#button_off94').click(function() {
return false;
});
$('#button_off95').click(function() {
return false;
});
$('#button_off96').click(function() {
return false;
});
$('#button_off97').click(function() {
return false;
});
$('#button_off90').click(function() {
return false;
});
$('#button_off99').click(function() {
return false;
});
$('#button_off100').click(function() {
return false;
});
$('#button_off101').click(function() {
return false;
});
$('#button_off102').click(function() {
return false;
});
$('#button_off103').click(function() {
return false;
});
$('#button_off104').click(function() {
return false;
});
$('#button_off105').click(function() {
return false;
});
$('#button_off106').click(function() {
return false;
});
$('#button_off107').click(function() {
return false;
});
$('#button_off100').click(function() {
return false;
});
$('#button_off109').click(function() {
return false;
});
$('#button_off110').click(function() {
return false;
});
$('#button_off111').click(function() {
return false;
});
$('#button_off112').click(function() {
return false;
});
$('#button_off113').click(function() {
return false;
});
$('#button_off114').click(function() {
return false;
});
$('#button_off115').click(function() {
return false;
});
$('#button_off116').click(function() {
return false;
});
$('#button_off117').click(function() {
return false;
});
$('#button_off110').click(function() {
return false;
});
$('#button_off119').click(function() {
return false;
});
$('#button_off120').click(function() {
return false;
});
$('#button_off121').click(function() {
return false;
});
$('#button_off122').click(function() {
return false;
});
$('#button_off123').click(function() {
return false;
});
$('#button_off124').click(function() {
return false;
});
$('#button_off125').click(function() {
return false;
});
$('#button_off126').click(function() {
return false;
});
$('#button_off127').click(function() {
return false;
});
$('#button_off120').click(function() {
return false;
});
$('#button_off129').click(function() {
return false;
});
</script>

63
app/View/Users/admin_view.ctp Normal file → Executable file
View File

@ -1,6 +1,12 @@
<?php
$buttonAddStatus = $isAclAdd ? 'button_on':'button_off';
$mayModify = $isAclModify || ($user['User']['org'] == $me['org']);
$buttonModifyStatus = $mayModify ? 'button_on':'button_off';
$buttonCounter = 0;
?>
<div class="users view">
<div class="actions" style="float:right;">
<ul><li><?php echo $this->Html->link(__('Edit Profile', true), array('admin' => true, 'action' => 'edit', $user['User']['id'])); ?> </li></ul>
<ul><li><?php echo $this->Html->link(__('Edit Profile', true), array('admin' => true, 'action' => 'edit', $user['User']['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus)); ?> </li></ul>
</div>
<h2><?php echo __('User');?></h2>
<dl>
@ -19,6 +25,11 @@
<?php echo h($user['User']['org']); ?>
&nbsp;
</dd>
<dt><?php echo __('Group'); ?></dt>
<dd>
<?php echo $this->Html->link($user['Group']['name'], array('controller' => 'groups', 'action' => 'view', $user['Group']['id'])); ?>
&nbsp;
</dd>
<dt><?php echo __('Email'); ?></dt>
<dd>
<?php echo h($user['User']['email']); ?>
@ -66,12 +77,15 @@
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('Edit User'), array('admin' => true, 'action' => 'edit', $user['User']['id'])); ?> </li>
<li><?php echo $this->Form->postLink(__('Delete User'), array('admin' => true, 'action' => 'delete', $user['User']['id']), null, __('Are you sure you want to delete # %s?', $user['User']['id'])); ?> </li>
<li><?php echo $this->Html->link(__('Edit User'), array('admin' => true, 'action' => 'edit', $user['User']['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus)); ?> </li>
<li><?php
if ($mayModify) echo $this->Form->postLink(__('Delete User'), array('admin' => true, 'action' => 'delete', $user['User']['id']), null, __('Are you sure you want to delete # %s?', $user['User']['id']));
else echo $this->Html->link(__('Delete User'), array('admin' => true, 'action' => 'delete', $user['User']['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus));
?> </li>
<li><?php echo $this->Html->link(__('List Users'), array('admin' => true, 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New User'), array('admin' => true, 'action' => 'add')); ?> </li>
<li><?php echo $this->Html->link(__('New User'), array('admin' => true, 'action' => 'add'), array('id' => $buttonAddStatus . $buttonCounter++, 'class' => $buttonAddStatus)); ?> </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>
<li><?php echo $this->Html->link(__('New Event'), array('controller' => 'events', 'action' => 'add'), array('id' => $buttonAddStatus . $buttonCounter++, 'class' => $buttonAddStatus)); ?> </li>
</ul>
</div>
<div class="related">
@ -103,8 +117,11 @@
<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'])); ?>
<?php echo $this->Html->link(__('Edit'), array('controller' => 'events', 'action' => 'edit', $event['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus)); ?>
<?php
if ($mayModify) echo $this->Form->postLink(__('Delete'), array('controller' => 'events', 'action' => 'delete', $event['id']), null, __('Are you sure you want to delete # %s?', $event['id']));
else echo $this->Html->link(__('Delete'), array('controller' => 'events', 'action' => 'delete', $event['id']), array('id' => $buttonModifyStatus . $buttonCounter++, 'class' => $buttonModifyStatus));
?>
</td>
</tr>
<?php endforeach; ?>
@ -112,3 +129,35 @@
<?php endif; ?>
</div>
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
$('#button_off0').click(function() {
return false;
});
$('#button_off1').click(function() {
return false;
});
$('#button_off2').click(function() {
return false;
});
$('#button_off3').click(function() {
return false;
});
$('#button_off4').click(function() {
return false;
});
$('#button_off5').click(function() {
return false;
});
$('#button_off6').click(function() {
return false;
});
$('#button_off7').click(function() {
return false;
});
$('#button_off8').click(function() {
return false;
});
</script>

View File

@ -8,6 +8,7 @@
echo $this->Form->input('confirm_password', array('type' => 'password', 'div' => array('class' => 'input password required')));
if ($isAdmin) echo $this->Form->input('org');
else echo $this->Form->input('org', array('disabled' => 'disabled'));
echo $this->Form->input('group_id', array('disabled' => 'disabled')); // TODO ACL, check, My Profile not edit group_id.
echo $this->Form->input('autoalert');
echo $this->Form->input('nids_sid');
echo $this->Form->input('gpgkey');
@ -22,4 +23,4 @@
<li>&nbsp;</li>
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
</div>

8
app/View/Users/news.ctp Normal file → Executable file
View File

@ -1,5 +1,13 @@
<div class="news view">
<h2>News</h2>
<h3>June 2012</h3>
<p><b>Audit</b><br/>
There is now log on every login, logout, addition, change and deletion.<br/>
<p>
<p><b>Access Control granulation</b><br/>
There is Access Control, an user must be bound to a users-group,<br/>
so we are able to grant global add, modify and publish rights.<br/>
<p>
<h3>April 2012</h3>
<p><b>REST API (output)</b><br/>
From now on you can use the REST API that uses this XML export. For more information check out the export page.<br/>

View File

@ -50,3 +50,8 @@ if (!$termsaccepted) {
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
</script>

View File

@ -19,6 +19,11 @@
<?php echo h($user['User']['org']); ?>
&nbsp;
</dd>
<dt><?php echo __('Group'); ?></dt>
<dd>
<?php echo h($user['Group']['name']); ?> <!-- TODO ACL, check, My Profile not edit group_id. -->
&nbsp;
</dd>
<dt><?php echo __('Autoalert'); ?></dt>
<dd>
<?php echo h(0 == ($user['User']['autoalert'])) ? 'no' : 'yes'; ?>
@ -55,3 +60,36 @@
<?php echo $this->element('actions_menu'); ?>
</ul>
</div>
<script type="text/javascript">
$('#button_off').click(function() {
return false;
});
$('#button_off0').click(function() {
return false;
});
$('#button_off1').click(function() {
return false;
});
$('#button_off2').click(function() {
return false;
});
$('#button_off3').click(function() {
return false;
});
$('#button_off4').click(function() {
return false;
});
$('#button_off5').click(function() {
return false;
});
$('#button_off6').click(function() {
return false;
});
$('#button_off7').click(function() {
return false;
});
$('#button_off8').click(function() {
return false;
});
</script>

16
app/technical_design/TD-ACL.txt Executable file
View File

@ -0,0 +1,16 @@
ACL Technical Design (TD)
To use Access Control in CakePHP we use itś own AclComponent.
http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html
http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/part-two.html
CakePHP example, just telling how to populate and connect the CakePHP AclController.
http://stackoverflow.com/questions/6154285/aros-table-in-cakephp-is-still-including-users-even-after-bindnode
If ACL on Group level add this small correction, to just only add Groups to CakePHP ACL tables and not to add the Users.
http://bakery.cakephp.org/articles/theshz/2006/11/28/user-permissions-and-cakephp-acl
Calling the ACL from within a controller.

View File

@ -0,0 +1,28 @@
Audit Technical Design (TD)
To log in CakePHP we use an existing Model Behavior,
to write to a log database table.
https://github.com/eskil-saatvedt/CakePHP-Assets/blob/master/models/behaviors/LogableBehavior.php
Adds the logable Model Behavior.
http://bakery.cakephp.org/articles/rikdc/2010/06/07/syslog-component
Ads the syslog capability.
http://bakery.cakephp.org/articles/alkemann/2008/10/21/logablebehavior
http://www.bitsntricks.com/cakephp-logable-behaviour/
Short explaination itś use.
http://stackoverflow.com/questions/9791633/check-if-cakephp-update-changes-a-variable-in-update
This Logable Model Behavior seemed not to work in the UsersController,
so the change checks are done manual coded in the UsersController.
https://github.com/joebeeson/referee#readme
Can be handy lateron for log to db or syslog?

View File

@ -0,0 +1,12 @@
Forum Technical Design (TD)
We use a plugin giving Forum use in CakePHP.
http://milesj.me/code/cakephp/forum
Alternative PhpBB in conjunction with CakePHP Users and Groups tables.
http://bakery.cakephp.org/articles/wilsonsheldon/2009/01/13/phpbb3-api-bridge
http://www.phpbb.com/community/viewtopic.php?f=71&t=993475
CakePHP and a PhpBB3 forum.

0
app/tmp/cache/models/empty vendored Normal file → Executable file
View File

0
app/tmp/cache/persistent/empty vendored Normal file → Executable file
View File

0
app/tmp/cache/views/empty vendored Normal file → Executable file
View File

0
app/tmp/logs/empty Normal file → Executable file
View File

0
app/tmp/sessions/empty Normal file → Executable file
View File

0
app/tmp/tests/empty Normal file → Executable file
View File

8
app/webroot/css/cake.generic.css Normal file → Executable file
View File

@ -772,3 +772,11 @@ pre {
#url-rewriting-warning {
display:none;
}
/* to show a button as off/not-usable */
a.button_off:link,a.button_off:visited, a.button_off:active {
color:#C1C1C1;
font-size:12px;
background-color:#ffffff;
text-decoration:none;
}

View File

@ -0,0 +1,101 @@
<script type="text/javascript">
// has to be done total different, f.i.:
// document.form1.button1.disabled=true
// disable?
// http://cakebaker.42dh.com/2007/02/21/referencing-javascript-files/
$('#button_off').click(function() {
return false;
});
$('#button_off0').click(function() {
return false;
});
$('#button_off1').click(function() {
return false;
});
$('#button_off2').click(function() {
return false;
});
$('#button_off3').click(function() {
return false;
});
$('#button_off4').click(function() {
return false;
});
$('#button_off5').click(function() {
return false;
});
$('#button_off6').click(function() {
return false;
});
$('#button_off7').click(function() {
return false;
});
$('#button_off8').click(function() {
return false;
});
$('#button_off9').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off11').click(function() {
return false;
});
$('#button_off12').click(function() {
return false;
});
$('#button_off13').click(function() {
return false;
});
$('#button_off14').click(function() {
return false;
});
$('#button_off15').click(function() {
return false;
});
$('#button_off16').click(function() {
return false;
});
$('#button_off17').click(function() {
return false;
});
$('#button_off10').click(function() {
return false;
});
$('#button_off19').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off21').click(function() {
return false;
});
$('#button_off22').click(function() {
return false;
});
$('#button_off23').click(function() {
return false;
});
$('#button_off24').click(function() {
return false;
});
$('#button_off25').click(function() {
return false;
});
$('#button_off26').click(function() {
return false;
});
$('#button_off27').click(function() {
return false;
});
$('#button_off20').click(function() {
return false;
});
$('#button_off29').click(function() {
return false;
});
</script>

View File

@ -0,0 +1,308 @@
<?php
/**
* Acl Extras Shell.
*
* Enhances the existing Acl Shell with a few handy functions
*
* Copyright 2008, Mark Story.
* 694B The Queensway
* toronto, ontario M8Y 1K9
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2008-2010, Mark Story.
* @link http://mark-story.com
* @author Mark Story <mark@mark-story.com>
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::uses('Controller', 'Controller');
App::uses('ComponentCollection', 'Controller');
App::uses('AclComponent', 'Controller/Component');
App::uses('DbAcl', 'Model');
/**
* Shell for ACO extras
*
* @package acl_extras
* @subpackage acl_extras.Console.Command
*/
class AclExtrasShell extends Shell {
/**
* Contains instance of AclComponent
*
* @var AclComponent
* @access public
*/
public $Acl;
/**
* Contains arguments parsed from the command line.
*
* @var array
* @access public
*/
public $args;
/**
* Contains database source to use
*
* @var string
* @access public
*/
public $dataSource = 'default';
/**
* Root node name.
*
* @var string
**/
public $rootNode = 'controllers';
/**
* Internal Clean Actions switch
*
* @var boolean
**/
public $_clean = false;
/**
* Start up And load Acl Component / Aco model
*
* @return void
**/
public function startup() {
parent::startup();
$collection = new ComponentCollection();
$this->Acl = new AclComponent($collection);
$controller = null;
$this->Acl->startup($controller);
$this->Aco = $this->Acl->Aco;
}
/**
* Sync the ACO table
*
* @return void
**/
function aco_sync() {
$this->_clean = true;
$this->aco_update();
}
/**
* Updates the Aco Tree with new controller actions.
*
* @return void
**/
function aco_update() {
$root = $this->_checkNode($this->rootNode, $this->rootNode, null);
$controllers = $this->getControllerList();
$this->_updateControllers($root, $controllers);
$plugins = CakePlugin::loaded();
foreach ($plugins as $plugin) {
$controllers = $this->getControllerList($plugin);
$path = $this->rootNode . '/' . $plugin;
$pluginRoot = $this->_checkNode($path, $plugin, $root['Aco']['id']);
$this->_updateControllers($pluginRoot, $controllers, $plugin);
}
$this->out(__('<success>Aco Update Complete</success>'));
return true;
}
/**
* Updates a collection of controllers.
*
* @param array $root Array or ACO information for root node.
* @param array $controllers Array of Controllers
* @param string $plugin Name of the plugin you are making controllers for.
* @return void
*/
function _updateControllers($root, $controllers, $plugin = null) {
$dotPlugin = $pluginPath = $plugin;
if ($plugin) {
$dotPlugin .= '.';
$pluginPath .= '/';
}
$appIndex = array_search($plugin . 'AppController', $controllers);
if ($appIndex !== false) {
App::uses($plugin . 'AppController', $dotPlugin . 'Controller');
unset($controllers[$appIndex]);
}
// look at each controller
foreach ($controllers as $controller) {
App::uses($controller, $dotPlugin . 'Controller');
$controllerName = preg_replace('/Controller$/', '', $controller);
$path = $this->rootNode . '/' . $pluginPath . $controllerName;
$controllerNode = $this->_checkNode($path, $controllerName, $root['Aco']['id']);
$this->_checkMethods($controller, $controllerName, $controllerNode, $pluginPath);
}
if ($this->_clean) {
if (!$plugin) {
$controllers = array_merge($controllers, App::objects('plugin', null, false));
}
$controllerFlip = array_flip($controllers);
$this->Aco->id = $root['Aco']['id'];
$controllerNodes = $this->Aco->children(null, true);
foreach ($controllerNodes as $ctrlNode) {
$alias = $ctrlNode['Aco']['alias'];
$name = $alias . 'Controller';
if (!isset($controllerFlip[$name]) && !isset($controllerFlip[$alias])) {
if ($this->Aco->delete($ctrlNode['Aco']['id'])) {
$this->out(__(
'Deleted %s and all children',
$this->rootNode . '/' . $ctrlNode['Aco']['alias']
), 1, Shell::VERBOSE);
}
}
}
}
}
/**
* Get a list of controllers in the app and plugins.
*
* Returns an array of path => import notation.
*
* @param string $plugin Name of plugin to get controllers for
* @return array
**/
function getControllerList($plugin = null) {
if (!$plugin) {
$controllers = App::objects('Controller', null, false);
} else {
$controllers = App::objects($plugin . '.Controller', null, false);
}
return $controllers;
}
/**
* Check a node for existance, create it if it doesn't exist.
*
* @param string $path
* @param string $alias
* @param int $parentId
* @return array Aco Node array
*/
function _checkNode($path, $alias, $parentId = null) {
$node = $this->Aco->node($path);
if (!$node) {
$this->Aco->create(array('parent_id' => $parentId, 'model' => null, 'alias' => $alias));
$node = $this->Aco->save();
$node['Aco']['id'] = $this->Aco->id;
$this->out(__('Created Aco node: %s', $path), 1, Shell::VERBOSE);
} else {
$node = $node[0];
}
return $node;
}
/**
* Check and Add/delete controller Methods
*
* @param string $controller
* @param array $node
* @param string $plugin Name of plugin
* @return void
*/
function _checkMethods($className, $controllerName, $node, $pluginPath = false) {
$baseMethods = get_class_methods('Controller');
$actions = get_class_methods($className);
$methods = array_diff($actions, $baseMethods);
foreach ($methods as $action) {
if (strpos($action, '_', 0) === 0) {
continue;
}
$path = $this->rootNode . '/' . $pluginPath . $controllerName . '/' . $action;
$this->_checkNode($path, $action, $node['Aco']['id']);
}
if ($this->_clean) {
$actionNodes = $this->Aco->children($node['Aco']['id']);
$methodFlip = array_flip($methods);
foreach ($actionNodes as $action) {
if (!isset($methodFlip[$action['Aco']['alias']])) {
$this->Aco->id = $action['Aco']['id'];
if ($this->Aco->delete()) {
$path = $this->rootNode . '/' . $controllerName . '/' . $action['Aco']['alias'];
$this->out(__('Deleted Aco node %s', $path), 1, Shell::VERBOSE);
}
}
}
}
return true;
}
public function getOptionParser() {
return parent::getOptionParser()
->description(__("Better manage, and easily synchronize you application's ACO tree"))
->addSubcommand('aco_update', array(
'help' => __('Add new ACOs for new controllers and actions. Does not remove nodes from the ACO table.')
))->addSubcommand('aco_sync', array(
'help' => __('Perform a full sync on the ACO table.' .
'Will create new ACOs or missing controllers and actions.' .
'Will also remove orphaned entries that no longer have a matching controller/action')
))->addSubcommand('verify', array(
'help' => __('Verify the tree structure of either your Aco or Aro Trees'),
'parser' => array(
'arguments' => array(
'type' => array(
'required' => true,
'help' => __('The type of tree to verify'),
'choices' => array('aco', 'aro')
)
)
)
))->addSubcommand('recover', array(
'help' => __('Recover a corrupted Tree'),
'parser' => array(
'arguments' => array(
'type' => array(
'required' => true,
'help' => __('The type of tree to recover'),
'choices' => array('aco', 'aro')
)
)
)
));
}
/**
* Verify a Acl Tree
*
* @param string $type The type of Acl Node to verify
* @access public
* @return void
*/
function verify() {
$type = Inflector::camelize($this->args[0]);
$return = $this->Acl->{$type}->verify();
if ($return === true) {
$this->out(__('Tree is valid and strong'));
} else {
$this->err(print_r($return, true));
return false;
}
}
/**
* Recover an Acl Tree
*
* @param string $type The Type of Acl Node to recover
* @access public
* @return void
*/
function recover() {
$type = Inflector::camelize($this->args[0]);
$return = $this->Acl->{$type}->recover();
if ($return === true) {
$this->out(__('Tree has been recovered, or tree did not need recovery.'));
} else {
$this->err(__('<error>Tree recovery failed.</error>'));
return false;
}
}
}

View File

@ -0,0 +1,535 @@
<?php
/**
* Logs saves and deletes of any model
*
* Requires the following to work as intended :
*
* - "Log" model ( empty but for a order variable [created DESC]
* - "logs" table with these fields required :
* - id [int] :
* - title [string] : automagically filled with the display field of the model that was modified.
* - created [date/datetime] : filled by cake in normal way
*
* - actsAs = array("Logable"); on models that should be logged
*
* Optional extra table fields for the "logs" table :
*
* - "description" [string] : Fill with a descriptive text of what, who and to which model/row :
* "Contact "John Smith"(34) added by User "Administrator"(1).
*
* or if u want more detail, add any combination of the following :
*
* - "model" [string] : automagically filled with the class name of the model that generated the activity.
* - "model_id" [int] : automagically filled with the primary key of the model that was modified.
* - "action" [string] : automagically filled with what action is made (add/edit/delete)
* - "user_id" [int] : populated with the supplied user info. (May be renamed. See bellow.)
* - "change" [string] : depending on setting either :
* [name (alek) => (Alek), age (28) => (29)] or [name, age]
*
* - "version_id" [int] : cooperates with RevisionBehavior to link the the shadow table (thus linking to old data)
*
* Remember that Logable behavior needs to be added after RevisionBehavior. In fact, just put it last to be safe.
*
* Optionally register what user was responisble for the activity :
*
* - Supply configuration only if defaults are wrong. Example given with defaults :
*
* class Apple extends AppModel {
* var $name = 'Apple';
* var $actsAs = array('Logable' => array('userModel' => 'User', 'userKey' => 'user_id'));
* [..]
*
* - In AppController (or single controller if only needed once) add these lines to beforeFilter :
*
* if (sizeof($this->uses) && $this->{$this->modelClass}->Behaviors->attached('Logable')) {
* $this->{$this->modelClass}->setUserData($this->activeUser);
* }
*
* This is not used any longer, as AuthComponent collect the user data instead.
*
* Where "$activeUser" should be an array in the standard format for the User model used :
*
* $activeUser = array( $UserModel->alias => array( $UserModel->primaryKey => 123, $UserModel->displayField => 'Alexander'));
* // any other key is just ignored by this behaviour.
*
* @author Alexander Morland (alexander#maritimecolours.no)
* @co-author Eskil Mjelva Saatvedt
* @co-author Ronny Vindenes
* @co-author Carl Erik Fyllingen
* @contributor Miha
* @category Behavior
* @version 2.3
* @modified 15.november 2011 by Eskil
*/
class LogableBehavior extends ModelBehavior {
public $user = NULL;
public $UserModel = FALSE;
public $settings = array();
public $defaults = array(
'enabled' => true,
'userModel' => 'User',
'userKey' => 'user_id',
'change' => 'list',
'description_ids' => TRUE,
'skip' => array(),
'ignore' => array(),
'classField' => 'model',
'foreignKey' => 'model_id');
public $schema = array();
/**
* Cake called intializer
* Config options are :
* userModel : 'User'. Class name of the user model you want to use (User by default), if you want to save User in log
* userKey : 'user_id'. The field for saving the user to (user_id by default).
* change : 'list' > [name, age]. Set to 'full' for [name (alek) => (Alek), age (28) => (29)]
* description_ids : TRUE. Set to FALSE to not include model id and user id in the title field
* skip : array(). String array of actions to not log
*
* @param Object $Model
* @param array $config
*/
function setup(&$Model, $config = array()) {
if (!is_array($config)) {
$config = array();
}
$this->settings[$Model->alias] = array_merge($this->defaults, $config);
$this->settings[$Model->alias]['ignore'][] = $Model->primaryKey;
$this->Log = & ClassRegistry::init('Log');
if ($this->settings[$Model->alias]['userModel'] != $Model->alias) {
$this->UserModel = & ClassRegistry::init($this->settings[$Model->alias]['userModel']);
} else {
$this->UserModel = $Model;
}
$this->schema = $this->Log->schema();
App::import('Component', 'Auth');
$this->user[$this->settings[$Model->alias]['userModel']] = AuthComponent::user();
}
function settings(&$Model) {
return $this->settings[$Model->alias];
}
function enableLog(&$Model, $enable = null) {
if ($enable !== null) {
$this->settings[$Model->alias]['enabled'] = $enable;
}
return $this->settings[$Model->alias]['enabled'];
}
/**
* Useful for getting logs for a model, takes params to narrow find.
* This method can actually also be used to find logs for all models or
* even another model. Using no params will return all activities for
* the models it is called from.
*
* Possible params :
* 'model' : mixed (NULL) String with className, NULL to get current or FALSE to get everything
* 'action' : string (NULL) String with action (add/edit/delete), NULL gets all
* 'order' : string ('created DESC') String with custom order
* 'conditions : array (array()) Add custom conditions
* 'model_id' : int (NULL) Add a int
*
* (remember to use your own user key if you're not using 'user_id')
* 'user_id' : int (NULL) Defaults to all users, supply id if you want for only one User
*
* @param Object $Model
* @param array $params
* @return array
*/
function findLog(&$Model, $params = array()) {
$defaults = array(
$this->settings[$Model->alias]['classField'] => NULL,
'action' => NULL,
'order' => 'created DESC',
$this->settings[$Model->alias]['userKey'] => NULL,
'conditions' => array(),
$this->settings[$Model->alias]['foreignKey'] => NULL,
'fields' => array(),
'limit' => 50);
$params = array_merge($defaults, $params);
$options = array(
'order' => $params['order'],
'conditions' => $params['conditions'],
'fields' => $params['fields'],
'limit' => $params['limit']);
if ($params[$this->settings[$Model->alias]['classField']] === NULL) {
$params[$this->settings[$Model->alias]['classField']] = $Model->alias;
}
if ($params[$this->settings[$Model->alias]['classField']]) {
if (isset($this->schema[$this->settings[$Model->alias]['classField']])) {
$options['conditions'][$this->settings[$Model->alias]['classField']] = $params[$this->settings[$Model->alias]['classField']];
} elseif (isset($this->schema['description'])) {
$options['conditions']['description LIKE '] = $params[$this->settings[$Model->alias]['classField']] . '%';
} else {
return FALSE;
}
}
if ($params['action'] && isset($this->schema['action'])) {
$options['conditions']['action'] = $params['action'];
}
if ($params[$this->settings[$Model->alias]['userKey']] && $this->UserModel && is_numeric($params[$this->settings[$Model->alias]['userKey']])) {
$options['conditions'][$this->settings[$Model->alias]['userKey']] = $params[$this->settings[$Model->alias]['userKey']];
}
if ($params[$this->settings[$Model->alias]['foreignKey']] && is_numeric($params[$this->settings[$Model->alias]['foreignKey']])) {
$options['conditions'][$this->settings[$Model->alias]['foreignKey']] = $params[$this->settings[$Model->alias]['foreignKey']];
}
return $this->Log->find('all', $options);
}
/**
* Get list of actions for one user.
* Params for getting (one line) activity descriptions
* and/or for just one model
*
* @example $this->Model->findUserActions(301,array('model' => 'BookTest'));
* @example $this->Model->findUserActions(301,array('events' => true));
* @example $this->Model->findUserActions(301,array('fields' => array('id','model'),'model' => 'BookTest');
* @param Object $Model
* @param int $user_id
* @param array $params
* @return array
*/
function findUserActions(&$Model, $user_id, $params = array()) {
if (!$this->UserModel) {
return NULL;
}
// if logged in user is asking for her own log, use the data we allready have
if (isset($this->user) && isset($this->user[$this->UserModel->alias][$this->UserModel->primaryKey]) && $user_id == $this->user[$this->UserModel->alias][$this->UserModel->primaryKey] && isset($this->user[$this->UserModel->alias][$this->UserModel->displayField])) {
$username = $this->user[$this->UserModel->alias][$this->UserModel->displayField];
} else {
$this->UserModel->recursive = -1;
$user = $this->UserModel->find(array(
$this->UserModel->primaryKey => $user_id));
$username = $user[$this->UserModel->alias][$this->UserModel->displayField];
}
$fields = array();
if (isset($params['fields'])) {
if (is_array($params['fields'])) {
$fields = $params['fields'];
} else {
$fields = array(
$params['fields']);
}
}
$conditions = array(
$this->settings[$Model->alias]['userKey'] => $user_id);
if (isset($params[$this->settings[$Model->alias]['classField']])) {
$conditions[$this->settings[$Model->alias]['classField']] = $params[$this->settings[$Model->alias]['classField']];
}
$data = $this->Log->find('all', array(
'conditions' => $conditions,
'recursive' => -1,
'fields' => $fields));
if (!isset($params['events']) || ( isset($params['events']) && $params['events'] == false )) {
return $data;
}
$result = array();
foreach ( $data as $key => $row ) {
$one = $row['Log'];
$result[$key]['Log']['id'] = $one['id'];
$result[$key]['Log']['event'] = $username;
// have all the detail models and change as list :
if (isset($one[$this->settings[$Model->alias]['classField']]) && isset($one['action']) && isset($one['change']) && isset($one[$this->settings[$Model->alias]['foreignKey']])) {
if ($one['action'] == 'edit') {
$result[$key]['Log']['event'] .= ' edited ' . $one['change'] . ' of ' . low($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->settings[$Model->alias]['foreignKey']] . ')';
// ' at '.$one['created'];
} elseif ($one['action'] == 'add') {
$result[$key]['Log']['event'] .= ' added a ' . low($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->settings[$Model->alias]['foreignKey']] . ')';
} elseif ($one['action'] == 'delete') {
$result[$key]['Log']['event'] .= ' deleted the ' . low($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->settings[$Model->alias]['foreignKey']] . ')';
}
} elseif (isset($one[$this->settings[$Model->alias]['classField']]) && isset($one['action']) && isset($one[$this->settings[$Model->alias]['foreignKey']])) { // have model,model_id and action
if ($one['action'] == 'edit') {
$result[$key]['Log']['event'] .= ' edited ' . low($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->settings[$Model->alias]['foreignKey']] . ')';
// ' at '.$one['created'];
} elseif ($one['action'] == 'add') {
$result[$key]['Log']['event'] .= ' added a ' . low($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->settings[$Model->alias]['foreignKey']] . ')';
} elseif ($one['action'] == 'delete') {
$result[$key]['Log']['event'] .= ' deleted the ' . low($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->settings[$Model->alias]['foreignKey']] . ')';
}
} else { // only description field exist
$result[$key]['Log']['event'] = $one['description'];
}
}
return $result;
}
/**
* Use this to supply a model with the data of the logged in User.
* Intended to be called in AppController::beforeFilter like this :
*
* if ($this->{$this->modelClass}->Behaviors->attached('Logable')) {
* $this->{$this->modelClass}->setUserData($activeUser);/
* }
*
* The $userData array is expected to look like the result of a
* User::find(array('id'=>123));
*
* @param Object $Model
* @param array $userData
*/
function setUserData(&$Model, $userData = null) {
if ($userData) {
$this->user = $userData;
}
}
/**
* Used for logging custom actions that arent crud, like login or download.
*
* @example $this->Boat->customLog('ship', 66, array('title' => 'Titanic heads out'));
* @param Object $Model
* @param string $action name of action that is taking place (dont use the crud ones)
* @param int $id id of the logged item (ie model_id in logs table)
* @param array $values optional other values for your logs table
*/
function customLog(&$Model, $action, $id, $values = array()) {
$logData['Log'] = $values;
/** @todo clean up $logData */
if (isset($this->schema[$this->settings[$Model->alias]['foreignKey']]) && is_numeric($id)) {
$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $id;
}
$title = NULL;
if (isset($values['title'])) {
$title = $values['title'];
unset($logData['Log']['title']);
}
$logData['Log']['action'] = $action;
$this->_saveLog($Model, $logData, $title);
}
function clearUserData(&$Model) {
$this->user = NULL;
}
function setUserIp(&$Model, $userIP = null) {
$this->userIP = $userIP;
}
function beforeDelete(&$Model) {
if (!$this->settings[$Model->alias]['enabled']) {
return true;
}
if (isset($this->settings[$Model->alias]['skip']['delete']) && $this->settings[$Model->alias]['skip']['delete']) {
return true;
}
$Model->recursive = -1;
$Model->read();
return true;
}
function afterDelete(&$Model) {
if (!$this->settings[$Model->alias]['enabled']) {
return true;
}
if (isset($this->settings[$Model->alias]['skip']['delete']) && $this->settings[$Model->alias]['skip']['delete']) {
return true;
}
$logData = array();
if (isset($this->schema['description'])) {
$logData['Log']['description'] = $Model->alias;
if (isset($Model->data[$Model->alias][$Model->displayField]) && $Model->displayField != $Model->primaryKey) {
$logData['Log']['description'] .= ' "' . $Model->data[$Model->alias][$Model->displayField] . '"';
}
if ($this->settings[$Model->alias]['description_ids']) {
$logData['Log']['description'] .= ' (' . $Model->id . ') ';
}
$logData['Log']['description'] .= __('deleted', TRUE);
}
$logData['Log']['action'] = 'delete';
$this->_saveLog($Model, $logData);
}
function beforeSave(&$Model) {
if (isset($this->schema['change']) && $Model->id) {
$this->old = $Model->find('first', array(
'conditions' => array(
$Model->alias . '.' . $Model->primaryKey => $Model->id),
'recursive' => -1));
}
return true;
}
function afterSave(&$Model, $created) {
if (!$this->settings[$Model->alias]['enabled']) {
return true;
}
if (isset($this->settings[$Model->alias]['skip']['add']) && $this->settings[$Model->alias]['skip']['add'] && $created) {
return true;
} elseif (isset($this->settings[$Model->alias]['skip']['edit']) && $this->settings[$Model->alias]['skip']['edit'] && !$created) {
return true;
}
$keys = array_keys($Model->data[$Model->alias]);
$diff = array_diff($keys, $this->settings[$Model->alias]['ignore']);
if (sizeof($diff) == 0 && empty($Model->logableAction)) {
return false;
}
if ($Model->id) {
$id = $Model->id;
} elseif ($Model->insertId) {
$id = $Model->insertId;
}
if (isset($this->schema[$this->settings[$Model->alias]['foreignKey']])) {
$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $id;
}
if (isset($this->schema['description'])) {
$logData['Log']['description'] = $Model->alias . ' ';
if (isset($Model->data[$Model->alias][$Model->displayField]) && $Model->displayField != $Model->primaryKey) {
$logData['Log']['description'] .= '"' . $Model->data[$Model->alias][$Model->displayField] . '" ';
}
if ($this->settings[$Model->alias]['description_ids']) {
$logData['Log']['description'] .= '(' . $id . ') ';
}
if ($created) {
$logData['Log']['description'] .= __('added', TRUE);
} else {
$logData['Log']['description'] .= __('updated', TRUE);
}
}
if (isset($this->schema['action'])) {
if ($created) {
$logData['Log']['action'] = 'add';
} else {
$logData['Log']['action'] = 'edit';
}
}
if (isset($this->schema['change'])) {
$logData['Log']['change'] = '';
$db_fields = array_keys($Model->schema());
$changed_fields = array();
foreach ( $Model->data[$Model->alias] as $key => $value ) {
if (isset($Model->data[$Model->alias][$Model->primaryKey]) && !empty($this->old) && isset($this->old[$Model->alias][$key])) {
$old = $this->old[$Model->alias][$key];
} else {
$old = '';
}
if ($key != 'modified' && !in_array($key, $this->settings[$Model->alias]['ignore']) && $value != $old && in_array($key, $db_fields)) {
if ($this->settings[$Model->alias]['change'] == 'full') {
$changed_fields[] = $key . ' (' . $old . ') => (' . $value . ')';
} else if ($this->settings[$Model->alias]['change'] == 'serialize') {
$changed_fields[$key] = array(
'old' => $old,
'value' => $value);
} else {
$changed_fields[] = $key;
}
}
}
$changes = sizeof($changed_fields);
if ($changes == 0) {
return true;
}
if ($this->settings[$Model->alias]['change'] == 'serialize') {
$logData['Log']['change'] = serialize($changed_fields);
} else {
$logData['Log']['change'] = implode(', ', $changed_fields);
}
$logData['Log']['changes'] = $changes;
}
$this->_saveLog($Model, $logData);
}
/**
* Does the actual saving of the Log model. Also adds the special field if possible.
*
* If model field in table, add the Model->alias
* If action field is NOT in table, remove it from dataset
* If the userKey field in table, add it to dataset
* If userData is supplied to model, add it to the title
*
* @param Object $Model
* @param array $logData
*/
function _saveLog(&$Model, $logData, $title = null) {
if ($title !== NULL) {
$logData['Log']['title'] = $title;
} elseif ($Model->displayField == $Model->primaryKey) {
$logData['Log']['title'] = $Model->alias . ' (' . $Model->id . ')';
} elseif (isset($Model->data[$Model->alias][$Model->displayField])) {
$logData['Log']['title'] = $Model->data[$Model->alias][$Model->displayField];
} else {
$logData['Log']['title'] = $Model->field($Model->displayField);
}
if (isset($this->schema[$this->settings[$Model->alias]['classField']])) {
// by miha nahtigal
$logData['Log'][$this->settings[$Model->alias]['classField']] = $Model->name;
}
if (isset($this->schema[$this->settings[$Model->alias]['foreignKey']]) && !isset($logData['Log'][$this->settings[$Model->alias]['foreignKey']])) {
if ($Model->id) {
$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $Model->id;
} elseif ($Model->insertId) {
$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $Model->insertId;
}
}
if (!isset($this->schema['action'])) {
unset($logData['Log']['action']);
} elseif (isset($Model->logableAction) && !empty($Model->logableAction)) {
$logData['Log']['action'] = implode(',', $Model->logableAction); // . ' ' . $logData['Log']['action'];
unset($Model->logableAction);
}
if (isset($this->schema['version_id']) && isset($Model->version_id)) {
$logData['Log']['version_id'] = $Model->version_id;
unset($Model->version_id);
}
if (isset($this->schema['ip']) && $this->userIP) {
$logData['Log']['ip'] = $this->userIP;
}
if (isset($this->schema[$this->settings[$Model->alias]['userKey']]) && $this->user) {
$logData['Log'][$this->settings[$Model->alias]['userKey']] = $this->user[$this->UserModel->alias][$this->UserModel->primaryKey];
}
if (isset($this->schema['description'])) {
if ($this->user && $this->UserModel) {
$logData['Log']['description'] .= ' by ' . $this->settings[$Model->alias]['userModel'] . ' "' . $this->user[$this->UserModel->alias][$this->UserModel->displayField] . '"';
if ($this->settings[$Model->alias]['description_ids']) {
$logData['Log']['description'] .= ' (' . $this->user[$this->UserModel->alias][$this->UserModel->primaryKey] . ')';
}
} else {
// UserModel is active, but the data hasnt been set. Assume system action.
$logData['Log']['description'] .= ' by System';
}
$logData['Log']['description'] .= '.';
}
$this->Log->create($logData);
$this->Log->save(null, array(
'validate' => false,
'callbacks' => false));
}
}

View File

@ -0,0 +1,91 @@
<?php
/**
* Syslog Storage stream for Logging
*
* PHP versions 4 and 5
*
* Copyright 2008-2010, UGR Works Limited.
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2008-2010, UGR Works Limited
* @package sunshine
* @subpackage sunshine.cake.libs.log
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* SysLog for Logging.
*
* @package sunshine
* @subpackage sunshine.cake.libs.log
*/
class SysLog {
/**
* Ident to send with the log files.
*
* @var string
*/
var $_ident = null;
/**
* The facility to use for storing log files.
*
* @var string
*/
var $_facility = null;
/**
* Constructs a new SysLog Logger.
*
* Options
*
* - `ident` the ident to be added to each message.
* - `facility` what type of application is recording a message. Default: LOG_LOCAL0. LOG_USER if Windows.
*
* @param array $options Options for the SysLog, see above.
* @return void
*/
function SysLog($options = array()) {
if ($this->isWindows()) {
$default_facility = LOG_USER;
} else {
$default_facility= LOG_LOCAL0;
}
$options += array('ident' => LOGS, 'facility' => $default_facility);
$this->_ident = $options['ident'];
$this->_facility = $options['facility'];
}
/**
* Utilty method to identify if we're running on a Windows box.
*
* @return boolean if running on windows.
*/
function isWindows() {
return (DIRECTORY_SEPARATOR == '\\' ? true : false);
}
/**
* Implements writing to the specified syslog
*
* @param string $type The type of log you are making.
* @param string $message The message you want to log.
* @return boolean success of write.
*/
function write($type, $message) {
$debugTypes = array('notice', 'info', 'debug');
$priority = LOG_INFO;
if ($type == 'error' || $type == 'warning') {
$priority = LOG_ERR;
} elseif (in_array($type, $debugTypes)) {
$priority = LOG_DEBUG;
}
$output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message . "\n";
if (!openlog($this->_ident, LOG_PID | LOG_PERROR, $this->_facility)) {
return false;
}
$result = syslog($priority, $output);
closelog();
return $result;
}
}
?>

4
plugins/index.txt Normal file
View File

@ -0,0 +1,4 @@
https://github.com/markstory/acl_extras
https://github.com/eskil-saatvedt/CakePHP-Assets (LogableBehavior)
http://bakery.cakephp.org/articles/rikdc/2010/06/07/syslog-component
http://xp-dev.com/trac/cakephp/browser/cakephp/libs/magic_tools

View File

@ -0,0 +1,126 @@
<?php
/**
* Prevents a record from being deleted when deletion would result in orphaned related records; if deletion is prevented, an explanatory error message is stored in the model's attribute $deletionError.
*
* Example: A user has written many posts. Now somebody tries to delete the user - which would result in orphaned posts with no user! So this behavior prevents deletion of the user.
*
* Notice: This behavior has only an effect when 'dependent' is set to false (otherwise the records are all deleted anyway and no orphans would be left behind).
*
* @author Joshua Muheim (Incense.ch)
* @copyright Joshua Muheim, 2011
* @package magic_tools
* @subpackage behaviors
*/
App::import('core', 'ModelBehavior');
class OrphansProtectableBehavior extends ModelBehavior {
/**
* Prepares the behavior.
*
* @param $model Model
* @param $settings array
*/
function setup(&$model, $settings) {
$Model->_deletionError = null; // Stores the deletion error message
$Model->orphansProtectableOptions = array_merge(array(
'listPossibleOrphans' => true,
'htmlError' => false
), $settings);
}
/**
* Checks if there would be orphaned record left behind after deletion of this record; if so, deletion is prevented.
*
* @param $model Model
* @param $cascade boolean
* @return boolean
*/
function beforeDelete(&$model, $cascade) {
if($cascade) return true;
return !$Model->wouldLeaveOrphanedRecordsBehind();
}
/**
* Checks if deletion of this record would leave orphaned associated records behind.
*
* @param $model Model
* @return boolean
*/
function wouldLeaveOrphanedRecordsBehind(&$model) {
$possibleOrphans = array();
foreach($Model->hasMany as $model => $settings) {
// Is relationship is dependent?
if($settings['dependent']){ // Yes! Possible orphans are deleted, too!
// Do nothing
} else { // No! Possible orphans should be protected!
// Is there a possible orphan for this relation?
$Model->{$model}->recursive = -1;
$objects = $Model->{$model}->find('all', array('conditions' => array($settings['className'].'.'.$settings['foreignKey'] => $Model->id), 'order' => 'id asc'));
if(count($objects) > 0) { // Yes, there is at least one possible orphan!
$objectIds = array();
foreach($objects as $object) {
$objectIds[] = $object[$model]['id'];
}
$possibleOrphans[$model] = $objectIds;
}
}
}
// Would orphans be left behind?
if(count($possibleOrphans) > 0) { // Yes! Create deletion error message!
$Model->_deletionError = $Model->createDeletionError($possibleOrphans);
return true;
} else { // No!
return false;
}
}
/**
* Returns the deletion error message (if there is one).
*
* @param $model Model
* @return string
*/
function getDeletionError(&$model) {
return $Model->_deletionError;
}
/**
* Creates the deletion error message and returns it.
*
* @param $model Model
* @param $possibleOrphans array
* @return string
*/
function createDeletionError(&$model, $possibleOrphans) {
$errorParts = array();
foreach($possibleOrphans as $model => $ids) {
$count = count($ids);
$modelName = $count > 1 ? Inflector::pluralize($model) : $model;
$errorParts[] = $count.' '.__($modelName, true).' (ID: '.$Model->createDeletionErrorIds($model, $ids).')';
}
return __('it has the following dependent items', true).': '.implode($errorParts, ', ');
}
/**
* Creates a string containing HTML-links to comma separated IDs of the potentially orphaned records of the specified model.
*
* @param $model Model
* @param $orphanModel string
* @param $ids array
* @return string
*/
function createDeletionErrorIds(&$model, $orphanModel, $ids) {
$messageParts = array();
if($Model->orphansProtectableOptions['htmlError']) {
foreach($ids as $id) {
$messageParts[] = '<a href="'.Inflector::pluralize(strtolower($orphanModel)).'/view/'.$id.'">'.$id.'</a>'; // TODO: Noch unschön! --zivi-muh
}
} else {
$messageParts = $ids;
}
return implode($messageParts, ', ');
}
}
?>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Event>
<id>14</id>
<org>NCIRC</org>
<org>ORG</org>
<date>2012-04-12</date>
<risk>Medium</risk>
<info>TT6666: malixioious XLS (EDIT 234..5)</info>
<user_id>3</user_id>
<info>info</info>
<user_id>1</user_id>
<alerted>0</alerted>
<uuid>4f8c2c4e-00dc-42c9-83ad-76e9ff32448e</uuid>
<private>0</private>
@ -31,8 +31,7 @@
<uuid>4f8c2d08-7e6c-4648-8730-50a7ff32448e</uuid>
<revision>1</revision>
<private>0</private>
<value>Summary_report_Vienna_2012 27 March
ok_z.doc|b34a8fcf8e5c81de3f6f177bb6171929</value>
<value>A.doc|3f6f1aaab6171925c81de9b34a8fcf8e</value>
<category_order>c</category_order>
<data />
</Attribute>
@ -45,22 +44,22 @@
<uuid>4f8c2c69-9bf8-4279-8d03-2138ff32448e</uuid>
<revision>1</revision>
<private>0</private>
<value>CVE-2010-3333</value>
<value>CVE-XXXX-XXXX</value>
<category_order>c</category_order>
</Attribute>
<RelatedEvent>
<id>11</id>
<date>2012-04-03</date>
<date>2011-01-03</date>
<uuid>4f8812ff-ded0-4592-9227-0615ff32448e</uuid>
</RelatedEvent>
<RelatedEvent>
<id>9</id>
<date>2012-04-02</date>
<date>2011-02-02</date>
<uuid>4f85981e-d044-4b16-bc16-0a35ff32448e</uuid>
</RelatedEvent>
<RelatedEvent>
<id>6</id>
<date>2012-03-22</date>
<date>2011-03-01</date>
<uuid>4f7a9faa-91d4-4c91-8ec6-0878ff32448e</uuid>
</RelatedEvent>
</Event>