From 44a060b0382ea77cccd54d29a965df51a4f19947 Mon Sep 17 00:00:00 2001 From: Victor Boctor Date: Fri, 5 Jan 2018 15:58:43 -0800 Subject: [PATCH] Implement IssueNoteDeleteCommand --- api/rest/restcore/issues_rest.php | 10 +- api/soap/mc_issue_api.php | 31 ++----- bugnote_delete.php | 44 +-------- core/bugnote_api.php | 5 +- core/commands/IssueNoteDeleteCommand.php | 111 +++++++++++++++++++++++ 5 files changed, 134 insertions(+), 67 deletions(-) create mode 100644 core/commands/IssueNoteDeleteCommand.php diff --git a/api/rest/restcore/issues_rest.php b/api/rest/restcore/issues_rest.php index 4e5f0e343e..5d72619a41 100644 --- a/api/rest/restcore/issues_rest.php +++ b/api/rest/restcore/issues_rest.php @@ -236,8 +236,14 @@ function rest_issue_note_delete( \Slim\Http\Request $p_request, \Slim\Http\Respo $t_issue_id = isset( $p_args['id'] ) ? $p_args['id'] : $p_request->getParam( 'id' ); $t_issue_note_id = isset( $p_args['note_id'] ) ? $p_args['note_id'] : $p_request->getParam( 'note_id' ); - $t_result = mc_issue_note_delete( '', '', $t_issue_note_id ); - ApiObjectFactory::throwIfFault( $t_result ); + $t_data = array( + 'query' => array( + 'id' => $t_issue_note_id, + 'issue_id' => $t_issue_id ) + ); + + $t_command = new IssueNoteDeleteCommand( $t_data ); + $t_command->execute(); $t_issue = mc_issue_get( /* username */ '', /* password */ '', $t_issue_id ); return $p_response->withStatus( HTTP_STATUS_SUCCESS, 'Issue Note Deleted' )-> diff --git a/api/soap/mc_issue_api.php b/api/soap/mc_issue_api.php index e97db5e2a0..70591e1214 100644 --- a/api/soap/mc_issue_api.php +++ b/api/soap/mc_issue_api.php @@ -1571,8 +1571,6 @@ function mc_issue_note_add( $p_username, $p_password, $p_issue_id, stdClass $p_n * @return boolean true: success, false: failure */ function mc_issue_note_delete( $p_username, $p_password, $p_issue_note_id ) { - global $g_project_override; - $t_user_id = mci_check_login( $p_username, $p_password ); if( $t_user_id === false ) { return mci_fault_login_failed(); @@ -1582,36 +1580,19 @@ function mc_issue_note_delete( $p_username, $p_password, $p_issue_note_id ) { return ApiObjectFactory::faultBadRequest( 'Invalid issue note id \'' . $p_issue_note_id . '\'.' ); } - if( !bugnote_exists( $p_issue_note_id ) ) { - return ApiObjectFactory::faultNotFound( 'Issue note \'' . $p_issue_note_id . '\' does not exist.' ); - } - $t_issue_id = bugnote_get_field( $p_issue_note_id, 'bug_id' ); $t_project_id = bug_get_field( $t_issue_id, 'project_id' ); - $g_project_override = $t_project_id; if( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) { return mci_fault_access_denied( $t_user_id ); } - $t_reporter_id = bugnote_get_field( $p_issue_note_id, 'reporter_id' ); - - # mirrors check from bugnote_delete.php - if( $t_user_id == $t_reporter_id ) { - $t_threshold_config_name = 'bugnote_user_delete_threshold'; - } else { - $t_threshold_config_name = 'delete_bugnote_threshold'; - } - - if( !access_has_bugnote_level( config_get( $t_threshold_config_name ), $p_issue_note_id ) ) { - return mci_fault_access_denied( $t_user_id ); - } - - if( bug_is_readonly( $t_issue_id ) ) { - return mci_fault_access_denied( $t_user_id, 'Issue \'' . $t_issue_id . '\' is readonly' ); - } + $t_data = array( + 'query' => array( 'id' => $p_issue_note_id ) + ); - log_event( LOG_WEBSERVICE, 'deleting bugnote id \'' . $p_issue_note_id . '\'' ); - return bugnote_delete( $p_issue_note_id ); + $t_command = new IssueNoteDeleteCommand( $t_data ); + $t_command->execute(); + return true; } /** diff --git a/bugnote_delete.php b/bugnote_delete.php index a9c1527b03..abe997e4ef 100644 --- a/bugnote_delete.php +++ b/bugnote_delete.php @@ -24,33 +24,15 @@ * @link http://www.mantisbt.org * * @uses core.php - * @uses access_api.php - * @uses authentication_api.php - * @uses bug_api.php - * @uses bugnote_api.php - * @uses config_api.php - * @uses constant_inc.php - * @uses event_api.php * @uses form_api.php * @uses gpc_api.php - * @uses helper_api.php - * @uses lang_api.php * @uses print_api.php * @uses string_api.php */ require_once( 'core.php' ); -require_api( 'access_api.php' ); -require_api( 'authentication_api.php' ); -require_api( 'bug_api.php' ); -require_api( 'bugnote_api.php' ); -require_api( 'config_api.php' ); -require_api( 'constant_inc.php' ); -require_api( 'event_api.php' ); require_api( 'form_api.php' ); require_api( 'gpc_api.php' ); -require_api( 'helper_api.php' ); -require_api( 'lang_api.php' ); require_api( 'print_api.php' ); require_api( 'string_api.php' ); @@ -58,30 +40,14 @@ $f_bugnote_id = gpc_get_int( 'bugnote_id' ); -$t_bug_id = bugnote_get_field( $f_bugnote_id, 'bug_id' ); - -$t_bug = bug_get( $t_bug_id, true ); -if( $t_bug->project_id != helper_get_current_project() ) { - # in case the current project is not the same project of the bug we are viewing... - # ... override the current project. This to avoid problems with categories and handlers lists etc. - $g_project_override = $t_bug->project_id; -} - -# Check if the current user is allowed to delete the bugnote -$t_user_id = auth_get_current_user_id(); -$t_reporter_id = bugnote_get_field( $f_bugnote_id, 'reporter_id' ); - -if( $t_user_id == $t_reporter_id ) { - access_ensure_bugnote_level( config_get( 'bugnote_user_delete_threshold' ), $f_bugnote_id ); -} else { - access_ensure_bugnote_level( config_get( 'delete_bugnote_threshold' ), $f_bugnote_id ); -} - helper_ensure_confirmed( lang_get( 'delete_bugnote_sure_msg' ), lang_get( 'delete_bugnote_button' ) ); -bugnote_delete( $f_bugnote_id ); +$t_data = array( 'query' => array( 'id' => $f_bugnote_id ) ); + +$t_command = new IssueNoteDeleteCommand( $t_data ); +$t_result = $t_command->execute(); form_security_purge( 'bugnote_delete' ); -print_successful_redirect( string_get_bug_view_url( $t_bug_id ) . '#bugnotes' ); +print_successful_redirect( string_get_bug_view_url( $t_result['issue_id'] ) . '#bugnotes' ); diff --git a/core/bugnote_api.php b/core/bugnote_api.php index 6cf516a70c..89b3091ea2 100644 --- a/core/bugnote_api.php +++ b/core/bugnote_api.php @@ -188,7 +188,10 @@ function bugnote_cache( BugnoteData $p_bugnote ) { */ function bugnote_ensure_exists( $p_bugnote_id ) { if( !bugnote_exists( $p_bugnote_id ) ) { - trigger_error( ERROR_BUGNOTE_NOT_FOUND, ERROR ); + throw new ClientException( + "Issue note #$p_bugnote_id not found", + ERROR_BUGNOTE_NOT_FOUND, + array( $p_bugnote_id ) ); } } diff --git a/core/commands/IssueNoteDeleteCommand.php b/core/commands/IssueNoteDeleteCommand.php new file mode 100644 index 0000000000..9429e5a44c --- /dev/null +++ b/core/commands/IssueNoteDeleteCommand.php @@ -0,0 +1,111 @@ +. + +require_api( 'authentication_api.php' ); +require_api( 'bug_api.php' ); +require_api( 'constant_inc.php' ); +require_api( 'config_api.php' ); +require_api( 'helper_api.php' ); +require_api( 'user_api.php' ); + +use Mantis\Exceptions\ClientException; + +/** + * A command that adds user to monitor an issue. + */ +class IssueNoteDeleteCommand extends Command { + /** + * @var integer issue note id to delete + */ + private $id; + + /** + * @var integer issue id + */ + private $issueId; + + /** + * Constructor + * + * @param array $p_data The command data. + */ + function __construct( array $p_data ) { + parent::__construct( $p_data ); + } + + /** + * Validate the data. + */ + function validate() { + $this->id = $this->query( 'id' ); + + if( (integer)$this->id < 1 ) { + throw new ClientException( "'id' must be >= 1", ERROR_INVALID_FIELD_VALUE, array( 'id' ) ); + } + + bugnote_ensure_exists( $this->id ); + + $this->issueId = bugnote_get_field( $this->id, 'bug_id' ); + $t_specified_issue_id = $this->query( 'issue_id' ); + if( $t_specified_issue_id !== null && $t_specified_issue_id != $this->issueId ) { + throw new ClientException( "Issue note doesn't belong to issue", ERROR_INVALID_FIELD_VALUE, array( 'id' ) ); + } + + $t_project_id = bug_get_field( $this->issueId, 'project_id' ); + if( $t_project_id != helper_get_current_project() ) { + # in case the current project is not the same project of the bug we are + # viewing, override the current project. This to avoid problems with + # categories and handlers lists etc. + global $g_project_override; + $g_project_override = $t_project_id; + } + + $t_reporter_id = bugnote_get_field( $this->id, 'reporter_id' ); + $t_user_id = auth_get_current_user_id(); + + # mirrors check from bugnote_delete.php + if( $t_user_id == $t_reporter_id ) { + $t_threshold_config_name = 'bugnote_user_delete_threshold'; + } else { + $t_threshold_config_name = 'delete_bugnote_threshold'; + } + + if( !access_has_bugnote_level( config_get( $t_threshold_config_name ), $this->id ) ) { + throw new ClientException( 'Access denied', ERROR_ACCESS_DENIED ); + } + + if( bug_is_readonly( $this->issueId ) ) { + throw new ClientException( + sprintf( "Issue '%d' is read-only.", $this->issueId ), + ERROR_BUG_READ_ONLY_ACTION_DENIED, + array( $this->issueId ) ); + } + } + + /** + * Process the command. + * + * @returns array Command response + */ + protected function process() { + bugnote_delete( $this->id ); + return array( + 'id' => $this->id, + 'issue_id' => $this->issueId + ); + } +} +