Skip to content

Commit 5561573

Browse files
committed
added backend login throotling, and modify built-in components command to be ready for API used aswell
1 parent 639e6ae commit 5561573

39 files changed

+408
-142
lines changed

src/Darryldecode/Backend/Base/Commands/Command.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ abstract class Command {
2121
*/
2222
protected $args;
2323

24+
/**
25+
* disable the permission checking on a command, this will be helpful
26+
* when the commands are being used as an API or something custom that does not need
27+
* to check a user permission. Just in case you need it to work freely
28+
*
29+
* @var bool
30+
*/
31+
protected $disablePermissionChecking = false;
32+
2433
public function __construct()
2534
{
2635
$app = app();

src/Darryldecode/Backend/Base/Console/ComponentMake.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,15 @@ public function handle(Filesystem $filesystem)
5050
$componentNamespace = $this->formatToComponentNamespace($componentTitle);
5151
$componentUrl = $this->formatToComponentUrl($componentTitle);
5252

53+
$backendCustomComponentsPath = app_path().'/Backend';
5354
$componentPath = app_path().'/Backend/Components/'.$componentNamespace;
5455

56+
if( ! $this->filesystem->isDirectory($backendCustomComponentsPath) )
57+
{
58+
$this->filesystem->makeDirectory($backendCustomComponentsPath);
59+
$this->filesystem->makeDirectory($backendCustomComponentsPath.'/Components');
60+
}
61+
5562
if( $this->filesystem->isDirectory($componentPath) )
5663
{
5764
$this->error('Component already exist.');

src/Darryldecode/Backend/Base/Etc/scaffolds/Controller

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@
33
namespace App\Backend\Components\{{componentNamespace}}\Controllers;
44

55
use Darryldecode\Backend\Base\Controllers\BaseController;
6+
use Darryldecode\Backend\Utility\Helpers;
67

78
class {{componentNamespace}}Controller extends BaseController {
89

910
public function index()
1011
{
12+
if( ! $this->user->hasAnyPermission(['{{componentNamespace}}.manage']) )
13+
{
14+
return Helpers::redirectDashboard();
15+
}
16+
1117
return view('{{componentNamespace}}::index');
1218
}
1319
}

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

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
use Darryldecode\Backend\Base\Controllers\BaseController;
66

7+
use Darryldecode\Backend\Components\User\Models\Throttle;
8+
use Darryldecode\Backend\Components\User\Models\User;
79
use Darryldecode\Backend\Utility\Helpers;
810
use Illuminate\Http\Request;
911
use Illuminate\Support\Facades\Auth;
12+
use Carbon\Carbon;
1013

1114
class AuthController extends BaseController {
1215

@@ -30,14 +33,68 @@ public function getLogin()
3033
* handle login post request
3134
*
3235
* @param Request $request
36+
* @param Throttle $throttle
37+
* @param User $user
3338
* @return $this|\Illuminate\Http\RedirectResponse
3439
*/
35-
public function postLogin(Request $request)
40+
public function postLogin(Request $request, Throttle $throttle, User $user)
3641
{
3742
$credentials = $request->only('email', 'password');
43+
$throttleEntry = false;
3844

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());
63+
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
3994
if (Auth::attempt($credentials, $request->has('remember')))
4095
{
96+
$throttleEntry->clearLoginAttempts();
97+
4198
if( $request->get('ru') != '' )
4299
{
43100
return redirect()->intended($request->get('ru'));
@@ -46,6 +103,18 @@ public function postLogin(Request $request)
46103
return redirect()->intended(Helpers::getDashboardRoute());
47104
}
48105

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+
49118
return redirect()->back()
50119
->withInput($request->only('email', 'remember'))
51120
->withErrors([

src/Darryldecode/Backend/Components/ContentBuilder/Commands/CreateContentCommand.php

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,21 @@ class CreateContentCommand extends Command implements SelfHandling {
5252
*/
5353
private $taxonomies;
5454

55-
/**
56-
* Create a new command instance.
57-
* @param string $title
58-
* @param string $body
59-
* @param string $slug
60-
* @param $status
61-
* @param int $authorId
62-
* @param int $contentTypeId
63-
* @param null|array $permissionRequirements
64-
* @param array $taxonomies
65-
* @param array $miscData
66-
* @param array $metaData
67-
*/
68-
public function __construct($title, $body, $slug, $status, $authorId, $contentTypeId, $permissionRequirements = null, $taxonomies = array(), $miscData = array(), $metaData = array())
55+
/**
56+
* Create a new command instance.
57+
* @param string $title
58+
* @param string $body
59+
* @param string $slug
60+
* @param $status
61+
* @param int $authorId
62+
* @param int $contentTypeId
63+
* @param null|array $permissionRequirements
64+
* @param array $taxonomies
65+
* @param array $miscData
66+
* @param array $metaData
67+
* @param bool $disablePermissionChecking
68+
*/
69+
public function __construct($title, $body, $slug, $status, $authorId, $contentTypeId, $permissionRequirements = null, $taxonomies = array(), $miscData = array(), $metaData = array(), $disablePermissionChecking = false)
6970
{
7071
parent::__construct();
7172
$this->title = $title;
@@ -78,6 +79,7 @@ public function __construct($title, $body, $slug, $status, $authorId, $contentTy
7879
$this->status = $status;
7980
$this->metaData = $metaData;
8081
$this->taxonomies = $taxonomies;
82+
$this->disablePermissionChecking = $disablePermissionChecking;
8183
}
8284

8385
/**
@@ -101,10 +103,13 @@ public function handle(Content $content, Factory $validator, ContentType $conten
101103
}
102104

103105
// check if user has permission
104-
if( ! $this->user->hasAnyPermission([$cTypeManage]) )
105-
{
106-
return new CommandResult(false, "Not enough permission.", null, 403);
107-
}
106+
if( ! $this->disablePermissionChecking )
107+
{
108+
if( ! $this->user->hasAnyPermission([$cTypeManage]) )
109+
{
110+
return new CommandResult(false, "Not enough permission.", null, 403);
111+
}
112+
}
108113

109114
// validate data
110115
$validationResult = $validator->make(array(

src/Darryldecode/Backend/Components/ContentBuilder/Commands/CreateContentTypeCommand.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,19 @@ class CreateContentTypeCommand extends Command implements SelfHandling {
1919
*/
2020
private $enableRevision;
2121

22-
/**
23-
* Create a new command instance.
24-
*
25-
* @param string $type
26-
* @param string $enableRevision
27-
*/
28-
public function __construct($type, $enableRevision = 'no')
22+
/**
23+
* Create a new command instance.
24+
*
25+
* @param string $type
26+
* @param string $enableRevision
27+
* @param bool $disablePermissionChecking
28+
*/
29+
public function __construct($type, $enableRevision = 'no', $disablePermissionChecking = false)
2930
{
3031
parent::__construct();
3132
$this->type = $type;
3233
$this->enableRevision = $enableRevision;
34+
$this->disablePermissionChecking = $disablePermissionChecking;
3335
}
3436

3537
/**
@@ -43,10 +45,13 @@ public function __construct($type, $enableRevision = 'no')
4345
public function handle(Factory $validator, ContentType $contentType, Dispatcher $dispatcher)
4446
{
4547
// validate authorization
46-
if( ! $this->user->hasAnyPermission(['contentBuilder.manage']) )
47-
{
48-
return new CommandResult(false, CommandResult::$responseForbiddenMessage, null, 403);
49-
}
48+
if( ! $this->disablePermissionChecking )
49+
{
50+
if( ! $this->user->hasAnyPermission(['contentBuilder.manage']) )
51+
{
52+
return new CommandResult(false, CommandResult::$responseForbiddenMessage, null, 403);
53+
}
54+
}
5055

5156
// validate data
5257
$validationResult = $validator->make(array(

src/Darryldecode/Backend/Components/ContentBuilder/Commands/CreateContentTypeTaxonomyCommand.php

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,22 @@ class CreateContentTypeTaxonomyCommand extends Command implements SelfHandling {
2424
*/
2525
private $description;
2626

27-
/**
28-
* Create a new command instance.
29-
*
30-
* @param string $taxonomy
31-
* @param string $description
32-
* @param int $contentTypeId
33-
*/
34-
public function __construct($taxonomy = null, $description = null, $contentTypeId = null)
27+
/**
28+
* Create a new command instance.
29+
*
30+
* @param string $taxonomy
31+
* @param string $description
32+
* @param int $contentTypeId
33+
* @param bool $disablePermissionChecking
34+
*/
35+
public function __construct($taxonomy = null, $description = null, $contentTypeId = null, $disablePermissionChecking = false)
3536
{
3637
parent::__construct();
3738
$this->taxonomy = $taxonomy;
3839
$this->contentTypeId = $contentTypeId;
3940
$this->description = $description;
4041
$this->args = get_defined_vars();
42+
$this->disablePermissionChecking = $disablePermissionChecking;
4143
}
4244

4345
/**
@@ -51,10 +53,13 @@ public function __construct($taxonomy = null, $description = null, $contentTypeI
5153
public function handle(ContentType $contentType, Validator $validator, Dispatcher $dispatcher)
5254
{
5355
// validate authorization
54-
if( ! $this->user->hasAnyPermission(['contentBuilder.manage']) )
55-
{
56-
return new CommandResult(false, CommandResult::$responseForbiddenMessage, null, 403);
57-
}
56+
if( ! $this->disablePermissionChecking )
57+
{
58+
if( ! $this->user->hasAnyPermission(['contentBuilder.manage']) )
59+
{
60+
return new CommandResult(false, CommandResult::$responseForbiddenMessage, null, 403);
61+
}
62+
}
5863

5964
// validate data
6065
$validationResult = $validator->make(array(

src/Darryldecode/Backend/Components/ContentBuilder/Commands/CreateFormGroupCommand.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ class CreateFormGroupCommand extends Command implements SelfHandling {
4747
* @param array $conditions
4848
* @param array $fields
4949
* @param null $contentTypeId
50+
* @param bool $disablePermissionChecking
5051
*/
5152
public function __construct($name = null,
5253
$formName = null,
5354
$conditions = array(),
5455
$fields = array(),
55-
$contentTypeId = null)
56+
$contentTypeId = null,
57+
$disablePermissionChecking = false)
5658
{
5759
parent::__construct();
5860
$this->name = $name;
@@ -61,6 +63,7 @@ public function __construct($name = null,
6163
$this->fields = $fields;
6264
$this->contentTypeId = $contentTypeId;
6365
$this->args = get_defined_vars();
66+
$this->disablePermissionChecking = $disablePermissionChecking;
6467
}
6568

6669
/**
@@ -73,9 +76,12 @@ public function __construct($name = null,
7376
public function handle(Factory $validator, Dispatcher $dispatcher, ContentType $contentType, ContentTypeFormGroup $contentTypeFormGroup)
7477
{
7578
// check if user has permission
76-
if( ! $this->user->hasAnyPermission(['contentBuilder.manage']) )
79+
if( ! $this->disablePermissionChecking )
7780
{
78-
return new CommandResult(false, "Not enough permission.", null, 403);
81+
if( ! $this->user->hasAnyPermission(['contentBuilder.manage']) )
82+
{
83+
return new CommandResult(false, "Not enough permission.", null, 403);
84+
}
7985
}
8086

8187
// validate data

src/Darryldecode/Backend/Components/ContentBuilder/Commands/CreateTypeTaxonomyTerm.php

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,21 @@ class CreateTypeTaxonomyTerm extends Command implements SelfHandling {
2424
*/
2525
private $slug;
2626

27-
/**
28-
* Create a new command instance.
29-
*
30-
* @param string $term
31-
* @param $slug
32-
* @param int $contentTypeTaxonomyId
33-
*/
34-
public function __construct($term = null, $slug = null, $contentTypeTaxonomyId = null)
27+
/**
28+
* Create a new command instance.
29+
*
30+
* @param string $term
31+
* @param $slug
32+
* @param int $contentTypeTaxonomyId
33+
* @param bool $disablePermissionChecking
34+
*/
35+
public function __construct($term = null, $slug = null, $contentTypeTaxonomyId = null, $disablePermissionChecking = false)
3536
{
3637
parent::__construct();
3738
$this->term = $term;
3839
$this->contentTypeTaxonomyId = $contentTypeTaxonomyId;
3940
$this->slug = $slug;
41+
$this->disablePermissionChecking = $disablePermissionChecking;
4042
}
4143

4244
/**
@@ -70,10 +72,13 @@ public function handle(ContentType $contentType, ContentTypeTaxonomy $contentTyp
7072
$canManageOnThisType = $type->type.'.manage';
7173

7274
// check if user has permission
73-
if( ! $this->user->hasAnyPermission([$canManageOnThisType]) )
74-
{
75-
return new CommandResult(false, "Not enough permission.", null, 403);
76-
}
75+
if( ! $this->disablePermissionChecking )
76+
{
77+
if( ! $this->user->hasAnyPermission([$canManageOnThisType]) )
78+
{
79+
return new CommandResult(false, "Not enough permission.", null, 403);
80+
}
81+
}
7782

7883
// validate data
7984
$validationResult = $validator->make(array(

0 commit comments

Comments
 (0)