keksAccount/app/Http/Controllers/API/UserController.php

316 lines
9.6 KiB
PHP
Raw Normal View History

2019-04-28 12:49:10 +00:00
<?php
namespace App\Http\Controllers\API;
use App\Exceptions\HTTPException;
use App\Exceptions\NoPermissionException;
use App\Exceptions\NotLoggedInException;
use App\Exceptions\ResourceNotFound;
use App\Http\Resources\oAuth\AccessToken;
2019-04-28 15:04:22 +00:00
use App\Jobs\Mails\ValidateMailAddressJob;
2019-04-28 12:49:10 +00:00
use App\Models\App;
use App\Models\AppAccess;
2019-04-28 15:04:22 +00:00
use App\Models\Invite;
use App\Models\Mail;
2019-04-28 12:49:10 +00:00
use App\Models\Setting;
use App\Models\User;
2019-12-25 17:49:20 +00:00
use Domnikl\Statsd\Client;
2019-04-28 12:49:10 +00:00
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
2019-04-28 15:04:22 +00:00
use Illuminate\Support\Facades\DB;
2019-04-28 12:49:10 +00:00
use Laravel\Lumen\Routing\Controller as BaseController;
use ReCaptcha\ReCaptcha;
use TaGeSo\APIResponse\Response;
class UserController extends BaseController
{
/*
* The Password login is just for the WebGUI
*/
2019-12-25 17:49:20 +00:00
public function passwordLogin(Request $request, Response $response, Client $statsd)
2019-04-28 12:49:10 +00:00
{
2019-12-25 17:49:20 +00:00
$statsd->count("login.try", 1);
2019-04-28 12:49:10 +00:00
//If Recptache is enabled check it at the beginning
if(Setting::getSettingValue("recaptcha_v2_login")) {
$reCaptcha = new ReCaptcha(Setting::getSettingValue("recaptcha_v2_secret"));
2019-09-24 15:24:21 +00:00
$reresponse = $reCaptcha->verify($request->input("g-recaptcha-response"));
2019-04-28 12:49:10 +00:00
2019-09-24 15:24:21 +00:00
if(!$reresponse->isSuccess()) {
2019-12-25 17:49:20 +00:00
$statsd->count("login.wrongcaptcha", 1);
2019-04-28 12:49:10 +00:00
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) {
2019-12-25 17:49:20 +00:00
$statsd->count("login.wronguser", 1);
2019-04-28 12:49:10 +00:00
throw new HTTPException("400", "Username or Password wrong");
}
if(!password_verify($request->input("password"), $user->password)) {
2019-12-25 17:49:20 +00:00
$statsd->count("login.wrongpassword", 1);
2019-04-28 12:49:10 +00:00
throw new HTTPException("400", "Username or Password wrong");
}
2019-06-20 14:46:50 +00:00
$app = App::query()->where("name", "=", "PHP-GUI")->firstOrFail()->id;
2019-04-28 12:49:10 +00:00
//Create Access Permission for WebGUI
2019-06-20 14:46:50 +00:00
$access = AppAccess::getOrCreate($user->id, $app);
2019-04-28 12:49:10 +00:00
$token = \App\Models\AccessToken::createToken($access);
//Save Token to Session
2019-06-20 14:46:50 +00:00
if(getenv("SAVE_TOKEN_TO_SESSION")) {
$_SESSION["token"] = $token->token;
}
2019-04-28 12:49:10 +00:00
2019-12-25 17:49:20 +00:00
$statsd->count("login.success", 1);
2019-07-17 14:28:34 +00:00
return $response->withData(new AccessToken($token));
2019-04-28 12:49:10 +00:00
}
2019-12-25 18:38:37 +00:00
public function checkPassword(Request $request, Response $response, Client $statsd) {
2019-11-19 17:41:55 +00:00
//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) {
2019-12-25 18:38:37 +00:00
$statsd->count("pwcheck.user_wrong", 1);
2019-11-19 17:41:55 +00:00
throw new HTTPException("400", "Username or Password wrong");
}
if(!password_verify($request->input("password"), $user->password)) {
2019-12-25 18:38:37 +00:00
$statsd->count("pwcheck.password_wrong", 1);
2019-11-19 17:41:55 +00:00
throw new HTTPException("400", "Username or Password wrong");
}
2019-12-25 18:38:37 +00:00
$statsd->count("pwcheck.ok", 1);
2019-11-19 17:41:55 +00:00
$response->setMessage("Account ok");
return $response;
}
2019-06-06 13:44:45 +00:00
public function me(Response $response) {
if(!Auth::check()) {
throw new NotLoggedInException();
}
return $response->withData(new \App\Http\Resources\API\User(Auth::user()));
}
2019-04-28 12:49:10 +00:00
public function register(Request $request, Response $response) {
2019-04-28 15:04:22 +00:00
//If Recptache is enabled check it at the beginning
if(Setting::getSettingValue("recaptcha_v2_register")) {
$reCaptcha = new ReCaptcha(Setting::getSettingValue("recaptcha_v2_secret"));
2019-04-28 15:55:38 +00:00
$captchaResponse = $reCaptcha->verify($request->input("g-recaptcha-response"));
2019-04-28 15:04:22 +00:00
2019-04-28 15:55:38 +00:00
if(!$captchaResponse->isSuccess()) {
2019-04-28 15:04:22 +00:00
throw new HTTPException(400, "Captcha validation failed");
}
}
2019-04-28 15:55:38 +00:00
$invite = Invite::query()->where("code", "=", $request->input("invite"))->first();
if($invite != null) {
if($invite->status != "active") {
2019-09-25 07:56:36 +00:00
throw new HTTPException(400, "Invite code invalide");
2019-04-28 15:55:38 +00:00
}
if(!empty($invite->username) && $request->input("username") != $invite->username) {
2019-09-25 07:56:36 +00:00
throw new HTTPException(400, "Invalide username for invite");
2019-04-28 15:55:38 +00:00
}
} else {
$setting = Setting::query()->where("name", "=", "registration_possible")->firstOrFail();
if(!$setting->value) {
throw new HTTPException("400", "Registration disabled");
}
}
2019-04-28 15:04:22 +00:00
$this->validate($request, [
'username' => 'required|max:255|min:5|regex:@^[a-z0-9]*$@|unique:users',
'password' => 'required|min:8',
'mail' => 'required|email|unique:mails'
]);
DB::beginTransaction();
$user = new User();
$user->username = $request->input("username");
$user->password = password_hash($request->input("password"), PASSWORD_BCRYPT);
if($invite != null) {
$user->inviteCode = $invite->code;
}
//Make first user an admin
$count = User::query()->count("*");
if($count == 1) {
$user->admin = 1;
$user->developer = 1;
}
$user->saveOrFail();
$mail = new Mail();
$mail->createValidationToken();
$mail->mail = $request->input("mail");
$mail->primary = false;
$mail->status = "waiting";
$mail->user_id = $user->id;
$mail->saveOrFail();
$this->dispatch(new ValidateMailAddressJob($mail));
if($invite != null) {
$invite->status = "used";
$invite->saveOrFail();
}
DB::commit();
return $response->withData(new \App\Http\Resources\API\User($user));
2019-04-28 12:49:10 +00:00
}
/*
* 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);
}
2019-04-28 15:04:22 +00:00
public function getInviteCodeInfo(Request $request, Response $response) {
$data = [];
$invite = Invite::query()->where("code", "=", $request->input("code"))->first();
if($invite == null) {
throw new ResourceNotFound();
}
$usable = false;
if($invite->status == "active") {
$usable = true;
}
$data["usable"] = $usable;
#$data["status"] = $invite->status;
$data["username"] = $invite->username;
return $response->withData($data);
}
2019-08-11 20:08:56 +00:00
public function listMails(Response $response) {
if(!Auth::check()) {
throw new NotLoggedInException();
}
$mails = Mail::query()->where("user_id", "=", Auth::id())->get();
return $response->withData(\App\Http\Resources\API\Mail::collection(collect($mails)));
}
2019-11-19 17:41:55 +00:00
public function addMail(Request $request, Response $response) {
if(!Auth::check()) {
throw new NotLoggedInException();
}
$this->validate($request, [
'mail' => 'required|email|unique:mails'
]);
$mail = new Mail();
$mail->createValidationToken();
$mail->mail = $request->input("mail");
$mail->primary = false;
$mail->status = "waiting";
$mail->user_id = Auth::user()->id;
$mail->saveOrFail();
$this->dispatch(new ValidateMailAddressJob($mail));
return $response;
}
public function removeMail(Request $request, Response $response, $id) {
if(!Auth::check()) {
abort(401);
}
$mail = Mail::query()->where("id", "=", $id)->firstOrFail();
if($mail->user_id != Auth::user()->id) {
abort(401);
}
if($mail->primary) {
throw new HTTPException(400, "You can't delete your primary mail");
}
$mail->delete();
$response->setMessage("Mail address deleted");
return $response;
}
2019-11-22 15:13:42 +00:00
public function changePrimaryMail(Request $request, Response $response, $id) {
if(!Auth::check()) {
abort(401);
}
$mail = Mail::query()->where("id", "=", $id)->firstOrFail();
if($mail->user_id != Auth::user()->id) {
abort(401);
}
if($mail->status != "valide") {
throw new HTTPException("Mail not validated, click the link in the mail first");
}
$mails = Mail::query()->where("user_id", "=", Auth::user()->id)->get();
foreach($mails as $m) {
$m->primary = false;
$m->saveOrFail();
}
$mail->primary = true;
$mail->saveOrFail();
$response->setMessage("Primary mail changed");
return $response;
}
public function changePassword(Request $request, Response $response) {
if(!Auth::check()) {
abort(401);
}
$this->validate($request, [
'password' => 'required|min:8'
]);
$user = Auth::user();
$user->password = password_hash($request->input("password"), PASSWORD_BCRYPT);
$user->saveOrFail();
$response->setMessage("Password changed");
return $response;
}
2019-04-28 12:49:10 +00:00
}