Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user roles #41

Merged
merged 17 commits into from Jan 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/Http/Controllers/ArticlesController.php
Expand Up @@ -6,6 +6,7 @@
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use App\Models\Settings;
use App\Models\ArticleCategory;
use App\Models\Article;
use App\Models\Comment;
Expand All @@ -21,6 +22,11 @@ class ArticlesController extends FrontendController {

public function index( Request $request ) {

// If there are no site settings, redirect to Dashboard
if (Settings::count() == 0) {
return redirect()->route('dashboard');
}

// Search query
$qry = $request->input( 'search' );

Expand Down
10 changes: 9 additions & 1 deletion app/Http/Controllers/Auth/LoginController.php
@@ -1,10 +1,10 @@
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
Expand Down Expand Up @@ -37,4 +37,12 @@ public function __construct()
{
$this->middleware('guest')->except('logout');
}

protected function authenticated()
{
if (Auth::user()->active !== 1) {
Auth::logout();
return redirect('/login')->withError('Your account is not active!');
}
}
}
15 changes: 11 additions & 4 deletions app/Http/Controllers/Auth/RegisterController.php
Expand Up @@ -63,6 +63,7 @@ protected function validator(array $data)
'last_name.required' => 'The "Last name" field is required',
'email.required' => 'Please provide a valid email address',
'email.email' => 'The email address you provided is not valid',
'email.unique' => 'The email address you provided is already in use',
'password.required' => 'A password is required',
'accept.required' => 'You must accept the Terms & conditions of service'
];
Expand All @@ -78,11 +79,17 @@ protected function validator(array $data)
*/
protected function create(array $data)
{
// All registered users have the role "Basic User",
// except the first, which is a "Super-admin"
$role_id = User::count() == 0 ? 4 : 1;

return User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'role_id' => $role_id,
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'active' => 1
]);
}
}
12 changes: 12 additions & 0 deletions app/Http/Controllers/Dashboard/ArticleController.php
Expand Up @@ -49,6 +49,18 @@ public function index(Request $request) {
->onEachSide(1);


/* Add 'allowActions' boolean to each article
Check if current user is the article's owner or an admin to allow actions */
foreach ($articles as $article) {
if (Auth::user()->role->name == 'author') {
$article->allowActions = $article->user_id == Auth::user()->id;
} else {
$article->allowActions = true;
}
}

//dd($articles->all());

return view('dashboard/articles',
[
'articles' => $articles,
Expand Down
42 changes: 42 additions & 0 deletions app/Http/Controllers/Dashboard/UserRightsController.php
@@ -0,0 +1,42 @@
<?php

namespace App\Http\Controllers\Dashboard;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Role;

class UserRightsController extends Controller
{
public function roles() {
return Role::all();
}

public function index() {
$users = User::paginate(10);
$users_count = User::count();
return view('dashboard/user-rights', ['users' => $users, 'users_count'=> $users_count]);
}

public function change_role($id) {
$user = User::find($id);
return view('dashboard/change-role',['user' => $user, 'roles' => $this->roles()]);
}

public function update_role(Request $request, $id) {
$user = User::find($id);
$user->role_id = $request->get('role_id');
$user->save();
return redirect()->route('user-rights')->with('success', 'The role for ' . $user->first_name . ' ' . $user->last_name . ' was updated');
}

public function ban_user($id){
User::find($id)->update(['active' => 0]);
return redirect()->back()->with('success', 'The user is now banned');
}

public function activate_user($id){
User::find($id)->update(['active' => 1]);
return redirect()->back()->with('success', 'The user is now active');
}
}
3 changes: 1 addition & 2 deletions app/Http/Controllers/FrontendController.php
Expand Up @@ -35,7 +35,6 @@ public function __construct()
$this->is_cookieconsent = $this->site_settings['is_cookieconsent'] ?? null;
$this->is_infinitescroll = $this->site_settings['is_infinitescroll'] ?? null;


// Article categories
$this->article_categories = ArticleCategory::all();

Expand All @@ -57,4 +56,4 @@ public function __construct()
'categories' => $this->article_categories,
];
}
}
}
1 change: 1 addition & 0 deletions app/Http/Kernel.php
Expand Up @@ -55,6 +55,7 @@ class Kernel extends HttpKernel
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'checkUserPermissions' => \App\Http\Middleware\CheckUserPermissions::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
Expand Down
34 changes: 34 additions & 0 deletions app/Http/Middleware/CheckUserPermissions.php
@@ -0,0 +1,34 @@
<?php

namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class CheckUserPermissions
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/

// Permissions checker
public function hasPermissionTo($permission) {
return in_array($permission, Auth::user()->role->permissions->pluck('slug')->toArray());
}

public function handle(Request $request, Closure $next, ...$permissions)
{
// Check user permissions
foreach ($permissions as $permission) {
if (!$this->hasPermissionTo($permission)) {
return redirect()->back()->with('error', 'You do not have permission to ' . str_replace('-', ' ', $permission));
}
}

return $next($request);
}
}
15 changes: 15 additions & 0 deletions app/Models/Permission.php
@@ -0,0 +1,15 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Permission extends Model
{
use HasFactory;

public function roles() {
return $this->belongsToMany(Role::class,'roles_permissions');
}
}
15 changes: 15 additions & 0 deletions app/Models/Role.php
@@ -0,0 +1,15 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
use HasFactory;

public function permissions() {
return $this->belongsToMany(Permission::class,'roles_permissions');
}
}
13 changes: 13 additions & 0 deletions app/Models/RolesPermissions.php
@@ -0,0 +1,13 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class RolesPermissions extends Model
{
use HasFactory;


}
6 changes: 6 additions & 0 deletions app/Models/User.php
Expand Up @@ -18,10 +18,12 @@ class User extends Authenticatable
* @var array<int, string>
*/
protected $fillable = [
'role_id',
'first_name',
'last_name',
'email',
'password',
'active'
];

/**
Expand All @@ -42,4 +44,8 @@ class User extends Authenticatable
protected $casts = [
'email_verified_at' => 'datetime',
];

public function role() {
return $this->belongsTo(Role::class);
}
}
6 changes: 6 additions & 0 deletions app/Providers/AppServiceProvider.php
Expand Up @@ -3,6 +3,8 @@
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Auth;
use Illuminate\Pagination\Paginator;

class AppServiceProvider extends ServiceProvider
Expand All @@ -29,5 +31,9 @@ public function boot()

// Use Twitter Bootstrap pagination
Paginator::useBootstrap();

Blade::if('userCan', function ($permission) {
return in_array($permission, Auth::user()->role->permissions->pluck('slug')->toArray());
});
}
}
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -17,7 +17,7 @@
"laravel/tinker": "^2.5",
"laravel/ui": "^3.4",
"spatie/laravel-newsletter": "^4.11",
"ext-json": "*",
"ext-json": "*"
},
"require-dev": {
"facade/ignition": "^2.5",
Expand Down
2 changes: 1 addition & 1 deletion database/factories/CommentFactory.php
Expand Up @@ -22,7 +22,7 @@ public function definition()
{
return [
'user_id' => $this->faker->randomElement([1, 2]),
'article_id' => $this->faker->randomElement([1, 2, 3, 4, 5, 6]),
'article_id' => $this->faker->randomElement([300, 299, 298, 297, 296, 295]),
'body' => $this->faker->sentence(2),
'approved' => $this->faker->randomElement([0, 1])
];
Expand Down
39 changes: 0 additions & 39 deletions database/factories/UserFactory.php

This file was deleted.

3 changes: 3 additions & 0 deletions database/migrations/2014_10_12_000000_create_users_table.php
Expand Up @@ -15,13 +15,16 @@ public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('role_id');
$table->foreign('role_id')->references('id')->on('roles');
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->longText('bio')->nullable();
$table->string('avatar')->default('default.png');
$table->string('password');
$table->tinyInteger('active')->default(1);
$table->rememberToken();
$table->timestamps();
});
Expand Down
34 changes: 34 additions & 0 deletions database/migrations/2022_12_31_174605_create_roles_table.php
@@ -0,0 +1,34 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateRolesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('label');
$table->text('description')->nullable();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('roles');
}
}