Merge branch '2.4' of https://github.com/MISP/MISP into rework_stix

pull/6022/head
chrisr3d 2020-04-08 16:44:03 +02:00
commit 3ec127bcbe
37 changed files with 1188 additions and 63 deletions

View File

@ -291,7 +291,7 @@ class AdminShell extends AppShell
$param = empty($this->args[0]) ? 'all' : $this->args[0];
$settings = $this->Server->serverSettingsRead();
$result = $settings;
if (!empty($param)) {
if ($param != 'all') {
$result = 'No valid setting found for ' . $param;
foreach ($settings as $setting) {
if ($setting['setting'] == $param) {

View File

@ -120,7 +120,6 @@ class AppController extends Controller
} else {
$this->Auth->logoutRedirect = Configure::read('MISP.baseurl') . '/users/login';
}
$this->__sessionMassage();
if (Configure::read('Security.allow_cors')) {
// Add CORS headers
@ -352,7 +351,7 @@ class AppController extends Controller
}
}
} else {
if (!($this->params['controller'] === 'users' && $this->params['action'] === 'login')) {
if ($this->params['controller'] !== 'users' || !in_array($this->params['action'], array('login', 'register'))) {
if (!$this->request->is('ajax')) {
$this->Session->write('pre_login_requested_url', $this->here);
}

View File

@ -549,6 +549,7 @@ class ACLComponent extends Component
'viewEvent' => array('*'),
),
'users' => array(
'acceptRegistrations' => array('perm_site_admin'),
'admin_add' => array('perm_admin'),
'admin_delete' => array('perm_admin'),
'admin_edit' => array('perm_admin'),
@ -564,6 +565,7 @@ class ACLComponent extends Component
'checkIfLoggedIn' => array('*'),
'dashboard' => array('*'),
'delete' => array('perm_admin'),
'discardRegistrations' => array('perm_site_admin'),
'downloadTerms' => array('*'),
'edit' => array('*'),
'searchGpgKey' => array('*'),
@ -572,6 +574,8 @@ class ACLComponent extends Component
'initiatePasswordReset' => array('perm_admin'),
'login' => array('*'),
'logout' => array('*'),
'register' => array('*'),
'registrations' => array('perm_site_admin'),
'resetAllSyncAuthKeys' => array(),
'resetauthkey' => array('*'),
'request_API' => array('*'),

View File

@ -15,7 +15,7 @@ class RestSearchComponent extends Component
'Event' => array(
'returnFormat', 'value', 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last', 'eventid', 'withAttachments',
'metadata', 'uuid', 'publish_timestamp', 'timestamp', 'published', 'enforceWarninglist', 'sgReferenceOnly',
'limit', 'page', 'requested_attributes', 'includeContext', 'headerless', 'includeWarninglistHits', 'attackGalaxy', 'deleted',
'limit', 'page', 'requested_attributes', 'includeContext', 'headerless', 'includeWarninglistHits', 'attackGalaxy', 'to_ids', 'deleted',
'excludeLocalTags', 'date', 'includeSightingdb', 'tag', 'object_relation'
),
'Object' => array(

View File

@ -3088,7 +3088,9 @@ class EventsController extends AppController
'named_params' => $this->params['named'],
'ordered_url_params' => func_get_args(),
'injectedParams' => array(
'returnFormat' => 'csv'
'returnFormat' => 'csv',
'to_ids' => '1',
'published' => '1'
)
));
return $this->restSearch();
@ -3996,26 +3998,26 @@ class EventsController extends AppController
'checkbox_default' => true
),
'openIOC' => array(
'url' => '/events/downloadOpenIOCEvent/download/' . $id,
'url' => '/events/restSearch/openioc/to_ids:1/published:1/eventid:' . $id . '.json',
'text' => 'OpenIOC (all indicators marked to IDS)',
'requiresPublished' => false,
'checkbox' => false,
),
'csv' => array(
'url' => '/events/csv/download/' . $id,
'url' => '/events/restSearch/returnFormat:csv/to_ids:1/published:1/includeContext:0/eventid:' . $id,
'text' => 'CSV',
'requiresPublished' => false,
'checkbox' => true,
'checkbox_text' => 'Include non-IDS marked attributes',
'checkbox_set' => '/events/csv/download/' . $id . '/1'
'checkbox_set' => '/events/restSearch/returnFormat:csv/to_ids:1||0/published:1||0/includeContext:0/eventid:' . $id
),
'csv_with_context' => array(
'url' => '/events/restSearch/returnFormat:csv/eventid:' . $id,
'url' => '/events/restSearch/returnFormat:csv/to_ids:1/published:1/includeContext:1/eventid:' . $id,
'text' => 'CSV with additional context',
'requiresPublished' => false,
'checkbox' => true,
'checkbox_text' => 'Include non-IDS marked attributes',
'checkbox_set' => '/events/restSearch/returnFormat:csv/to_ids:1||0/published:1||0/eventid:' . $id
'checkbox_set' => '/events/restSearch/returnFormat:csv/to_ids:1||0/published:1||0/includeContext:1/eventid:' . $id
),
'stix_xml' => array(
'url' => '/events/restSearch/stix/eventid:' . $id,
@ -4061,6 +4063,7 @@ class EventsController extends AppController
),
'bro' => array(
'url' => '/attributes/bro/download/all/false/' . $id,
// 'url' => '/attributes/restSearch/returnFormat:bro/published:1||0/eventid:' . $id,
'text' => 'Download Bro rules',
'requiresPublished' => false,
'checkbox' => false
@ -4081,7 +4084,7 @@ class EventsController extends AppController
}
}
$exports['csv'] = array(
'url' => '/events/csv/download/' . $id . '/1',
'url' => '/events/restSearch/returnFormat:csv/includeContext:0/eventid:' . $id,
'text' => 'CSV (event not published, IDS flag ignored)',
'requiresPublished' => false,
'checkbox' => false

View File

@ -0,0 +1,17 @@
<?php
App::uses('AppController', 'Controller');
class InboxController extends AppController
{
public $components = array('Session', 'RequestHandler');
public function beforeFilter()
{
parent::beforeFilter();
}
public $paginate = array(
'limit' => 60,
'maxLimit' => 9999
);
}

View File

@ -143,6 +143,13 @@ class OrganisationsController extends AppController
} else {
if ($this->_isRest()) {
return $this->RestResponse->describe('Organisations', 'admin_add', false, $this->response->type());
} else {
if (!empty($this->params['named']['name'])) {
$this->request->data['Organisation']['name'] = $this->params['named']['name'];
}
if (!empty($this->params['named']['uuid'])) {
$this->request->data['Organisation']['uuid'] = $this->params['named']['uuid'];
}
}
}
$this->set('countries', $this->_arrayToValuesIndexArray($this->Organisation->countries));

View File

@ -30,7 +30,11 @@ class UsersController extends AppController
parent::beforeFilter();
// what pages are allowed for non-logged-in users
$this->Auth->allow('login', 'logout');
$allowedActions = array('login', 'logout');
if (!empty(Configure::read('Security.allow_self_registration'))) {
$allowedActions[] = 'register';
}
$this->Auth->allow($allowedActions);
}
public function view($id = null)
@ -438,7 +442,7 @@ class UsersController extends AppController
$users[$key]['User']['authkey'] = __('Redacted');
}
} else if (!empty(Configure::read('Security.user_monitoring_enabled'))) {
$users[$key]['User']['monitored'] = $redis->sismember('misp:monitored_users', $id);
$users[$key]['User']['monitored'] = $redis->sismember('misp:monitored_users', $value['User']['id']);
}
unset($users[$key]['User']['password']);
}
@ -1523,17 +1527,17 @@ class UsersController extends AppController
if ($isPostOrPut) {
$recipient = $this->request->data['User']['recipient'];
} else {
$recipient = isset($this->request->query['recipient']) ? $this->request->query['recipient'] : null;
$recipient = isset($this->params['named']['recipient']) ? $this->params['named']['recipient'] : null;
}
if ($isPostOrPut) {
$recipientEmailList = $this->request->data['User']['recipientEmailList'];
} else {
$recipientEmailList = isset($this->request->query['recipientEmailList']) ? $this->request->query['recipientEmailList'] : null;
$recipientEmailList = isset($this->params['named']['recipientEmailList']) ? $this->params['named']['recipientEmailList'] : null;
}
if ($isPostOrPut) {
$orgNameList = $this->request->data['User']['orgNameList'];
} else {
$orgNameList = isset($this->request->query['orgNameList']) ? $this->request->query['orgNameList'] : null;
$orgNameList = isset($this->params['named']['orgNameList']) ? $this->params['named']['orgNameList'] : null;
}
if (!is_null($recipient) && $recipient == 0) {
@ -2241,4 +2245,262 @@ class UsersController extends AppController
}
}
}
public function register()
{
if (empty(Configure::read('Security.allow_self_registration'))) {
throw new MethodNotAllowedException(__('Self registration is not enabled on this instance.'));
}
if ($this->request->is('post')) {
if (isset($this->request->data['User'])) {
$this->request->data = $this->request->data['User'];
}
$validKeys = array(
'email',
'org_name',
'org_uuid',
'message',
'custom_perms',
'perm_sync',
'perm_publish',
'perm_admin'
);
$requestObject = array();
foreach ($validKeys as $key) {
if (isset($this->request->data[$key])) {
$requestObject[$key] = trim($this->request->data[$key]);
}
}
if (empty($requestObject['email'])) {
throw new InvalidArgumentException(__('We require at least the email field to be filled.'));
}
$this->loadModel('Inbox');
$this->Inbox->create();
$data = array(
'Inbox' => array(
'title' => __('User registration for %s.', $requestObject['email']),
'type' => 'registration',
'comment' => $requestObject['message'],
'data' => json_encode($requestObject)
)
);
$result = $this->Inbox->save($data);
if (empty($result)) {
$message = __('Request could not be created. Make sure that the email and org name fields are filled.');
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Users', 'register', false, $message, $this->response->type());
} else {
$this->Flash->error($message);
}
} else {
$message = __('Request sent. The administrators of this community have been notified.');
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('User', 'register', false, $this->response->type(), $message);
} else {
$this->Flash->success($message);
$this->redirect('/');
}
}
} else {
$message = Configure::read('Security.self_registration_message');
if (empty($message)) {
$this->loadModel('Server');
$message = $this->Server->serverSettings['Security']['self_registration_message']['value'];
}
$this->set('message', $message);
}
}
public function registrations()
{
$this->loadModel('Inbox');
$params = array(
'recursive' => -1,
'conditions' => array(
'deleted' => 0,
'type' => 'registration'
),
'order' => array(
'timestamp desc'
)
);
$passedArgs = $this->passedArgs;
if (!empty($passedArgs['value'])) {
$lookup = strtolower($passedArgs['value']);
$allSearchFields = array('data', 'user_agent', 'ip');
foreach ($allSearchFields as $field) {
$params['conditions']['AND']['OR'][] = array('LOWER(Inbox.' . $field . ') LIKE' => '%' . $lookup . '%');
}
}
$this->set('passedArgs', json_encode($passedArgs));
if ($this->_isRest()) {
$data = $this->Inbox->find('all', array(
'recursive' => -1,
'conditions' => $params['conditions']
));
foreach ($data as $k => $v) {
$data[$k]['Inbox']['data'] = json_decode($data[$k]['Inbox']['data'], true);
}
return $this->RestResponse->viewData($data, $this->response->type());
} else {
$this->paginate = $params;
$data = $this->paginate('Inbox');
foreach ($data as $k => $message) {
$data[$k]['Inbox']['data'] = json_decode($data[$k]['Inbox']['data'], true);
$data[$k]['Inbox']['requested_role'] = __('default');
if (!empty($data[$k]['Inbox']['data']['custom_perms'])) {
$data[$k]['Inbox']['requested_role'] = array(
'perm_publish' => !empty($data[$k]['Inbox']['data']['perm_publish']) ? __('Yes') : __('No'),
'perm_sync' => !empty($data[$k]['Inbox']['data']['perm_sync']) ? __('Yes') : __('No'),
'perm_admin' => !empty($data[$k]['Inbox']['data']['perm_admin']) ? __('Yes') : __('No')
);
}
}
$this->set('data', $data);
}
}
public function discardRegistrations($id = false)
{
if (!$this->request->is('post') && !$this->request->is('delete')) {
$this->set('id', $id);
$this->set('type', 'discardRegistrations');
$this->render('ajax/discardRegistrations');
} else {
if (empty($id) && !empty($this->params['named']['id'])) {
$id = $this->params['named']['id'];
}
$this->loadModel('Inbox');
$registrations = $this->Inbox->find('all', array(
'recursive' => -1,
'conditions' => array(
'deleted' => 0,
'type' => 'registration',
'id' => $id
)
));
foreach ($registrations as $registration) {
$this->Inbox->delete($registration['Inbox']['id']);
}
$message = sprintf(
'%s registration(s) discarded.',
count($registrations)
);
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('User', 'discardRegistrations', false, $this->response->type(), $message);
} else {
$this->Flash->success($message);
$this->redirect(array('controller' => 'users', 'action' => 'registrations'));
}
}
}
public function acceptRegistrations($id = false)
{
if (empty($id) && !empty($this->params['named']['id'])) {
$id = $this->params['named']['id'];
}
$this->loadModel('Inbox');
$registrations = $this->Inbox->find('all', array(
'recursive' => -1,
'conditions' => array(
'deleted' => 0,
'type' => 'registration',
'id' => $id
)
));
$suggestedOrg = null;
$suggestedRole = null;
$orgCache = array();
foreach ($registrations as $k => $v) {
$registrations[$k]['Inbox']['data'] = json_decode($registrations[$k]['Inbox']['data'], true);
$roleRequirements = array();
if ($this->request->is('get')) {
$suggestedOrg = $this->User->Organisation->checkDesiredOrg($suggestedOrg, $registrations[$k]);
$suggestedRole = $this->User->Role->checkDesiredRole($suggestedRole, $registrations[$k]);
}
}
if ($this->request->is('get')) {
if (!is_array($id)) {
$id = array($id);
}
foreach ($id as $k => $v) {
$id[$k] = 'id[]:' . intval($v);
}
$roles_raw = $this->User->Role->find('all', array(
'recursive' => -1
));
//roles = id => name
$roles = array();
$role_perms = array();
foreach ($roles_raw as $role) {
$roles[$role['Role']['id']] = $role['Role']['name'];
$role_perms[$role['Role']['id']] = array(
'perm_publish' => $role['Role']['perm_publish'],
'perm_sync' => $role['Role']['perm_sync'],
'perm_admin' => $role['Role']['perm_admin']
);
}
$default_role = $this->User->Role->find('first', array(
'recursive' => -1,
'conditions' => array('Role.default_role' => 1),
'fields' => array('Role.id')
));
if (!empty($default_role)) {
$this->request->data['User']['role_id'] = $default_role['Role']['id'];
}
$this->set('roles', $roles);
$this->set('role_perms', $role_perms);
$orgConditions = array('OR' => array('local' => 1));
if (!empty($suggestedOrg)) {
$orgConditions['OR'][] = array('Organisation.id' => $suggestedOrg[0]);
}
$this->set('orgs', $this->User->Organisation->find('list', array(
'fields' => array('id', 'name'),
'recursive' => -1,
'conditions' => $orgConditions
)));
$this->set('registration', $registrations[$k]);
$this->set('suggestedOrg', $suggestedOrg);
$this->set('suggestedRole', $suggestedRole);
$id = implode('/', $id);
$this->set('id', $id);
$this->layout = false;
} else {
$results = array('successes' => 0, 'fails' => 0);
foreach ($registrations as $registration) {
$result = $this->User->registerUser(
$this->Auth->user(),
$registration['Inbox'],
$this->request->data['User']['org_id'],
$this->request->data['User']['role_id']
);
$results[($result ? 'successes' : 'fails')] += 1;
}
$message = array();
if (!empty($results['successes'])) {
$message[] = __('Added %s user(s).', $results['successes']);
}
if (!empty($results['fails'])) {
$message[] = __('Could not add %s user(s), reasons for the failure have been logged.', $results['fails']);
}
if (empty($message)) {
$message[] = __('No new users added - there was nothing to add.');
}
$message = implode(' ', $message);
if ($this->_isRest()) {
if (empty($results['fails']) && !empty($results['successes'])) {
return $this->RestResponse->saveSuccessResponse('User', 'acceptRegistrations', false, $this->response->type(), $message);
} else {
return $this->RestResponse->saveFailResponse('Users', 'acceptRegistrations', false, $message, $this->response->type());
}
} else {
if (empty($results['fails']) && !empty($results['successes'])) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'errors' => $message)), 'status'=>200, 'type' => 'json'));
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'success' => $message)), 'status'=>200, 'type' => 'json'));
}
}
}
}
}

@ -1 +1 @@
Subproject commit d2e1681eb8ec75e6c2819fa113834843fed6995a
Subproject commit 5ccb12354dfc08ca1b3e0a430e8668bf1610b5d3

View File

@ -77,7 +77,7 @@ class AppModel extends Model
27 => false, 28 => false, 29 => false, 30 => false, 31 => false, 32 => false,
33 => false, 34 => false, 35 => false, 36 => false, 37 => false, 38 => false,
39 => false, 40 => false, 41 => false, 42 => false, 43 => false, 44 => false,
45 => false, 46 => false, 47 => false, 48 => false, 49 => false
45 => false, 46 => false, 47 => false, 48 => false, 49 => false, 50 => false
);
public $advanced_updates_description = array(
@ -1349,6 +1349,29 @@ class AppModel extends Model
INDEX `restrict_to_permission_flag` (`restrict_to_permission_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
break;
case 50:
$sqlArray[] = "CREATE TABLE IF NOT EXISTS inbox (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) COLLATE utf8_bin NOT NULL,
`title` varchar(191) NOT NULL,
`type` varchar(191) NOT NULL,
`ip` varchar(191) NOT NULL,
`user_agent` text,
`user_agent_sha256` varchar(64) NOT NULL,
`comment` text,
`deleted` tinyint(1) NOT NULL DEFAULT 0,
`timestamp` int(11) NOT NULL,
`store_as_file` tinyint(1) NOT NULL DEFAULT 0,
`data` longtext,
PRIMARY KEY (id),
INDEX `title` (`title`),
INDEX `type` (`type`),
INDEX `uuid` (`uuid`),
INDEX `user_agent_sha256` (`user_agent_sha256`),
INDEX `ip` (`ip`),
INDEX `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
break;
case 'fixNonEmptySharingGroupID':
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';

28
app/Model/Inbox.php Normal file
View File

@ -0,0 +1,28 @@
<?php
App::uses('AppModel', 'Model');
class Inbox extends AppModel
{
public $useTable = 'inbox';
public $recursive = -1;
public $actsAs = array(
'Containable',
);
public $validate = array(
);
public function beforeValidate($options = array())
{
parent::beforeValidate();
$this->data['Inbox']['uuid'] = CakeText::uuid();
$this->data['Inbox']['timestamp'] = time();
$this->data['Inbox']['ip'] = $_SERVER['REMOTE_ADDR'];
$this->data['Inbox']['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
$this->data['Inbox']['user_agent_sha256'] = hash('sha256', $_SERVER['HTTP_USER_AGENT']);
return true;
}
}

View File

@ -21,6 +21,7 @@ class Log extends AppModel
array( // ensure that the length of the rules is < 20 in length
'accept',
'accept_delegation',
'acceptRegistrations',
'add',
'admin_email',
'auth',
@ -30,11 +31,13 @@ class Log extends AppModel
'delete',
'disable',
'discard',
'discardRegistrations',
'edit',
'email',
'enable',
'error',
'export',
'failed_registration',
'file_upload',
'galaxy',
'include_formula',

View File

@ -428,4 +428,32 @@ class Organisation extends AppModel
}
return array_values($orgIds);
}
public function checkDesiredOrg($suggestedOrg, $registration)
{
if ($suggestedOrg !== false && $suggestedOrg !== -1) {
$conditions = array();
if (!empty($registration['Inbox']['data']['org_uuid'])) {
$conditions = array('Organisation.uuid' => $registration['Inbox']['data']['org_uuid']);
} else if (!empty($registration['Inbox']['data']['org_name'])) {
$conditions = array('Organisation.name' => $registration['Inbox']['data']['org_name']);
} else {
$domain = explode('@', $registration['Inbox']['data']['email'])[1];
$conditions = array('LOWER(Organisation.name)' => strtolower($domain));
}
$identifiedOrg = $this->User->Organisation->find('first', array(
'recursive' => -1,
'fields' => array('id', 'name', 'local'),
'conditions' => $conditions
));
if (empty($identifiedOrg)) {
$suggestedOrg = -1;
} else if (!empty($suggestedOrg) && $suggestedOrg[0] !== $identifiedOrg['Organisation']['id']) {
$suggestedOrg = false;
} else {
$suggestedOrg = array($identifiedOrg['Organisation']['id'], $identifiedOrg['Organisation']['name'], $identifiedOrg['Organisation']['local']);
}
}
return $suggestedOrg;
}
}

View File

@ -254,4 +254,34 @@ class Role extends AppModel
}
return true;
}
/*
* Helper function to find out if a list of registrations has the same role requirements
* If no role requirements have been passed yet, null is assumed for $suggestedRole
* Returns an array with the permission flags required
*/
public function checkDesiredRole($suggestedRole, $registration)
{
if ($suggestedRole !== false) {
$currentRole = array();
$roleFlags = array('perm_publish', 'perm_admin', 'perm_sync');
foreach ($roleFlags as $roleFlag) {
if (isset($registration['Inbox']['data'][$roleFlag])) {
$currentRole[$roleFlag] = $registration['Inbox']['data'][$roleFlag];
}
}
if ($suggestedRole !== null) {
if (count($suggestedRole) != count($currentRole) || !empty(array_diff_key($suggestedRole, $currentRole))) {
return false;
}
foreach (array_keys($currentRole) as $perm) {
if ($currentRole[$perm] !== $suggestedRole[$perm]) {
return false;
}
}
}
return $currentRole;
}
return $suggestedRole;
}
}

View File

@ -1252,6 +1252,24 @@ class Server extends AppModel
'type' => 'boolean',
'null' => true
),
'allow_self_registration' => array(
'level' => 1,
'description' => __('Enabling this setting will allow users to have access to the pre-auth registration form. This will create an inbox entry for administrators to review.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean',
'null' => true
),
'self_registration_message' => array(
'level' => 1,
'bigField' => true,
'description' => __('The message sent shown to anyone trying to self-register.'),
'value' => 'If you would like to send us a registration request, please fill out the form below. Make sure you fill out as much information as possible in order to ease the task of the administrators.',
'errorMessage' => '',
'test' => false,
'type' => 'string'
),
'password_policy_length' => array(
'level' => 2,
'description' => __('Password length requirement. If it is not set or it is set to 0, then the default value is assumed (12).'),
@ -4533,7 +4551,7 @@ class Server extends AppModel
$field['column_name'],
$field['expected']['data_type'],
$length !== null ? sprintf('(%d)', $length) : '',
isset($field['expected']['column_default']) ? $field['expected']['column_default'] . '"' : '',
isset($field['expected']['column_default']) ? 'DEFAULT "' . $field['expected']['column_default'] . '"' : '',
$field['expected']['is_nullable'] === 'NO' ? 'NOT NULL' : 'NULL',
empty($field['expected']['collation_name']) ? '' : 'COLLATE ' . $field['expected']['collation_name']
);
@ -4777,7 +4795,7 @@ class Server extends AppModel
} else {
$keyLength = '';
}
$sql = sprintf('CREATE INDEX `%s` ON `%s` (%s%s);',
$sql = sprintf('CREATE INDEX `%s` ON `%s` (`%s`%s);',
$columnDiff,
$tableName,
$columnDiff,

View File

@ -1502,4 +1502,59 @@ class User extends AppModel
}
Configure::write('Security.monitored', 0);
}
public function registerUser($added_by, $registration, $org_id, $role_id) {
$user = array(
'email' => $registration['data']['email'],
'gpgkey' => empty($registration['data']['pgp']) ? '' : $registration['data']['pgp'],
'disabled' => 0,
'newsread' => 0,
'change_pw' => 1,
'authkey' => $this->generateAuthKey(),
'termsaccepted' => 0,
'org_id' => $org_id,
'role_id' => $role_id,
'invited_by' => $added_by['id'],
'contactalert' => 1,
'autoalert' => Configure::check('MISP.default_publish_alert') ? Configure::read('MISP.default_publish_alert') : 1
);
$this->create();
$this->Log = ClassRegistry::init('Log');
$result = $this->save(array('User' => $user));
$currentOrg = $this->Organisation->find('first', array(
'recursive' => -1,
'conditions' => array('Organisation.id' => $org_id)
));
if (!empty($currentOrg) && empty($currentOrg['Organisation']['local'])) {
$currentOrg['Organisation']['local'] = 1;
$this->Organisation->save($currentOrg);
}
if (empty($result)) {
$error = array();
foreach ($this->validationErrors as $key => $errors) {
$error[$key] = $key . ': ' . implode(', ', $errors);
}
$error = implode(PHP_EOL, $error);
$this->Log->save(array(
'org' => 'SYSTEM',
'model' => 'User',
'model_id' => $added_by['id'],
'email' => $added_by['email'],
'action' => 'failed_registration',
'title' => 'User registration failed for ' . $user['email'] . '. Reason(s): ' . $error,
'change' => null,
));
return false;
} else {
$user = $this->find('first', array(
'recursive' => -1,
'conditions' => array('id' => $this->id)
));
$this->initiatePasswordReset($user, true, true, false);
$this->Inbox = ClassRegistry::init('Inbox');
$this->Inbox->delete($registration['id']);
return true;
}
}
}

View File

@ -58,6 +58,14 @@
array(
'name' => __('Description'),
'data_path' => 'description',
),
array(
'name' => __('Self-reg'),
'element' => 'self_registration',
'class' => 'short',
'title' => __('This community allows for self-registration'),
'data_path' => 'url',
'data_path_requirement' => 'self_registration'
)
),
'title' => __('Communities index'),

View File

@ -17,7 +17,7 @@
h($data['model']);
$fieldsString = '';
$simpleFieldWhitelist = array(
'default', 'type', 'options', 'placeholder', 'label', 'empty', 'rows', 'div'
'default', 'type', 'options', 'placeholder', 'label', 'empty', 'rows', 'div', 'required'
);
$fieldsArrayForPersistence = array();
$formCreate = $this->Form->create($modelForForm);
@ -116,10 +116,12 @@
);
} else {
echo sprintf(
'<div class="form">%s<fieldset><legend>%s</legend>%s%s</fieldset>%s%s%s</div>',
'<div class="%s">%s<fieldset><legend>%s</legend>%s<div class="clear" style="padding-bottom:10px;">%s</div>%s</fieldset>%s%s%s</div>',
empty($data['skip_side_menu']) ? 'form' : 'menuless-form',
$formCreate,
empty($data['title']) ? h(Inflector::humanize($this->request->params['action'])) . ' ' . $modelForForm : h($data['title']),
$ajaxFlashMessage,
empty($data['description']) ? '' : $data['description'],
$fieldsString,
$formEnd,
$metaFieldString,

View File

@ -1,7 +1,15 @@
<?php
$data = Hash::extract($row, $field['data_path']);
foreach ($data as &$element) {
$element = h($element);
foreach ($data as $key => $element) {
if (!is_numeric($key)) {
$data[$key] = sprintf(
'<span>%s</span>: %s',
h($key),
h($element)
);
} else {
$data[$key] = h($element);
}
}
$data = implode('<br />', $data);
echo $data;

View File

@ -14,8 +14,8 @@
$i = 0;
foreach ($orgs as $org) {
$i++;
if (!empty($org['id'])) {
if ($field['fields']['allow_picture']) {
if (!empty($org['id']) || !empty($org['name'])) {
if ($field['fields']['allow_picture'] && !empty($org['id'])) {
echo $this->OrgImg->getOrgImg(array('name' => $org['name'], 'id' => $org['id'], 'size' => 24));
} else {
echo sprintf(

View File

@ -0,0 +1,17 @@
<?php
$self_registration_flag = Hash::extract($row, $field['data_path_requirement']);
if (empty($self_registration_flag[0])) {
echo '<i class="black fa fa-times"></i>';
} else {
$url = Hash::extract($row, $field['data_path'])[0];
echo sprintf(
'<i class="black fa fa-%s"></i>%s',
(!empty($self_registration_flag[0])) ? 'check' : 'times',
(empty($self_registration_flag[0])) ? '' :
sprintf(
' (<a href="%s/users/register">' . __('click here') . '</a>)',
h($url)
)
);
}
?>

View File

@ -1,3 +1,7 @@
<?php
echo h(Hash::extract($row, $field['data_path'])[0]);
$timestamp = Hash::extract($row, $field['data_path'])[0];
if (!empty($field['time_format'])) {
$timestamp = date($field['time_format'], $timestamp);
}
echo h($timestamp);
?>

View File

@ -12,7 +12,7 @@
} else {
if (!empty($header['element']) && $header['element'] === 'selector') {
$header_data = sprintf(
'<input class="%s" type="checkbox" %s>',
'<input id="select_all" class="%s" type="checkbox" %s>',
empty($header['select_all_class']) ? 'select_all' : $header['select_all_class'],
empty($header['select_all_function']) ? 'onclick="toggleAllAttributeCheckboxes();"' : 'onclick="' . $header['select_all_function'] . '"'
);
@ -38,3 +38,14 @@
$thead .= '</thead>';
echo $thead;
?>
<script type="text/javascript">
$(document).ready(function() {
$('.select_attribute').add('#select_all').on('change', function() {
if ($('.select_attribute:checked').length > 0) {
$('.mass-select').show();
} else {
$('.mass-select').hide();
}
});
});
</script>

View File

@ -734,6 +734,11 @@
'url' => '/admin/users/index',
'text' => __('List Users')
));
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'registrations',
'url' => '/users/registrations',
'text' => __('Pending registrations')
));
}
if ($isAdmin) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
@ -773,13 +778,16 @@
),
'text' => __('Merge Organisation')
));
}
if ($menuItem === 'editOrg' || $menuItem === 'viewOrg') {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'viewOrg',
'url' => '/organisations/view/' . h($id),
'text' => __('View Organisation')
));
echo $this->element('/genericElements/SideMenu/side_menu_post_link', array(
'url' => '/admin/organisations/delete/' . h($id),
'text' => __('Delete Organisation'),
'message' => __('Are you sure you want to delete # %s?', h($id))
));
}
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'indexOrg',
@ -804,6 +812,10 @@
'url' => '/servers/serverSettings',
'text' => __('Server Settings & Maintenance')
));
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => '/inbox',
'text' => __('Inbox')
));
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => '/servers/updateProgress',
'text' => __('Update Progress')

View File

@ -304,6 +304,10 @@
'text' => __('Contact Users'),
'url' => '/admin/users/email'
),
array(
'text' => __('User Registrations'),
'url' => '/users/registrations'
),
array(
'type' => 'separator'
),

64
app/View/Inbox/index.ctp Normal file
View File

@ -0,0 +1,64 @@
<?php
echo '<div class="index">';
echo $this->element('/genericElements/IndexTable/index_table', array(
'data' => array(
'data' => $data,
'top_bar' => array(
'children' => array(
array(
'type' => 'search',
'button' => __('Filter'),
'placeholder' => __('Enter value to search'),
'data' => '',
'searchKey' => 'value'
)
)
),
'fields' => array(
array(
'name' => __('Id'),
'sort' => 'id',
'class' => 'short',
'data_path' => 'Inbox.id',
),
array(
'name' => __('Type'),
'sort' => 'type',
'class' => 'short',
'data_path' => 'Inbox.type',
),
array(
'name' => __('Title'),
'sort' => 'Inbox.title',
'data_path' => 'Inbox.title',
),
array(
'name' => __('Comment'),
'data_path' => 'Inbox.comment',
)
),
'title' => __('Instance inbox'),
'description' => __('You can find messages sent to this instance in the following list. Type denotes the type of request (such as registration). View each entry to see more details about the request\'s contents.'),
'actions' => array(
array(
'url' => '/inbox/view',
'url_params_data_paths' => array(
'Inbox.uuid'
),
'icon' => 'eye'
),
array(
'url' => '/inbox/delete',
'url_params_data_paths' => array(
'Inbox.uuid'
),
'postLink' => 1,
'postLinkConfirm' => __('Are you sure you want to delete the message from the inbox?'),
'icon' => 'trash'
)
)
)
));
echo '</div>';
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'administration', 'menuItem' => 'inbox'));
?>

View File

@ -0,0 +1,112 @@
<?php
$suggestedOrgText = __('No preference');
$suggestedRoleText = '';
$domain = explode('@', $registration['Inbox']['data']['email'])[1];
if ($suggestedOrg !== null) {
if ($suggestedOrg === false) {
$suggestedOrgText = '<br />&nbsp;&nbsp;<span class="bold red">' . __('Conflicting requirements') . '</span>';
} else if ($suggestedOrg === -1){
$suggestedOrgText = sprintf(
'<span class="red">%s%s%s</span>%s <a href="%s/admin/organisations/add%s%s%s" class="black fas fa-plus" title="%s"></a>',
(empty($registration['Inbox']['data']['org_name']) && empty($registration['Inbox']['data']['org_uuid'])) ? h($domain) . ' ' : '',
empty($registration['Inbox']['data']['org_name']) ? '' : h($registration['Inbox']['data']['org_name']) . ' ',
empty($registration['Inbox']['data']['org_uuid']) ? '' : h($registration['Inbox']['data']['org_uuid']) . ' ',
__('Requested organisation not found.'),
$baseurl,
(empty($registration['Inbox']['data']['org_name']) && empty($registration['Inbox']['data']['org_uuid'])) ? '/name:' . h($domain) : '',
empty($registration['Inbox']['data']['org_name']) ? '' : '/name:' . h($registration['Inbox']['data']['org_name']),
empty($registration['Inbox']['data']['org_uuid']) ? '' : '/uuid:' . h($registration['Inbox']['data']['org_uuid']),
__('Create a new organisation')
);
} else {
$suggestedOrgText = sprintf(
'<span class="bold %s">(%s)%s</span>%s',
$suggestedOrg[2] ? 'green' : 'orange',
h($suggestedOrg[0]),
h($suggestedOrg[1]),
$suggestedOrg[2] ? '' : ' - <span class="red bold">' . __('known remote organisation, will be converted to local') . '</span>'
);
}
}
if ($suggestedRole !== null) {
if ($suggestedRole === false) {
$suggestedRoleText = '<br />&nbsp;&nbsp;<span class="bold red">' . __('Conflicting requirements') . '</span>';
} else {
foreach ($suggestedRole as $perm_flag => $perm_flag_value) {
$perm_flag_name = substr($perm_flag, 5);
if ($perm_flag_value) {
$suggestedRoleText .= sprintf(
'<br />&nbsp;&nbsp;<span class="perm-requirements bold" data-perm="%s" data-value="%s">%s</span> ',
h($perm_flag_name),
$perm_flag_value ? '1' : '0',
h($perm_flag_name)
);
}
}
}
} else {
$suggestedRoleText = '<br />&nbsp;&nbsp;<span class="bold red">' . __('No preference') . '</span>';
}
$description = __(
"The requested details were as follows\n\nOrganisation:\n&nbsp;&nbsp;%s\nRole: %s\n\n",
$suggestedOrgText,
$suggestedRoleText
);
echo $this->element('genericElements/Form/genericForm', array(
'form' => $this->Form,
'data' => array(
'title' => __('Accept registrations'),
'description' => nl2br($description),
'model' => 'User',
'fields' => array(
array(
'field' => 'org_id',
'label' => __('Organisation'),
'class' => 'input-xxlarge',
'required' => 1,
'options' => $orgs,
'default' => empty($suggestedOrg[0]) ? false : $suggestedOrg[0]
),
array(
'field' => 'role_id',
'label' => __('Role'),
'class' => 'input-xxlarge',
'required' => 1,
'options' => $roles
)
),
'submit' => array(
'ajaxSubmit' => sprintf(
'submitPopoverForm(%s, %s, 0, 1)',
"'acceptUserRegistrations'",
"' . $id . '"
)
)
)
));
?>
</div>
<script type="text/javascript">
var role_perms = <?= json_encode($role_perms) ?>;
function checkPermConditions() {
var selectedRole = $('#UserRoleId').val();
var selectedRoleDetails = role_perms[selectedRole];
$.each($('.perm-requirements'), function() {
if (selectedRoleDetails["perm_" + $(this).data('perm')] != $(this).data('value')) {
$(this).removeClass('green');
$(this).addClass('red');
$(this).attr('title', '<?= __("The selected Role does not satisfy the user request") ?>')
} else {
$(this).removeClass('red');
$(this).addClass('green');
$(this).attr('title', '<?= __("The selected Role satisfies the user request") ?>')
}
});
}
$(document).ready(function() {
checkPermConditions();
$('#UserRoleId').on('change', function() {
checkPermConditions();
});
});
</script>

View File

@ -76,10 +76,10 @@ $(document).ready(function() {
// Confirm before submit
$('#UserAdminEmailForm').submit(function(e) {
var url = '<?php echo $baseurl; ?>/admin/users/email/true?';
url += 'recipient=' + $('#recipient').val();
url += '&recipientEmailList=' + $('#UserRecipientEmailList').val();
url += '&orgNameList=' + $('#UserOrgNameList').val();
var url = '<?php echo $baseurl; ?>/admin/users/email/true';
url += '/recipient:' + $('#recipient').val();
url += '/recipientEmailList:' + $('#UserRecipientEmailList').val();
url += '/orgNameList:' + $('#UserOrgNameList').val();
$.get(url, function(data) {
$("#confirmation_box").html(data);
openPopup("#confirmation_box");

View File

@ -0,0 +1,15 @@
<?php
echo $this->element('genericElements/Form/genericForm', array(
'form' => $this->Form,
'data' => array(
'title' => __('Discard User Registrations'),
'model' => 'User',
'fields' => array(
),
'description' => __('Are you sure you wish to remove the registration request(s) selected?'),
'submit' => array(
'ajaxSubmit' => "$('#UserDiscardRegistrationsForm').submit();"
)
)
));
?>

View File

@ -39,16 +39,22 @@
echo $this->Form->input('email', array('autocomplete' => 'off', 'autofocus'));
echo $this->Form->input('password', array('autocomplete' => 'off'));
?>
<div class="clear"></div>
<div class="clear">
<?php
echo empty(Configure::read('Security.allow_self_registration')) ? '' : sprintf(
'<a href="%s/users/register" title="%s">%s</span>',
$baseurl,
__('Registration will be sent to the administrators of the instance for consideration.'),
__('No account yet? Register now!')
);
?>
</div>
<?php
echo $this->Form->button(__('Login'), array('class' => 'btn btn-primary'));
echo $this->Form->end();
if (true == Configure::read('ApacheShibbAuth')):
?>
<div class="clear"></div>
<a class="btn btn-info" href="/Shibboleth.sso/Login">Login with SAML</a>
<?php
endif;
if (Configure::read('ApacheShibbAuth') == true) {
echo '<div class="clear"></div><a class="btn btn-info" href="/Shibboleth.sso/Login">Login with SAML</a>';
}
?>
</td>
<td style="width:250px;padding-left:50px">

View File

@ -0,0 +1,81 @@
<?php
echo $this->element('genericElements/Form/genericForm', array(
'form' => $this->Form,
'data' => array(
'description' => nl2br(h($message)),
'title' => __('Register for a new user account'),
'model' => 'User',
'skip_side_menu' => 1,
'fields' => array(
array(
'field' => 'email',
'label' => __('Your email address'),
'class' => 'input-xxlarge',
'required' => 1
),
array(
'field' => 'org_name',
'label' => __('Your organisation\'s name (optional)'),
'class' => 'input-xxlarge'
),
array(
'field' => 'org_uuid',
'label' => __('Your MISP org uuid (optional)'),
'class' => 'input-xxlarge'
),
array(
'field' => 'custom_perms',
'type' => 'checkbox',
'label' => __("Request custom role")
),
array(
'field' => 'perm_publish',
'type' => 'checkbox',
'label' => __("Publish permission"),
'class' => 'role-field',
'hidden' => 1
),
array(
'field' => 'perm_admin',
'type' => 'checkbox',
'label' => __("Org admin permission"),
'class' => 'role-field',
'hidden' => 1
),
array(
'field' => 'perm_sync',
'type' => 'checkbox',
'class' => 'role-field',
'label' => __("Sync permission"),
'hidden' => 1
),
array(
'field' => 'pgp',
'label' => __('PGP key (optional)'),
'class' => 'input-xxlarge',
'type' => 'textarea'
),
array(
'field' => 'message',
'label' => __('Message to the admins'),
'class' => 'input-xxlarge',
'type' => 'textarea'
)
),
'submit' => array(
'action' => $this->request->params['action']
)
)
));
?>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#UserCustomPerms').change(function() {
if ($('#UserCustomPerms').prop("checked") != true) {
$('.role-field').prop("checked", false)
}
$('.role-field').parent().parent().toggleClass('hidden');
});
});
</script>

View File

@ -0,0 +1,147 @@
<?php
echo '<div class="index">';
echo $this->element('/genericElements/IndexTable/index_table', array(
'data' => array(
'data' => $data,
'top_bar' => array(
'children' => array(
array(
'children' => array(
array(
'fa-icon' => 'check',
'title' => __('Process the selected registrations'),
'id' => 'multi-accept-button',
'class' => 'btn btn-small btn-inverse mass-select hidden'
),
array(
'fa-icon' => 'times',
'title' => __('Discard the selected registrations'),
'id' => 'multi-discard-button',
'class' => 'btn btn-small btn-inverse mass-select hidden'
)
)
),
array(
'type' => 'search',
'button' => __('Filter'),
'placeholder' => __('Enter value to search'),
'data' => '',
'searchKey' => 'value'
)
)
),
'fields' => array(
array(
'element' => 'selector',
'class' => 'short'
),
array(
'name' => __('Id'),
'class' => 'short',
'data_path' => 'Inbox.id',
),
array(
'name' => __('Time'),
'class' => 'short',
'element' => 'timestamp',
'time_format' => 'Y-m-d H:i:s',
'data_path' => 'Inbox.timestamp',
),
array(
'name' => __('IP'),
'class' => 'short',
'data_path' => 'Inbox.ip',
),
array(
'name' => __('User Agent'),
'class' => 'shortish',
'data_path' => 'Inbox.user_agent',
),
array(
'name' => __('Email'),
'class' => 'short',
'data_path' => 'Inbox.data.email',
),
array(
'name' => __('Org'),
'class' => 'short',
'data_path' => 'Inbox.data.org_name',
),
array(
'name' => __('Org uuid'),
'class' => 'shortish',
'data_path' => 'Inbox.data.org_uuid',
),
array(
'name' => __('Requested role'),
'class' => 'short',
'element' => 'list',
'data_path' => 'Inbox.requested_role',
),
array(
'name' => __('PGP'),
'class' => 'short',
'element' => 'boolean',
'data_path' => 'Inbox.data.pgp'
),
array(
'name' => __('Comment'),
'data_path' => 'Inbox.comment',
)
),
'title' => __('Registrations index'),
'description' => __('You can find messages sent to this instance in the following list. Type denotes the type of request (such as registration). View each entry to see more details about the request\'s contents.'),
'actions' => array(
array(
'onclick' => sprintf(
'openGenericModal(\'%s/users/acceptRegistrations/[onclick_params_data_path]\')',
$baseurl
),
'onclick_params_data_path' => 'Inbox.id',
'icon' => 'check',
'title' => __('Process registration')
),
array(
'onclick' => sprintf(
'openGenericModal(\'%s/users/discardRegistrations/[onclick_params_data_path]\')',
$baseurl
),
'onclick_params_data_path' => 'Inbox.id',
'icon' => 'times',
'title' => __('Discard registration')
)
)
)
));
echo '</div>';
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'admin', 'menuItem' => 'registrations'));
?>
<script type="text/javascript">
var passedArgsArray = <?php echo $passedArgs; ?>;
function handleInboxMultiActions(action) {
var selectedInboxIds = '';
$.each($('.select_attribute:checked'), function() {
selectedInboxIds += "/id[]:" + ($(this).parent().parent().find('[data-path="Inbox.id"]').text());
});
if (selectedInboxIds.length >= 1) {
openGenericModal(baseurl + "/users/" + action + selectedInboxIds)
}
}
$(document).ready(function() {
$('#multi-accept-button').on('click', function() {
handleInboxMultiActions("acceptRegistrations");
});
$('#multi-discard-button').on('click', function() {
handleInboxMultiActions("discardRegistrations");
});
$('#quickFilterButton').click(function() {
runIndexQuickFilter();
});
$('#quickFilterField').on('keypress', function (e) {
if(e.which === 13) {
runIndexQuickFilter();
}
});
});
</script>

View File

@ -92,5 +92,21 @@
"pgp_key": "\r\n\r\n-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\n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\r\nWw==\r\n=4aXp\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n",
"misp_project_vetted": true,
"scope_of_data_to_be_shared": "Information Operation Threat Intelligence including disinformation, indicators, threat intelligence information, reports, contextual threat actor information or financial fraud information."
},
{
"name": "COVID-19 MISP community",
"uuid": "5e59659e-8e24-4e5d-b3fa-2ba744b7dd05",
"org_uuid": "55f6e5ae-2c60-40e5-964f-47a8950d210f",
"org_name": "CIRCL",
"description": "A community for tracking both health and cyber threat related information around COVID-19.",
"url": "https://covid-19.iglocska.eu",
"sector": "undefined",
"nationality": "International",
"type": "Open topical community",
"email": "info@circl.lu",
"pgp_key": "\r\n\r\n-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\n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\r\nxJlLUC2lY9a62qs8kTCX88338AuN\r\n=+5Rm\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n",
"misp_project_vetted": true,
"scope_of_data_to_be_shared": "Anything around COVID-19 that might help the community.",
"self_registration": true
}
]

@ -1 +1 @@
Subproject commit bad8b17fffd059f8fd739ce16fc885d79e749022
Subproject commit 28687d90d575332776480cd5d683361e7485033c

View File

@ -191,6 +191,13 @@ div.actions {
width:170px;
}
div.menuless-form {
padding: 10px;
padding-bottom:40px;
margin: 0 auto;
width:550px;
}
div.actions h3 {
padding-top:0;

View File

@ -1201,7 +1201,7 @@ function openGenericModalPost(url, body) {
});
}
function submitPopoverForm(context_id, referer, update_context_id, modal, popover_dissmis_id_to_close) {
function submitPopoverForm(context_id, referer, update_context_id, modal, popover_dismiss_id_to_close) {
var url = null;
var context = 'event';
var contextNamingConvention = 'Attribute';
@ -1241,8 +1241,11 @@ function submitPopoverForm(context_id, referer, update_context_id, modal, popove
url = "/objectReferences/add/" + context_id;
break;
case 'quickAddAttributeForm':
url = "/objects/quickAddAttributeForm/" + context_id;
break;
url = "/objects/quickAddAttributeForm/" + context_id;
break;
case 'acceptUserRegistrations':
url = "/users/acceptRegistrations/" + context_id
break;
}
if ($("#submitButton").parent().hasClass('modal-footer')) {
var $form = $("#submitButton").parent().parent().find('.modal-body form');
@ -1261,8 +1264,8 @@ function submitPopoverForm(context_id, referer, update_context_id, modal, popove
if (closePopover) {
$("#gray_out").fadeOut();
$("#popover_form").fadeOut();
if (popover_dissmis_id_to_close !== undefined) {
$('[data-dismissid="' + popover_dissmis_id_to_close + '"]').popover('destroy');
if (popover_dismiss_id_to_close !== undefined) {
$('[data-dismissid="' + popover_dismiss_id_to_close + '"]').popover('destroy');
}
$(".loading").show();
}

View File

@ -1649,6 +1649,16 @@
"column_type": "int(11)",
"column_default": null
},
{
"column_name": "uuid",
"is_nullable": "NO",
"data_type": "varchar",
"character_maximum_length": "255",
"numeric_precision": null,
"collation_name": "utf8_bin",
"column_type": "varchar(255)",
"column_default": ""
},
{
"column_name": "collection_uuid",
"is_nullable": "NO",
@ -1738,16 +1748,6 @@
"collation_name": null,
"column_type": "int(11)",
"column_default": "0"
},
{
"column_name": "uuid",
"is_nullable": "NO",
"data_type": "varchar",
"character_maximum_length": "255",
"numeric_precision": null,
"collation_name": "utf8_bin",
"column_type": "varchar(255)",
"column_default": ""
}
],
"galaxy_elements": [
@ -1854,6 +1854,128 @@
"column_default": null
}
],
"inbox": [
{
"column_name": "id",
"is_nullable": "NO",
"data_type": "int",
"character_maximum_length": null,
"numeric_precision": "10",
"collation_name": null,
"column_type": "int(11)",
"column_default": null
},
{
"column_name": "uuid",
"is_nullable": "NO",
"data_type": "varchar",
"character_maximum_length": "40",
"numeric_precision": null,
"collation_name": "utf8_bin",
"column_type": "varchar(40)",
"column_default": null
},
{
"column_name": "title",
"is_nullable": "NO",
"data_type": "varchar",
"character_maximum_length": "191",
"numeric_precision": null,
"collation_name": "utf8mb4_general_ci",
"column_type": "varchar(191)",
"column_default": null
},
{
"column_name": "type",
"is_nullable": "NO",
"data_type": "varchar",
"character_maximum_length": "191",
"numeric_precision": null,
"collation_name": "utf8mb4_general_ci",
"column_type": "varchar(191)",
"column_default": null
},
{
"column_name": "ip",
"is_nullable": "NO",
"data_type": "varchar",
"character_maximum_length": "191",
"numeric_precision": null,
"collation_name": "utf8mb4_general_ci",
"column_type": "varchar(191)",
"column_default": null
},
{
"column_name": "user_agent",
"is_nullable": "YES",
"data_type": "text",
"character_maximum_length": "65535",
"numeric_precision": null,
"collation_name": "utf8mb4_general_ci",
"column_type": "text",
"column_default": null
},
{
"column_name": "user_agent_sha256",
"is_nullable": "NO",
"data_type": "varchar",
"character_maximum_length": "64",
"numeric_precision": null,
"collation_name": "utf8mb4_general_ci",
"column_type": "varchar(64)",
"column_default": null
},
{
"column_name": "comment",
"is_nullable": "YES",
"data_type": "text",
"character_maximum_length": "65535",
"numeric_precision": null,
"collation_name": "utf8mb4_general_ci",
"column_type": "text",
"column_default": null
},
{
"column_name": "deleted",
"is_nullable": "NO",
"data_type": "tinyint",
"character_maximum_length": null,
"numeric_precision": "3",
"collation_name": null,
"column_type": "tinyint(1)",
"column_default": "0"
},
{
"column_name": "timestamp",
"is_nullable": "NO",
"data_type": "int",
"character_maximum_length": null,
"numeric_precision": "10",
"collation_name": null,
"column_type": "int(11)",
"column_default": null
},
{
"column_name": "store_as_file",
"is_nullable": "NO",
"data_type": "tinyint",
"character_maximum_length": null,
"numeric_precision": "3",
"collation_name": null,
"column_type": "tinyint(1)",
"column_default": "0"
},
{
"column_name": "data",
"is_nullable": "YES",
"data_type": "longtext",
"character_maximum_length": "4294967295",
"numeric_precision": null,
"collation_name": "utf8mb4_general_ci",
"column_type": "longtext",
"column_default": null
}
],
"jobs": [
{
"column_name": "id",
@ -6162,12 +6284,12 @@
"galaxy_clusters": [
"id",
"value",
"uuid",
"collection_uuid",
"galaxy_id",
"version",
"tag_name",
"type",
"uuid",
"collection_uuid"
"type"
],
"galaxy_elements": [
"id",
@ -6182,6 +6304,15 @@
"referenced_galaxy_cluster_value",
"referenced_galaxy_cluster_type"
],
"inbox": [
"id",
"title",
"type",
"uuid",
"user_agent_sha256",
"ip",
"timestamp"
],
"jobs": [
"id"
],
@ -6273,8 +6404,8 @@
"servers": [
"id",
"org_id",
"remote_org_id",
"priority"
"priority",
"remote_org_id"
],
"shadow_attribute_correlations": [
"id",
@ -6426,5 +6557,5 @@
"id"
]
},
"db_version": "49"
"db_version": "50"
}