blessing-skin-server/app/Http/Controllers/AuthController.php

318 lines
11 KiB
PHP
Raw Normal View History

2016-07-21 22:01:57 +08:00
<?php
2016-08-28 10:05:21 +08:00
namespace App\Http\Controllers;
2016-07-21 22:01:57 +08:00
2016-11-07 22:34:34 +08:00
use Log;
2016-07-21 22:01:57 +08:00
use Mail;
use View;
2016-08-06 19:38:37 +08:00
use Utils;
2016-10-23 11:41:52 +08:00
use Cookie;
2016-07-21 22:01:57 +08:00
use Option;
2016-08-28 10:05:21 +08:00
use Session;
use Validator;
2016-11-17 17:32:12 +08:00
use App\Events;
use App\Models\User;
use App\Models\Player;
use Illuminate\Http\Request;
use App\Exceptions\PrettyPageException;
2016-10-23 11:41:52 +08:00
use App\Services\Repositories\UserRepository;
2016-07-21 22:01:57 +08:00
2016-09-03 23:50:55 +08:00
class AuthController extends Controller
2016-07-21 22:01:57 +08:00
{
public function login()
{
2016-08-28 10:05:21 +08:00
return view('auth.login');
2016-07-21 22:01:57 +08:00
}
2016-10-23 11:41:52 +08:00
public function handleLogin(Request $request, UserRepository $users)
2016-07-21 22:01:57 +08:00
{
2016-09-03 23:50:55 +08:00
$this->validate($request, [
2016-10-02 20:30:27 +08:00
'identification' => 'required',
'password' => 'required|min:6|max:64'
2016-09-03 23:50:55 +08:00
]);
2016-10-02 20:30:27 +08:00
$identification = $request->input('identification');
2018-02-16 17:31:04 +08:00
// Guess type of identification
$authType = (validate($identification, 'email')) ? "email" : "username";
2016-09-03 23:50:55 +08:00
2018-02-16 17:31:04 +08:00
event(new Events\UserTryToLogin($identification, $authType));
2016-10-17 17:51:51 +08:00
2016-10-23 11:41:52 +08:00
// Get user instance from repository.
// If the given identification is not registered yet,
// it will return a null value.
2018-02-16 17:31:04 +08:00
$user = $users->get($identification, $authType);
2016-07-21 22:01:57 +08:00
2016-08-28 10:05:21 +08:00
if (session('login_fails', 0) > 3) {
2016-09-03 23:50:55 +08:00
if (strtolower($request->input('captcha')) != strtolower(session('phrase')))
2016-09-15 09:20:02 +08:00
return json(trans('auth.validation.captcha'), 1);
2016-07-21 22:01:57 +08:00
}
2018-02-16 17:31:04 +08:00
if (! $user) {
2016-09-15 09:20:02 +08:00
return json(trans('auth.validation.user'), 2);
2016-07-21 22:01:57 +08:00
} else {
if ($user->verifyPassword($request->input('password'))) {
2016-09-03 23:50:55 +08:00
Session::forget('login_fails');
2016-07-21 22:01:57 +08:00
2016-08-28 10:05:21 +08:00
Session::put('uid' , $user->uid);
Session::put('token', $user->getToken());
2016-07-21 22:01:57 +08:00
2018-02-16 17:31:04 +08:00
// Time in minutes
2016-10-23 11:41:52 +08:00
$time = $request->input('keep') == true ? 10080 : 60;
2016-07-21 22:01:57 +08:00
2016-11-17 17:32:12 +08:00
event(new Events\UserLoggedIn($user));
2016-10-17 17:51:51 +08:00
session()->forget('last_requested_path');
2016-10-02 20:30:27 +08:00
return json(trans('auth.login.success'), 0, [
2016-07-21 22:01:57 +08:00
'token' => $user->getToken()
2018-02-16 17:31:04 +08:00
]) // Set cookies
2016-10-23 11:41:52 +08:00
->withCookie('uid', $user->uid, $time)
->withCookie('token', $user->getToken(), $time);
2016-07-21 22:01:57 +08:00
} else {
2016-10-02 20:30:27 +08:00
Session::put('login_fails', session('login_fails', 0) + 1);
2016-08-16 13:27:06 +08:00
2016-10-02 20:30:27 +08:00
return json(trans('auth.validation.password'), 1, [
2016-08-28 10:05:21 +08:00
'login_fails' => session('login_fails')
2016-07-21 22:01:57 +08:00
]);
}
}
}
2016-10-23 11:41:52 +08:00
public function logout(Request $request)
2016-07-21 22:01:57 +08:00
{
2017-10-30 12:40:34 +08:00
if (Session::has('uid') && Session::has('token')) {
2018-02-16 17:31:04 +08:00
// Flush sessions
2016-08-28 10:05:21 +08:00
Session::flush();
2018-02-16 17:31:04 +08:00
// Delete cookies
2016-10-23 11:41:52 +08:00
return json(trans('auth.logout.success'), 0)
->withCookie(Cookie::forget('uid'))
->withCookie(Cookie::forget('token'));
2016-07-21 22:01:57 +08:00
} else {
2016-10-06 17:57:07 +08:00
return json(trans('auth.logout.fail'), 1);
2016-07-21 22:01:57 +08:00
}
}
public function register()
{
2016-10-23 11:41:52 +08:00
if (option('user_can_register')) {
2016-08-28 10:05:21 +08:00
return view('auth.register');
} else {
2016-09-15 09:20:02 +08:00
throw new PrettyPageException(trans('auth.register.close'), 7);
}
2016-07-21 22:01:57 +08:00
}
2016-10-23 11:41:52 +08:00
public function handleRegister(Request $request, UserRepository $users)
2016-07-21 22:01:57 +08:00
{
2018-02-16 17:31:04 +08:00
if (! $this->checkCaptcha($request))
2016-09-15 09:20:02 +08:00
return json(trans('auth.validation.captcha'), 1);
2016-07-21 22:01:57 +08:00
2016-09-03 23:50:55 +08:00
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:8|max:16',
'nickname' => 'required|nickname|max:255'
]);
2018-02-16 17:31:04 +08:00
if (! option('user_can_register')) {
2016-10-23 11:41:52 +08:00
return json(trans('auth.register.close'), 7);
}
// If amount of registered accounts of IP is more than allowed amounts,
// then reject the register.
if (User::where('ip', Utils::getClientIp())->count() < option('regs_per_ip'))
2016-10-23 11:41:52 +08:00
{
// Register a new user.
// If the email is already registered,
// it will return a false value.
$user = User::register(
$request->input('email'),
$request->input('password'), function($user) use ($request)
2016-10-23 11:41:52 +08:00
{
$user->ip = Utils::getClientIp();
2016-10-23 11:41:52 +08:00
$user->score = option('user_initial_score');
$user->register_at = Utils::getTimeFormatted();
$user->last_sign_at = Utils::getTimeFormatted(time() - 86400);
$user->permission = User::NORMAL;
$user->nickname = $request->input('nickname');
});
2018-02-16 17:31:04 +08:00
if (! $user) {
2016-10-23 11:41:52 +08:00
return json(trans('auth.register.registered'), 5);
2016-07-21 22:01:57 +08:00
}
2016-10-23 11:41:52 +08:00
2016-11-17 17:32:12 +08:00
event(new Events\UserRegistered($user));
$msg = trans('auth.register.success');
$redirect = true;
if ($request->input('addPlayer') == 'add') {
2018-02-16 17:31:04 +08:00
if (! Player::where('player_name', $request->nickname)->first()) {
if (! Validator::make(
['name' => $request->nickname],
['name' => option('allow_chinese_playername') ? 'pname_chinese' : 'playername']
)->fails()) {
$player = new Player;
$player->uid = $user->uid;
$player->player_name = $request->input('nickname');
$player->preference = "default";
$player->last_modified = Utils::getTimeFormatted();
$player->save();
event(new Events\PlayerWasAdded($player));
} else {
$msg = trans('auth.register.success-with-chinese-player-name');
$redirect = false;
}
} else {
$msg = trans('auth.register.success-without-player');
$redirect = false;
}
}
2016-10-23 11:41:52 +08:00
return json([
'errno' => 0,
'msg' => $msg,
'token' => $user->getToken(),
'redirect' => $redirect,
2018-02-16 17:31:04 +08:00
]) // Set cookies
2016-10-23 11:41:52 +08:00
->withCookie('uid', $user->uid, 60)
->withCookie('token', $user->getToken(), 60);
2016-07-21 22:01:57 +08:00
} else {
2016-10-23 11:41:52 +08:00
return json(trans('auth.register.max', ['regs' => option('regs_per_ip')]), 7);
2016-07-21 22:01:57 +08:00
}
}
public function forgot()
{
2016-09-03 23:50:55 +08:00
if (config('mail.host') != "") {
2016-08-28 10:05:21 +08:00
return view('auth.forgot');
} else {
2016-09-15 09:20:02 +08:00
throw new PrettyPageException(trans('auth.forgot.close'), 8);
}
2016-07-21 22:01:57 +08:00
}
2016-10-23 11:41:52 +08:00
public function handleForgot(Request $request, UserRepository $users)
2016-07-21 22:01:57 +08:00
{
2018-02-16 17:31:04 +08:00
if (! $this->checkCaptcha($request))
2016-09-15 09:20:02 +08:00
return json(trans('auth.validation.captcha'), 1);
2016-07-21 22:01:57 +08:00
2016-09-03 23:50:55 +08:00
if (config('mail.host') == "")
2016-09-15 09:20:02 +08:00
return json(trans('auth.forgot.close'), 1);
2016-09-04 16:15:11 +08:00
if (Session::has('last_mail_time') && (time() - session('last_mail_time')) < 60)
2016-09-15 09:20:02 +08:00
return json(trans('auth.forgot.frequent-mail'), 1);
2016-07-21 22:01:57 +08:00
2018-02-16 17:31:04 +08:00
// Get user instance
2016-10-23 11:41:52 +08:00
$user = $users->get($request->input('email'), 'email');
2016-07-21 22:01:57 +08:00
2018-02-16 17:31:04 +08:00
if (! $user)
2016-09-15 09:20:02 +08:00
return json(trans('auth.forgot.unregistered'), 1);
2016-07-21 22:01:57 +08:00
2016-10-23 11:41:52 +08:00
$uid = $user->uid;
2018-02-16 17:31:04 +08:00
// Generate token for password resetting
2017-01-08 13:44:03 +08:00
$token = base64_encode($user->getToken().substr(time(), 4, 6).str_random(16));
2016-07-21 22:01:57 +08:00
2016-08-16 13:27:06 +08:00
$url = Option::get('site_url')."/auth/reset?uid=$uid&token=$token";
2016-09-04 16:15:11 +08:00
try {
Mail::send('auth.mail', ['reset_url' => $url], function ($m) use ($request) {
$site_name = Option::get('site_name');
2016-07-21 22:01:57 +08:00
2016-09-04 16:15:11 +08:00
$m->from(config('mail.username'), $site_name);
2016-09-15 09:20:02 +08:00
$m->to($request->input('email'))->subject(trans('auth.mail.title', ['sitename' => $site_name]));
2016-09-04 16:15:11 +08:00
});
2016-11-07 22:34:34 +08:00
Log::info("[Password Reset] Mail has been sent to [{$request->input('email')}] with token [$token]");
2016-09-04 16:15:11 +08:00
} catch(\Exception $e) {
2016-09-15 09:20:02 +08:00
return json(trans('auth.mail.failed', ['msg' => $e->getMessage()]), 2);
2016-07-21 22:01:57 +08:00
}
2016-09-04 16:15:11 +08:00
Session::put('last_mail_time', time());
2016-09-15 09:20:02 +08:00
return json(trans('auth.mail.success'), 0);
2016-07-21 22:01:57 +08:00
}
2016-10-23 11:41:52 +08:00
public function reset(UserRepository $users, Request $request)
2016-07-21 22:01:57 +08:00
{
2016-10-23 11:41:52 +08:00
if ($request->has('uid') && $request->has('token')) {
2018-02-16 17:31:04 +08:00
// Get user instance from repository
2016-10-23 11:41:52 +08:00
$user = $users->get($request->input('uid'));
2018-02-16 17:31:04 +08:00
if (! $user)
2016-09-15 09:20:02 +08:00
return redirect('auth/forgot')->with('msg', trans('auth.reset.invalid'));
2016-07-21 22:01:57 +08:00
2018-02-16 17:31:04 +08:00
// Unpack to get user token & timestamp
$decoded = base64_decode($request->input('token'));
$token = substr($decoded, 0, -22);
$timestamp = substr($decoded, strlen($token), 6);
2016-07-21 22:01:57 +08:00
if ($user->getToken() != $token) {
2016-09-15 09:20:02 +08:00
return redirect('auth/forgot')->with('msg', trans('auth.reset.invalid'));
2016-07-21 22:01:57 +08:00
}
2018-02-16 17:31:04 +08:00
// More than 1 hour
2016-07-21 22:01:57 +08:00
if ((substr(time(), 4, 6) - $timestamp) > 3600) {
2016-09-15 09:20:02 +08:00
return redirect('auth/forgot')->with('msg', trans('auth.reset.expired'));
2016-07-21 22:01:57 +08:00
}
2016-09-04 16:15:11 +08:00
return view('auth.reset')->with('user', $user);
2016-07-21 22:01:57 +08:00
} else {
2016-09-15 09:20:02 +08:00
return redirect('auth/login')->with('msg', trans('auth.check.anonymous'));
2016-07-21 22:01:57 +08:00
}
}
2016-10-23 11:41:52 +08:00
public function handleReset(Request $request, UserRepository $users)
2016-07-21 22:01:57 +08:00
{
2016-09-03 23:50:55 +08:00
$this->validate($request, [
'uid' => 'required|integer',
'password' => 'required|min:8|max:16',
'token' => 'required',
2016-09-03 23:50:55 +08:00
]);
2016-07-21 22:01:57 +08:00
$decoded = base64_decode($request->input('token'));
$token = substr($decoded, 0, -22);
$timestamp = intval(substr($decoded, strlen($token), 6));
$user = $users->get($request->input('uid'));
2018-02-16 17:31:04 +08:00
if (! $user)
return json(trans('auth.reset.invalid'), 1);
if ($user->getToken() != $token) {
return json(trans('auth.reset.invalid'), 1);
}
2018-02-16 17:31:04 +08:00
// More than 1 hour
if ((intval(substr(time(), 4, 6)) - $timestamp) > 3600) {
return json(trans('auth.reset.expired'), 1);
}
2016-10-23 11:41:52 +08:00
$users->get($request->input('uid'))->changePasswd($request->input('password'));
2016-07-21 22:01:57 +08:00
2016-11-07 22:34:34 +08:00
Log::info("[Password Reset] Password of user [{$request->input('uid')}] has been changed");
2016-09-15 09:20:02 +08:00
return json(trans('auth.reset.success'), 0);
2016-07-21 22:01:57 +08:00
}
public function captcha()
{
$builder = new \Gregwar\Captcha\CaptchaBuilder;
$builder->build($width = 100, $height = 34);
2016-08-28 10:05:21 +08:00
Session::put('phrase', $builder->getPhrase());
2017-10-30 12:40:34 +08:00
ob_start();
2016-07-21 22:01:57 +08:00
$builder->output();
2017-10-30 12:40:34 +08:00
$captcha = ob_get_contents();
ob_end_clean();
2016-08-29 23:08:09 +08:00
2017-10-30 12:40:34 +08:00
return \Response::png($captcha);
2016-07-21 22:01:57 +08:00
}
protected function checkCaptcha($request)
2016-10-23 11:41:52 +08:00
{
return (strtolower($request->input('captcha')) == strtolower(session('phrase')));
}
2016-07-21 22:01:57 +08:00
}