diff --git a/app/Http/Controllers/Api/V1/Organisation/OrganisationController.php b/app/Http/Controllers/Api/V1/Organisation/OrganisationController.php index 28c062c8..00f542a7 100755 --- a/app/Http/Controllers/Api/V1/Organisation/OrganisationController.php +++ b/app/Http/Controllers/Api/V1/Organisation/OrganisationController.php @@ -13,6 +13,8 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use App\Http\Resources\OrganisationResource; +use App\Models\Role; +use Illuminate\Support\Facades\Auth; class OrganisationController extends Controller { @@ -20,71 +22,71 @@ class OrganisationController extends Controller * Display a listing of the resource. */ public function index($user_id) -{ - try { - // Ensure that the authenticated user is accessing their own organisations - $authUser = auth('api')->user(); - if (!$authUser) { - return response()->json([ - 'status' => 'error', - 'message' => 'Unauthorized', - 'status_code' => 401 - ], 401); - } + { + try { + // Ensure that the authenticated user is accessing their own organisations + $authUser = auth('api')->user(); + if (!$authUser) { + return response()->json([ + 'status' => 'error', + 'message' => 'Unauthorized', + 'status_code' => 401 + ], 401); + } - // Check if the authenticated user is trying to access their own data - if ($authUser->id !== (string) $user_id) { - Log::info('Authenticated User ID:', ['id' => $authUser->id]); - Log::info('Requested User ID:', ['requested_id' => $user_id]); - return response()->json([ - 'status' => 'error', - 'message' => 'Forbidden', - 'status_code' => 403 - ], 403); - } + // Check if the authenticated user is trying to access their own data + if ($authUser->id !== (string) $user_id) { + Log::info('Authenticated User ID:', ['id' => $authUser->id]); + Log::info('Requested User ID:', ['requested_id' => $user_id]); + return response()->json([ + 'status' => 'error', + 'message' => 'Forbidden', + 'status_code' => 403 + ], 403); + } - // Find the user by ID, handling potential non-existence - $user = User::where('id', $user_id)->first(); - if (!$user) { - return response()->json([ - 'status' => 'error', - 'message' => 'User not found', - 'status_code' => 404 - ], 404); - } + // Find the user by ID, handling potential non-existence + $user = User::where('id', $user_id)->first(); + if (!$user) { + return response()->json([ + 'status' => 'error', + 'message' => 'User not found', + 'status_code' => 404 + ], 404); + } - // Retrieve the user's organisations - $organisations = $user->organisations; + // Retrieve the user's organisations + $organisations = $user->organisations; + + if ($organisations->isEmpty()) { + return response()->json([ + 'status' => 'success', + 'message' => 'No organisations available', + 'status_code' => 200, + 'data' => [ + 'organisations' => [] + ] + ], 200); + } - if ($organisations->isEmpty()) { return response()->json([ 'status' => 'success', - 'message' => 'No organisations available', + 'message' => 'Organisations retrieved successfully', 'status_code' => 200, 'data' => [ - 'organisations' => [] + 'organisations' => OrganisationResource::collection($organisations) ] - ], 200); + ]); + } catch (\Exception $e) { + Log::error('An error occurred while retrieving organisations:', ['error' => $e->getMessage()]); + return response()->json([ + 'status' => 'error', + 'message' => 'An error occurred', + 'status_code' => 500, + 'error' => $e->getMessage() + ], 500); } - - return response()->json([ - 'status' => 'success', - 'message' => 'Organisations retrieved successfully', - 'status_code' => 200, - 'data' => [ - 'organisations' => OrganisationResource::collection($organisations) - ] - ]); - } catch (\Exception $e) { - Log::error('An error occurred while retrieving organisations:', ['error' => $e->getMessage()]); - return response()->json([ - 'status' => 'error', - 'message' => 'An error occurred', - 'status_code' => 500, - 'error' => $e->getMessage() - ], 500); } -} /** @@ -92,9 +94,9 @@ public function index($user_id) */ public function store(StoreOrganisationRequest $request) { - if($validPayload = $request->validated()){ + if ($validPayload = $request->validated()) { $user = auth()->user(); - if(!$user){ + if (!$user) { return ResponseHelper::response("Authentication failed", 401, null); } $validPayload['user_id'] = $user->id; @@ -109,7 +111,7 @@ public function store(StoreOrganisationRequest $request) DB::rollBack(); return ResponseHelper::response("Client error", 400, null); } - }else{ + } else { return ResponseHelper::response("Client error", 400, null); } } @@ -127,20 +129,20 @@ public function show(string $id) */ public function update(StoreOrganisationRequest $request, $org_id) { - if($validPayload = $request->validated()){ + if ($validPayload = $request->validated()) { $user = auth('api')->user(); - if(!$user) return ResponseHelper::response("Authentication failed", 401, null); + if (!$user) return ResponseHelper::response("Authentication failed", 401, null); $organisation = Organisation::find($org_id); - if(!$organisation) return ResponseHelper::response("Organisation not found", 404, null); - if(!$organisation->users->contains($user->id)) return ResponseHelper::response("You are not authorised to perform this action", 403, null); + if (!$organisation) return ResponseHelper::response("Organisation not found", 404, null); + if (!$organisation->users->contains($user->id)) return ResponseHelper::response("You are not authorised to perform this action", 403, null); try { unset($validPayload['email']); $organisation->update($validPayload); return ResponseHelper::response("Organisation updated successfully", 200, $organisation->getPublicColumns()); - }catch (\Exception $e) { + } catch (\Exception $e) { return ResponseHelper::response("Client error", 400, null); } - }else{ + } else { return ResponseHelper::response("Client error", 400, null); } } @@ -151,19 +153,19 @@ public function update(StoreOrganisationRequest $request, $org_id) public function destroy($org_id) { $user = auth('api')->user(); - if(!$user) return ResponseHelper::response("Authentication failed", 401, null); + if (!$user) return ResponseHelper::response("Authentication failed", 401, null); $organisation = Organisation::find($org_id); - if(!$organisation) return ResponseHelper::response("Organisation not found", 404, null); - if(!$organisation->users->contains($user->id)) return ResponseHelper::response("You are not authorised to perform this action", 401, null); + if (!$organisation) return ResponseHelper::response("Organisation not found", 404, null); + if (!$organisation->users->contains($user->id)) return ResponseHelper::response("You are not authorised to perform this action", 401, null); try { // Soft delete the org $organisation->delete(); return ResponseHelper::response("Organisation deleted successfully", 204, null); - }catch (\Exception $e) { + } catch (\Exception $e) { return ResponseHelper::response("Client error", 400, null); } } - + public function removeUser(Request $request, $org_id, $user_id) { $organisation = Organisation::findOrFail($org_id); @@ -193,4 +195,42 @@ public function removeUser(Request $request, $org_id, $user_id) 'status_code' => 200 ], 200); } + + + public function getRoleId(Request $request, $org_id, $role_id) + { + $role = Role::where('id', $role_id)->where('org_id', $org_id)->first(); + + if (!$role) { + return response()->json([ + 'status' => 'error', + 'message' => 'Role not found or does not belong to the specified organisation', + 'status_code' => 404 + ], 404); + } + + $user = Auth::user(); + if (!$user->organisations->contains('org_id', $org_id)) { + return response()->json([ + 'status' => 'forbidden', + 'message' => 'User does not have permission to access this role', + 'status_code' => 403 + ], 403); + } + + + return response()->json([ + 'status' => 'success', + 'message' => 'Role retrieved successfully', + 'status_code' => 200, + 'data' => [ + 'role_id' => $role->id, + 'name' => $role->name, + 'description' => $role->description, + 'org_id' => $role->org_id, + 'is_active' => $role->is_active, + 'is_default' => $role->is_default, + ] + ]); + } } diff --git a/database/factories/RoleFactory.php b/database/factories/RoleFactory.php index 22f0a4a6..389111c8 100755 --- a/database/factories/RoleFactory.php +++ b/database/factories/RoleFactory.php @@ -11,10 +11,12 @@ class RoleFactory extends Factory protected $model = Role::class; public function definition() - { + { $organisation = Organisation::factory()->create(); + + return [ 'name' => $this->faker->jobTitle, - 'org_id' => Organisation::factory(), + 'org_id' => $organisation->org_id, 'description' => $this->faker->sentence, 'is_active' => true, 'is_default' => false, diff --git a/database/migrations/2024_07_21_121543_create_roles_table.php b/database/migrations/2024_07_21_121543_create_roles_table.php index 35ae640c..1fbea6b5 100755 --- a/database/migrations/2024_07_21_121543_create_roles_table.php +++ b/database/migrations/2024_07_21_121543_create_roles_table.php @@ -10,7 +10,7 @@ * Run the migrations. */ public function up(): void - { +{ Schema::create('roles', function (Blueprint $table) { $table->id(); $table->string('name'); diff --git a/routes/api.php b/routes/api.php index 6816cb5c..0cdf50e8 100755 --- a/routes/api.php +++ b/routes/api.php @@ -63,6 +63,7 @@ | */ + Route::any('/', function () { return 'Language Learning AI Game'; }); @@ -133,6 +134,8 @@ Route::delete('/organisations/{org_id}/products/{product_id}', [ProductController::class, 'destroy']); }); + + //comment Route::middleware('auth:api')->group(function () { Route::post('/blogs/{blogId}/comments', [CommentController::class, 'createComment']); @@ -212,6 +215,11 @@ Route::delete('/organisations/{org_id}/users/{user_id}', [OrganisationController::class, 'removeUser']); Route::get('/organisations/{organisation}/users', [organisationMemberController::class, 'index']); + //Role Organisations + + + Route::get('/organisation/{org_id}/roles/{role_id}', [OrganisationController::class, 'getRoleId']); + // members Route::get('/members/{org_id}/search', [OrganisationMemberController::class, 'searchMembers']); Route::get('/members/{org_id}/export', [OrganisationMemberController::class, 'download']); diff --git a/tests/Feature/OrganisationRoleTest.php b/tests/Feature/OrganisationRoleTest.php new file mode 100644 index 00000000..cecae281 --- /dev/null +++ b/tests/Feature/OrganisationRoleTest.php @@ -0,0 +1,106 @@ +create(); + $user = User::factory()->create(); + $organisation->users()->attach($user->id); + + $role = Role::create([ + 'name' => 'Craft Artist', + 'description' => 'Quae voluptas fuga animi expedita natus qui.', + 'org_id' => $organisation->org_id, + 'is_active' => true, + 'is_default' => false, + ]); + + // Generate a JWT token + $token = JWTAuth::fromUser($user); + + // Send request with the JWT token + $response = $this->withHeaders([ + 'Authorization' => "Bearer $token" + ])->getJson("/api/v1/organisation/{$organisation->org_id}/roles/{$role->id}"); + + // Assert success response + $response->assertStatus(200) + ->assertJson([ + 'status' => 'success', + 'message' => 'Role retrieved successfully', + 'data' => [ + 'role_id' => $role->id, + 'name' => $role->name, + 'description' => $role->description, + 'org_id' => $role->org_id, + 'is_active' => $role->is_active, + 'is_default' => $role->is_default, + ] + ]); + + $this->assertDatabaseHas('roles', [ + 'id' => $role->id, + 'org_id' => $organisation->org_id, + ]); + } + + public function test_get_role_by_org_and_role_id_forbidden() + { + $user = User::factory()->create(); + $organisation = Organisation::factory()->create(); + $organisation->users()->attach($user->id); + + $otherUser = User::factory()->create(); + $token = JWTAuth::fromUser($otherUser); + + $role = Role::factory()->create([ + 'org_id' => $organisation->org_id + ]); + + $response = $this->withHeaders([ + 'Authorization' => "Bearer $token" + ])->getJson("/api/v1/organisation/{$organisation->org_id}/roles/{$role->id}"); + + // Assert forbidden response + $response->assertStatus(403) + ->assertJson([ + 'status' => 'forbidden', + 'message' => 'User does not have permission to access this role', + ]); + } + + public function test_get_role_by_org_and_role_id_not_found() + { + $user = User::factory()->create(); + $organisation = Organisation::factory()->create(); + $organisation->users()->attach($user->id); + + // Generate a JWT token + $token = JWTAuth::fromUser($user); + + // Send request for a non-existent role + $response = $this->withHeaders([ + 'Authorization' => "Bearer $token" + ])->getJson("/api/v1/organisation/{$organisation->org_id}/roles/999"); + + // Assert not found response + $response->assertStatus(404) + ->assertJson([ + 'status' => 'error', + 'message' => 'Role not found or does not belong to the specified organisation', + ]); + } +}