diff --git a/app/config/auth.php b/app/config/auth.php index 75c8de7d76..6e606f0ebe 100644 --- a/app/config/auth.php +++ b/app/config/auth.php @@ -9,7 +9,7 @@ return [ 'table' => 'password_reminders', 'expire' => 60, ], - 'verify_mail' => false, + 'verify_mail' => true, 'verify_reset' => true, 'allow_register' => true diff --git a/app/controllers/UserController.php b/app/controllers/UserController.php index ab0570fa82..0e7d7d813c 100644 --- a/app/controllers/UserController.php +++ b/app/controllers/UserController.php @@ -6,6 +6,12 @@ use Firefly\Storage\User\UserRepositoryInterface as URI; class UserController extends BaseController { + /** + * Constructor. + * + * @param URI $user + * @param EHI $email + */ public function __construct(URI $user, EHI $email) { $this->user = $user; @@ -13,11 +19,22 @@ class UserController extends BaseController } + /** + * Show the login view. + * + * @return \Illuminate\View\View + */ public function login() { return View::make('user.login'); } + + /** + * Login. + * + * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View + */ public function postLogin() { $rememberMe = Input::get('remember_me') == '1'; @@ -33,6 +50,11 @@ class UserController extends BaseController return View::make('user.login'); } + /** + * If allowed, show the register form. + * + * @return $this|\Illuminate\View\View + */ public function register() { if (Config::get('auth.allow_register') !== true) { @@ -41,6 +63,16 @@ class UserController extends BaseController return View::make('user.register'); } + /** + * If allowed, register the user. + * + * Then: + * + * - Send password OR + * - Send reset code. + * + * @return $this|\Illuminate\View\View + */ public function postRegister() { if (Config::get('auth.allow_register') !== true) { @@ -58,17 +90,34 @@ class UserController extends BaseController return View::make('user.register'); } + /** + * Logout user. + * + * @return \Illuminate\Http\RedirectResponse + */ public function logout() { Auth::logout(); + Session::flush(); return Redirect::route('index'); } + /** + * Show form to help user get a new password. + * + * @return \Illuminate\View\View + */ public function remindme() { return View::make('user.remindme'); } + /** + * If need to verify, send new reset code. + * Otherwise, send new password. + * + * @return \Illuminate\View\View + */ public function postRemindme() { $user = $this->user->findByEmail(Input::get('email')); @@ -85,16 +134,13 @@ class UserController extends BaseController } - public function verify($verification) - { - $user = $this->user->findByVerification($verification); - if ($user) { - $this->email->sendPasswordMail($user); - return View::make('user.registered'); - } - return View::make('error')->with('message', 'Yo no hablo verification code!'); - } - + /** + * Send a user a password based on his reset code. + * + * @param $reset + * + * @return $this|\Illuminate\View\View + */ public function reset($reset) { $user = $this->user->findByReset($reset); diff --git a/app/database/migrations/2014_06_27_163032_create_users_table.php b/app/database/migrations/2014_06_27_163032_create_users_table.php index 29ea724880..c104d7ca98 100644 --- a/app/database/migrations/2014_06_27_163032_create_users_table.php +++ b/app/database/migrations/2014_06_27_163032_create_users_table.php @@ -18,7 +18,6 @@ class CreateUsersTable extends Migration { $table->timestamps(); $table->string('email',100); $table->string('password',60); - $table->string('verification',32)->nullable(); $table->string('reset',32)->nullable(); $table->string('remember_token',255)->nullable(); $table->boolean('migrated'); diff --git a/app/database/seeds/DefaultUserSeeder.php b/app/database/seeds/DefaultUserSeeder.php index f8cebf254d..4babf03f25 100644 --- a/app/database/seeds/DefaultUserSeeder.php +++ b/app/database/seeds/DefaultUserSeeder.php @@ -16,7 +16,6 @@ class DefaultUserSeeder extends Seeder [ 'email' => 's@nder.be', 'password' => Hash::make('sander'), - 'verification' => null, 'reset' => null, 'remember_token' => null, 'migrated' => false diff --git a/app/lib/Firefly/Exception/FireflyException.php b/app/lib/Firefly/Exception/FireflyException.php new file mode 100644 index 0000000000..2fcdae1733 --- /dev/null +++ b/app/lib/Firefly/Exception/FireflyException.php @@ -0,0 +1,14 @@ +verification = $verification; + $reset = \Str::random(32); + $user->reset = $reset; $user->save(); $email = $user->email; - $data = ['verification' => $verification]; + $data = ['reset' => $reset]; \Mail::send( ['emails.user.verify-html', 'emails.user.verify-text'], $data, function ($message) use ($email) { @@ -24,7 +24,7 @@ class EmailHelper implements EmailHelperInterface $password = \Str::random(12); $user->password = \Hash::make($password); - $user->verification = \Str::random(32); // new one. + $user->reset = \Str::random(32); // new one. $user->save(); $email = $user->email; diff --git a/app/lib/Firefly/Helper/HelperServiceProvider.php b/app/lib/Firefly/Helper/HelperServiceProvider.php index b1caf87e12..02f5814510 100644 --- a/app/lib/Firefly/Helper/HelperServiceProvider.php +++ b/app/lib/Firefly/Helper/HelperServiceProvider.php @@ -15,6 +15,12 @@ class HelperServiceProvider extends ServiceProvider 'Firefly\Helper\Email\EmailHelperInterface', 'Firefly\Helper\Email\EmailHelper' ); + + // migration: + $this->app->bind( + 'Firefly\Helper\Migration\MigrationHelperInterface', + 'Firefly\Helper\Migration\MigrationHelper' + ); } } \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Migration/MigrationHelper.php b/app/lib/Firefly/Helper/Migration/MigrationHelper.php index a01effa954..3336485f16 100644 --- a/app/lib/Firefly/Helper/Migration/MigrationHelper.php +++ b/app/lib/Firefly/Helper/Migration/MigrationHelper.php @@ -24,6 +24,7 @@ class MigrationHelper implements MigrationHelperInterface { // file does not exist: if (!file_exists($this->path)) { + \Log::error('Migration file ' . $this->path . ' does not exist!'); return false; } @@ -38,20 +39,39 @@ class MigrationHelper implements MigrationHelperInterface if (is_null($this->JSON)) { return false; } + \Log::info('Migration file ' . $this->path . ' is valid!'); + return true; } public function migrate() { + \Log::info('Start of migration.'); + \DB::beginTransaction(); - // create the accounts: - $this->_createAccounts(); + try { + $this->_importAccounts(); + $this->_importComponents(); + $this->_importPiggybanks(); + + + } catch (\Firefly\Exception\FireflyException $e) { + \DB::rollBack(); + \Log::error('Rollback because of error!'); + \Log::error($e->getMessage()); + return false; + } + + \DB::commit(); + \Log::info('Done!'); + return true; } - protected function _createAccounts() + protected function _importAccounts() { - $accounts = App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - + /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ + $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); + \Log::info('Going to import ' . count($this->JSON->accounts) . ' accounts.'); foreach ($this->JSON->accounts as $entry) { // create account: if ($entry->openingbalance == 0) { @@ -59,13 +79,66 @@ class MigrationHelper implements MigrationHelperInterface } else { $account = $accounts->storeWithInitialBalance( ['name' => $entry->name], - new Carbon($entry->openingbalancedate), + new \Carbon\Carbon($entry->openingbalancedate), floatval($entry->openingbalance) ); } - if ($account) { - $this->map['accounts'][$entry->id] = $account->id; - } + $this->map['accounts'][$entry->id] = $account->id; + \Log::info('Imported account "' . $entry->name . '" with balance ' . $entry->openingbalance); } } + + protected function _importComponents() + { + $beneficiaryAT = \AccountType::where('description', 'Beneficiary account')->first(); + $budgetType = \ComponentType::where('type', 'budget')->first(); + $categoryType = \ComponentType::where('type', 'category')->first(); + foreach ($this->JSON->components as $entry) { + switch ($entry->type->type) { + case 'beneficiary': + $beneficiary = $this->_importBeneficiary($entry, $beneficiaryAT); + $this->map['accounts'][$entry->id] = $beneficiary->id; + break; + case 'category': + $component = $this->_importComponent($entry, $categoryType); + $this->map['components'][$entry->id] = $component->id; + break; + case 'budget': + $component = $this->_importComponent($entry, $budgetType); + $this->map['components'][$entry->id] = $component->id; + break; + } + + } + } + + protected function _importPiggybanks() { + + /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ + $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); + + // get type for piggy: + $piggyAT = \AccountType::where('description', 'Piggy bank')->first(); + foreach($this->JSON->piggybanks as $piggyBank) { + } + } + + protected function _importBeneficiary($component, \AccountType $beneficiaryAT) + { + /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ + $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); + return $accounts->store( + [ + 'name' => $component->name, + 'account_type' => $beneficiaryAT + ] + ); + } + + protected function _importComponent($component, \ComponentType $type) + { + /** @var \Firefly\Storage\Component\ComponentRepositoryInterface $components */ + $components = \App::make('Firefly\Storage\Component\ComponentRepositoryInterface'); + return $components->store(['name' => $component->name, 'component_type' => $type]); + } } \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php b/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php index 10a39e39e2..81e5ee3d60 100644 --- a/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php +++ b/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php @@ -3,6 +3,8 @@ namespace Firefly\Storage\Account; +use Firefly\Helper\MigrationException; + class EloquentAccountRepository implements AccountRepositoryInterface { public $validator; @@ -28,11 +30,17 @@ class EloquentAccountRepository implements AccountRepositoryInterface $initial->user()->associate(\Auth::user()); $initial->name = $data['name'] . ' initial balance'; $initial->active = 0; - $initial->save(); + try { + $initial->save(); + } catch (\Illuminate\Database\QueryException $e) { + \Log::error('DB ERROR: ' . $e->getMessage()); + throw new FireflyException('Could not save counterbalance account for ' . $data['name']); + } // create new transaction journal (and transactions): - /** @var \Firefly\Storage\TransactionJournal\TransactionJournalInterface $transactionJournal */ - $transactionJournal = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalInterface'); + /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $transactionJournal */ + $transactionJournal = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); + $transactionJournal->createSimpleJournal( $initial, $account, 'Initial Balance for ' . $data['name'], $amount, $date ); @@ -54,7 +62,13 @@ class EloquentAccountRepository implements AccountRepositoryInterface $account->user()->associate(\Auth::user()); $account->name = $data['name']; $account->active = isset($data['active']) ? $data['active'] : 1; - $account->save(); + try { + $account->save(); + } catch (\Illuminate\Database\QueryException $e) { + \Log::error('DB ERROR: ' . $e->getMessage()); + throw new \Firefly\Exception\FireflyException('Could not save account ' . $data['name']); + } + return $account; } diff --git a/app/lib/Firefly/Storage/Component/ComponentRepositoryInterface.php b/app/lib/Firefly/Storage/Component/ComponentRepositoryInterface.php new file mode 100644 index 0000000000..72745564f5 --- /dev/null +++ b/app/lib/Firefly/Storage/Component/ComponentRepositoryInterface.php @@ -0,0 +1,14 @@ +accounts()->count(); + + } + + + public function store($data) + { + if (!isset($data['component_type'])) { + throw new \Firefly\Exception\FireflyException('No component type present.'); + } + $component = new \Component; + $component->componentType()->associate($data['component_type']); + $component->name = $data['name']; + $component->user()->associate(\Auth::user()); + try { + $component->save(); + } catch (\Illuminate\Database\QueryException $e) { + \Log::error('DB ERROR: ' . $e->getMessage()); + throw new \Firefly\Exception\FireflyException('Could not save component ' . $data['name']); + } + + return $component; + } + +} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/StorageServiceProvider.php b/app/lib/Firefly/Storage/StorageServiceProvider.php index 644bc46200..e2c9d326c4 100644 --- a/app/lib/Firefly/Storage/StorageServiceProvider.php +++ b/app/lib/Firefly/Storage/StorageServiceProvider.php @@ -21,9 +21,13 @@ class StorageServiceProvider extends ServiceProvider 'Firefly\Storage\Account\EloquentAccountRepository' ); $this->app->bind( - 'Firefly\Storage\TransactionJournal\TransactionJournalInterface', + 'Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface', 'Firefly\Storage\TransactionJournal\EloquentTransactionJournalRepository' ); + $this->app->bind( + 'Firefly\Storage\Component\ComponentRepositoryInterface', + 'Firefly\Storage\Component\EloquentComponentRepository' + ); } } \ No newline at end of file diff --git a/app/lib/Firefly/Storage/TransactionJournal/EloquentTransactionJournalRepository.php b/app/lib/Firefly/Storage/TransactionJournal/EloquentTransactionJournalRepository.php index d56065b148..515cb5ad38 100644 --- a/app/lib/Firefly/Storage/TransactionJournal/EloquentTransactionJournalRepository.php +++ b/app/lib/Firefly/Storage/TransactionJournal/EloquentTransactionJournalRepository.php @@ -9,7 +9,7 @@ namespace Firefly\Storage\TransactionJournal; -class EloquentTransactionJournalRepository implements TransactionJournalInterface +class EloquentTransactionJournalRepository implements TransactionJournalRepositoryInterface { public function createSimpleJournal(\Account $from, \Account $to, $description, $amount, \Carbon\Carbon $date) @@ -45,6 +45,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalInterfac $toAT = $to->accountType->description; $fromAT = $from->accountType->description; + $journalType = null; switch (true) { // is withdrawal from one of your own accounts: @@ -66,8 +67,17 @@ class EloquentTransactionJournalRepository implements TransactionJournalInterfac $journalType = \TransactionType::where('type', 'Deposit')->first(); break; } + if (is_null($journalType)) { + \Log::error('Could not figure out transacion type!'); + throw new \Firefly\Exception\FireflyException('Could not figure out transaction type.'); + } + // always the same currency: $currency = \TransactionCurrency::where('code', 'EUR')->first(); + if (is_null($currency)) { + \Log::error('No currency for journal!'); + throw new \Firefly\Exception\FireflyException('No currency for journal!'); + } // new journal: $journal = new \TransactionJournal(); @@ -77,7 +87,9 @@ class EloquentTransactionJournalRepository implements TransactionJournalInterfac $journal->description = $description; $journal->date = $date; if (!$journal->isValid()) { - return false; + \Log::error('Cannot create valid journal.'); + \Log::error('Errors: ' . print_r($journal->validator->messages()->all(), true)); + throw new \Firefly\Exception\FireflyException('Cannot create valid journal.'); } $journal->save(); @@ -88,7 +100,9 @@ class EloquentTransactionJournalRepository implements TransactionJournalInterfac $fromTransaction->description = null; $fromTransaction->amount = $amountFrom; if (!$fromTransaction->isValid()) { - return false; + \Log::error('Cannot create valid transaction (from) for journal #' . $journal->id); + \Log::error('Errors: ' . print_r($fromTransaction->validator->messages()->all(), true)); + throw new \Firefly\Exception\FireflyException('Cannot create valid transaction (from).'); } $fromTransaction->save(); @@ -98,7 +112,11 @@ class EloquentTransactionJournalRepository implements TransactionJournalInterfac $toTransaction->description = null; $toTransaction->amount = $amountTo; if (!$toTransaction->isValid()) { - return false; + if (!$toTransaction->isValid()) { + \Log::error('Cannot create valid transaction (to) for journal #' . $journal->id); + \Log::error('Errors: ' . print_r($toTransaction->validator->messages()->all(), true)); + throw new \Firefly\Exception\FireflyException('Cannot create valid transaction (to).'); + } } $toTransaction->save(); @@ -107,7 +125,6 @@ class EloquentTransactionJournalRepository implements TransactionJournalInterfac return; - echo 'saved!'; } diff --git a/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalInterface.php b/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php similarity index 83% rename from app/lib/Firefly/Storage/TransactionJournal/TransactionJournalInterface.php rename to app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php index f0239936a1..fe7fb8cffc 100644 --- a/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalInterface.php +++ b/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php @@ -9,7 +9,7 @@ namespace Firefly\Storage\TransactionJournal; -interface TransactionJournalInterface { +interface TransactionJournalRepositoryInterface { public function createSimpleJournal(\Account $from, \Account $to, $description, $amount, \Carbon\Carbon $date); diff --git a/app/lib/Firefly/Storage/User/EloquentUserRepository.php b/app/lib/Firefly/Storage/User/EloquentUserRepository.php index 855f5415d5..35365aaaca 100644 --- a/app/lib/Firefly/Storage/User/EloquentUserRepository.php +++ b/app/lib/Firefly/Storage/User/EloquentUserRepository.php @@ -14,12 +14,12 @@ class EloquentUserRepository implements UserRepositoryInterface $user = new \User; $user->email = isset($array['email']) ? $array['email'] : null; $user->migrated = 0; - $user->verification = \Str::random(32); + $user->reset = \Str::random(32); $user->password = \Hash::make(\Str::random(12)); if (!$user->isValid()) { \Log::error('Invalid user'); - \Session::flash('error', 'Input invalid, please try again.'); + \Session::flash('error', 'Input invalid, please try again: ' . $user->validator->messages()->first()); return false; } $user->save(); @@ -36,11 +36,6 @@ class EloquentUserRepository implements UserRepositoryInterface return false; } - public function findByVerification($verification) - { - return \User::where('verification', $verification)->first(); - } - public function findByReset($reset) { return \User::where('reset', $reset)->first(); diff --git a/app/lib/Firefly/Storage/User/UserRepositoryInterface.php b/app/lib/Firefly/Storage/User/UserRepositoryInterface.php index 2aef50b4b3..b092658bcf 100644 --- a/app/lib/Firefly/Storage/User/UserRepositoryInterface.php +++ b/app/lib/Firefly/Storage/User/UserRepositoryInterface.php @@ -10,12 +10,11 @@ interface UserRepositoryInterface public function auth($array); - public function findByVerification($verification); public function findByReset($reset); public function findByEmail($email); - public function updatePassword(\User $user,$password); + public function updatePassword(\User $user, $password); } \ No newline at end of file diff --git a/app/models/Component.php b/app/models/Component.php index cd86792b62..7407255d17 100644 --- a/app/models/Component.php +++ b/app/models/Component.php @@ -1,8 +1,16 @@ 'exists:users,id|required', + 'name' => 'required|between:1,255', + 'component_type_id' => 'required|exists:component_types,id' + ]; + + public function componentType() { return $this->belongsTo('ComponentType'); diff --git a/app/models/TransactionJournal.php b/app/models/TransactionJournal.php index 6f2f8f9cf7..099fd09a9b 100644 --- a/app/models/TransactionJournal.php +++ b/app/models/TransactionJournal.php @@ -10,6 +10,7 @@ class TransactionJournal extends Elegant 'transaction_currency_id' => 'required|exists:transaction_currencies,id', 'description' => 'between:1,255', 'date' => 'date', + 'completed' => 'required|between:0,1' ]; public function transactionType() diff --git a/app/models/User.php b/app/models/User.php index f6f3ba91d2..51cde6260a 100644 --- a/app/models/User.php +++ b/app/models/User.php @@ -1,9 +1,9 @@ 'required|email|unique:users,email', + 'migrated' => 'required|numeric|between:0,1', + 'password' => 'required|between:60,60', + 'reset' => 'between:32,32', + ]; /** * The database table used by the model. * * @var string */ protected $table = 'users'; - - public static $rules - = [ - 'email' => 'required|email|unique:users,email', - 'migrated' => 'required|numeric|between:0,1', - 'password' => 'required|between:60,60', - 'verification' => 'between:32,32', - ]; - /** * The attributes excluded from the model's JSON form. * @@ -33,7 +31,8 @@ class User extends Elegant implements UserInterface, RemindableInterface */ protected $hidden = array('remember_token'); - public function accounts() { + public function accounts() + { return $this->hasMany('Account'); } diff --git a/app/routes.php b/app/routes.php index b6f5bbc517..ed721149db 100644 --- a/app/routes.php +++ b/app/routes.php @@ -30,7 +30,7 @@ Route::group(['before' => 'csrf|auth'], function () { ); // guest routes: -Route::group(['before' => 'csrf|auth'], function () { +Route::group(['before' => 'guest'], function () { // user controller Route::get('/login', ['uses' => 'UserController@login', 'as' => 'login']); Route::get('/register', ['uses' => 'UserController@register', 'as' => 'register']); diff --git a/app/views/emails/user/verify-html.blade.php b/app/views/emails/user/verify-html.blade.php index 3e29447837..961b9c79ac 100644 --- a/app/views/emails/user/verify-html.blade.php +++ b/app/views/emails/user/verify-html.blade.php @@ -9,7 +9,7 @@ Hi!

- To verify your registration, please verify your e-mail address. + To verify your registration, please verify your e-mail address.

Cya! diff --git a/app/views/emails/user/verify-text.blade.php b/app/views/emails/user/verify-text.blade.php index d37ef85306..5b82b79d99 100644 --- a/app/views/emails/user/verify-text.blade.php +++ b/app/views/emails/user/verify-text.blade.php @@ -2,6 +2,6 @@ Hi! To verify your registration, please verify your e-mail address: -{{route('verify',$verification)}} +{{route('reset',$reset)}} Cya! \ No newline at end of file