Skip to content

Commit

Permalink
fixed permissions so they work per organization
Browse files Browse the repository at this point in the history
  • Loading branch information
roncodes committed Aug 29, 2024
1 parent 2ba9ae1 commit e0c00ef
Show file tree
Hide file tree
Showing 11 changed files with 727 additions and 265 deletions.
50 changes: 50 additions & 0 deletions src/Console/Commands/AssignAdminRoles.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Fleetbase\Console\Commands;

use Fleetbase\Models\Company;
use Fleetbase\Models\User;
use Illuminate\Console\Command;

class AssignAdminRoles extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'fleetbase:assign-admin-roles';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Assigns the Administrator role to all company owners.';

/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$companies = Company::with('owner')->get();

foreach ($companies as $company) {
/** @var Company $company */
$company->loadMissing('owner');
if ($company->owner instanceof User) {
$company->owner->setCompanyUserRelation($company);
try {
$company->owner->assignSingleRole('Administrator');
$this->info($company->name . ' - Owner: ' . $company->owner->email . ' has been made Administrator.');
} catch (\Throwable $e) {
$this->error($e->getMessage());
}
}
}

return Command::SUCCESS;
}
}
12 changes: 12 additions & 0 deletions src/Console/Commands/ForceResetDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Fleetbase\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

Expand Down Expand Up @@ -32,6 +33,17 @@ public function handle()
// Get the connection name or use the default
$connection = $this->option('connection') ?: config('database.default');

// If connection is "all"
if (strtolower($connection) === 'all') {
$connections = config('database.connections', []);
foreach ($connections as $connectionName => $connectionConfig) {
Artisan::call('db:force-reset', ['--connection' => $connectionName]);
echo Artisan::output();
}

return;
}

// Set the connection for the schema builder and DB facade
$schema = Schema::connection($connection);
$db = DB::connection($connection);
Expand Down
7 changes: 7 additions & 0 deletions src/Exceptions/InvalidVerificationCodeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Fleetbase\Exceptions;

class InvalidVerificationCodeException extends \Exception
{
}
43 changes: 10 additions & 33 deletions src/Http/Controllers/Internal/v1/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Fleetbase\Http\Controllers\Internal\v1;

use Fleetbase\Exceptions\InvalidVerificationCodeException;
use Fleetbase\Http\Controllers\Controller;
use Fleetbase\Http\Requests\Internal\ResetPasswordRequest;
use Fleetbase\Http\Requests\Internal\UserForgotPasswordRequest;
Expand Down Expand Up @@ -354,56 +355,32 @@ public function verifyEmail(Request $request)
return response()->error('User is already verified.');
}

// get verification code for session
$verifyCode = VerificationCode::where([
'subject_uuid' => $user->uuid,
'for' => 'email_verification',
'code' => $code,
])->first();

// check if sms verification
if (!$verifyCode) {
$verifyCode = VerificationCode::where([
'subject_uuid' => $user->uuid,
'for' => 'phone_verification',
'code' => $code,
])->first();
}

// no verification code found
if (!$verifyCode) {
// Verify the user using the verification code
try {
$user->verify($code);
} catch (InvalidVerificationCodeException $e) {
return response()->error('Invalid verification code.');
}

// get verify time
$verifiedAt = Carbon::now();

// verify users email address or phone depending
if ($verifyCode->for === 'email_verification') {
$user->email_verified_at = $verifiedAt;
} elseif ($verifyCode->for === 'phone_verification') {
$user->phone_verified_at = $verifiedAt;
}

// Activate user
$user->status = 'active';
$user->save();
$user->activate();

// if authenticate is set
// If authenticate is set, generate and return a token
if ($authenticate) {
$user->updateLastLogin();
$token = $user->createToken($user->uuid);

return response()->json([
'status' => 'ok',
'verified_at' => $verifiedAt,
'verified_at' => $user->getDateVerified(),
'token' => $token->plainTextToken,
]);
}

// Return success response without token
return response()->json([
'status' => 'ok',
'verified_at' => $verifiedAt,
'verified_at' => $user->getDateVerified(),
'token' => null,
]);
}
Expand Down
10 changes: 2 additions & 8 deletions src/Http/Controllers/Internal/v1/OnboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use Fleetbase\Http\Controllers\Controller;
use Fleetbase\Http\Requests\OnboardRequest;
use Fleetbase\Models\Company;
use Fleetbase\Models\CompanyUser;
use Fleetbase\Models\User;
use Fleetbase\Models\VerificationCode;
use Illuminate\Http\Request;
Expand Down Expand Up @@ -67,20 +66,15 @@ public function createAccount(OnboardRequest $request)
// set the user type
$user->setUserType($isAdmin ? 'admin' : 'user');

// assign admin role
$user->assignSingleRole('Administrator');

// create company
$company = new Company(['name' => $request->input('organization_name')]);
$company->setOwner($user)->save();

// assign user to organization
$user->assignCompany($company);

// Create company user record
if (CompanyUser::where(['company_uuid' => $company->uuid, 'user_uuid' => $user->uuid])->doesntExist()) {
CompanyUser::create(['company_uuid' => $company->uuid, 'user_uuid' => $user->uuid, 'status' => $user->status]);
}
// assign admin role
$user->assignSingleRole('Administrator');

// send account created event
event(new AccountCreated($user, $company));
Expand Down
9 changes: 2 additions & 7 deletions src/Http/Controllers/Internal/v1/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,7 @@ public function deactivate($id)
return response()->error('No user found', 401);
}

// $user->deactivate();
// deactivate for company session
$user->companies()->where('company_uuid', session('company'))->update(['status' => 'inactive']);
$user->deactivate();
$user = $user->refresh();

return response()->json([
Expand All @@ -395,10 +393,7 @@ public function activate($id)
return response()->error('No user found', 401);
}

// $user->activate();
// activate for company session
// maybe we dont want to activate for all organizations
$user->companies()->where('company_uuid', session('company'))->update(['status' => 'active']);
$user->activate();
$user = $user->refresh();

return response()->json([
Expand Down
84 changes: 84 additions & 0 deletions src/Models/CompanyUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

namespace Fleetbase\Models;

use Fleetbase\Traits\HasPolicies;
use Fleetbase\Traits\HasUuid;
use Fleetbase\Traits\TracksApiCredential;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Spatie\Permission\Traits\HasRoles;

class CompanyUser extends Model
{
use HasUuid;
use TracksApiCredential;
use HasRoles;
use HasPolicies;

/**
* The database table used by the model.
Expand All @@ -28,6 +34,13 @@ class CompanyUser extends Model
'status',
];

/**
* The default guard for this model.
*
* @var string
*/
public $guard_name = 'sanctum';

/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
Expand All @@ -53,4 +66,75 @@ public function setStatusAttribute($value = 'active')
{
$this->attributes['status'] = $value ?? 'active';
}

/**
* Assign a single role to the user, removing any existing roles.
*
* This method deletes all existing roles assigned to the user and then assigns the specified role.
*
* @param string|int|\Spatie\Permission\Models\Role $role The role to assign to the user (can be a role name, ID, or instance)
*
* @return User The assigned role instance
*/
public function assignSingleRole($role): self
{
DB::table('model_has_roles')->where('model_uuid', $this->uuid)->delete();

return $this->assignRole($role);
}

/**
* Return all the permissions the model has, both directly and via roles and policies.
*/
public function getAllPermissions()
{
/** @var \Illuminate\Database\Eloquent\Model|\Spatie\Permission\Traits\HasPermissions $this */
/** @var Collection $permissions */
$permissions = $this->permissions;

if (method_exists($this, 'roles')) {
$permissions = $permissions->merge($this->getPermissionsViaRoles());
}

if (method_exists($this, 'policies')) {
$permissions = $permissions->merge($this->getPermissionsViaPolicies());
$permissions = $permissions->merge($this->getPermissionsViaRolePolicies());
}

return $permissions->sort()->values();
}

/**
* Checks if the user has any of the given permissions.
*
* This method checks if the user's attached permissions intersect with the given permissions.
* If there is at least one matching permission, the method returns true.
*
* @param Collection|array $permissions The permissions to check against
*
* @return bool True if the user has any of the given permissions, false otherwise
*/
public function hasPermissions(Collection|array $permissions): bool
{
$attachedPermissions = $this->getAllPermissions();

return $attachedPermissions->filter(function ($permission) use ($permissions) {
return $permissions->contains($permission);
})->isNotEmpty();
}

/**
* Checks if the user does not have any of the given permissions.
*
* This method checks if the user's attached permissions do not intersect with the given permissions.
* If there are no matching permissions, the method returns true.
*
* @param Collection|array $permissions The permissions to check against
*
* @return bool True if the user does not have any of the given permissions, false otherwise
*/
public function doesntHavePermissions(Collection|array $permissions): bool
{
return !$this->hasPermissions($permissions);
}
}
Loading

0 comments on commit e0c00ef

Please sign in to comment.