diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index d65622a84..103a133f6 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -140,6 +140,16 @@ jobs:
sudo chmod +x /home
sudo chmod +x /
+ - name: Python setup
+ run: |
+ # Dirty install python stuff
+ python3 -m virtualenv -p python3 ./venv
+ sudo -E su $USER -c 'app/Console/cake Admin setSetting "MISP.python_bin" "$GITHUB_WORKSPACE/venv/bin/python"'
+ . ./venv/bin/activate
+ export PYTHONPATH=$PYTHONPATH:./app/files/scripts
+ pip install ./PyMISP[fileobjects,email] ./app/files/scripts/python-stix ./app/files/scripts/cti-python-stix2 pyzmq redis plyara pytest
+ deactivate
+
- name: DB Update
run: |
sudo -E su $USER -c 'app/Console/cake Admin setSetting "MISP.osuser" $USER'
@@ -148,7 +158,7 @@ jobs:
- name: Configure MISP
run: |
- sudo -u $USER app/Console/cake userInit -q | sudo tee ./key.txt
+ sudo -u $USER app/Console/cake User init | sudo tee ./key.txt
echo "AUTH=`cat key.txt`" >> $GITHUB_ENV
sudo -u $USER app/Console/cake Admin setSetting "Session.autoRegenerate" 0
sudo -u $USER app/Console/cake Admin setSetting "Session.timeout" 600
@@ -166,9 +176,6 @@ jobs:
sudo -u $USER app/Console/cake Admin setSetting "GnuPG.homedir" "`pwd`/.gnupg"
sudo -u $USER app/Console/cake Admin setSetting "GnuPG.password" "travistest"
sudo -u $USER app/Console/cake Admin setSetting "MISP.download_gpg_from_homedir" 1
-
- - name: Configure ZMQ
- run: |
sudo -u $USER app/Console/cake Admin setSetting "Plugin.ZeroMQ_redis_host" "127.0.0.1"
sudo -u $USER app/Console/cake Admin setSetting "Plugin.ZeroMQ_redis_port" 6379
sudo -u $USER app/Console/cake Admin setSetting "Plugin.ZeroMQ_redis_database" 1
@@ -192,7 +199,7 @@ jobs:
run: sudo -E su $USER -c 'app/Console/cake Admin updateObjectTemplates 1'
- name: Turn MISP live
- run: sudo -E su $USER -c 'app/Console/cake Live 1'
+ run: sudo -E su $USER -c 'app/Console/cake Admin live 1'
- name: Check if Redis is ready
run: sudo -E su $USER -c 'app/Console/cake Admin redisReady'
@@ -202,19 +209,6 @@ jobs:
sudo chmod +x app/Console/worker/start.sh
sudo -u www-data 'app/Console/worker/start.sh'
- - name: Python setup
- run: |
- sudo chmod 777 ./key.txt
- sudo chmod -R 777 ./tests
- # Start workers
- # Dirty install python stuff
- python3 -m virtualenv -p python3 ./venv
- sudo -E su $USER -c 'app/Console/cake Admin setSetting "MISP.python_bin" "$GITHUB_WORKSPACE/venv/bin/python"'
- . ./venv/bin/activate
- export PYTHONPATH=$PYTHONPATH:./app/files/scripts
- pip install ./PyMISP[fileobjects,email] ./app/files/scripts/python-stix ./app/files/scripts/cti-python-stix2 pyzmq redis plyara pytest
- deactivate
-
- name: Test if apache is working
run: |
sudo systemctl status apache2 --no-pager -l
@@ -234,7 +228,7 @@ jobs:
- name: Run PHP tests
run: |
- ./app/Vendor/bin/parallel-lint --exclude app/Lib/cakephp/ --exclude app/Vendor/ --exclude app/Lib/random_compat/ -e php,ctp app/
+ ./app/Vendor/bin/parallel-lint --exclude app/Lib/cakephp/ --exclude app/Vendor/ -e php,ctp app/
sudo -u www-data ./app/Vendor/bin/phpunit app/Test/
- name: Clone test files
diff --git a/app/Console/Command/AdminShell.php b/app/Console/Command/AdminShell.php
index e8333dbf6..218ac517c 100644
--- a/app/Console/Command/AdminShell.php
+++ b/app/Console/Command/AdminShell.php
@@ -46,11 +46,11 @@ class AdminShell extends AppShell
'help' => __('Update the JSON definition of taxonomies.'),
));
$parser->addSubcommand('setSetting', [
- 'help' => __('Set setting in PHP config file.'),
+ 'help' => __('Set setting in MISP config'),
'parser' => [
'arguments' => [
'name' => ['help' => __('Setting name'), 'required' => true],
- 'value' => ['help' => __('Setting value'), 'required' => true],
+ 'value' => ['help' => __('Setting value')],
],
'options' => [
'force' => [
@@ -507,32 +507,47 @@ class AdminShell extends AppShell
}
}
}
- echo json_encode($result, JSON_PRETTY_PRINT) . PHP_EOL;
+ $this->out($this->json($result));
}
public function setSetting()
{
- list($setting_name, $value) = $this->args;
- if ($value === 'false') {
- $value = 0;
- } elseif ($value === 'true') {
- $value = 1;
- }
- if ($this->params['null']) {
+ list($settingName) = $this->args;
+
+ if ($this->params['null'] && isset($this->args[1])) {
+ $this->error(__('Trying to set setting to null value, but value was provided.'));
+ } else if ($this->params['null']) {
$value = null;
+ } elseif (isset($this->args[1])) {
+ $value = $this->args[1];
+ } else {
+ $this->error(__('No setting value provided.'));
}
- $cli_user = array('id' => 0, 'email' => 'SYSTEM', 'Organisation' => array('name' => 'SYSTEM'));
- if (empty($setting_name) || ($value === null && !$this->params['null'])) {
- die('Usage: ' . $this->Server->command_line_functions['console_admin_tasks']['data']['Set setting'] . PHP_EOL);
- }
- $setting = $this->Server->getSettingData($setting_name);
+
+ $setting = $this->Server->getSettingData($settingName);
if (empty($setting)) {
- $message = 'Invalid setting "' . $setting_name . '". Please make sure that the setting that you are attempting to change exists and if a module parameter, the modules are running.' . PHP_EOL;
+ $message = 'Invalid setting "' . $settingName . '". Please make sure that the setting that you are attempting to change exists and if a module parameter, the modules are running.' . PHP_EOL;
$this->error(__('Setting change rejected.'), $message);
}
- $result = $this->Server->serverSettingsEditValue($cli_user, $setting, $value, $this->params['force']);
+
+ // Convert value to boolean or to int
+ if ($value !== null) {
+ if ($setting['type'] === 'boolean') {
+ $value = $this->toBoolean($value);
+ } else if ($setting['type'] === 'numeric') {
+ if (is_numeric($value)) {
+ $value = (int)$value;
+ } elseif ($value === 'true' || $value === 'false') {
+ $value = $value === 'true' ? 1 : 0; // special case for `debug` setting
+ } else {
+ $this->error(__('Setting "%s" change rejected.', $settingName), __('Provided value %s is not a number.', $value));
+ }
+ }
+ }
+
+ $result = $this->Server->serverSettingsEditValue('SYSTEM', $setting, $value, $this->params['force']);
if ($result === true) {
- $this->out(__('Setting "%s" changed to %s', $setting_name, is_string($value) ? '"' . $value . '"' : (string)$value));
+ $this->out(__('Setting "%s" changed to %s', $settingName, is_string($value) ? '"' . $value . '"' : json_encode($value)));
} else {
$message = __("The setting change was rejected. MISP considers the requested setting value as invalid and would lead to the following error:\n\n\"%s\"\n\nIf you still want to force this change, please supply the --force argument.\n", $result);
$this->error(__('Setting change rejected.'), $message);
diff --git a/app/Console/Command/AppShell.php b/app/Console/Command/AppShell.php
index 639ef9136..25b06fcac 100644
--- a/app/Console/Command/AppShell.php
+++ b/app/Console/Command/AppShell.php
@@ -90,7 +90,7 @@ abstract class AppShell extends Shell
*/
protected function deprecated($newCommand)
{
- $this->err("This method is deprecated. Next time please use `$newCommand`.");
+ $this->err("Warning: This method is deprecated. Next time please use `$newCommand`.");
}
/**
diff --git a/app/Console/Command/UserInitShell.php b/app/Console/Command/UserInitShell.php
index f0a0d7225..bc5238f69 100644
--- a/app/Console/Command/UserInitShell.php
+++ b/app/Console/Command/UserInitShell.php
@@ -1,7 +1,13 @@
deprecated('cake user init');
+
if (!Configure::read('Security.salt')) {
$this->loadModel('Server');
$this->Server->serverSettingsSaveValue('Security.salt', $this->User->generateRandomPassword(32));
diff --git a/app/Console/Command/UserShell.php b/app/Console/Command/UserShell.php
index db0b5ffbd..568c867e8 100644
--- a/app/Console/Command/UserShell.php
+++ b/app/Console/Command/UserShell.php
@@ -22,6 +22,9 @@ class UserShell extends AppShell
],
]
]);
+ $parser->addSubcommand('init', [
+ 'help' => __('Create default role, organisation and user when not exists.'),
+ ]);
$parser->addSubcommand('authkey', [
'help' => __('Get information about given authkey.'),
'parser' => [
@@ -121,7 +124,7 @@ class UserShell extends AppShell
public function list()
{
- $userId = isset($this->args[0]) ? $this->args[0] : null;
+ $userId = $this->args[0] ?? null;
if ($userId) {
$conditions = ['OR' => [
'User.id' => $userId,
@@ -163,6 +166,21 @@ class UserShell extends AppShell
}
}
+ public function init()
+ {
+ if (!Configure::read('Security.salt')) {
+ $this->loadModel('Server');
+ $this->Server->serverSettingsSaveValue('Security.salt', $this->User->generateRandomPassword(32));
+ }
+
+ $authKey = $this->User->init();
+ if ($authKey === null) {
+ $this->err('Script aborted: MISP instance already initialised.');
+ } else {
+ $this->out($authKey);
+ }
+ }
+
public function authkey()
{
if (isset($this->args[0])) {
diff --git a/app/Controller/UsersController.php b/app/Controller/UsersController.php
index c2735ab6e..09bc73493 100644
--- a/app/Controller/UsersController.php
+++ b/app/Controller/UsersController.php
@@ -1244,8 +1244,6 @@ class UsersController extends AppController
// login was successful, do everything that is needed such as logging and more:
$this->_postlogin();
} else {
- $dataSourceConfig = ConnectionManager::getDataSource('default')->config;
- $dataSource = $dataSourceConfig['datasource'];
// don't display authError before first login attempt
if (str_replace("//", "/", $this->webroot . $this->Session->read('Auth.redirect')) == $this->webroot && $this->Session->read('Message.auth.message') == $this->Auth->authError) {
$this->Session->delete('Message.auth');
@@ -1260,73 +1258,7 @@ class UsersController extends AppController
}
}
- //
- // Actions needed for the first access, when the database is not populated yet.
- //
-
- // populate the DB with the first role (site admin) if it's empty
- if (!$this->User->Role->hasAny()) {
- $siteAdmin = array('Role' => array(
- 'id' => 1,
- 'name' => 'Site Admin',
- 'permission' => 3,
- 'perm_add' => 1,
- 'perm_modify' => 1,
- 'perm_modify_org' => 1,
- 'perm_publish' => 1,
- 'perm_sync' => 1,
- 'perm_admin' => 1,
- 'perm_audit' => 1,
- 'perm_auth' => 1,
- 'perm_site_admin' => 1,
- 'perm_regexp_access' => 1,
- 'perm_sharing_group' => 1,
- 'perm_template' => 1,
- 'perm_tagger' => 1,
- ));
- $this->User->Role->save($siteAdmin);
- // PostgreSQL: update value of auto incremented serial primary key after setting the column by force
- if ($dataSource === 'Database/Postgres') {
- $sql = "SELECT setval('roles_id_seq', (SELECT MAX(id) FROM roles));";
- $this->User->Role->query($sql);
- }
- }
- if (!$this->User->Organisation->hasAny(array('Organisation.local' => true))) {
- $this->User->runUpdates();
- $date = date('Y-m-d H:i:s');
- $org = array('Organisation' => array(
- 'id' => 1,
- 'name' => !empty(Configure::read('MISP.org')) ? Configure::read('MISP.org') : 'ADMIN',
- 'description' => 'Automatically generated admin organisation',
- 'type' => 'ADMIN',
- 'uuid' => CakeText::uuid(),
- 'local' => 1,
- 'date_created' => $date,
- 'sector' => '',
- 'nationality' => ''
- ));
- $this->User->Organisation->save($org);
- // PostgreSQL: update value of auto incremented serial primary key after setting the column by force
- if ($dataSource === 'Database/Postgres') {
- $sql = "SELECT setval('organisations_id_seq', (SELECT MAX(id) FROM organisations));";
- $this->User->Organisation->query($sql);
- }
- $org_id = $this->User->Organisation->id;
- }
- // populate the DB with the first user if it's empty
- if (!$this->User->hasAny()) {
- if (!isset($org_id)) {
- $hostOrg = $this->User->Organisation->find('first', array('conditions' => array('Organisation.name' => Configure::read('MISP.org'), 'Organisation.local' => true), 'recursive' => -1));
- if (!empty($hostOrg)) {
- $org_id = $hostOrg['Organisation']['id'];
- } else {
- $firstOrg = $this->User->Organisation->find('first', array('conditions' => array('Organisation.local' => true), 'order' => 'Organisation.id ASC'));
- $org_id = $firstOrg['Organisation']['id'];
- }
- }
- $this->User->runUpdates();
- $this->User->createInitialUser($org_id);
- }
+ $this->User->init();
}
}
diff --git a/app/Lib/Tools/JSONConverterTool.php b/app/Lib/Tools/JSONConverterTool.php
index 7ede8dd25..04666aee1 100644
--- a/app/Lib/Tools/JSONConverterTool.php
+++ b/app/Lib/Tools/JSONConverterTool.php
@@ -153,7 +153,7 @@ class JSONConverterTool
return;
}
yield '{"Event":{';
- $firstKey = key($event['Event']);
+ $firstKey = array_key_first($event['Event']);
foreach ($event['Event'] as $key => $value) {
if ($key === 'Attribute' || $key === 'Object') { // Encode every object or attribute separately
yield ($firstKey === $key ? '' : ',') . json_encode($key) . ":[";
diff --git a/app/Lib/Tools/JsonTool.php b/app/Lib/Tools/JsonTool.php
index 5958190c7..a3c27727e 100644
--- a/app/Lib/Tools/JsonTool.php
+++ b/app/Lib/Tools/JsonTool.php
@@ -75,7 +75,7 @@ class JsonTool
*/
public static function escapeNonUnicode($string)
{
- if (json_encode($string, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS) !== false) {
+ if (mb_check_encoding($string, 'UTF-8')) {
return $string; // string is valid unicode
}
diff --git a/app/Model/AppModel.php b/app/Model/AppModel.php
index dc9446a95..02e0b2bc1 100644
--- a/app/Model/AppModel.php
+++ b/app/Model/AppModel.php
@@ -2374,9 +2374,9 @@ class AppModel extends Model
}
// alternative to the build in notempty/notblank validation functions, compatible with cakephp <= 2.6 and cakephp and cakephp >= 2.7
- public function valueNotEmpty($value)
+ public function valueNotEmpty(array $value)
{
- $field = array_keys($value)[0];
+ $field = array_key_first($value);
$value = trim($value[$field]);
if (!empty($value)) {
return true;
@@ -2384,27 +2384,27 @@ class AppModel extends Model
return ucfirst($field) . ' cannot be empty.';
}
- public function valueIsJson($value)
+ public function valueIsJson(array $value)
{
- $value = array_values($value)[0];
+ $value = current($value);
if (!JsonTool::isValid($value)) {
return __('Invalid JSON.');
}
return true;
}
- public function valueIsID($value)
+ public function valueIsID(array $value)
{
- $field = array_keys($value)[0];
+ $field = array_key_first($value);
if (!is_numeric($value[$field]) || $value[$field] < 0) {
return 'Invalid ' . ucfirst($field) . ' ID';
}
return true;
}
- public function stringNotEmpty($value)
+ public function stringNotEmpty(array $value)
{
- $field = array_keys($value)[0];
+ $field = array_key_first($value);
$value = trim($value[$field]);
if (!isset($value) || ($value == false && $value !== "0")) {
return ucfirst($field) . ' cannot be empty.';
@@ -3713,7 +3713,7 @@ class AppModel extends Model
if (!$isRule) {
$args = func_get_args();
$fields = $args[1];
- $or = isset($args[2]) ? $args[2] : true;
+ $or = $args[2] ?? true;
}
}
if (!is_array($fields)) {
@@ -3858,8 +3858,7 @@ class AppModel extends Model
protected function isMysql()
{
$dataSource = ConnectionManager::getDataSource('default');
- $dataSourceName = $dataSource->config['datasource'];
- return $dataSourceName === 'Database/Mysql' || $dataSourceName === 'Database/MysqlObserver' || $dataSourceName === 'Database/MysqlExtended' || $dataSource instanceof Mysql;
+ return $dataSource instanceof Mysql;
}
/**
@@ -3995,21 +3994,21 @@ class AppModel extends Model
");
}
- public function findOrder($order, $order_model, $valid_order_fields)
+ public function findOrder($order, $orderModel, $validOrderFields)
{
if (!is_array($order)) {
- $order_rules = explode(' ', strtolower($order));
- $order_field = explode('.', $order_rules[0]);
- $order_field = end($order_field);
- if (in_array($order_field, $valid_order_fields)) {
+ $orderRules = explode(' ', strtolower($order));
+ $orderField = explode('.', $orderRules[0]);
+ $orderField = end($orderField);
+ if (in_array($orderField, $validOrderFields, true)) {
$direction = 'asc';
- if (!empty($order_rules[1]) && trim($order_rules[1]) === 'desc') {
+ if (!empty($orderRules[1]) && trim($orderRules[1]) === 'desc') {
$direction = 'desc';
}
} else {
return null;
}
- return $order_model . '.' . $order_field . ' ' . $direction;
+ return $orderModel . '.' . $orderField . ' ' . $direction;
}
return null;
}
diff --git a/app/Model/Attribute.php b/app/Model/Attribute.php
index 6ea5a12bd..e032d4490 100644
--- a/app/Model/Attribute.php
+++ b/app/Model/Attribute.php
@@ -434,7 +434,7 @@ class Attribute extends AppModel
public function afterSave($created, $options = array())
{
// Passing event in `parentEvent` field will speed up correlation
- $passedEvent = isset($options['parentEvent']) ? $options['parentEvent'] : false;
+ $passedEvent = $options['parentEvent'] ?? false;
$attribute = $this->data['Attribute'];
@@ -808,7 +808,7 @@ class Attribute extends AppModel
// check whether the variable is null or datetime
public function datetimeOrNull($fields)
{
- $seen = array_values($fields)[0];
+ $seen = current($fields);
if ($seen === null) {
return true;
}
diff --git a/app/Model/Server.php b/app/Model/Server.php
index 18e09b44a..b110f00a0 100644
--- a/app/Model/Server.php
+++ b/app/Model/Server.php
@@ -2371,23 +2371,21 @@ class Server extends AppModel
return $setting;
}
- public function serverSettingsEditValue(array $user, array $setting, $value, $forceSave = false)
+ /**
+ * @param array|string $user
+ * @param array $setting
+ * @param mixed $value
+ * @param bool $forceSave
+ * @return mixed|string|true|null
+ * @throws Exception
+ */
+ public function serverSettingsEditValue($user, array $setting, $value, $forceSave = false)
{
if (isset($setting['beforeHook'])) {
- $beforeResult = call_user_func_array(array($this, $setting['beforeHook']), array($setting['name'], $value));
+ $beforeResult = $this->{$setting['beforeHook']}($setting['name'], $value);
if ($beforeResult !== true) {
- $this->Log = ClassRegistry::init('Log');
- $this->Log->create();
- $this->Log->saveOrFailSilently(array(
- 'org' => $user['Organisation']['name'],
- 'model' => 'Server',
- 'model_id' => 0,
- 'email' => $user['email'],
- 'action' => 'serverSettingsEdit',
- 'user_id' => $user['id'],
- 'title' => 'Server setting issue',
- 'change' => 'There was an issue witch changing ' . $setting['name'] . ' to ' . $value . '. The error message returned is: ' . $beforeResult . 'No changes were made.',
- ));
+ $change = 'There was an issue witch changing ' . $setting['name'] . ' to ' . $value . '. The error message returned is: ' . $beforeResult . 'No changes were made.';
+ $this->loadLog()->createLogEntry($user, 'serverSettingsEdit', 'Server', 0, 'Server setting issue', $change);
return $beforeResult;
}
}
@@ -2396,7 +2394,7 @@ class Server extends AppModel
if ($setting['type'] === 'boolean') {
$value = (bool)$value;
} else if ($setting['type'] === 'numeric') {
- $value = (int)($value);
+ $value = (int)$value;
}
if (isset($setting['test'])) {
if ($setting['test'] instanceof Closure) {
@@ -2437,7 +2435,7 @@ class Server extends AppModel
if ($setting['afterHook'] instanceof Closure) {
$afterResult = $setting['afterHook']($setting['name'], $value, $oldValue);
} else {
- $afterResult = call_user_func_array(array($this, $setting['afterHook']), array($setting['name'], $value, $oldValue));
+ $afterResult = $this->{$setting['afterHook']}($setting['name'], $value, $oldValue);
}
if ($afterResult !== true) {
$change = 'There was an issue after setting a new setting. The error message returned is: ' . $afterResult;
diff --git a/app/Model/SystemSetting.php b/app/Model/SystemSetting.php
index 0f0746a8d..875a57c75 100644
--- a/app/Model/SystemSetting.php
+++ b/app/Model/SystemSetting.php
@@ -46,7 +46,7 @@ class SystemSetting extends AppModel
{
/** @var self $systemSetting */
$systemSetting = ClassRegistry::init('SystemSetting');
- if (!$systemSetting->databaseExists()) {
+ if (!$systemSetting->tableExists()) {
return;
}
$settings = $systemSetting->getSettings();
@@ -58,7 +58,7 @@ class SystemSetting extends AppModel
}
}
- public function databaseExists()
+ private function tableExists()
{
$tables = ConnectionManager::getDataSource($this->useDbConfig)->listSources();
return in_array('system_settings', $tables, true);
diff --git a/app/Model/User.php b/app/Model/User.php
index 1965ec560..2c3b49dc0 100644
--- a/app/Model/User.php
+++ b/app/Model/User.php
@@ -1105,13 +1105,18 @@ class User extends AppModel
return $hashed;
}
- public function createInitialUser($org_id)
+ /**
+ * @param int $orgId
+ * @return string User auth key
+ * @throws Exception
+ */
+ public function createInitialUser($orgId)
{
$authKey = $this->generateAuthKey();
$admin = array('User' => array(
'id' => 1,
'email' => 'admin@admin.test',
- 'org_id' => $org_id,
+ 'org_id' => $orgId,
'password' => 'admin',
'confirm_password' => 'admin',
'authkey' => $authKey,
@@ -1123,7 +1128,6 @@ class User extends AppModel
$this->validator()->remove('password'); // password is too simple, remove validation
$this->save($admin);
if (!empty(Configure::read("Security.advanced_authkeys"))) {
- $this->AuthKey = ClassRegistry::init('AuthKey');
$newKey = [
'authkey' => $authKey,
'user_id' => 1,
@@ -2156,7 +2160,7 @@ class User extends AppModel
if (!ctype_alnum($token)) {
return false;
}
- $redis = $this->setupRedis();
+ $redis = RedisTool::init();
$userId = $redis->get('misp:forgot:' . $token);
if (empty($userId)) {
return false;
@@ -2167,8 +2171,78 @@ class User extends AppModel
public function purgeForgetToken($token)
{
- $redis = $this->setupRedis();
- $userId = $redis->del('misp:forgot:' . $token);
+ $redis = RedisTool::init();
+ $redis->del('misp:forgot:' . $token);
return true;
}
+
+ /**
+ * Create default Role, Organisation and User
+ * @return string|null Created user auth key
+ * @throws Exception
+ */
+ public function init()
+ {
+ if (!$this->Role->hasAny()) {
+ $siteAdmin = ['Role' => [
+ 'id' => 1,
+ 'name' => 'Site Admin',
+ 'permission' => 3,
+ 'perm_add' => 1,
+ 'perm_modify' => 1,
+ 'perm_modify_org' => 1,
+ 'perm_publish' => 1,
+ 'perm_sync' => 1,
+ 'perm_admin' => 1,
+ 'perm_audit' => 1,
+ 'perm_auth' => 1,
+ 'perm_site_admin' => 1,
+ 'perm_regexp_access' => 1,
+ 'perm_sharing_group' => 1,
+ 'perm_template' => 1,
+ 'perm_tagger' => 1,
+ ]];
+ $this->Role->save($siteAdmin);
+ // PostgreSQL: update value of auto incremented serial primary key after setting the column by force
+ if (!$this->isMysql()) {
+ $sql = "SELECT setval('roles_id_seq', (SELECT MAX(id) FROM roles));";
+ $this->Role->query($sql);
+ }
+ }
+
+ if (!$this->Organisation->hasAny(['Organisation.local' => true])) {
+ $this->runUpdates();
+ $org = ['Organisation' => [
+ 'id' => 1,
+ 'name' => !empty(Configure::read('MISP.org')) ? Configure::read('MISP.org') : 'ADMIN',
+ 'description' => 'Automatically generated admin organisation',
+ 'type' => 'ADMIN',
+ 'date_created' => date('Y-m-d H:i:s'),
+ 'local' => 1,
+ ]];
+ $this->Organisation->save($org);
+ // PostgreSQL: update value of auto incremented serial primary key after setting the column by force
+ if (!$this->isMysql()) {
+ $sql = "SELECT setval('organisations_id_seq', (SELECT MAX(id) FROM organisations));";
+ $this->Organisation->query($sql);
+ }
+ $orgId = $this->Organisation->id;
+ }
+
+ if (!$this->hasAny()) {
+ if (!isset($orgId)) {
+ $hostOrg = $this->Organisation->find('first', array('conditions' => array('Organisation.name' => Configure::read('MISP.org'), 'Organisation.local' => true), 'recursive' => -1));
+ if (!empty($hostOrg)) {
+ $orgId = $hostOrg['Organisation']['id'];
+ } else {
+ $firstOrg = $this->Organisation->find('first', array('conditions' => array('Organisation.local' => true), 'order' => 'Organisation.id ASC'));
+ $orgId = $firstOrg['Organisation']['id'];
+ }
+ }
+ $this->runUpdates();
+ return $this->createInitialUser($orgId);
+ }
+
+ return null;
+ }
}
diff --git a/app/View/AuthKeys/view.ctp b/app/View/AuthKeys/view.ctp
index 2dbac015a..5bd195ff0 100644
--- a/app/View/AuthKeys/view.ctp
+++ b/app/View/AuthKeys/view.ctp
@@ -3,12 +3,12 @@ $keyUsageCsv = null;
if (isset($keyUsage)) {
$todayString = date('Y-m-d');
$today = strtotime($todayString);
- $startDate = key($keyUsage); // oldest date for sparkline
+ $startDate = array_key_first($keyUsage); // oldest date for sparkline
$startDate = strtotime($startDate) - (3600 * 24 * 3);
$keyUsageCsv = 'Date,Close\n';
for ($date = $startDate; $date <= $today; $date += (3600 * 24)) {
$dateAsString = date('Y-m-d', $date);
- $keyUsageCsv .= $dateAsString . ',' . (isset($keyUsage[$dateAsString]) ? $keyUsage[$dateAsString] : 0) . '\n';
+ $keyUsageCsv .= $dateAsString . ',' . ($keyUsage[$dateAsString] ?? '0') . '\n';
}
} else {
$lastUsed = null;