Browse Source

Set user to orphan 2FAs/groups when behind auth proxy - Fix #176

Bubka 2 years ago
parent
commit
a584c21670

+ 9 - 0
app/Api/v1/Controllers/GroupController.php

@@ -9,6 +9,7 @@ use App\Api\v1\Resources\TwoFAccountCollection;
 use App\Facades\Groups;
 use App\Http\Controllers\Controller;
 use App\Models\Group;
+use App\Models\User;
 use Illuminate\Http\Request;
 
 class GroupController extends Controller
@@ -20,6 +21,14 @@ class GroupController extends Controller
      */
     public function index(Request $request)
     {
+        // Quick fix for #176
+        if (config('auth.defaults.guard') === 'reverse-proxy-guard' && User::count() === 1) {
+            if (Group::orphans()->exists()) {
+                $groups = Group::orphans()->get();
+                Groups::setUser($groups, $request->user());
+            }
+        }
+        
         // We do not use fluent call all over the call chain to ease tests
         $user   = $request->user();
         $groups = $user->groups()->withCount('twofaccounts')->get();

+ 9 - 0
app/Api/v1/Controllers/TwoFAccountController.php

@@ -18,6 +18,7 @@ use App\Facades\TwoFAccounts;
 use App\Helpers\Helpers;
 use App\Http\Controllers\Controller;
 use App\Models\TwoFAccount;
+use App\Models\User;
 use Illuminate\Http\Request;
 use Illuminate\Support\Arr;
 
@@ -30,6 +31,14 @@ class TwoFAccountController extends Controller
      */
     public function index(Request $request)
     {
+        // Quick fix for #176
+        if (config('auth.defaults.guard') === 'reverse-proxy-guard' && User::count() === 1) {
+            if (TwoFAccount::orphans()->exists()) {
+                $twofaccounts = TwoFAccount::orphans()->get();
+                TwoFAccounts::setUser($twofaccounts, $request->user());
+            }
+        }
+
         return new TwoFAccountCollection($request->user()->twofaccounts->sortBy('order_column'));
     }
 

+ 11 - 0
app/Models/Group.php

@@ -103,4 +103,15 @@ class Group extends Model
    {
        return $this->belongsTo(\App\Models\User::class);
    }
+
+   /**
+    * Scope a query to only include orphan (userless) groups.
+    *
+    * @param  \Illuminate\Database\Eloquent\Builder<User>  $query
+    * @return \Illuminate\Database\Eloquent\Builder<User>
+    */
+   public function scopeOrphans($query)
+   {
+       return $query->where('user_id', null);
+   }
 }

+ 11 - 0
app/Models/TwoFAccount.php

@@ -215,6 +215,17 @@ class TwoFAccount extends Model implements Sortable
         return $this->belongsTo(\App\Models\User::class);
     }
 
+    /**
+     * Scope a query to only include orphan (userless) accounts.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder<User>  $query
+     * @return \Illuminate\Database\Eloquent\Builder<User>
+     */
+    public function scopeOrphans($query)
+    {
+        return $query->where('user_id', null);
+    }
+
     /**
      * Get legacy_uri attribute
      *

+ 14 - 0
app/Services/GroupService.php

@@ -60,6 +60,20 @@ class GroupService
         return $groups->prepend($theAllGroup);
     }
 
+    /**
+     * Set owner of given groups
+     * 
+     * @param  Collection<int, Group>  $groups
+     * @param  \App\Models\User  $user
+     */
+    public static function setUser(Collection $groups, User $user) : void
+    {
+        $groups->each(function ($group, $key) use ($user) {
+            $group->user_id = $user->id;
+            $group->save();
+        });
+    }
+
     /**
      * Determines the default group of the given user
      *

+ 15 - 0
app/Services/TwoFAccountService.php

@@ -5,6 +5,7 @@ namespace App\Services;
 use App\Factories\MigratorFactoryInterface;
 use App\Helpers\Helpers;
 use App\Models\TwoFAccount;
+use App\Models\User;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Log;
@@ -93,6 +94,20 @@ class TwoFAccountService
         return $deleted;
     }
 
+    /**
+     * Set owner of given twofaccounts
+     * 
+     * @param  \Illuminate\Support\Collection<int, TwoFAccount>  $twofaccounts
+     * @param  \App\Models\User  $user
+     */
+    public static function setUser(Collection $twofaccounts, User $user) : void
+    {
+        $twofaccounts->each(function ($twofaccount, $key) use ($user) {
+            $twofaccount->user_id = $user->id;
+            $twofaccount->save();
+        });
+    }
+
     /**
      * Return the given collection with items marked as Duplicates (using id=-1) if similar records exist
      * in the authenticated user accounts