Browse Source

Move DB protection logic to a dedicated class

Bubka 4 years ago
parent
commit
6712613a20
2 changed files with 116 additions and 94 deletions
  1. 113 0
      app/Classes/DbProtection.php
  2. 3 94
      app/Http/Controllers/Settings/OptionController.php

+ 113 - 0
app/Classes/DbProtection.php

@@ -0,0 +1,113 @@
+<?php
+
+namespace App\Classes;
+
+use Throwable;
+use Exception;
+use App\TwoFAccount;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Crypt;
+
+class DbProtection
+{
+    /**
+     * Encrypt 2FA sensitive data
+     * @return boolean
+     */
+    public static function enable() : bool
+    {
+        // All existing records have to be encrypted without exception.
+        // This means that if any of the encryption failed we have to rollback
+        // all records to their original value.
+        
+        $EncryptFailed = false;
+        $twofaccounts = DB::table('twofaccounts')->get();
+
+        $twofaccounts->each(function ($item, $key) use(&$EncryptFailed) {
+            try {
+                $item->uri = Crypt::encryptString($item->uri);
+                $item->account = Crypt::encryptString($item->account);
+            }
+            catch (Exception $e) {
+                $EncryptFailed = true;
+                return false;
+            }
+        });
+                
+        if( $EncryptFailed ) {
+            return false;
+        }
+
+        return self::tryUpdate($twofaccounts);
+    }
+
+
+    /**
+     * Decrypt 2FA sensitive data
+     * @return boolean
+     */
+    public static function disable() : bool
+    {
+        // All existing records have to be decrypted without exception.
+        // This means that if any of the encryption failed we have to rollback
+        // all records to their original value.
+        
+        $DecryptFailed = false;
+        $EncryptedTwofaccounts = DB::table('twofaccounts')->get();
+
+        $EncryptedTwofaccounts->each(function ($item, $key) use(&$DecryptFailed) {
+            try {
+                $item->uri = Crypt::decryptString($item->uri);
+                $item->account = Crypt::decryptString($item->account);
+            }
+            catch (Exception $e) {
+                $DecryptFailed = true;
+                return false;
+            }
+        });
+                
+        if( $DecryptFailed ) {
+            return false;
+        }
+
+        return DbProtection::tryUpdate($EncryptedTwofaccounts);
+    }
+
+
+    /**
+     * Try to update all records of the collection
+     * @param  Illuminate\Database\Eloquent\Collection $twofaccounts
+     * @return boolean                  
+     */
+    private static function tryUpdate(\Illuminate\Support\Collection $twofaccounts) : bool
+    {
+        // The whole collection has its sensible data encrypted/decrypted, now we update the db
+        // using a transaction to ensure rollback if an exception is thrown
+
+        DB::beginTransaction();
+
+        try {
+            $twofaccounts->each(function ($item, $key) {
+                DB::table('twofaccounts')
+                    ->where('id', $item->id)
+                    ->update([
+                        'uri' => $item->uri,
+                        'account' => $item->account
+                    ]);
+            });
+
+            DB::commit();
+        }
+        // @codeCoverageIgnoreStart
+        // Dont now how to fake that :(
+        catch (Throwable $e) {
+            DB::rollBack();
+
+            return false;
+        }
+        // @codeCoverageIgnoreEnd
+
+        return true;
+    }
+
+}

+ 3 - 94
app/Http/Controllers/Settings/OptionController.php

@@ -2,15 +2,10 @@
 
 namespace App\Http\Controllers\Settings;
 
-use Throwable;
-use App\TwoFAccount;
 use App\Classes\Options;
 use Illuminate\Http\Request;
-use Illuminate\Support\Facades\DB;
+use App\Classes\DbProtection;
 use App\Http\Controllers\Controller;
-use Illuminate\Support\Facades\Crypt;
-use Illuminate\Contracts\Encryption\EncryptException;
-use Illuminate\Contracts\Encryption\DecryptException;
 
 class OptionController extends Controller
 {
@@ -42,14 +37,14 @@ class OptionController extends Controller
         if( $request->useEncryption && !Options::get('useEncryption') ) {
 
             // user enabled the encryption
-            if( !$this->encryptAccounts() ) {
+            if( !DbProtection::enable() ) {
                 return response()->json(['message' => __('errors.error_during_encryption'), 'settings' => Options::get()], 422);
             }
         }
         else if( !$request->useEncryption && Options::get('useEncryption') ) {
 
             // user disabled the encryption
-            if( !$this->decryptAccounts() ) {
+            if( !DbProtection::disable() ) {
                 return response()->json(['message' => __('errors.error_during_decryption'), 'settings' => Options::get()], 422);
             }
         }
@@ -60,90 +55,4 @@ class OptionController extends Controller
         return response()->json(['message' => __('settings.forms.setting_saved'), 'settings' => Options::get()], 200);
     }
 
-
-    /**
-     * Encrypt 2FA sensitive data
-     * @return boolean
-     */
-    private function encryptAccounts() : bool
-    {
-        // All existing records have to be encrypted without exception.
-        // This means that if any of the encryption failed we have to rollback
-        // all records to their original value.
-        
-        $twofaccounts = TwoFAccount::all();
-
-        $twofaccounts->each(function ($item, $key) {
-            try {
-                $item->uri = Crypt::encryptString($item->uri);
-                $item->account = Crypt::encryptString($item->account);
-            }
-            catch (EncryptException $e) {
-                return false;
-            }
-        });
-
-        return $this->tryUpdate($twofaccounts);
-    }
-
-
-    /**
-     * Decrypt 2FA sensitive data
-     * @return boolean
-     */
-    private function decryptAccounts() : bool
-    {
-        // All existing records have to be decrypted without exception.
-        // This means that if any of the encryption failed we have to rollback
-        // all records to their original value.
-        
-        $twofaccounts = TwoFAccount::all();
-
-        $twofaccounts->each(function ($item, $key) {
-            try {
-                $item->uri = Crypt::decryptString($item->uri);
-                $item->account = Crypt::decryptString($item->account);
-            }
-            catch (DecryptException $e) {
-                return false;
-            }
-        });
-
-        return $this->tryUpdate($twofaccounts);
-    }
-
-
-    /**
-     * Try to update all records of the collection
-     * @param  Illuminate\Database\Eloquent\Collection $twofaccounts
-     * @return boolean                  
-     */
-    private function tryUpdate(\Illuminate\Database\Eloquent\Collection $twofaccounts) : bool
-    {
-        // The whole collection has its sensible data encrypted/decrypted, now we update the db
-        // using a transaction to ensure rollback if an exception is thrown
-
-        DB::beginTransaction();
-
-        try {
-            $twofaccounts->each(function ($item, $key) {
-                DB::table('twofaccounts')
-                    ->where('id', $item->id)
-                    ->update([
-                        'uri' => $item->uri,
-                        'account' => $item->account
-                    ]);
-            });
-
-            DB::commit();
-        }
-        catch (Throwable $e) {
-            DB::rollBack();
-
-            return false;
-        }
-
-        return true;
-    }
-
 }