2015-03-11 07:35:16 -04:00
< ? php
2024-05-24 13:43:47 -04:00
2015-03-11 07:35:16 -04:00
/**
2024-05-24 13:43:47 -04:00
* SPDX - FileCopyrightText : 2016 - 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX - FileCopyrightText : 2016 ownCloud , Inc .
* SPDX - License - Identifier : AGPL - 3.0 - only
2015-03-11 07:35:16 -04:00
*/
namespace OC\Core\Command\User ;
2016-02-16 05:46:35 -05:00
use OC\Files\Filesystem ;
2021-10-16 07:27:28 -04:00
use OCA\Settings\Mailer\NewUserMailHelper ;
use OCP\EventDispatcher\IEventDispatcher ;
2024-02-23 18:21:48 -05:00
use OCP\IAppConfig ;
2019-10-09 13:13:27 -04:00
use OCP\IGroup ;
2015-03-11 07:35:16 -04:00
use OCP\IGroupManager ;
use OCP\IUser ;
use OCP\IUserManager ;
2025-07-07 04:48:23 -04:00
use OCP\Mail\IEmailValidator ;
2021-10-16 07:27:28 -04:00
use OCP\Security\Events\GenerateSecurePasswordEvent ;
use OCP\Security\ISecureRandom ;
2015-03-11 07:35:16 -04:00
use Symfony\Component\Console\Command\Command ;
2016-09-06 14:48:22 -04:00
use Symfony\Component\Console\Helper\QuestionHelper ;
2019-11-22 14:52:10 -05:00
use Symfony\Component\Console\Input\InputArgument ;
2015-03-11 07:35:16 -04:00
use Symfony\Component\Console\Input\InputInterface ;
use Symfony\Component\Console\Input\InputOption ;
use Symfony\Component\Console\Output\OutputInterface ;
use Symfony\Component\Console\Question\Question ;
class Add extends Command {
2023-06-12 10:41:17 -04:00
public function __construct (
2023-09-30 01:17:59 -04:00
protected IUserManager $userManager ,
protected IGroupManager $groupManager ,
2025-07-07 04:48:23 -04:00
private IEmailValidator $emailValidator ,
2024-02-23 18:21:48 -05:00
private IAppConfig $appConfig ,
2023-09-30 01:17:59 -04:00
private NewUserMailHelper $mailHelper ,
private IEventDispatcher $eventDispatcher ,
private ISecureRandom $secureRandom ,
2023-06-12 10:41:17 -04:00
) {
2015-03-11 07:35:16 -04:00
parent :: __construct ();
}
2024-02-23 18:21:48 -05:00
protected function configure () : void {
2015-03-11 07:35:16 -04:00
$this
-> setName ( 'user:add' )
2022-09-21 11:44:32 -04:00
-> setDescription ( 'adds an account' )
2015-03-11 07:35:16 -04:00
-> addArgument (
'uid' ,
InputArgument :: REQUIRED ,
2022-09-21 11:44:32 -04:00
'Account ID used to login (must only contain a-z, A-Z, 0-9, -, _ and @)'
2015-03-11 07:35:16 -04:00
)
-> addOption (
2015-04-04 07:24:57 -04:00
'password-from-env' ,
null ,
InputOption :: VALUE_NONE ,
2025-06-20 04:34:20 -04:00
'read password from environment variable NC_PASS/OC_PASS'
2015-03-11 07:35:16 -04:00
)
2024-02-23 18:21:48 -05:00
-> addOption (
'generate-password' ,
null ,
InputOption :: VALUE_NONE ,
'Generate a secure password. A welcome email with a reset link will be sent to the user via an email if --email option and newUser.sendEmail config are set'
)
2015-03-11 07:35:16 -04:00
-> addOption (
'display-name' ,
null ,
InputOption :: VALUE_OPTIONAL ,
2024-02-13 08:37:09 -05:00
'Login used in the web UI (can contain any characters)'
2015-03-11 07:35:16 -04:00
)
-> addOption (
'group' ,
'g' ,
InputOption :: VALUE_OPTIONAL | InputOption :: VALUE_IS_ARRAY ,
2022-09-21 11:44:32 -04:00
'groups the account should be added to (The group will be created if it does not exist)'
2021-10-16 07:27:28 -04:00
)
-> addOption (
'email' ,
null ,
InputOption :: VALUE_REQUIRED ,
2024-02-23 18:21:48 -05:00
'When set, users may register using the default email verification workflow'
2015-03-11 07:35:16 -04:00
);
}
2020-06-26 08:54:51 -04:00
protected function execute ( InputInterface $input , OutputInterface $output ) : int {
2015-03-11 07:35:16 -04:00
$uid = $input -> getArgument ( 'uid' );
if ( $this -> userManager -> userExists ( $uid )) {
2022-09-21 11:44:32 -04:00
$output -> writeln ( '<error>The account "' . $uid . '" already exists.</error>' );
2015-03-31 18:54:11 -04:00
return 1 ;
2015-03-11 07:35:16 -04:00
}
2023-09-30 01:17:59 -04:00
$password = '' ;
2024-01-31 17:51:15 -05:00
// Setup password.
if ( $input -> getOption ( 'password-from-env' )) {
2025-06-20 04:34:20 -04:00
$password = getenv ( 'NC_PASS' ) ? : getenv ( 'OC_PASS' );
2024-01-31 17:51:15 -05:00
if ( ! $password ) {
2025-06-20 04:34:20 -04:00
$output -> writeln ( '<error>--password-from-env given, but NC_PASS/OC_PASS is empty!</error>' );
2024-01-31 17:51:15 -05:00
return 1 ;
}
2024-02-23 18:21:48 -05:00
} elseif ( $input -> getOption ( 'generate-password' )) {
2023-09-30 01:17:59 -04:00
$passwordEvent = new GenerateSecurePasswordEvent ();
$this -> eventDispatcher -> dispatchTyped ( $passwordEvent );
$password = $passwordEvent -> getPassword () ? ? $this -> secureRandom -> generate ( 20 );
2015-04-04 07:24:57 -04:00
} elseif ( $input -> isInteractive ()) {
2016-09-06 14:48:22 -04:00
/** @var QuestionHelper $helper */
$helper = $this -> getHelper ( 'question' );
$question = new Question ( 'Enter password: ' );
$question -> setHidden ( true );
$password = $helper -> ask ( $input , $output , $question );
$question = new Question ( 'Confirm password: ' );
$question -> setHidden ( true );
2022-01-12 14:44:38 -05:00
$confirm = $helper -> ask ( $input , $output , $question );
2015-03-11 07:35:16 -04:00
2015-04-04 07:24:57 -04:00
if ( $password !== $confirm ) {
2024-08-23 09:10:27 -04:00
$output -> writeln ( '<error>Passwords did not match!</error>' );
2015-04-04 07:24:57 -04:00
return 1 ;
}
} else {
2024-08-23 09:10:27 -04:00
$output -> writeln ( '<error>Interactive input or --password-from-env or --generate-password is needed for setting a password!</error>' );
2015-04-04 07:24:57 -04:00
return 1 ;
2015-03-11 07:35:16 -04:00
}
2016-09-07 03:28:42 -04:00
try {
$user = $this -> userManager -> createUser (
$input -> getArgument ( 'uid' ),
2023-09-30 01:17:59 -04:00
$password ,
2016-09-07 03:28:42 -04:00
);
} catch ( \Exception $e ) {
$output -> writeln ( '<error>' . $e -> getMessage () . '</error>' );
return 1 ;
}
2015-03-11 07:35:16 -04:00
if ( $user instanceof IUser ) {
2022-09-21 11:44:32 -04:00
$output -> writeln ( '<info>The account "' . $user -> getUID () . '" was created successfully</info>' );
2015-03-11 07:35:16 -04:00
} else {
2022-09-21 11:44:32 -04:00
$output -> writeln ( '<error>An error occurred while creating the account</error>' );
2015-03-31 18:54:11 -04:00
return 1 ;
2015-03-11 07:35:16 -04:00
}
if ( $input -> getOption ( 'display-name' )) {
$user -> setDisplayName ( $input -> getOption ( 'display-name' ));
2023-09-30 01:17:59 -04:00
$output -> writeln ( 'Display name set to "' . $user -> getDisplayName () . '"' );
2015-03-11 07:35:16 -04:00
}
2016-02-16 05:46:35 -05:00
$groups = $input -> getOption ( 'group' );
if ( ! empty ( $groups )) {
// Make sure we init the Filesystem for the user, in case we need to
// init some group shares.
Filesystem :: init ( $user -> getUID (), '' );
}
foreach ( $groups as $groupName ) {
2015-03-11 07:35:16 -04:00
$group = $this -> groupManager -> get ( $groupName );
if ( ! $group ) {
$this -> groupManager -> createGroup ( $groupName );
$group = $this -> groupManager -> get ( $groupName );
2020-04-10 08:19:56 -04:00
if ( $group instanceof IGroup ) {
2019-10-09 13:13:27 -04:00
$output -> writeln ( 'Created group "' . $group -> getGID () . '"' );
}
}
2020-04-10 08:19:56 -04:00
if ( $group instanceof IGroup ) {
2019-10-09 13:13:27 -04:00
$group -> addUser ( $user );
2022-09-21 11:44:32 -04:00
$output -> writeln ( 'Account "' . $user -> getUID () . '" added to group "' . $group -> getGID () . '"' );
2015-03-11 07:35:16 -04:00
}
}
2021-10-16 07:27:28 -04:00
2024-02-23 18:21:48 -05:00
$email = $input -> getOption ( 'email' );
if ( ! empty ( $email )) {
2025-07-07 04:48:23 -04:00
if ( ! $this -> emailValidator -> isValid ( $email )) {
2024-02-23 18:21:48 -05:00
$output -> writeln ( \sprintf (
'<error>The given email address "%s" is invalid. Email not set for the user.</error>' ,
$email ,
));
return 1 ;
}
$user -> setSystemEMailAddress ( $email );
2021-10-16 07:27:28 -04:00
2024-02-23 18:21:48 -05:00
if ( $this -> appConfig -> getValueString ( 'core' , 'newUser.sendEmail' , 'yes' ) === 'yes' ) {
2023-09-30 01:17:59 -04:00
try {
$this -> mailHelper -> sendMail ( $user , $this -> mailHelper -> generateTemplate ( $user , true ));
2024-02-23 18:21:48 -05:00
$output -> writeln ( 'Welcome email sent to ' . $email );
2023-09-30 01:17:59 -04:00
} catch ( \Exception $e ) {
2024-02-23 18:21:48 -05:00
$output -> writeln ( 'Unable to send the welcome email to ' . $email );
2023-09-30 01:17:59 -04:00
}
}
}
2021-10-16 07:27:28 -04:00
2023-09-30 01:17:59 -04:00
return 0 ;
2021-10-16 07:27:28 -04:00
}
2015-03-11 07:35:16 -04:00
}