]> BookStack Code Mirror - bookstack/commitdiff
Added command to add a new admin user
authorDan Brown <redacted>
Sun, 28 Jan 2018 18:09:26 +0000 (18:09 +0000)
committerDan Brown <redacted>
Sun, 28 Jan 2018 18:09:26 +0000 (18:09 +0000)
Closes #609

app/Console/Commands/CreateAdmin.php [new file with mode: 0644]
app/Http/Controllers/UserController.php
app/Repos/UserRepo.php
config/services.php
tests/CommandsTest.php

diff --git a/app/Console/Commands/CreateAdmin.php b/app/Console/Commands/CreateAdmin.php
new file mode 100644 (file)
index 0000000..c7a9969
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+namespace BookStack\Console\Commands;
+
+use BookStack\Repos\UserRepo;
+use Illuminate\Console\Command;
+
+class CreateAdmin extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'bookstack:create-admin
+                            {--email= : The email address for the new admin user}
+                            {--name= : The name of the new admin user}
+                            {--password= : The password to assign to the new admin user}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Add a new admin user to the system';
+
+    protected $userRepo;
+
+    /**
+     * Create a new command instance.
+     *
+     * @param UserRepo $userRepo
+     */
+    public function __construct(UserRepo $userRepo)
+    {
+        $this->userRepo = $userRepo;
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     * @throws \BookStack\Exceptions\NotFoundException
+     */
+    public function handle()
+    {
+        $email = trim($this->option('email'));
+        if (empty($email)) {
+            $email = $this->ask('Please specify an email address for the new admin user');
+        }
+        if (strlen($email) < 5 || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
+            return $this->error('Invalid email address provided');
+        }
+
+        if ($this->userRepo->getByEmail($email) !== null) {
+            return $this->error('A user with the provided email already exists!');
+        }
+
+        $name = trim($this->option('name'));
+        if (empty($name)) {
+            $name = $this->ask('Please specify an name for the new admin user');
+        }
+        if (strlen($name) < 2) {
+            return $this->error('Invalid name provided');
+        }
+
+        $password = trim($this->option('password'));
+        if (empty($password)) {
+            $password = $this->secret('Please specify a password for the new admin user');
+        }
+        if (strlen($password) < 5) {
+            return $this->error('Invalid password provided, Must be at least 5 characters');
+        }
+
+
+        $user = $this->userRepo->create(['email' => $email, 'name' => $name, 'password' => $password]);
+        $this->userRepo->attachSystemRole($user, 'admin');
+        $this->userRepo->downloadGravatarToUserAvatar($user);
+        $user->email_confirmed = true;
+        $user->save();
+
+        $this->info("Admin account with email \"{$user->email}\" successfully created!");
+    }
+}
index 7aa7b31d23cbba64418c52a47d91351e0e1c6679..d50baa86f484b59bc14fd491c457d1c86209fd62 100644 (file)
@@ -93,16 +93,7 @@ class UserController extends Controller
             $user->roles()->sync($roles);
         }
 
-        // Get avatar from gravatar and save
-        if (!config('services.disable_services')) {
-            try {
-                $avatar = \Images::saveUserGravatar($user);
-                $user->avatar()->associate($avatar);
-                $user->save();
-            } catch (Exception $e) {
-                \Log::error('Failed to save user gravatar image');
-            }
-        }
+        $this->userRepo->downloadGravatarToUserAvatar($user);
 
         return redirect('/settings/users');
     }
index d329c307c81c5e4f1e422370c114292ac5a0cd90..3cfd61d279b427dd79400180659ec6504df722eb 100644 (file)
@@ -1,6 +1,7 @@
 <?php namespace BookStack\Repos;
 
 use Activity;
+use BookStack\Exceptions\NotFoundException;
 use BookStack\Image;
 use BookStack\Role;
 use BookStack\User;
@@ -86,16 +87,7 @@ class UserRepo
         $this->attachDefaultRole($user);
 
         // Get avatar from gravatar and save
-        if (!config('services.disable_services')) {
-            try {
-                $avatar = Images::saveUserGravatar($user);
-                $user->avatar()->associate($avatar);
-                $user->save();
-            } catch (Exception $e) {
-                $user->save();
-                \Log::error('Failed to save user gravatar image');
-            }
-        }
+        $this->downloadGravatarToUserAvatar($user);
 
         return $user;
     }
@@ -113,6 +105,21 @@ class UserRepo
         $user->attachRoleId($roleId);
     }
 
+    /**
+     * Assign a user to a system-level role.
+     * @param User $user
+     * @param $systemRoleName
+     * @throws NotFoundException
+     */
+    public function attachSystemRole(User $user, $systemRoleName)
+    {
+        $role = $this->role->newQuery()->where('system_name', '=', $systemRoleName)->first();
+        if ($role === null) {
+            throw new NotFoundException("Role '{$systemRoleName}' not found");
+        }
+        $user->attachRole($role);
+    }
+
     /**
      * Checks if the give user is the only admin.
      * @param User $user
@@ -228,4 +235,28 @@ class UserRepo
     {
         return $this->role->where('system_name', '!=', 'admin')->get();
     }
+
+    /**
+     * Get a gravatar image for a user and set it as their avatar.
+     * Does not run if gravatar disabled in config.
+     * @param User $user
+     * @return bool
+     */
+    public function downloadGravatarToUserAvatar(User $user)
+    {
+        // Get avatar from gravatar and save
+        if (!config('services.gravatar')) {
+            return false;
+        }
+
+        try {
+            $avatar = Images::saveUserGravatar($user);
+            $user->avatar()->associate($avatar);
+            $user->save();
+            return true;
+        } catch (Exception $e) {
+            \Log::error('Failed to save user gravatar image');
+            return false;
+        }
+    }
 }
index 8695ea91c461ddae30b43caaaa93089e5f6c3e4a..18649c093ef379b996ca6fcbb6c96e2fc4891098 100644 (file)
@@ -16,6 +16,7 @@ return [
 
     // Single option to disable non-auth external services such as Gravatar and Draw.io
     'disable_services' => env('DISABLE_EXTERNAL_SERVICES', false),
+    'gravatar' => env('GRAVATAR', !env('DISABLE_EXTERNAL_SERVICES', false)),
     'drawio' => env('DRAWIO', !env('DISABLE_EXTERNAL_SERVICES', false)),
 
 
index 5df82ee513aeef49c2bc6d5f837539f5bc46c37c..25516c31732bd04ae2ba9f6dc8743305b6b245be 100644 (file)
@@ -3,6 +3,7 @@
 use BookStack\JointPermission;
 use BookStack\Page;
 use BookStack\Repos\EntityRepo;
+use BookStack\User;
 
 class CommandsTest extends TestCase
 {
@@ -99,4 +100,22 @@ class CommandsTest extends TestCase
 
         $this->assertDatabaseHas('joint_permissions', ['entity_id' => $page->id]);
     }
+
+    public function test_add_admin_command()
+    {
+        $exitCode = \Artisan::call('bookstack:create-admin', [
+            '--email' => '[email protected]',
+            '--name' => 'Admin Test',
+            '--password' => 'testing-4',
+        ]);
+        $this->assertTrue($exitCode === 0, 'Command executed successfully');
+
+        $this->assertDatabaseHas('users', [
+            'email' => '[email protected]',
+            'name' => 'Admin Test'
+        ]);
+
+        $this->assertTrue(User::where('email', '=', '[email protected]')->first()->hasSystemRole('admin'), 'User has admin role as expected');
+        $this->assertTrue(\Auth::attempt(['email' => '[email protected]', 'password' => 'testing-4']), 'Password stored as expected');
+    }
 }