mirror of https://github.com/MISP/MISP
291 lines
14 KiB
PHP
291 lines
14 KiB
PHP
<?php
|
|
|
|
App::uses('AppController', 'Controller');
|
|
|
|
/**
|
|
* Posts Controller
|
|
*
|
|
*/
|
|
class PostsController extends AppController
|
|
{
|
|
public $components = array(
|
|
'Security',
|
|
'Session',
|
|
'RequestHandler'
|
|
);
|
|
|
|
public $paginate = array(
|
|
'limit' => 60,
|
|
);
|
|
|
|
public function pushMessageToZMQ($message = null)
|
|
{
|
|
if (Configure::read("Plugin.ZeroMQ_enable")) {
|
|
$pubSubTool = $this->Post->getPubSubTool();
|
|
$pubSubTool->publishConversation($message);
|
|
}
|
|
}
|
|
|
|
// Find the thread_id and post_id in advance. If a user clicks post comment on the event view, send the event's related thread's ID
|
|
// Usage:
|
|
// /posts/add : Creates new thread with the added post as the first post. Title set by user
|
|
// /posts/add/event/id : Checks if the event already has a thread, if no it creates one. The post is added to the event's thread
|
|
// /posts/add/thread/id : Adds a post to the thread specified
|
|
// /posts/add/post/id : Adds a post as a reply to another post. The system finds the appropriate thread, adds the post to the thread and links to the post that is being replied to.
|
|
public function add($target_type = null, $target_id = null, $quick = false)
|
|
{
|
|
$this->loadModel('Thread');
|
|
$this->Thread->recursive = -1;
|
|
$distribution = 1;
|
|
$event_id = 0;
|
|
$post_id = 0;
|
|
if ($this->request->is('ajax')) {
|
|
$this->layout = 'ajax';
|
|
}
|
|
// we have a target type and a target id. The target id defines what type of object we want to attach this event to (is it a reply to another post,
|
|
// did someone add a post to a thread, does a thread for the event exist already, etc.
|
|
switch ($target_type) {
|
|
case 'event':
|
|
$this->loadModel('Event');
|
|
$event = $this->Event->fetchSimpleEvent($this->Auth->user(), $target_id);
|
|
if (!$event) {
|
|
throw new NotFoundException(__('Invalid event'));
|
|
}
|
|
$eventDiscussionTitle = __('Discussion about Event #%s (%s)', $event['Event']['id'], $event['Event']['info']);
|
|
$thread = $this->Thread->find('first', array('conditions' => array('event_id' => $event['Event']['id'])));
|
|
$title = $eventDiscussionTitle;
|
|
if (isset($thread['Thread']['id'])) {
|
|
$target_thread_id = $thread['Thread']['id'];
|
|
} else {
|
|
$target_thread_id = null;
|
|
}
|
|
$distribution = $event['Event']['distribution'];
|
|
$sgid = $event['Event']['sharing_group_id'];
|
|
$event_id = $event['Event']['id'];
|
|
break;
|
|
case 'thread':
|
|
$target_thread_id = $target_id;
|
|
if ($target_id != null) {
|
|
$thread = $this->Thread->read(null, $target_thread_id);
|
|
if ($thread == null) {
|
|
throw new NotFoundException(__('Invalid thread'));
|
|
}
|
|
if (!$this->_isSiteAdmin()) {
|
|
if ($thread['Thread']['distribution'] == 0 && $this->Auth->user('org_id') != $thread['Thread']['org_id']) {
|
|
throw new MethodNotAllowedException(__('You don\'t have permission to do that.'));
|
|
}
|
|
}
|
|
$title = $this->Thread->data['Thread']['title'];
|
|
$event_id = $this->Thread->data['Thread']['event_id'];
|
|
}
|
|
break;
|
|
case 'post':
|
|
$this->Post->read(null, $target_id);
|
|
$target_thread_id = $this->Post->data['Post']['thread_id'];
|
|
$thread = $this->Thread->read(null, $target_thread_id);
|
|
if (!$this->_isSiteAdmin()) {
|
|
if ($thread['Thread']['distribution'] == 0 && $this->Auth->user('org_id') != $thread['Thread']['org_id']) {
|
|
throw new MethodNotAllowedException(('You don\'t have permission to do that.'));
|
|
}
|
|
}
|
|
$title = $this->Thread->data['Thread']['title'];
|
|
$previousPost = $this->_grabPreviousPost($target_id);
|
|
$distribution = $previousPost['Thread']['distribution'];
|
|
$sgid = $previousPost['Thread']['sharing_group_id'];
|
|
$event_id = $previousPost['Thread']['event_id'];
|
|
$post_id = $target_id;
|
|
$target_thread_id = $previousPost['Thread']['id'];
|
|
|
|
break;
|
|
default:
|
|
$target_thread_id = null;
|
|
break;
|
|
}
|
|
if ($this->request->is('post')) {
|
|
if (empty($this->request->data['Post']['message'])) {
|
|
throw new MethodNotAllowedException(__('Cannot post an empty message.'));
|
|
}
|
|
// Set the default values that we'll alter before actually saving data. These are the default values unless specifically modified.
|
|
// By default, all discussions will be visibile to everyone on the platform
|
|
|
|
// Set the title if it is setable in the add view.
|
|
if (empty($thread_id) && empty($target_type)) {
|
|
$title = $this->request->data['Post']['title'];
|
|
}
|
|
|
|
if ($target_thread_id == null) {
|
|
// We have a post that was posted in a new thread. This could also mean that someone created the first post related to an event!
|
|
$this->Thread->create();
|
|
// Take the title from above if we are adding a post to an event.
|
|
if ($target_type === 'event') {
|
|
$title = $eventDiscussionTitle;
|
|
}
|
|
$newThread = array(
|
|
'date_created' => date('Y/m/d H:i:s'),
|
|
'date_modified' => date('Y/m/d H:i:s'),
|
|
'user_id' => $this->Auth->user('id'),
|
|
'event_id' => $event_id,
|
|
'title' => $title,
|
|
'distribution' => isset($distribution) ? $distribution : 1,
|
|
'sharing_group_id' => isset($sgid) ? $sgid : 0,
|
|
'post_count' => 1,
|
|
'org_id' => $this->Auth->user('org_id')
|
|
);
|
|
if ($this->Thread->save($newThread)) {
|
|
$newThread['org_name'] = $this->Auth->user('Organisation')['name'];
|
|
$newThread['user_email'] = $this->Auth->user('email');
|
|
$this->pushMessageToZMQ(array("Thread" => $newThread));
|
|
}
|
|
$target_thread_id = $this->Thread->getId();
|
|
} else {
|
|
// In this case, we have a post that was posted in an already existing thread. Update the thread!
|
|
$this->Thread->read(null, $target_thread_id);
|
|
$this->Thread->data['Thread']['date_modified'] = date('Y/m/d H:i:s');
|
|
$this->Thread->save();
|
|
}
|
|
// Time to create our post!
|
|
$this->Post->create();
|
|
$newPost = array(
|
|
'date_created' => date('Y/m/d H:i:s'),
|
|
'date_modified' => date('Y/m/d H:i:s'),
|
|
'user_id' => $this->Auth->user('id'),
|
|
'contents' => $this->request->data['Post']['message'],
|
|
'post_id' => $post_id,
|
|
'thread_id' => $target_thread_id,
|
|
);
|
|
|
|
if ($this->Post->save($newPost)) {
|
|
$newPost['user_email'] = $this->Auth->user('email');
|
|
$newPost['org_id'] = $this->Auth->user('org_id');
|
|
$newPost['org_name'] = $this->Auth->user('Organisation')['name'];
|
|
$this->pushMessageToZMQ(array("Post" => $newPost));
|
|
$this->Thread->recursive = 0;
|
|
$this->Thread->contain('Post');
|
|
$thread = $this->Thread->read(null, $target_thread_id);
|
|
$this->Thread->updateAfterPostChange($thread, true);
|
|
if (!$this->request->is('ajax')) {
|
|
$this->Flash->success(__('Post added'));
|
|
}
|
|
$post_id = $this->Post->getId();
|
|
$this->Post->sendPostsEmailRouter($this->Auth->user('id'), $post_id, $event_id, $title, $this->request->data['Post']['message']);
|
|
|
|
// redirect to thread view
|
|
if ($target_type != 'event') {
|
|
$target_id = $target_thread_id;
|
|
}
|
|
$pageNr = $this->Post->findPageNr($target_id, $target_type, $this->Post->id);
|
|
$this->redirect(array('controller' => 'threads', 'action' => 'view', $target_id, $target_type == 'event', 'page:' . $pageNr, 'post_id:' . $this->Post->id));
|
|
return true;
|
|
} else {
|
|
$this->Flash->error(__('The post could not be added.'));
|
|
}
|
|
} else {
|
|
if ($target_type === 'post') {
|
|
$this->set('previous', $previousPost['Post']['contents']);
|
|
}
|
|
$this->set('thread_id', $target_thread_id);
|
|
$this->set('target_type', $target_type);
|
|
$this->set('target_id', $target_id);
|
|
if (isset($title)) {
|
|
$this->set('title', $title);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function edit($post_id, $context = 'thread')
|
|
{
|
|
$post = $this->Post->find('first', array('conditions' => array('Post.id' => $post_id), 'recursive' => -1, 'contain' => array('Thread')));
|
|
if (empty($post)) {
|
|
throw new NotFoundException(__('Invalid post'));
|
|
}
|
|
if (!$this->_isSiteAdmin() && $this->Auth->user('id') != $post['Post']['user_id']) {
|
|
throw new MethodNotAllowedException(__('This is not your post.'));
|
|
}
|
|
|
|
if ($this->request->is('post') || $this->request->is('put')) {
|
|
$post['Post']['date_modified'] = date('Y/m/d H:i:s');
|
|
$fieldList = array('date_modified', 'contents');
|
|
$post['Post']['contents'] = $this->request->data['Post']['contents'];
|
|
if ($this->Post->save($post['Post'], true, $fieldList)) {
|
|
$this->Flash->success(__('Post edited'));
|
|
$thread = $this->Post->Thread->find('first', array(
|
|
'recursive' => -1,
|
|
'contain' => array(
|
|
'Post' => array(
|
|
'fields' => array('Post.id')
|
|
)
|
|
),
|
|
'conditions' => array('Thread.id' => $post['Post']['thread_id'])
|
|
));
|
|
$this->Post->Thread->updateAfterPostChange($thread);
|
|
if ($context != 'event') {
|
|
$target_id = $post['Post']['thread_id'];
|
|
} else {
|
|
$target_id = $thread['Thread']['event_id'];
|
|
}
|
|
$context = ($context == 'event');
|
|
$pageNr = $this->Post->findPageNr($target_id, $context, $post_id);
|
|
$this->redirect(array('controller' => 'threads', 'action' => 'view', $target_id, $context, 'page:' . $pageNr, 'post_id:' . $post_id));
|
|
return true;
|
|
} else {
|
|
$this->Flash->error(__('The post could not be edited. Please, try again.'));
|
|
}
|
|
}
|
|
$this->set('title', $post['Thread']['title']);
|
|
$this->set('contents', $post['Post']['contents']);
|
|
$this->set('id', $post_id);
|
|
$this->set('thread_id', $post['Post']['thread_id']);
|
|
}
|
|
|
|
public function delete($post_id, $context = 'thread')
|
|
{
|
|
if (!$this->request->is('post')) {
|
|
throw new MethodNotAllowedException();
|
|
}
|
|
$this->Post->id = $post_id;
|
|
if (!$this->Post->exists()) {
|
|
throw new NotFoundException(__('Invalid post'));
|
|
}
|
|
$this->Post->read();
|
|
$temp = $this->Post->data;
|
|
if ($this->Auth->user('id') != $this->Post->data['Post']['user_id'] && !$this->_isSiteAdmin()) {
|
|
throw new MethodNotAllowedException(__('This post doesn\'t belong to you, so you cannot delete it.'));
|
|
}
|
|
if ($this->Post->delete()) {
|
|
$thread = $this->Post->Thread->find('first', array(
|
|
'recursive' => -1,
|
|
'contain' => array(
|
|
'Post' => array(
|
|
'fields' => array('Post.id')
|
|
)
|
|
),
|
|
'conditions' => array('Thread.id' => $temp['Post']['thread_id'])
|
|
));
|
|
if (!$this->Post->Thread->updateAfterPostChange($thread)) {
|
|
$this->Flash->success(__('Post and thread deleted'));
|
|
if ($context == 'event') {
|
|
$this->redirect(array('controller' => 'events', 'action' => 'view', $thread['Thread']['event_id']));
|
|
return true;
|
|
} else {
|
|
$this->redirect(array('controller' => 'threads', 'action' => 'index'));
|
|
return true;
|
|
}
|
|
} else {
|
|
$this->Flash->success(__('Post deleted'));
|
|
if ($context == 'event') {
|
|
$this->redirect(array('controller' => 'events', 'action' => 'view', $thread['Thread']['event_id']));
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
$this->redirect(array('controller' => 'threads', 'action' => 'view', $thread['Thread']['id']));
|
|
}
|
|
|
|
private function _grabPreviousPost($post_id)
|
|
{
|
|
$this->Post->id = $post_id;
|
|
$this->Post->read();
|
|
return $this->Post->data;
|
|
}
|
|
}
|