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

Roles and Permissions #803

Open
wants to merge 99 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
fddf5ac
Do not escape html for post order message
bagage Apr 28, 2019
6699ed0
Fix XSS and 500 error if version check fails
publicarray Dec 28, 2019
55e5dcb
Merge branch 'master' into version-check-fixes
samdb Apr 14, 2020
aa74389
Merge branch 'develop' into fix-post-order-display-message-escaping
johannac Apr 21, 2020
fd2b178
Merge pull request #629 from bagage/fix-post-order-display-message-es…
johannac Apr 21, 2020
117ab90
Merge branch 'develop' into version-check-fixes
johannac Apr 21, 2020
f959b28
Add installed function back to utils to fix 500 error in tests
johannac Apr 23, 2020
b8115fe
Consolidate two getVersionInfo functions into 1
johannac Apr 23, 2020
56ff9b7
Add unit test for new parse_version function
johannac Apr 23, 2020
bf017b6
Fix types in new parse_version function and expand regex a bit
johannac Apr 23, 2020
a471c08
Change version check to use github version file instead of old attend…
johannac Apr 23, 2020
ff56b58
Merge pull request #743 from publicarray/version-check-fixes
johannac Apr 23, 2020
6c894dc
Update ManageAccountController.php
chrisbrosnan Apr 28, 2020
b9842db
Merge pull request #789 from chrisbrosnan/develop
johannac May 12, 2020
d3da9a3
Add docker production environment
Leen15 Jul 13, 2018
7cd4248
fix typos
Leen15 Jul 13, 2018
0aa0901
Setup German translation and translate all emails
ftbastler Oct 11, 2018
6954ebc
German Translation of Footer.blade.php
Modding Oct 11, 2018
27ee0be
Translation of Emails
Modding Oct 11, 2018
ee07a0e
lang de erstellt und die ersten Dateien bearbeitet.
Modding Oct 11, 2018
d8624e8
weitere Dateien bearbeitet
Modding Oct 17, 2018
576e04b
Fees bearbeitet.
Modding Feb 21, 2019
5dc41a5
Installer.php bearbeitet
Modding Feb 21, 2019
89968e5
Installer.php fertiggestellt
Modding Feb 23, 2019
795693d
Javascript.php fertiggestellt
Modding Feb 23, 2019
bbb9641
anpassungen
Modding Mar 5, 2019
1e8a749
erste änderungen
Modding Mar 18, 2019
f161d62
Public_ViewEvent.php bearbeitet
Modding Mar 18, 2019
5b61c4c
Rechtschreibfehler
Modding Mar 19, 2019
a597805
anpassungen
Modding Mar 20, 2019
aff46bc
Prevent duplicate queries
AdrienPoupa Dec 7, 2018
d1dcc58
Update FirstRunMiddleware.php
AdrienPoupa Dec 10, 2018
0ccd792
Remove some duplicate queries
AdrienPoupa Dec 11, 2018
d2b5ce1
First commit Italian localization
falcecamogli Feb 19, 2020
9d77cf9
Fixed missed translation in Italian localization
falcecamogli Feb 19, 2020
acc1d4c
Added missing translations for Italian localization
falcecamogli Feb 19, 2020
64ae3cb
Fixed wrong translations for Italian localization
falcecamogli Feb 19, 2020
6f33ddb
Enable Italian locale
falcecamogli Feb 19, 2020
6cafbcb
Added missing translatable strings in Stripe, also for other languages
falcecamogli Feb 19, 2020
c3a7f5f
Fix translation for Italian localization
falcecamogli Feb 19, 2020
45c1114
Added missing translation label
falcecamogli Feb 19, 2020
426bd2a
Update dependencies and install roles and permissions package
May 30, 2020
6a1ad45
Add better minimal error pages
May 30, 2020
61987ed
Add permissions config, Add roles and permissions migrations. Add org…
May 30, 2020
be491bb
Link user to organiser. Fetch events with organisers
May 30, 2020
a79de4c
Add missing translations. Wrap UI parts in role/permissions checks to…
May 30, 2020
df3ea91
Add organiser to user in the test seeds. Add basic seeds for roles an…
May 30, 2020
60e01b9
Wrap organiser routes in the correct middleware checks for roles
May 30, 2020
4ddcd61
Add CanManageOrganisers middleware. Implicitly allow super admin user…
May 30, 2020
ce2d291
Cleanup the database seeder class names. Update the index controller …
May 30, 2020
00484cc
Bump version to 2.1.0
May 30, 2020
a8fe0bb
Fix regression in sending mail to a new user
May 30, 2020
7b9fbbb
Fix installer so it shows default values in the form
johannac May 27, 2020
b7a692c
Refactor docker config so nginx and php run on 1 container.
johannac May 27, 2020
96864f5
Add some comments to the docker set up
johannac May 27, 2020
5db7fa3
Add apache support
johannac May 28, 2020
1c33975
Fix the copy env file in makefile
johannac Jun 2, 2020
aea3126
Version bump
johannac Jun 2, 2020
a9db31b
Remove old compose file
johannac Jun 2, 2020
c8a679a
Add hCaptcha (#793)
publicarray Jun 3, 2020
17d061f
Add reCAPTCHA (#585)
publicarray Jun 3, 2020
42ff4a5
Update Fees.php (#810)
SamuelNitsche Jun 22, 2020
08d5f9e
Allow use of both reCaptcha hCaptcha or no capture based on config (#…
melvinthoabala Jun 22, 2020
d1184fa
Add min reqs to the readme file
johannac Jun 22, 2020
8fe013d
Add commands to makefile for clearing laravel cache and recompiling a…
johannac Jun 23, 2020
a8a3d0d
Add artisan migrate to the setup scripts in case there's database mig…
johannac Jun 23, 2020
9779bbd
Last name is required by the database schema so needs to be required …
johannac Jun 23, 2020
7c55e21
Fix redirect on the signup page - the import was missing, but also th…
johannac Jun 23, 2020
3cecc6e
Change the use of Utils::isAttendize() to Utils::isCloud() during the…
johannac Jun 23, 2020
092c5d2
Remove dupe translation
johannac Jun 23, 2020
5bffeaf
Refactor a bit of the captcha logic for the signup page
johannac Jun 23, 2020
ced63e9
Refactor login page to use captcha services
johannac Jun 23, 2020
16bb882
Refactor contact form page to use captcha services
johannac Jun 23, 2020
966ec2e
Use promises to initialise camera for check-in (#712)
scottyeung Jun 26, 2020
bd9fa02
Merge branch 'develop' into feature/roles-and-permissions
Jun 27, 2020
07f9594
Add seeder to run with migration to pre seed default roles and permis…
Jun 27, 2020
72d4e13
Update the account users UI with the roles assigned to the users in t…
Jun 27, 2020
bc6d1d8
Update the invite user form to take a first/last name along with emai…
Jun 27, 2020
97639a9
Layout the table better. Default select the user role for sensible de…
Jun 27, 2020
bbbf1f5
Update the user management screen with role selection dropdowns. Bind…
Jun 27, 2020
5abc186
Allow super admin users to give permission to User role types to mana…
Jun 27, 2020
8731f01
Clean up unused javascript
Jun 27, 2020
dadfd5f
Fix the error pages translations method
Jul 14, 2020
e578b64
Force the seed class to run on the migration to add permissions and r…
Jul 14, 2020
96836ef
Update the installation flow to include checks for first run and assi…
Jul 14, 2020
09c2925
Merge branch 'develop' into feature/roles-and-permissions
Jul 14, 2020
09b4507
Update the permissions seed to assign super admin roles to all legacy…
Jul 15, 2020
e182cd4
Merge with latest develop
quentincaffeino Aug 4, 2021
1ec0a39
Roles and Permissions: Deactivate, Restore and Delete users
quentincaffeino Aug 9, 2021
f77b59e
merge with origin/feature/roles-and-permissions
quentincaffeino Aug 9, 2021
43941ea
Merge branch 'feature/roles-and-permissions' into feature/roles-and-p…
quentincaffeino Aug 9, 2021
41dc199
Added prebuild backend js
quentincaffeino Aug 9, 2021
970634e
Created dropdownmenu to make things look better and to allow to fit m…
quentincaffeino Aug 9, 2021
1c426ae
Added `Send invitation` button
quentincaffeino Aug 9, 2021
451e4bf
fix: if user has no roles whole settings is broken, check if user has…
quentincaffeino Sep 23, 2021
8ec618e
Merge branch 'develop' into feature/roles-and-permissions-deleting-users
quentincaffeino Sep 23, 2021
b1c6856
fix: password is empty on user save
quentincaffeino Sep 24, 2021
d653d91
Merge pull request #957 from quentincaffeino/feature/roles-and-permis…
johannac Jan 6, 2023
a923618
Merge branch 'develop' into feature/roles-and-permissions
johannac Jan 6, 2023
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
44 changes: 43 additions & 1 deletion app/Http/Controllers/IndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Auth;

class IndexController extends Controller
{
Expand All @@ -13,6 +14,47 @@ class IndexController extends Controller
*/
public function showIndex(Request $request)
{
return redirect()->route('showSelectOrganiser');
/** @var $user App\Models\User */
$user = Auth::user();

// super admin users will get shown the organiser selection page
if ($user->can('manage organisers')) {
return redirect()->route('showSelectOrganiser');
}

$isCheckinUser = $user->hasRole('attendee check in');

// Normal users will get shown their dashboard
$organiser = $user->organiser;
$allowed_sorts = ['created_at', 'start_date', 'end_date', 'title'];

$searchQuery = $request->get('q');
$sort_by = (in_array($request->get('sort_by'), $allowed_sorts) ? $request->get('sort_by') : 'start_date');

// If user can manage events, then they can see all events, otherwise just their own
$events = $organiser->events()
etiennemarais marked this conversation as resolved.
Show resolved Hide resolved
->where('organiser_id', $organiser->id)
->orderBy($sort_by, 'desc');

// We only want to filter for normal users here. Check in users get a limited event UI
if (!$user->can('manage events') && !$isCheckinUser) {
$events->where('user_id', $user->id);
}

if ($searchQuery) {
$events->where('title', 'like', '%' . $searchQuery . '%');
}

$data = [
'events' => $events->paginate(12),
'organiser' => $organiser,
'search' => [
'q' => $searchQuery ? $searchQuery : '',
'sort_by' => $request->get('sort_by') ? $request->get('sort_by') : '',
'showPast' => $request->get('past'),
],
];

return view('ManageOrganiser.Events', $data);
}
}
226 changes: 214 additions & 12 deletions app/Http/Controllers/ManageAccountController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
use App\Models\PaymentGateway;
use App\Models\Timezone;
use App\Models\User;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Mail\Message;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
Expand All @@ -20,8 +18,11 @@
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Services\PaymentGateway\Dummy;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Services\PaymentGateway\Stripe;
use Services\PaymentGateway\StripeSCA;
use Spatie\Permission\Exceptions\RoleDoesNotExist;
use Utils;
use Illuminate\Support\Facades\Lang;

Expand All @@ -43,6 +44,8 @@ public function showEditAccount(Request $request)
'default_payment_gateway_id' => PaymentGateway::getDefaultPaymentGatewayId(),
'account_payment_gateways' => AccountPaymentGateway::scope()->get(),
'version_info' => $this->getVersionInfo(),
// Only super admin users gets to manage users so this call is safe
'roles' => Role::all(),
];

return view('ManageAccount.Modals.EditAccount', $data);
Expand Down Expand Up @@ -167,13 +170,17 @@ public function postEditAccountPayment(Request $request)
public function postInviteUser(Request $request)
{
$rules = [
'organiser' => ['required'],
'role' => ['required'],
'email' => ['required', 'email', 'unique:users,email,NULL,id,account_id,' . Auth::user()->account_id],
];

$messages = [
'email.email' => trans('Controllers.error.email.email'),
'email.required' => trans('Controllers.error.email.required'),
'email.unique' => trans('Controllers.error.email.unique'),
'organiser.required' => trans('Controllers.error.organiser.required'),
'role.required' => trans('Controllers.error.role.required'),
];

$validation = Validator::make($request->all(), $rules, $messages);
Expand All @@ -185,33 +192,228 @@ public function postInviteUser(Request $request)
]);
}

$temp_password = Str::random(8);

$user = new User();

$user->first_name = $request->input('first_name');
$user->last_name = $request->input('last_name');
$user->email = $request->input('email');
$user->password = Hash::make($temp_password);
$user->account_id = Auth::user()->account_id;
$user->organiser_id = $request->input('organiser');

$temp_password = Str::random(8);
$user->password = Hash::make($temp_password);

$user->save();

// Assigning role to user from selection. If for some reason the role errors out, we assign the default role.
try {
$assignedRole = Role::findById($request->input('role'));
} catch (RoleDoesNotExist $e) {
$assignedRole = Role::findByName('user');
}

$user->assignRole($assignedRole);
$user->givePermissionTo($user->getAllPermissions());

$this->sentInvitationEmailTo($user, $temp_password);

return response()->json([
'status' => 'success',
'message' => trans('Controllers.success_name_has_received_instruction', ['name' => $user->email]),
]);
}

/**
* Update the user role
*
* @return JsonResponse
*/
public function postUpdateUserRole(Request $request)
{
$rules = [
'assigned_role' => ['required'],
'user_id' => ['required'],
];

$messages = [
'user_id.required' => trans('Controllers.error.role.required'),
'assigned_role.required' => trans('Controllers.error.role.required'),
];

$validation = Validator::make($request->all(), $rules, $messages);

if ($validation->fails()) {
return response()->json([
'status' => 'error',
'messages' => $validation->messages()->toArray(),
]);
}

/** @var \App\Models\User $user */
$user = User::find($request->input('user_id'));
$assignedRole = Role::findById($request->input('assigned_role'));
$user->syncRoles($assignedRole);
$user->syncPermissions($assignedRole->permissions()->get());

return response()->json([
'status' => 'success',
'message' => trans('Controllers.success_user_updated_role', ['name' => $user->email]),
]);
}

/**
* Toggle the user can manage events
*
* @return JsonResponse
*/
public function postToggleUserCanManageEvents(Request $request)
{
$rules = [
'user_id' => ['required'],
];

$messages = [
'user_id.required' => trans('Controllers.error.role.required'),
];

$validation = Validator::make($request->all(), $rules, $messages);

if ($validation->fails()) {
return response()->json([
'status' => 'error',
'messages' => $validation->messages()->toArray(),
]);
}

/** @var \App\Models\User $user */
$user = User::find($request->input('user_id'));

// Toggle between the extended manage events permission
$isChecked = $request->boolean('checked');
$manageEvents = Permission::findByName('manage events', 'web');

if ($isChecked && !$user->can('manage events')) {
$user->givePermissionTo($manageEvents);
$message = trans('Controllers.success_user_can_manage_events', ['name' => $user->email]);
} elseif (!$isChecked) {
$user->revokePermissionTo($manageEvents);
$message = trans('Controllers.success_user_cannot_manage_events', ['name' => $user->email]);
}

return response()->json([
'status' => 'success',
'message' => $message,
]);
}

/**
* Delete user
*
* @param Request $request
* @param integer $userId
*
* @return JsonResponse
*/
public function userDelete(Request $request, $userId)
{
/** @var \App\Models\User|null $user */
$user = User::withTrashed()->find($userId);
if (!$user) {
return response()->json([
'status' => 'error',
'message' => trans('Controllers.error_user_was_not_found'),
], 404);
}

if ($request->get('force', false)) {
$user->forceDelete();
} else {
$user->delete();
}

$message = trans('Controllers.success_user_was_deleted', ['name' => $user->email]);
return response()->json([
'status' => 'success',
'message' => $message,
]);
}

/**
* Restore deleted user
*
* @param Request $request
* @param integer $userId
*
* @return JsonResponse
*/
public function userRestore(Request $request, $userId)
{
/** @var \App\Models\User|null $user */
$user = User::withTrashed()->find($userId);
if (!$user) {
return response()->json([
'status' => 'error',
'message' => trans('Controllers.error_user_was_not_found'),
], 404);
}

$user->restore();

$message = trans('Controllers.success_user_was_restored', ['name' => $user->email]);
return response()->json([
'status' => 'success',
'message' => $message,
]);
}

/**
* @param Request $request
* @param integer $userId
*
* @return JsonResponse
*/
public function sendInvitationMessage(Request $request, $userId) {
/** @var \App\Models\User|null $user */
$user = User::find($userId);
if (!$user) {
return response()->json([
'status' => 'error',
'message' => trans('Controllers.error_user_was_not_found'),
], 404);
}

$temp_password = Str::random(8);
$user->password = Hash::make($temp_password);
$user->save();

$this->sentInvitationEmailTo($user, $temp_password);

return response()->json([
'status' => 'success',
'message' => trans('Controllers.success_name_has_received_instruction', ['name' => $user->email]),
]);
}

/**
* Send an invitation email
*
* @param User $user
* @param string $password
*/
protected function sentInvitationEmailTo(User $user, string $password)
{
$data = [
'user' => $user,
'temp_password' => $temp_password,
'temp_password' => $password,
'inviter' => Auth::user(),
];

Mail::send(Lang::locale().'.Emails.inviteUser', $data, static function (Message $message) use ($data) {
Mail::send('Emails.inviteUser', $data, static function ($message) use ($data) {
$message->to($data['user']->email)
->subject(trans('Email.invite_user', [
'name' => $data['inviter']->first_name . ' ' . $data['inviter']->last_name,
'app' => config('attendize.app_name')
]));
});

return response()->json([
'status' => 'success',
'message' => trans('Controllers.success_name_has_received_instruction', ['name' => $user->email]),
]);
}
}
8 changes: 7 additions & 1 deletion app/Http/Controllers/OrganiserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use App\Models\Organiser;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Image;
use App\Models\User;

class OrganiserController extends MyBaseController
{
Expand Down Expand Up @@ -71,6 +71,12 @@ public function postCreateOrganiser(Request $request)

$organiser->save();

// After the organiser gets added as the first run, we should also update the super user to
// belong to that organiser
if ($request->get('first_run') === 'yup') {
User::first()->update(['organiser_id' => $organiser->id]);
}

session()->flash('message', trans("Controllers.successfully_created_organiser"));

return response()->json([
Expand Down
5 changes: 5 additions & 0 deletions app/Http/Controllers/UserSignupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ public function postSignup(Request $request)
$user_data['is_registered'] = 1;
$user = User::create($user_data);

// We need to assign the first ever user as super admin to be able to add the first organiser
if ($request->get('first_run') === 'yup') {
$user->assignRole('super admin');
}

$payment_gateway_data = [
'payment_gateway_id' => PaymentGateway::getDefaultPaymentGatewayId(),
'account_id' => $account->id,
Expand Down
1 change: 1 addition & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Kernel extends HttpKernel
/**** ATTENDIZE MIDDLEWARE ****/
'first.run' => \App\Http\Middleware\FirstRunMiddleware::class,
'installed' => \App\Http\Middleware\CheckInstalled::class,
'manage.organisers' => \App\Http\Middleware\CanManageOrganisers::class,

/**** OTHER MIDDLEWARE ****/
'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
Expand Down