Skip to content

Commit aa13042

Browse files
Merge pull request #60 from IFRCGo/WN-349
Add application rules field and upsert API
2 parents af0dfaa + 0d10da3 commit aa13042

6 files changed

Lines changed: 122 additions & 11 deletions

File tree

app/Http/Controllers/ApplicationController.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use App\Classes\Repositories\ApplicationRepositoryInterface;
66
use App\Classes\Transformers\ApplicationTransformer;
7+
use App\Http\Requests\UpsertApplicationRulesRequest;
8+
use App\Models\Application;
79
use Illuminate\Database\Eloquent\Collection;
810
use Illuminate\Http\Request;
911
use Illuminate\Support\Facades\Log;
@@ -494,4 +496,29 @@ public function deactivate($id)
494496

495497
return response()->json($response->toArray(), 200);
496498
}
499+
500+
/**
501+
* Bulk replace rules for all applications belonging to a tenant user.
502+
*
503+
* @param UpsertApplicationRulesRequest $request
504+
* @return \Illuminate\Http\JsonResponse
505+
*/
506+
public function upsertRules(UpsertApplicationRulesRequest $request)
507+
{
508+
$validated = $request->validated();
509+
510+
$updated = Application::query()
511+
->where('tenant_user_id', $validated['tenant_user_id'])
512+
->update([
513+
'rules' => $validated['rules'],
514+
'updated_at' => now(),
515+
]);
516+
517+
return response()->json([
518+
'status' => 200,
519+
'message' => 'Application rules updated successfully.',
520+
'tenant_user_id' => $validated['tenant_user_id'],
521+
'updated_count' => $updated,
522+
], 200);
523+
}
497524
}

app/Http/Middleware/ApiAuthMiddleware.php

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,17 @@
66
use App\Models\UsageLog;
77
use Carbon\Carbon;
88
use Closure;
9+
use Illuminate\Support\Facades\Log;
910

1011
class ApiAuthMiddleware extends BasicAuthMiddleware
1112
{
12-
/**
13-
* Handle an incoming request.
14-
*
15-
* @param \Illuminate\Http\Request $request
16-
* @param \Closure $next
17-
* @return mixed
18-
*/
1913
public function handle($request, Closure $next)
2014
{
2115
$apiKey = $request->header('x-api-key');
2216
$authHeader = $request->header('Authorization');
2317
$isBasicAuth = $authHeader && str_starts_with($authHeader, 'Basic ');
2418

25-
if (!$apiKey && !$isBasicAuth) {
19+
if (!$apiKey && !$isBasicAuth) {
2620
return response()->json(['error' => 'Authentication required. Provide API key or Basic auth'], 401);
2721
}
2822

@@ -31,15 +25,24 @@ public function handle($request, Closure $next)
3125
}
3226

3327
if ($apiKey) {
34-
$application = Application::where('key', '=', $apiKey)->first();
28+
$application = Application::query()->where('key', '=', $apiKey)->first();
3529

3630
if (!$application) {
31+
3732
return response()->json(['error' => 'Invalid API key'], 401);
3833
}
3934

40-
if (!$application->is_active) {
41-
return response()->json(['error' => 'Application is inactive'], 403);
35+
36+
if ($application->trashed() || !$application->is_active) {
37+
return response()->json(['error' => 'Application is unavailable'], 403);
4238
}
39+
40+
$canAccess = $this->canAccessRequestedVersion($request->path(), (array) $application->rules);
41+
42+
if (!$canAccess) {
43+
return response()->json(['error' => 'Application is not allowed to access this API version'], 403);
44+
}
45+
4346
$usageLog = new UsageLog;
4447
$usageLog->application_id = $application->id;
4548
$usageLog->method = $request->method();
@@ -55,4 +58,17 @@ public function handle($request, Closure $next)
5558

5659
return $next($request);
5760
}
61+
62+
private function canAccessRequestedVersion(string $path, array $rules): bool
63+
{
64+
if (strpos($path, 'v1/') === 0) {
65+
return $rules['can_access_legacy_whatnow'];
66+
}
67+
68+
if (strpos($path, 'v2/') === 0) {
69+
return $rules['can_access_preparedness_v2'];
70+
}
71+
72+
return true;
73+
}
5874
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace App\Http\Requests;
4+
5+
use Illuminate\Foundation\Http\FormRequest;
6+
7+
class UpsertApplicationRulesRequest extends FormRequest
8+
{
9+
/**
10+
* Determine if the user is authorized to make this request.
11+
*
12+
* @return bool
13+
*/
14+
public function authorize()
15+
{
16+
return true;
17+
}
18+
19+
/**
20+
* Get the validation rules that apply to the request.
21+
*
22+
* @return array
23+
*/
24+
public function rules()
25+
{
26+
return [
27+
'tenant_user_id' => 'required|string|max:255',
28+
'rules' => 'required|array',
29+
];
30+
}
31+
}
32+

app/Models/Application.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class Application extends Model
3131
'estimated_users_count',
3232
'key',
3333
'is_active',
34+
'rules',
3435
];
3536

3637
protected $dates = ['deleted_at'];
@@ -42,6 +43,7 @@ class Application extends Model
4243
*/
4344
protected $casts = [
4445
'is_active' => 'boolean',
46+
'rules' => 'array',
4547
];
4648

4749
/**
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class AddRulesToApplicationsTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('applications', function (Blueprint $table) {
17+
$table->json('rules')->nullable()->after('is_active');
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*
24+
* @return void
25+
*/
26+
public function down()
27+
{
28+
Schema::table('applications', function (Blueprint $table) {
29+
$table->dropColumn('rules');
30+
});
31+
}
32+
}
33+

routes/api.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
// Route::delete('org/{code}/image', 'OrganisationController@deleteImageById');
5959

6060
// "Applications" endpoints
61+
Route::post('applications/rules', 'ApplicationController@upsertRules');
6162
Route::get('apps', 'ApplicationController@getAllForUser');
6263
Route::post('apps', 'ApplicationController@create');
6364
Route::get('apps/{id}', 'ApplicationController@getById');

0 commit comments

Comments
 (0)