8
8
use Illuminate \Support \Facades \Validator ;
9
9
use Illuminate \Support \Str ;
10
10
use Illuminate \Validation \Rules \Password ;
11
- use Illuminate \Validation \Rules \Unique ;
12
11
13
12
class CreateAdminCommand extends Command
14
13
{
@@ -21,7 +20,9 @@ class CreateAdminCommand extends Command
21
20
{--email= : The email address for the new admin user}
22
21
{--name= : The name of the new admin user}
23
22
{--password= : The password to assign to the new admin user}
24
- {--external-auth-id= : The external authentication system id for the new admin user (SAML2/LDAP/OIDC)} ' ;
23
+ {--external-auth-id= : The external authentication system id for the new admin user (SAML2/LDAP/OIDC)}
24
+ {--generate-password : Generate a random password for the new admin user}
25
+ {--initial : Indicate if this should set/update the details of the initial admin user} ' ;
25
26
26
27
/**
27
28
* The console command description.
@@ -35,26 +36,12 @@ class CreateAdminCommand extends Command
35
36
*/
36
37
public function handle (UserRepo $ userRepo ): int
37
38
{
38
- $ details = $ this ->snakeCaseOptions ();
39
-
40
- if (empty ($ details ['email ' ])) {
41
- $ details ['email ' ] = $ this ->ask ('Please specify an email address for the new admin user ' );
42
- }
43
-
44
- if (empty ($ details ['name ' ])) {
45
- $ details ['name ' ] = $ this ->ask ('Please specify a name for the new admin user ' );
46
- }
47
-
48
- if (empty ($ details ['password ' ])) {
49
- if (empty ($ details ['external_auth_id ' ])) {
50
- $ details ['password ' ] = $ this ->ask ('Please specify a password for the new admin user (8 characters min) ' );
51
- } else {
52
- $ details ['password ' ] = Str::random (32 );
53
- }
54
- }
39
+ $ initialAdminOnly = $ this ->option ('initial ' );
40
+ $ shouldGeneratePassword = $ this ->option ('generate-password ' );
41
+ $ details = $ this ->gatherDetails ($ shouldGeneratePassword , $ initialAdminOnly );
55
42
56
43
$ validator = Validator::make ($ details , [
57
- 'email ' => ['required ' , 'email ' , 'min:5 ' , new Unique ( ' users ' , ' email ' ) ],
44
+ 'email ' => ['required ' , 'email ' , 'min:5 ' ],
58
45
'name ' => ['required ' , 'min:2 ' ],
59
46
'password ' => ['required_without:external_auth_id ' , Password::default ()],
60
47
'external_auth_id ' => ['required_without:password ' ],
@@ -68,16 +55,101 @@ public function handle(UserRepo $userRepo): int
68
55
return 1 ;
69
56
}
70
57
58
+ $ adminRole = Role::getSystemRole ('admin ' );
59
+
60
+ if ($ initialAdminOnly ) {
61
+ $ handled = $ this ->handleInitialAdminIfExists ($ userRepo , $ details , $ shouldGeneratePassword , $ adminRole );
62
+ if ($ handled !== null ) {
63
+ return $ handled ;
64
+ }
65
+ }
66
+
67
+ $ emailUsed = $ userRepo ->getByEmail ($ details ['email ' ]) !== null ;
68
+ if ($ emailUsed ) {
69
+ $ this ->error ("Could not create admin account. " );
70
+ $ this ->error ("An account with the email address \"{$ details ['email ' ]}\" already exists. " );
71
+ return 1 ;
72
+ }
73
+
71
74
$ user = $ userRepo ->createWithoutActivity ($ validator ->validated ());
72
- $ user ->attachRole (Role:: getSystemRole ( ' admin ' ) );
75
+ $ user ->attachRole ($ adminRole );
73
76
$ user ->email_confirmed = true ;
74
77
$ user ->save ();
75
78
76
- $ this ->info ("Admin account with email \"{$ user ->email }\" successfully created! " );
79
+ if ($ shouldGeneratePassword ) {
80
+ $ this ->line ($ details ['password ' ]);
81
+ } else {
82
+ $ this ->info ("Admin account with email \"{$ user ->email }\" successfully created! " );
83
+ }
77
84
78
85
return 0 ;
79
86
}
80
87
88
+ /**
89
+ * Handle updates to the original admin account if it exists.
90
+ * Returns an int return status if handled, otherwise returns null if not handled (new user to be created).
91
+ */
92
+ protected function handleInitialAdminIfExists (UserRepo $ userRepo , array $ data , bool $ generatePassword , Role $ adminRole ): int |null
93
+ {
94
+ $ defaultAdmin =
$ userRepo->
getByEmail (
'[email protected] ' );
95
+ if ($ defaultAdmin && $ defaultAdmin ->hasSystemRole ('admin ' )) {
96
+ if ($ defaultAdmin ->email !== $ data ['email ' ] && $ userRepo ->getByEmail ($ data ['email ' ]) !== null ) {
97
+ $ this ->error ("Could not create admin account. " );
98
+ $ this ->error ("An account with the email address \"{$ data ['email ' ]}\" already exists. " );
99
+ return 1 ;
100
+ }
101
+
102
+ $ userRepo ->updateWithoutActivity ($ defaultAdmin , $ data , true );
103
+ if ($ generatePassword ) {
104
+ $ this ->line ($ data ['password ' ]);
105
+ } else {
106
+ $ this ->info ("The default admin user has been updated with the provided details! " );
107
+ }
108
+
109
+ return 0 ;
110
+ } else if ($ adminRole ->users ()->count () > 0 ) {
111
+ $ this ->warn ('Non-default admin user already exists. Skipping creation of new admin user. ' );
112
+ return 2 ;
113
+ }
114
+
115
+ return null ;
116
+ }
117
+
118
+ protected function gatherDetails (bool $ generatePassword , bool $ initialAdmin ): array
119
+ {
120
+ $ details = $ this ->snakeCaseOptions ();
121
+
122
+ if (empty ($ details ['email ' ])) {
123
+ if ($ initialAdmin ) {
124
+ $ details[
'email ' ] =
'[email protected] ' ;
125
+ } else {
126
+ $ details ['email ' ] = $ this ->ask ('Please specify an email address for the new admin user ' );
127
+ }
128
+ }
129
+
130
+ if (empty ($ details ['name ' ])) {
131
+ if ($ initialAdmin ) {
132
+ $ details ['name ' ] = 'Admin ' ;
133
+ } else {
134
+ $ details ['name ' ] = $ this ->ask ('Please specify a name for the new admin user ' );
135
+ }
136
+ }
137
+
138
+ if (empty ($ details ['password ' ])) {
139
+ if (empty ($ details ['external_auth_id ' ])) {
140
+ if ($ generatePassword ) {
141
+ $ details ['password ' ] = Str::random (32 );
142
+ } else {
143
+ $ details ['password ' ] = $ this ->ask ('Please specify a password for the new admin user (8 characters min) ' );
144
+ }
145
+ } else {
146
+ $ details ['password ' ] = Str::random (32 );
147
+ }
148
+ }
149
+
150
+ return $ details ;
151
+ }
152
+
81
153
protected function snakeCaseOptions (): array
82
154
{
83
155
$ returnOpts = [];
0 commit comments