rappasoft/laravel-boilerplate

Would Like to add ability to use separate connection for Auth Domain

inmanturbo opened this issue · 4 comments

Before you create an issue make sure that:

  • Your issue is strictly related to the boilerplate itself. Questions about Laravel in general belongs to the laravel or laracasts forums.
  • You have read the documentation thoroughly.
  • You have searched for a similar issue among all the former issues (even closed ones).
  • You have tried to replicate the issue with a clean install of the project.

I would like to extend the Boilerplate's functionality to include configurable connection trait for the Auth Domain. This would allow users like myself to (optionally) use a separate database connection for the auth models. I personally use this usually just to set a prefix for all the auth tables that came form the boilerplate just so I know what I added and what was there initially. This also allows easily exporting users from one application to another, without disturbing any application data.

Since env(), config(), Schema::connection() and DB::connection() all default to null, and null simply returns the default connection, this won't be a breaking change.

In my own projects I've been adding the following to the boilerplate config:

    /*
    |--------------------------------------------------------------------------
    | Configurations for Domains
    |--------------------------------------------------------------------------
    |
    | Domain-specific configurations
    |
    */
    'domains' => [

      /*
      |--------------------------------------------------------------------------
      | Configurations for App\Domains\Auth
      |--------------------------------------------------------------------------
      |
      | Configurations specific to the Auth domain
      |
      */
        'auth' => [

            'database_connection' => env('AUTH_DB_CONNECTION'),
            'default_super_admin_name' => env('DEFAULT_SUPER_ADMIN_NAME', 'Super Admin'),
            'default_super_admin_email' => env('DEFAULT_SUPER_ADMIN_EMAIL', 'admin@admin.com'),
            'default_super_admin_password' => env('DEFAULT_SUPER_ADMIN_PASSWORD', 'secret'),
        ],

And adding the trait to the
Auth models:

<?php

namespace App\Domains\Auth\Models\Traits\Connection;

trait AuthConnection
{
    /**
     * Get the current connection name for the model.
     *
     * Maybe this should be in an abstract base class?
     * @return string
     */
    public function getConnectionName()
    {
        return config('boilerplate.domains.auth.database_connection');
    }
}

This includes publishing vendor/darkghosthunter/laraguard/config/laraguard.php to add the following:

-  'model' => \DarkGhostHunter\Laraguard\Eloquent\TwoFactorAuthentication::class,
+  'model' => \App\Domain\Auth\Models\TwoFactorAuthentication::class,

So that the trait can be added. And publishing the migration as well. I'm also using config('boilerplate.domains.auth.database_connection') in the migrations and to set the connection on the seeders, and well as adding a $connection = null parameter to the disableForeignKeys() enableForeignKeys and truncate() methods in the seeder traits, so that the connection can be used in their respective the calls to the DB facade. I'm also using

 <server name="AUTH_DB_CONNECTION" value="sqlite"/>

in phpunit.xml so that arbitrary connection changes don't break any tests.

Please let me know if you are interested in a PR.

I should mention that I've also had to add a method to the UserService for this to work:

    public function getTableName() : string
    {

        return $this->model->getConnectionName() .
            '.' .
            config('database.connections.' .
                $this->model->getConnectionName() .
                '.prefix') .
            $this->model->getTable();
    }

So that I could make the following change to App\Domains\Auth\Http\Controllers\Frontend\Auth\RegisterController::validator :

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:100'],
-            'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users')],
+            'email' => ['required', 'string', 'email', 'max:255', Rule::unique($this->userService->getTableName())],
            'password' => array_merge(['max:100'], PasswordRules::register($data['email'] ?? null)),
            'terms' => ['required', 'in:1'],
            'g-recaptcha-response' => ['required_if:captcha_status,true', new Captcha],
        ], [
            'terms.required' => __('You must accept the Terms & Conditions.'),
            'g-recaptcha-response.required_if' => __('validation.required', ['attribute' => 'captcha']),
        ]);
    }

Hmm I guess I don't fully understand the need. I feel like this would most likely confuse new people installing, and wouldn't probably be as useful to everyone. But i'm open to suggestions.

It's definitely a good thing to have here for other people to search on. I do my best to limit the amount of code I have to manage because over the years it has become quite large and I don't have as much time to work on all my open source as I used to. I appreciate the work and research you put into it. This project will hopefully grow with the times, maybe it will make its way into a future version.