Skip to content

Commit

Permalink
Support creating users via REST API
Browse files Browse the repository at this point in the history
Fixes #23838
  • Loading branch information
vboctor committed Jan 20, 2018
1 parent f577d61 commit 3f29dcc
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 19 deletions.
24 changes: 24 additions & 0 deletions api/rest/restcore/users_rest.php
Expand Up @@ -24,6 +24,9 @@

$g_app->group('/users', function() use ( $g_app ) {
$g_app->get( '/me', 'rest_user_get_me' );

$g_app->post( '/', 'rest_user_create' );
$g_app->post( '', 'rest_user_create' );
});

/**
Expand All @@ -39,4 +42,25 @@ function rest_user_get_me( \Slim\Http\Request $p_request, \Slim\Http\Response $p
return $p_response->withStatus( HTTP_STATUS_SUCCESS )->withJson( $t_result );
}

/**
* A method that creates a user.
*
* @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_user_create( \Slim\Http\Request $p_request, \Slim\Http\Response $p_response, array $p_args ) {
$t_payload = $p_request->getParsedBody();
if( $t_payload === null ) {
return $p_response->withStatus( HTTP_STATUS_BAD_REQUEST, "Unable to parse body, specify content type" );
}

$t_data = array( 'payload' => $t_payload );
$t_command = new UserCreateCommand( $t_data );
$t_result = $t_command->execute();
$t_user_id = $t_result['id'];

return $p_response->withStatus( HTTP_STATUS_CREATED, "User created with id $t_user_id" )->
withJson( array( 'user' => mci_user_get( $t_user_id ) ) );
}
17 changes: 8 additions & 9 deletions core/commands/UserCreateCommand.php
Expand Up @@ -83,7 +83,9 @@ function __construct( array $p_data ) {
*/
function validate() {
# Ensure user has access level to create users
access_ensure_global_level( config_get_global( 'manage_user_threshold' ) );
if( !access_has_global_level( config_get_global( 'manage_user_threshold' ) ) ) {
throw new ClientException( 'Access denied to create users', ERROR_ACCESS_DENIED );
}

# Access Level
$this->access_level = access_parse_array(
Expand All @@ -93,25 +95,22 @@ function validate() {

# Don't allow the creation of accounts with access levels higher than that of
# the user creating the account.
access_ensure_global_level( $this->access_level );
if( !access_has_global_level( $this->access_level ) ) {
throw new ClientException(
'Access denied to create users with higher access level',
ERROR_ACCESS_DENIED );
}

# Username and Real Name
$this->username = trim( $this->payload( 'username', '' ) );
if( is_blank( $this->username ) ) {
throw new ClientException( 'username must be specified', ERROR_EMPTY_FIELD );
}

$this->realname = string_normalize( $this->payload( 'real_name', '' ) );
user_ensure_name_valid( $this->username );
user_ensure_realname_unique( $this->username, $this->realname );

# Protected and Enabled Flags
$this->protected = $this->payload( 'protected', false );
$this->enabled = $this->payload( 'enabled', true );

# Email
$this->email = trim( $this->payload( 'email', '' ) );
email_ensure_not_disposable( $this->email );

# Password
$this->password = $this->payload( 'password', '' );
Expand Down
11 changes: 9 additions & 2 deletions core/email_api.php
Expand Up @@ -74,6 +74,8 @@
require_api( 'user_pref_api.php' );
require_api( 'utility_api.php' );

use Mantis\Exceptions\ClientException;

# reusable object of class SMTP
$g_phpMailer = null;

Expand Down Expand Up @@ -184,7 +186,9 @@ function email_is_valid( $p_email ) {
*/
function email_ensure_valid( $p_email ) {
if( !email_is_valid( $p_email ) ) {
trigger_error( ERROR_EMAIL_INVALID, ERROR );
throw new ClientException(
sprintf( "Email '%s' is invalid.", $p_email ),
ERROR_EMAIL_INVALID );
}
}

Expand All @@ -205,7 +209,10 @@ function email_is_disposable( $p_email ) {
*/
function email_ensure_not_disposable( $p_email ) {
if( email_is_disposable( $p_email ) ) {
trigger_error( ERROR_EMAIL_DISPOSABLE, ERROR );
throw new ClientException(
sprintf( "Email '%s' is disposable.", $p_email ),
ERROR_EMAIL_DISPOSABLE
);
}
}

Expand Down
25 changes: 17 additions & 8 deletions core/user_api.php
Expand Up @@ -256,7 +256,9 @@ function user_is_name_unique( $p_username ) {
*/
function user_ensure_name_unique( $p_username ) {
if( !user_is_name_unique( $p_username ) ) {
trigger_error( ERROR_USER_NAME_NOT_UNIQUE, ERROR );
throw new ClientException(
sprintf( "Username '%s' already used.", $p_username ),
ERROR_USER_NAME_NOT_UNIQUE );
}
}

Expand Down Expand Up @@ -304,17 +306,18 @@ function user_ensure_email_unique( $p_email, $p_user_id = null ) {
}

if( !user_is_email_unique( $p_email, $p_user_id ) ) {
trigger_error( ERROR_USER_EMAIL_NOT_UNIQUE, ERROR );
throw new ClientException(
sprintf( "Email '%s' already used.", $p_email ),
ERROR_USER_EMAIL_NOT_UNIQUE );
}
}

/**
* Check if the realname is a valid username (does not account for uniqueness)
* Return 0 if it is invalid, The number of matches + 1
* Check if realname is specified, a unique real name, and doesn't match a username of another user.
*
* @param string $p_username The username to check.
* @param string $p_realname The realname to check.
* @return integer
* @return integer 0 realname matches another user's username, 1 no conflicts, >1 realname not unique.
*/
function user_is_realname_unique( $p_username, $p_realname ) {
if( is_blank( $p_realname ) ) {
Expand Down Expand Up @@ -369,8 +372,11 @@ function user_is_realname_unique( $p_username, $p_realname ) {
* @return void
*/
function user_ensure_realname_unique( $p_username, $p_realname ) {
if( 1 > user_is_realname_unique( $p_username, $p_realname ) ) {
trigger_error( ERROR_USER_REAL_MATCH_USER, ERROR );
$t_result = user_is_realname_unique( $p_username, $p_realname );
if( $t_result == 0 || $t_result > 1 ) {
throw new ClientException(
sprintf( "Realname '%s' is not unique", $p_realname ),
ERROR_USER_REAL_MATCH_USER );
}
}

Expand Down Expand Up @@ -407,7 +413,9 @@ function user_is_name_valid( $p_username ) {
*/
function user_ensure_name_valid( $p_username ) {
if( !user_is_name_valid( $p_username ) ) {
trigger_error( ERROR_USER_NAME_INVALID, ERROR );
throw new ClientException(
sprintf( "Invalid username '%s'", $p_username ),
ERROR_USER_NAME_INVALID );
}
}

Expand Down Expand Up @@ -585,6 +593,7 @@ function user_create( $p_username, $p_password, $p_email = '',
user_ensure_email_unique( $p_email );
user_ensure_realname_unique( $p_username, $p_realname );
email_ensure_valid( $p_email );
email_ensure_not_disposable( $p_email );

$t_cookie_string = auth_generate_unique_cookie_string();

Expand Down

0 comments on commit 3f29dcc

Please sign in to comment.