Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REST API to fetch project users #1843

Merged
merged 9 commits into from Aug 25, 2022
81 changes: 81 additions & 0 deletions api/rest/restcore/projects_rest.php
Expand Up @@ -52,8 +52,89 @@
$g_app->patch( '/{id}/subprojects/{subproject_id}/', 'rest_project_hierarchy_update' );
$g_app->delete( '/{id}/subprojects/{subproject_id}', 'rest_project_hierarchy_delete' );
$g_app->delete( '/{id}/subprojects/{subproject_id}/', 'rest_project_hierarchy_delete' );

# Project Users that can handle issues
$g_app->get( '/{id}/handlers', 'rest_project_handlers' );

# Project Users
$g_app->get( '/{id}/users', 'rest_project_users' );
});

/**
* A method to get list of users with the specified access level in the specified project.
*
* @param \Slim\Http\Request $p_request The request.
* @param \Slim\Http\Response $p_response The response.
* @param array $p_args Arguments
* @return \Slim\Http\Response The augmented response.
*/
function rest_project_users(\Slim\Http\Request $p_request, \Slim\Http\Response $p_response, array $p_args ) {
$t_project_id = $p_args['id'];
if( is_blank( $t_project_id ) ) {
$t_message = "Project id is missing.";
return $p_response->withStatus( HTTP_STATUS_BAD_REQUEST, $t_message );
}

$t_project_id = (int)$t_project_id;
$t_page_size = $p_request->getParam( 'page_size' );
$t_page = $p_request->getParam( 'page' );
$t_access_level = $p_request->getParam( 'access_level' );
$t_include_access_levels = $p_request->getParam( 'include_access_levels' );

$t_data = array(
'query' => array(
'id' => $t_project_id,
'page_size' => $t_page_size,
'page' => $t_page,
'access_level' => $t_access_level,
'include_access_levels' => $t_include_access_levels
)
);

$t_command = new ProjectUsersGetCommand( $t_data );
$t_result = $t_command->execute();

return $p_response->withStatus( HTTP_STATUS_SUCCESS )->withJson( $t_result );
}

/**
* A method to get list of users with the handler access level in the specified project.
*
* @param \Slim\Http\Request $p_request The request.
* @param \Slim\Http\Response $p_response The response.
* @param array $p_args Arguments
* @return \Slim\Http\Response The augmented response.
*/
function rest_project_handlers(\Slim\Http\Request $p_request, \Slim\Http\Response $p_response, array $p_args ) {
$t_project_id = $p_args['id'];
if( is_blank( $t_project_id ) ) {
$t_message = "Project id is missing.";
return $p_response->withStatus( HTTP_STATUS_BAD_REQUEST, $t_message );
}

$t_project_id = (int)$t_project_id;
$t_page_size = $p_request->getParam( 'page_size' );
$t_page = $p_request->getParam( 'page' );
$t_include_access_levels = $p_request->getParam( 'include_access_levels' );

$t_access_level = config_get( 'handle_bug_threshold', null, null, $t_project_id );

$t_data = array(
'query' => array(
'id' => $t_project_id,
'page_size' => $t_page_size,
'page' => $t_page,
'access_level' => $t_access_level,
'include_access_levels' => $t_include_access_levels
)
);

$t_command = new ProjectUsersGetCommand( $t_data );
$t_result = $t_command->execute();

return $p_response->withStatus( HTTP_STATUS_SUCCESS )->withJson( $t_result );
}

/**
* A method to get list of projects accessible to user with all their related information.
*
Expand Down
34 changes: 12 additions & 22 deletions api/soap/mc_project_api.php
Expand Up @@ -1295,29 +1295,19 @@ function mc_project_get_users( $p_username, $p_password, $p_project_id, $p_acces
return mci_fault_login_failed();
}

$g_project_override = $p_project_id;

$t_users = project_get_all_user_rows( $p_project_id, $p_access ); # handles ALL_PROJECTS case

$t_display = array();
$t_sort = array();

foreach( $t_users as $t_user ) {
$t_user_name = user_get_name_from_row( $t_user );
$t_display[] = string_attribute( $t_user_name );
$t_sort[] = user_get_name_for_sorting_from_row( $t_user );
}

array_multisort( $t_sort, SORT_ASC, SORT_STRING, $t_users, $t_display );
$t_data = array(
'query' => array(
'id' => $p_project_id,
'page' => 1,
'page_size' => 0,
'access_level' => $p_access,
'include_access_levels' => 0
)
);

$t_result = array();
for( $i = 0;$i < count( $t_sort );$i++ ) {
$t_row = $t_users[$i];
$cmd = new ProjectUsersGetCommand( $t_data );
vboctor marked this conversation as resolved.
Show resolved Hide resolved
$t_result = $cmd->execute();
$t_result = $t_result['users'];

# This is not very performant - But we have to assure that the data returned is exactly
# the same as the data that comes with an issue (test for equality - $t_row[] does not
# contain email fields).
$t_result[] = mci_account_get_array_by_id( $t_row['id'] );
}
return $t_result;
}
188 changes: 188 additions & 0 deletions core/commands/ProjectUsersGetCommand.php
@@ -0,0 +1,188 @@
<?php
# MantisBT - A PHP based bugtracking system

# MantisBT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# MantisBT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with MantisBT. If not, see <http://www.gnu.org/licenses/>.

use Mantis\Exceptions\ClientException;

require_api( 'authentication_api.php' );
require_api( 'user_pref_api.php' );

require_once( dirname( __FILE__ ) . '/../../api/soap/mc_account_api.php' );
require_once( dirname( __FILE__ ) . '/../../api/soap/mc_enum_api.php' );

/**
* Sample:
* {
* "query": {
* 'id' => 1,
* 'page' => 1,
* 'page_size' => 50,
* 'access_level' => 1,
* 'include_access_levels' => 1
* }
* }
*/

/**
* A command to get the users within a project with the specified access level
* or higher.
*/
class ProjectUsersGetCommand extends Command {
/**
* The project id
*
* @var integer
*/
private $project_id;

/**
* The minimum access level, users with access level greater or equal to this access level
* will be returned.
*
* @var integer
*/
private $access_level;

/**
* The page number (starts with 1)
*
* @var integer
*/
private $page;

/**
* The number of users to return per page.
*
* @var integer
*/
private $page_size;

/**
* Include effective access level of users on the project?
*
* @var integer
*/
private $include_access_levels;

/**
* The authenticated user id
*
* @var integer
*/
private $user_id;

/**
* Constructor
*
* @param array $p_data The command data.
*/
function __construct( array $p_data ) {
parent::__construct( $p_data );
}

/**
* Validate the data.
*/
function validate() {
$this->user_id = auth_get_current_user_id();
$this->project_id = (int)$this->query( 'id' );
$this->access_level = (int)$this->query( 'access_level' );
$this->page = (int)$this->query( 'page', 1 );
$this->page_size = (int)$this->query( 'page_size', 50 );
$this->include_access_levels = (int)$this->query( 'include_access_levels', true );

if( $this->project_id <= ALL_PROJECTS ) {
throw new ClientException(
sprintf( "Must specify a specific project id.", $this->project_id ),
vboctor marked this conversation as resolved.
Show resolved Hide resolved
ERROR_PROJECT_NOT_FOUND,
array( $this->project_id ) );
}
vboctor marked this conversation as resolved.
Show resolved Hide resolved

if( !project_exists( $this->project_id ) ) {
throw new ClientException(
sprintf( "Project '%d' not found", $this->project_id ),
ERROR_PROJECT_NOT_FOUND,
array( $this->project_id ) );
}

# If user doesn't have access to project, return project doesn't exist
if( !access_has_project_level( VIEWER, $this->project_id, $this->user_id ) ) {
throw new ClientException(
sprintf( "Project '%d' not found", $this->project_id ),
ERROR_PROJECT_NOT_FOUND,
array( $this->project_id ) );
}

if( $this->page < 1 ) {
$this->page = 1;
}
}

/**
* Process the command.
*
* @returns array Command response
*/
protected function process() {
global $g_project_override;
$g_project_override = $this->project_id;

$t_users = project_get_all_user_rows(
$this->project_id,
$this->access_level,
/* include_global_users */ true );

$t_display = array();
$t_sort = array();

foreach( $t_users as $t_user ) {
$t_user_name = user_get_name_from_row( $t_user );
$t_display[] = $t_user_name;
$t_sort[] = user_get_name_for_sorting_from_row( $t_user );
}

array_multisort( $t_sort, SORT_ASC, SORT_STRING, $t_users, $t_display );

unset( $t_display );
unset( $t_sort );

$t_skip = ( $this->page - 1 ) * $this->page_size;
$t_taken = 0;
$t_users_result = array();

$t_lang = user_pref_get_pref( auth_get_current_user_id(), 'language' );

for( $i = $t_skip; $i < count( $t_users ); $i++ ) {
$t_user_id = (int)$t_users[$i]['id'];
$t_user = mci_account_get_array_by_id( $t_user_id );

if( $this->include_access_levels ) {
$t_access_level = (int)$t_users[$i]['access_level'];
$t_user['access_level'] =
mci_enum_get_array_by_id( $t_access_level, 'access_levels', $t_lang );
}

$t_users_result[] = $t_user;
$t_taken++;

if( $this->page_size != 0 && $t_taken == $this->page_size ) {
break;
}
}

$t_result = array( 'users' => $t_users_result );
return $t_result;
}
}