diff --git a/app/Exceptions/HTTPException.php b/app/Exceptions/HTTPException.php index be3e504..1d25289 100644 --- a/app/Exceptions/HTTPException.php +++ b/app/Exceptions/HTTPException.php @@ -3,20 +3,14 @@ namespace App\Exceptions; class HTTPException extends \Exception { - // Die Exception neu definieren, damit die Mitteilung nicht optional ist - public function __construct($httpCode, $message, $code = 0, Exception $previous = null) { - // etwas Code + private $httpCode = 500; - // sicherstellen, dass alles korrekt zugewiesen wird + public function __construct($httpCode, $message, $code = 0, Exception $previous = null) { + $this->httpCode = $httpCode; parent::__construct($message, $code, $previous); } - - // maßgeschneiderte Stringdarstellung des Objektes - public function __toString() { - return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; + public function getHttpStatusCode() { + return $this->httpCode; } - public function customFunction() { - echo "Eine eigene Funktion dieses Exceptiontyps\n"; - } } \ No newline at end of file diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 1131ee6..dd7340b 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -8,6 +8,7 @@ use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Database\Eloquent\ModelNotFoundException; use Laravel\Lumen\Exceptions\Handler as ExceptionHandler; use Symfony\Component\HttpKernel\Exception\HttpException; +use TaGeSo\APIResponse\Response; class Handler extends ExceptionHandler { @@ -45,6 +46,26 @@ class Handler extends ExceptionHandler */ public function render($request, Exception $exception) { - return parent::render($request, $exception); + //Handle Excepions + try { + throw $exception; + } catch (\App\Exceptions\HTTPException $e) { + $res = new Response(); + $res->setStatus(false); + $res->setMessage($e->getMessage()); + $res->setStatusCode($e->getHttpStatusCode()); + return $res; + } catch (ValidationException $e) { + $res = new Response(); + $res->setStatus(false); + $res->setMessage($e->getMessage()); + $res->setStatusCode(422); + $res->withData($e->errors()); + return $res; + } + catch (Exception $e) { + return parent::render($request, $exception); + } + } } diff --git a/app/Http/Controllers/API/AccountController.php b/app/Http/Controllers/API/AccountController.php index eef4960..95e48a2 100644 --- a/app/Http/Controllers/API/AccountController.php +++ b/app/Http/Controllers/API/AccountController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\API; +use App\Exceptions\HTTPException; use App\Exceptions\NoPermissionException; use App\Exceptions\NotLoggedInException; use App\Exceptions\ResourceNotFound; @@ -13,6 +14,7 @@ use TaGeSo\APIResponse\Response; class AccountController extends BaseController { public function getUsers(Response $response) { + if(!Auth::check()) { throw new NotLoggedInException(); } diff --git a/app/Http/Controllers/API/UserController.php b/app/Http/Controllers/API/UserController.php new file mode 100644 index 0000000..068aebd --- /dev/null +++ b/app/Http/Controllers/API/UserController.php @@ -0,0 +1,81 @@ +verify($request->input("g-recaptcha-response")); + + if(!$response->isSuccess()) { + throw new HTTPException(400, "Captcha validation failed"); + } + } + + + //Validate Input + $this->validate($request, [ + 'username' => 'required', + 'password' => 'required' + ]); + + //Get User + $user = User::query()->where("username", "=", $request->input("username"))->first(); + + //Check if a user is found + if($user == null) { + throw new HTTPException("400", "Username or Password wrong"); + } + + if(!password_verify($request->input("password"), $user->password)) { + throw new HTTPException("400", "Username or Password wrong"); + } + + //Create Access Permission for WebGUI + $access = AppAccess::getOrCreate($user->id, App::query()->where("name", "=", "PHP-GUI")->firstOrFail()->id); + $token = \App\Models\AccessToken::createToken($access); + + //Save Token to Session + $_SESSION["token"] = $token->token; + + return new AccessToken($token); + } + + public function register(Request $request, Response $response) { + + } + + /* + * Return Captcha Settings used by the public webpage bevore the user is loggedin + */ + public function reCAPTCHA(Response $response) { + $data = []; + $data["key"] = Setting::getSettingValue("recaptcha_v2_key"); + $data["login"] = (bool)Setting::getSettingValue("recaptcha_v2_login"); + $data["register"] = (bool)Setting::getSettingValue("recaptcha_v2_register"); + return $response->withData($data); + } +} diff --git a/app/Http/Controllers/GUI/AccountController.php b/app/Http/Controllers/GUI/AccountController.php index abe1b60..762d749 100644 --- a/app/Http/Controllers/GUI/AccountController.php +++ b/app/Http/Controllers/GUI/AccountController.php @@ -113,27 +113,7 @@ class AccountController extends Controller public function loginView() { return view('account/login', ["msg"=>""]); } - public function login(Request $request) { - $this->validate($request, [ - 'username' => 'required', - 'password' => 'required' - ]); - $user = User::query()->where("username", "=", $request->input("username"))->first(); - if($user==null) { - abort(401, "Username or Password wrong"); - } - - if(!password_verify($request->input("password"), $user->password)) { - abort(401, "Username or Password wrong"); - } - - $access = AppAccess::getOrCreate($user->id, App::query()->where("name", "=", "PHP-GUI")->firstOrFail()->id); - $token = \App\Models\AccessToken::createToken($access); - $_SESSION["token"] = $token->token; - - return new AccessToken($token); - } public function logout() { session_destroy(); return view('account/login', ["msg"=>"Logout successful", "user" => null]); @@ -153,13 +133,6 @@ class AccountController extends Controller $mail->primary = true; } - //Dont set new Mails as primary - /*$mails = Mail::query()->where("user_id", "=", $mail->user_id)->where("primary", "=", true)->get("*"); - foreach($mails as $m) { - $m->primary = false; - $m->saveOrFail(); - }*/ - $mail->saveOrFail(); echo "E-Mail wurde validiert"; } diff --git a/app/Http/Controllers/GUI/AppController.php b/app/Http/Controllers/GUI/AppController.php index c299467..d805982 100644 --- a/app/Http/Controllers/GUI/AppController.php +++ b/app/Http/Controllers/GUI/AppController.php @@ -22,6 +22,9 @@ class AppController extends Controller } public function appList() { + if(!Auth::check()) { + abort(401); + } $apps = App::query()->where("user_id", "=", Auth::user()->id)->get(); return view('app/list', ["msg"=>"", "apps" => $apps]); } diff --git a/app/Http/Controllers/oAuthController.php b/app/Http/Controllers/oAuthController.php index 726f4ba..f2386e2 100644 --- a/app/Http/Controllers/oAuthController.php +++ b/app/Http/Controllers/oAuthController.php @@ -142,6 +142,7 @@ class oAuthController extends Controller $data["sub"] = $user->username; $data["email"] = $user->getMail(); $data["name"] = $user->username; + $data["displayName"] = $user->username; //Param for Nextcloud $data["state"] = "active"; $data["avatar_url"] = "https://www.alzforum.org/sites/default/files/member-default.jpg"; #$data["web_url"] = "http://www.kekskurse.de"; diff --git a/app/Http/Middleware/View.php b/app/Http/Middleware/View.php index 1765f52..c6c13be 100644 --- a/app/Http/Middleware/View.php +++ b/app/Http/Middleware/View.php @@ -19,6 +19,11 @@ class View { view()->share('user', Auth::user()); view()->share('settingsArray', Setting::getSettingsAsArray()); - return $next($request); + $response = $next($request); + if($response->status() == 401) { + return redirect('/gui/login'); + } + + return $response; } } diff --git a/composer.json b/composer.json index 9056632..a62e6eb 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "laravel/lumen-framework": "5.8.*", "vlucas/phpdotenv": "^3.3", "phpmailer/phpmailer": "~6.0", - "tageso/api-response": "*" + "tageso/api-response": "*", + "google/recaptcha": "^1.2" }, "require-dev": { "fzaninotto/faker": "^1.4", diff --git a/composer.lock b/composer.lock index 0a2832c..5191e10 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "265697a07793434d0d8ac306debafc74", + "content-hash": "0a69119706b0705d3100af89a96435b6", "packages": [ { "name": "doctrine/inflector", @@ -238,6 +238,53 @@ ], "time": "2018-12-04T22:38:24+00:00" }, + { + "name": "google/recaptcha", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/google/recaptcha.git", + "reference": "e7add3be59211482ecdb942288f52da64a35f61a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/google/recaptcha/zipball/e7add3be59211482ecdb942288f52da64a35f61a", + "reference": "e7add3be59211482ecdb942288f52da64a35f61a", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.2.20|^2.12", + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^4.8.36|^5.7.27|^6.59|^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "ReCaptcha\\": "src/ReCaptcha" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Client library for reCAPTCHA, a free service that protects websites from spam and abuse.", + "homepage": "https://www.google.com/recaptcha/", + "keywords": [ + "Abuse", + "captcha", + "recaptcha", + "spam" + ], + "time": "2018-08-05T09:31:53+00:00" + }, { "name": "illuminate/auth", "version": "v5.8.14", @@ -2785,12 +2832,12 @@ "source": { "type": "git", "url": "https://github.com/tageso/apiResponse.git", - "reference": "510e4233d31506f5bd4e6d3456d55297d8c0376d" + "reference": "c545bc4cf7649d5d193e05f06d0328e3f4dc58e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tageso/apiResponse/zipball/510e4233d31506f5bd4e6d3456d55297d8c0376d", - "reference": "510e4233d31506f5bd4e6d3456d55297d8c0376d", + "url": "https://api.github.com/repos/tageso/apiResponse/zipball/c545bc4cf7649d5d193e05f06d0328e3f4dc58e1", + "reference": "c545bc4cf7649d5d193e05f06d0328e3f4dc58e1", "shasum": "" }, "require": { @@ -2816,7 +2863,7 @@ "source": "https://github.com/tageso/apiResponse/tree/master", "issues": "https://github.com/tageso/apiResponse/issues" }, - "time": "2019-04-25T15:20:37+00:00" + "time": "2019-04-26T14:12:17+00:00" }, { "name": "vlucas/phpdotenv", diff --git a/database/migrations/2019_04_26_092613_recaptcha.php b/database/migrations/2019_04_26_092613_recaptcha.php new file mode 100644 index 0000000..c93511c --- /dev/null +++ b/database/migrations/2019_04_26_092613_recaptcha.php @@ -0,0 +1,54 @@ +name = "recaptcha_v2_register"; + $setting->description = "Enabled Recaptcha for Register Page"; + $setting->typ = "checkbox"; + $setting->value = 0; + $setting->saveOrFail(); + $setting = new \App\Models\Setting(); + $setting->name = "recaptcha_v2_login"; + $setting->description = "Enabled Recaptcha for Login to Account-Service"; + $setting->typ = "checkbox"; + $setting->value = 0; + $setting->saveOrFail(); + $setting = new \App\Models\Setting(); + $setting->name = "recaptcha_v2_key"; + $setting->description = "Recaptcha V2 Key"; + $setting->typ = "textinput"; + $setting->value = ""; + $setting->saveOrFail(); + $setting = new \App\Models\Setting(); + $setting->name = "recaptcha_v2_secret"; + $setting->description = "Recaptcha V2 Secret"; + $setting->typ = "textinput"; + $setting->value = ""; + $setting->saveOrFail(); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + \App\Models\Setting::query()->where("name", "=", "recaptcha_v2_register")->delete(); + \App\Models\Setting::query()->where("name", "=", "recaptcha_v2_login")->delete(); + \App\Models\Setting::query()->where("name", "=", "recaptcha_v2_key")->delete(); + \App\Models\Setting::query()->where("name", "=", "recaptcha_v2_secret")->delete(); + } +} diff --git a/resources/views/account/login.php b/resources/views/account/login.php index dbd46e9..bfb0ccf 100644 --- a/resources/views/account/login.php +++ b/resources/views/account/login.php @@ -1,43 +1,59 @@ +
-

Register

- - - +

Login

Username: Password: - +
+ +
+
+
diff --git a/routes/web.php b/routes/web.php index bc6d256..45a8865 100644 --- a/routes/web.php +++ b/routes/web.php @@ -43,8 +43,13 @@ $router->group(['prefix' => 'api', 'middleware' => 'auth'], function () use ($ro $router->get("/", ['uses' => 'API\AccountController@getUsers']); $router->get("/{id}", ['uses' => 'API\AccountController@getUser']); }); + $router->group(['prefix' => 'user'], function () use ($router) { + + }); }); }); +$router->post("api/v1/user/login", ['uses' => 'API\UserController@passwordLogin']); +$router->get("api/v1/user/captcha", ['uses' => 'API\UserController@reCAPTCHA']); $router->group(['prefix' => 'gui', 'middleware' => 'gui'], function () use ($router) { $router->get('/register', ['uses' => 'GUI\AccountController@registerView']);