Skip to content

Commit 6b09032

Browse files
committed
added auth command together with its tests
1 parent 30f6900 commit 6b09032

File tree

4 files changed

+389
-68
lines changed

4 files changed

+389
-68
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
3+
namespace Darryldecode\Backend\Components\Auth\Commands;
4+
5+
use Darryldecode\Backend\Base\Commands\Command;
6+
use Darryldecode\Backend\Base\Commands\CommandResult;
7+
use Illuminate\Contracts\Bus\SelfHandling;
8+
use Illuminate\Contracts\Validation\Factory;
9+
use Darryldecode\Backend\Components\User\Models\Throttle;
10+
use Darryldecode\Backend\Components\User\Models\User;
11+
use Illuminate\Support\Facades\Auth;
12+
use Carbon\Carbon;
13+
14+
class AuthenticateCommand extends Command implements SelfHandling {
15+
/**
16+
* @var null
17+
*/
18+
private $email;
19+
/**
20+
* @var null
21+
*/
22+
private $password;
23+
/**
24+
* @var bool
25+
*/
26+
private $remember;
27+
28+
/**
29+
* @param string $email
30+
* @param string $password
31+
* @param bool $remember
32+
*/
33+
public function __construct($email, $password, $remember = false)
34+
{
35+
parent::__construct();
36+
$this->email = $email;
37+
$this->password = $password;
38+
$this->remember = $remember;
39+
$this->args = func_get_args();
40+
}
41+
42+
/**
43+
* @param Factory $validator
44+
* @param Throttle $throttle
45+
* @param User $user
46+
* @return CommandResult
47+
*/
48+
public function handle(Factory $validator, Throttle $throttle, User $user)
49+
{
50+
// validate data
51+
$validationResult = $validator->make(array(
52+
'email' => $this->email,
53+
'password' => $this->password,
54+
), array(
55+
'email' => 'required|email',
56+
'password' => 'required',
57+
));
58+
59+
if( $validationResult->fails() )
60+
{
61+
return new CommandResult(false, $validationResult->getMessageBag()->first(), null, 400);
62+
}
63+
64+
// we need to flag that a user that is authenticating has no throttle entry by default
65+
$throttleEntry = false;
66+
67+
// check if the user exist and get its throttle entry
68+
// then we will check if the user is suspended or banned
69+
if( $user = $user->where('email',$this->email)->first() )
70+
{
71+
if( ! $throttleEntry = $throttle->where('user_id',$user->id)->first() )
72+
{
73+
$throttleEntry = $throttle::create(array(
74+
'user_id' => $user->id
75+
));
76+
}
77+
78+
// if the user is currently suspended, lets check its suspension is already expire
79+
// so we can clear its login attempts and attempt it to login again,
80+
// if not expired yet, then we will redirect it back with the suspended notice
81+
if( $throttleEntry->isSuspended() )
82+
{
83+
$now = Carbon::now();
84+
$suspendedUntil = Carbon::createFromTimeStamp(strtotime($throttleEntry->suspended_at))->addMinutes($throttle->getSuspensionTime());
85+
86+
if( $now > $suspendedUntil )
87+
{
88+
$throttleEntry->clearLoginAttempts();
89+
$throttleEntry->unSuspend();
90+
}
91+
else
92+
{
93+
$minsRemaining = $now->diffInMinutes($suspendedUntil);
94+
95+
return new CommandResult(false, 'This account is currently suspended. You can login after '.$minsRemaining.' minutes.', null, 401);
96+
}
97+
}
98+
99+
// if the user is currently banned, no need to do anything
100+
// we will just redirect it back with banned notice
101+
elseif( $throttleEntry->isBanned() )
102+
{
103+
return new CommandResult(false, "This account is currently banned.", null, 401);
104+
}
105+
}
106+
107+
// attempt to login
108+
if (Auth::attempt(array('email'=>$this->email, 'password'=>$this->password), $this->remember))
109+
{
110+
$throttleEntry->clearLoginAttempts();
111+
112+
return new CommandResult(true, "Authentication Successful.", Auth::user(), 200);
113+
}
114+
115+
// login attempt failed, let's increment login attempt
116+
if( $throttleEntry )
117+
{
118+
$throttleEntry->addLoginAttempt();
119+
120+
return new CommandResult(false, "These credentials do not match our records. Login attempt remaining: ".$throttleEntry->getRemainingLoginAttempts(), null, 401);
121+
}
122+
123+
return new CommandResult(false, "These credentials do not match our records.", null, 401);
124+
}
125+
}

src/Darryldecode/Backend/Components/Auth/Controllers/AuthController.php

Lines changed: 7 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -40,61 +40,15 @@ public function getLogin()
4040
public function postLogin(Request $request, Throttle $throttle, User $user)
4141
{
4242
$credentials = $request->only('email', 'password');
43-
$throttleEntry = false;
4443

45-
// check if the user exist and get its throttle entry
46-
// then we will check if the user is suspended or banned
47-
if( $user = $user->where('email',$credentials['email'])->first() )
48-
{
49-
if( ! $throttleEntry = $throttle->where('user_id',$user->id)->first() )
50-
{
51-
$throttleEntry = $throttle::create(array(
52-
'user_id' => $user->id
53-
));
54-
}
55-
56-
// if the user is currently suspended, lets check its suspension is already expire
57-
// so we can clear its login attempts and attempt it to login again,
58-
// if not expired yet, then we will redirect it back with the suspended notice
59-
if( $throttleEntry->isSuspended() )
60-
{
61-
$now = Carbon::now();
62-
$suspendedUntil = Carbon::createFromTimeStamp(strtotime($throttleEntry->suspended_at))->addMinutes($throttle->getSuspensionTime());
44+
$result = $this->dispatchFromArray(
45+
'Darryldecode\Backend\Components\Auth\Commands\AuthenticateCommand',
46+
$credentials
47+
);
6348

64-
if( $now > $suspendedUntil )
65-
{
66-
$throttleEntry->clearLoginAttempts();
67-
$throttleEntry->unSuspend();
68-
}
69-
else
70-
{
71-
$minsRemaining = $now->diffInMinutes($suspendedUntil);
72-
73-
return redirect()->back()
74-
->withInput($request->only('email', 'remember'))
75-
->withErrors([
76-
'email' => 'This account is currently suspended. You can login after '.$minsRemaining.' minutes.',
77-
]);
78-
}
79-
}
80-
81-
// if the user is currently banned, no need to do anything
82-
// we will just redirect it back with banned notice
83-
elseif( $throttleEntry->isBanned() )
84-
{
85-
return redirect()->back()
86-
->withInput($request->only('email', 'remember'))
87-
->withErrors([
88-
'email' => 'This account is currently banned.',
89-
]);
90-
}
91-
}
92-
93-
// attempt to login
94-
if (Auth::attempt($credentials, $request->has('remember')))
49+
// if authentication is good
50+
if( $result->isSuccessful() )
9551
{
96-
$throttleEntry->clearLoginAttempts();
97-
9852
if( $request->get('ru') != '' )
9953
{
10054
return redirect()->intended($request->get('ru'));
@@ -103,23 +57,9 @@ public function postLogin(Request $request, Throttle $throttle, User $user)
10357
return redirect()->intended(Helpers::getDashboardRoute());
10458
}
10559

106-
// login attempt failed, let's increment login attempt
107-
if( $throttleEntry )
108-
{
109-
$throttleEntry->addLoginAttempt();
110-
111-
return redirect()->back()
112-
->withInput($request->only('email', 'remember'))
113-
->withErrors([
114-
'email' => 'These credentials do not match our records. Login attempt remaining: '.$throttleEntry->getRemainingLoginAttempts(),
115-
]);
116-
}
117-
11860
return redirect()->back()
11961
->withInput($request->only('email', 'remember'))
120-
->withErrors([
121-
'email' => 'These credentials do not match our records.',
122-
]);
62+
->withErrors(array('errors' => $result->getMessage()));
12363
}
12464

12565
/**

src/Darryldecode/Backend/Components/User/Models/Throttle.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,18 @@ class Throttle extends BaseModel {
4040
*
4141
* @var array
4242
*/
43-
protected $fillable = ['name', 'permissions', 'user_id'];
43+
protected $fillable = [
44+
'name',
45+
'permissions',
46+
'user_id',
47+
'banned',
48+
'suspended',
49+
'attempts',
50+
'ip_address',
51+
'last_attempt_at',
52+
'suspended_at',
53+
'banned_at'
54+
];
4455

4556
/**
4657
* Attempt limit.

0 commit comments

Comments
 (0)