]> BookStack Code Mirror - bookstack/blob - app/Console/Commands/CreateAdmin.php
Fixed comment count update error
[bookstack] / app / Console / Commands / CreateAdmin.php
1 <?php
2
3 namespace BookStack\Console\Commands;
4
5 use BookStack\Auth\Role;
6 use BookStack\Auth\UserRepo;
7 use BookStack\Exceptions\NotFoundException;
8 use Illuminate\Console\Command;
9 use Illuminate\Support\Facades\Validator;
10 use Illuminate\Support\Str;
11 use Illuminate\Validation\Rules\Password;
12 use Illuminate\Validation\Rules\Unique;
13 use Symfony\Component\Console\Command\Command as SymfonyCommand;
14
15 class CreateAdmin extends Command
16 {
17     /**
18      * The name and signature of the console command.
19      *
20      * @var string
21      */
22     protected $signature = 'bookstack:create-admin
23                             {--email= : The email address for the new admin user}
24                             {--name= : The name of the new admin user}
25                             {--password= : The password to assign to the new admin user}
26                             {--external-auth-id= : The external authentication system id for the new admin user (SAML2/LDAP/OIDC)}';
27
28     /**
29      * The console command description.
30      *
31      * @var string
32      */
33     protected $description = 'Add a new admin user to the system';
34
35     protected $userRepo;
36
37     /**
38      * Create a new command instance.
39      */
40     public function __construct(UserRepo $userRepo)
41     {
42         $this->userRepo = $userRepo;
43         parent::__construct();
44     }
45
46     /**
47      * Execute the console command.
48      *
49      * @throws NotFoundException
50      *
51      * @return mixed
52      */
53     public function handle()
54     {
55         $details = $this->snakeCaseOptions();
56
57         if (empty($details['email'])) {
58             $details['email'] = $this->ask('Please specify an email address for the new admin user');
59         }
60
61         if (empty($details['name'])) {
62             $details['name'] = $this->ask('Please specify a name for the new admin user');
63         }
64
65         if (empty($details['password'])) {
66             if (empty($details['external_auth_id'])) {
67                 $details['password'] = $this->ask('Please specify a password for the new admin user (8 characters min)');
68             } else {
69                 $details['password'] = Str::random(32);
70             }
71         }
72
73         $validator = Validator::make($details, [
74             'email'            => ['required', 'email', 'min:5', new Unique('users', 'email')],
75             'name'             => ['required', 'min:2'],
76             'password'         => ['required_without:external_auth_id', Password::default()],
77             'external_auth_id' => ['required_without:password'],
78         ]);
79
80         if ($validator->fails()) {
81             foreach ($validator->errors()->all() as $error) {
82                 $this->error($error);
83             }
84
85             return SymfonyCommand::FAILURE;
86         }
87
88         $user = $this->userRepo->createWithoutActivity($validator->validated());
89         $user->attachRole(Role::getSystemRole('admin'));
90         $user->email_confirmed = true;
91         $user->save();
92
93         $this->info("Admin account with email \"{$user->email}\" successfully created!");
94
95         return SymfonyCommand::SUCCESS;
96     }
97
98     protected function snakeCaseOptions(): array
99     {
100         $returnOpts = [];
101         foreach ($this->options() as $key => $value) {
102             $returnOpts[str_replace('-', '_', $key)] = $value;
103         }
104
105         return $returnOpts;
106     }
107 }