@@ -21,7 +21,9 @@ class CreateAdminCommand extends Command
2121 {--email= : The email address for the new admin user}
2222 {--name= : The name of the new admin user}
2323 {--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)} ' ;
24+ {--external-auth-id= : The external authentication system id for the new admin user (SAML2/LDAP/OIDC)}
25+ {--generate-password : Generate a random password for the new admin user}
26+ {--first-admin : Indicate if this should set/update the details of the initial admin user} ' ;
2527
2628 /**
2729 * The console command description.
@@ -35,23 +37,9 @@ class CreateAdminCommand extends Command
3537 */
3638 public function handle (UserRepo $ userRepo ): int
3739 {
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- }
40+ $ firstAdminOnly = $ this ->option ('first-admin ' );
41+ $ shouldGeneratePassword = $ this ->option ('generate-password ' );
42+ $ details = $ this ->gatherDetails ($ shouldGeneratePassword );
5543
5644 $ validator = Validator::make ($ details , [
5745 'email ' => ['required ' , 'email ' , 'min:5 ' , new Unique ('users ' , 'email ' )],
@@ -68,16 +56,81 @@ public function handle(UserRepo $userRepo): int
6856 return 1 ;
6957 }
7058
59+ $ adminRole = Role::getSystemRole ('admin ' );
60+
61+ if ($ firstAdminOnly ) {
62+ $ handled = $ this ->handleFirstAdminIfExists ($ userRepo , $ details , $ shouldGeneratePassword , $ adminRole );
63+ if ($ handled ) {
64+ return 0 ;
65+ }
66+ }
67+
7168 $ user = $ userRepo ->createWithoutActivity ($ validator ->validated ());
72- $ user ->attachRole (Role:: getSystemRole ( ' admin ' ) );
69+ $ user ->attachRole ($ adminRole );
7370 $ user ->email_confirmed = true ;
7471 $ user ->save ();
7572
76- $ this ->info ("Admin account with email \"{$ user ->email }\" successfully created! " );
73+ if ($ shouldGeneratePassword ) {
74+ $ this ->line ($ details ['password ' ]);
75+ } else {
76+ $ this ->info ("Admin account with email \"{$ user ->email }\" successfully created! " );
77+ }
7778
7879 return 0 ;
7980 }
8081
82+ /**
83+ * Handle updates to the first admin if exists.
84+ * Returns true if the action has been handled (user updated or already a non-default admin user) otherwise
85+ * returns false if no action has been taken, and we therefore need to proceed with a normal account creation.
86+ */
87+ protected function handleFirstAdminIfExists (UserRepo $ userRepo , array $ data , bool $ generatePassword , Role $ adminRole ): bool
88+ {
89+ $ defaultAdmin =
$ userRepo->
getByEmail (
'[email protected] ' );
90+ if ($ defaultAdmin && $ defaultAdmin ->hasSystemRole ('admin ' )) {
91+ $ userRepo ->updateWithoutActivity ($ defaultAdmin , $ data , true );
92+ if ($ generatePassword ) {
93+ $ this ->line ($ data ['password ' ]);
94+ } else {
95+ $ this ->info ("The default admin user has been updated with the provided details! " );
96+ }
97+
98+ return true ;
99+ } else if ($ adminRole ->users ()->count () > 0 ) {
100+ $ this ->warn ('Non-default admin user already exists. Skipping creation of new admin user. ' );
101+ return true ;
102+ }
103+
104+ return false ;
105+ }
106+
107+ protected function gatherDetails (bool $ generatePassword ): array
108+ {
109+ $ details = $ this ->snakeCaseOptions ();
110+
111+ if (empty ($ details ['email ' ])) {
112+ $ details ['email ' ] = $ this ->ask ('Please specify an email address for the new admin user ' );
113+ }
114+
115+ if (empty ($ details ['name ' ])) {
116+ $ details ['name ' ] = $ this ->ask ('Please specify a name for the new admin user ' );
117+ }
118+
119+ if (empty ($ details ['password ' ])) {
120+ if (empty ($ details ['external_auth_id ' ])) {
121+ if ($ generatePassword ) {
122+ $ details ['password ' ] = Str::random (32 );
123+ } else {
124+ $ details ['password ' ] = $ this ->ask ('Please specify a password for the new admin user (8 characters min) ' );
125+ }
126+ } else {
127+ $ details ['password ' ] = Str::random (32 );
128+ }
129+ }
130+
131+ return $ details ;
132+ }
133+
81134 protected function snakeCaseOptions (): array
82135 {
83136 $ returnOpts = [];
0 commit comments