From c61b156f1bd93ec4aadd8adc78523b42b0232918 Mon Sep 17 00:00:00 2001
From: Camil Staps
Date: Sun, 4 Sep 2016 23:30:15 +0200
Subject: User creation and authentication
---
 app/Http/Controllers/UserController.php | 67 +++++++++++++++++++++++++++
 app/Http/Middleware/Authenticate.php    | 45 ++++++++++++++++++
 app/Http/routes.php                     | 56 ++++++++++++++--------
 app/Observers/UserObserver.php          | 34 ++++++++++++++
 app/Providers/AppServiceProvider.php    | 25 ++++++----
 app/Providers/AuthServiceProvider.php   | 39 ++++++++++++++++
 app/User.php                            | 82 +++++++++++++++++++++++++++++++++
 7 files changed, 319 insertions(+), 29 deletions(-)
 create mode 100644 app/Http/Controllers/UserController.php
 create mode 100644 app/Http/Middleware/Authenticate.php
 create mode 100644 app/Observers/UserObserver.php
 create mode 100644 app/Providers/AuthServiceProvider.php
 create mode 100644 app/User.php
(limited to 'app')
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
new file mode 100644
index 0000000..7036439
--- /dev/null
+++ b/app/Http/Controllers/UserController.php
@@ -0,0 +1,67 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+namespace App\Http\Controllers;
+
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\ValidationException;
+use Laravel\Lumen\Routing\Controller as BaseController;
+
+use HebrewParseTrainer\User;
+
+class UserController extends BaseController {
+
+	public function createForm(Request $request) {
+		$messages = [];
+
+		if ($request->isMethod('post')) {
+			$validator = Validator::make($request->input(), [
+				'email'    => 'required|unique:users|email',
+				'name'     => 'required|unique:users',
+				'password' => 'required|confirmed|min:8',
+			]);
+
+			if ($validator->fails()) {
+				foreach ($validator->errors()->all() as $error) {
+					$messages[] = ['danger', $error];
+				}
+			} else {
+				$user = new User;
+				$user->name = $request->input('name');
+				$user->email = $request->input('email');
+				$user->password = $request->input('password');
+				if ($user->save()) {
+					$messages[] = ['success', 'Your account has been created.'];
+				} else {
+					$messages[] = ['danger', 'Your account could not be created.'];
+				}
+			}
+		}
+
+		return view('user.create',
+			[
+				'messages' => $messages,
+				'form' => [
+					'email' => $request->input('email'),
+					'name' => $request->input('name')
+				]
+			]);
+	}
+
+}
diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php
new file mode 100644
index 0000000..6db8bb0
--- /dev/null
+++ b/app/Http/Middleware/Authenticate.php
@@ -0,0 +1,45 @@
+auth = $auth;
+	}
+
+	/**
+	 * Handle an incoming request.
+	 *
+	 * @param  \Illuminate\Http\Request  $request
+	 * @param  \Closure  $next
+	 * @param  string|null  $guard
+	 * @return mixed
+	 */
+	public function handle($request, Closure $next, $guard = null)
+	{
+		if ($this->auth->guard($guard)->guest()) {
+			return response('Unauthorized.', 401)
+				->header('WWW-Authenticate', 'Basic realm="Please enter your email and password"');
+		}
+
+		return $next($request);
+	}
+}
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 67b661b..9cf12b4 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -28,24 +28,40 @@
 |
 */
 
-$app->group(['prefix' => parse_url(env('APP_URL'), PHP_URL_PATH)], function ($app) {
-    
-    $app->get('/', function () use ($app) {
-        return view('trainer');
-    });
-    
-    $app->get('/stem', function () use ($app) {
-        return \HebrewParseTrainer\Stem::all();
-    });
-    
-    $app->get('/tense', function () use ($app) {
-        return \HebrewParseTrainer\Tense::all();
-    });
-    
-    $app->get('/verb/random', 'App\Http\Controllers\RandomVerbController@show');
-
-    $app->get('/stats', function () use ($app) {
-        return view('stats');
-    });
-    
+$app->group(
+	['prefix' => parse_url(env('APP_URL'), PHP_URL_PATH)],
+	function ($app) {
+
+		$app->get('/', function () use ($app) {
+			return view('trainer');
+		});
+
+		$app->get('/stem', function () use ($app) {
+			return \HebrewParseTrainer\Stem::all();
+		});
+
+		$app->get('/tense', function () use ($app) {
+			return \HebrewParseTrainer\Tense::all();
+		});
+
+		$app->get('/logout', function () use ($app) {
+			return response('Unauthorized.', 401)
+				->header('WWW-Authenticate', 'Basic realm="Please click OK, then Cancel to logout."');
+		});
+
+		$app->get('/verb/random', 'App\Http\Controllers\RandomVerbController@show');
+
+		$app->get('/user/create', 'App\Http\Controllers\UserController@createForm');
+		$app->post('/user/create', 'App\Http\Controllers\UserController@createForm');
+
+		$app->group(
+			['middleware' => 'auth:basic-http'],
+			function ($app) {
+
+				$app->get('/stats', function () use ($app) {
+					return view('stats');
+				});
+
+			});
+
 });
diff --git a/app/Observers/UserObserver.php b/app/Observers/UserObserver.php
new file mode 100644
index 0000000..0989bb2
--- /dev/null
+++ b/app/Observers/UserObserver.php
@@ -0,0 +1,34 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+namespace App\Observers;
+
+use Illuminate\Support\Facades\Mail;
+
+use HebrewParseTrainer\User;
+
+class UserObserver {
+
+	public function created(User $user) {
+		Mail::plain('mails.user.create', ['user' => $user], function ($msg) {
+			$msg->to(['info@camilstaps.nl']);
+			$msg->from(['test@camilstaps.nl']);
+		});
+	}
+
+}
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index ddec046..9bc5fd1 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -3,16 +3,23 @@
 namespace App\Providers;
 
 use Illuminate\Support\ServiceProvider;
+use App\Observers\UserObserver;
+use HebrewParseTrainer\User;
 
 class AppServiceProvider extends ServiceProvider
 {
-    /**
-     * Register any application services.
-     *
-     * @return void
-     */
-    public function register()
-    {
-        //
-    }
+	/**
+	 * Register any application services.
+	 *
+	 * @return void
+	 */
+	public function register()
+	{
+		$this->app->singleton('mailer', function ($app) {
+			$app->configure('services');
+			return $app->loadComponent('mail', 'Illuminate\Mail\MailServiceProvider', 'mailer');
+		});
+
+		User::observe(UserObserver::class);
+	}
 }
diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php
new file mode 100644
index 0000000..7cf4b27
--- /dev/null
+++ b/app/Providers/AuthServiceProvider.php
@@ -0,0 +1,39 @@
+input('api_token')) {
+				return User::where('api_token', $request->input('api_token'))->first();
+			}
+		});
+	}
+}
diff --git a/app/User.php b/app/User.php
new file mode 100644
index 0000000..3c1799d
--- /dev/null
+++ b/app/User.php
@@ -0,0 +1,82 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+namespace HebrewParseTrainer;
+
+use Illuminate\Contracts\Auth\Authenticatable;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\Hash;
+
+class User extends Model implements Authenticatable {
+
+	protected $table = 'users';
+	public $timestamps = false;
+	protected $fillable = ['email', 'name'];
+
+	public function changePoints($kind, $change, $verb = null) {
+		$change = new PointChange;
+		$change->user = $this->id;
+		$change->change = $change;
+		$change->kind = $kind;
+		$change->verb = is_null($verb) ? null : $verb->id;
+		$change->save();
+		
+		$this->points += $change;
+		$this->save();
+	}
+
+	public function setPasswordAttribute($pass) {
+		$this->attributes['password'] = Hash::make($pass);
+	}
+
+	public function verifyPassword($pass) {
+		if (!Hash::check($pass, $this->password))
+			return false;
+
+		if (Hash::needsRehash($this->password)) {
+			$this->password = $pass;
+			$this->save();
+		}
+
+		return true;
+	}
+
+	public function getAuthIdentifierName() {
+		return $this->email;
+	}
+
+	public function getAuthIdentifier() {
+		return $this->id;
+	}
+
+	public function getAuthPassword() {
+		return $this->password;
+	}
+
+	public function getRememberToken() {
+		return null;
+	}
+
+	public function setRememberToken($token) {
+	}
+
+	public function getRememberTokenName() {
+		return null;
+	}
+
+}
-- 
cgit v1.2.3