Skip to content

Commit 6d746ad

Browse files
authored
Merge pull request #52 from fhict-skilltree/feature/45-courses-endpoint
Create courses endpoints
2 parents baab3dc + b048d7e commit 6d746ad

35 files changed

+1284
-26
lines changed

.github/workflows/ci.yml

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ jobs:
6060
- name: Clear Config
6161
run: php artisan config:clear
6262

63+
- name: Create the Passport encryption Keys
64+
run: php artisan passport:keys
65+
6366
- name: Test code style pint
6467
run: composer run pint-test
6568

app/App/Authentication/Http/Controllers/CurrentUserController.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace App\Authentication\Http\Controllers;
66

77
use App\Authentication\Http\Resources\UserResource;
8-
use Illuminate\Http\Request;
8+
use Illuminate\Auth\AuthManager;
99
use Illuminate\Routing\Controller;
1010
use OpenApi\Attributes as OA;
1111

@@ -14,7 +14,7 @@ class CurrentUserController extends Controller
1414
#[OA\Get(
1515
path: '/auth/current-user',
1616
summary: 'Get current authenticated user',
17-
tags: ['User'],
17+
tags: ['Authentication'],
1818
)]
1919
#[OA\Response(
2020
response: 200,
@@ -23,8 +23,10 @@ class CurrentUserController extends Controller
2323
)]
2424
#[OA\Response(ref: '#/components/responses/401', response: 401)]
2525
#[OA\Response(ref: '#/components/responses/403', response: 403)]
26-
public function show(Request $request): UserResource
26+
public function show(AuthManager $authManager): UserResource
2727
{
28-
return new UserResource($request->user());
28+
$currentUser = $authManager->guard()->user();
29+
30+
return new UserResource($currentUser);
2931
}
3032
}

app/App/Authentication/Http/Resources/UserResource.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class UserResource extends JsonResource
2323
schema: 'UserResource',
2424
properties: [
2525
new OA\Property(
26-
property: 'id',
27-
description: 'The id of the user',
26+
property: 'uuid',
27+
description: 'The uuid of the user',
2828
type: 'integer'
2929
),
3030
new OA\Property(
@@ -60,7 +60,7 @@ class UserResource extends JsonResource
6060
public function toArray(Request $request): array
6161
{
6262
return [
63-
'id' => $this->id,
63+
'uuid' => $this->uuid,
6464
'first_name' => $this->first_name,
6565
'last_name' => $this->last_name,
6666
'email' => $this->email,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Authentication\Policies;
6+
7+
use Domain\Users\Models\User;
8+
9+
class UserPolicy
10+
{
11+
public function view(User $authenticatedUser, User $user): bool
12+
{
13+
return $authenticatedUser->id === $user->id;
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Courses\Http\Controllers;
6+
7+
use App\Courses\Http\Resources\CourseResource;
8+
use Domain\Courses\Models\Course;
9+
use Illuminate\Auth\Access\AuthorizationException;
10+
use Illuminate\Contracts\Auth\Access\Gate;
11+
use Illuminate\Http\Request;
12+
use Illuminate\Routing\Controller;
13+
use OpenApi\Attributes as OA;
14+
15+
class ShowController extends Controller
16+
{
17+
/**
18+
* @throws AuthorizationException
19+
*/
20+
#[OA\Get(
21+
path: '/courses/{courseUuid} ',
22+
summary: 'Get the course details',
23+
security: [
24+
[
25+
'LocalhostOAuth' => [],
26+
],
27+
],
28+
tags: ['Courses']
29+
)]
30+
#[OA\Parameter(
31+
name: 'courseUuid',
32+
description: 'The UUID of the course',
33+
in: 'path',
34+
required: true,
35+
schema: new OA\Schema(type: 'string', format: 'uuid'),
36+
)]
37+
#[OA\Response(
38+
response: 200,
39+
description: 'OK',
40+
content: new OA\JsonContent(ref: '#/components/schemas/CourseResource'),
41+
)]
42+
#[OA\Response(ref: '#/components/responses/401', response: 401)]
43+
#[OA\Response(ref: '#/components/responses/403', response: 403)]
44+
public function __invoke(Request $request, Course $course, Gate $gate): CourseResource
45+
{
46+
$gate->authorize('view', $course);
47+
48+
return new CourseResource($course);
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Courses\Http\Controllers;
6+
7+
use App\Courses\Http\Resources\CourseCollection;
8+
use Domain\Users\Models\User;
9+
use Illuminate\Auth\Access\AuthorizationException;
10+
use Illuminate\Contracts\Auth\Access\Gate;
11+
use Illuminate\Routing\Controller;
12+
use OpenApi\Attributes as OA;
13+
use Spatie\QueryBuilder\QueryBuilder;
14+
15+
class UserEnrolledCoursesController extends Controller
16+
{
17+
/**
18+
* @throws AuthorizationException
19+
*/
20+
#[OA\Get(
21+
path: '/users/{userUuid}/enrolled_courses ',
22+
summary: 'Get the enrolled courses of a user',
23+
security: [
24+
[
25+
'LocalhostOAuth' => [],
26+
],
27+
],
28+
tags: ['Users']
29+
)]
30+
#[OA\Parameter(
31+
name: 'userUuid',
32+
description: 'The UUID of the user',
33+
in: 'path',
34+
required: true,
35+
schema: new OA\Schema(type: 'string', format: 'uuid'),
36+
)]
37+
#[OA\Parameter(
38+
name: 'page[number]',
39+
description: 'The page number (default: 1)',
40+
in: 'query',
41+
required: false,
42+
schema: new OA\Schema(type: 'string'),
43+
)]
44+
#[OA\Parameter(
45+
name: 'page[size]',
46+
description: 'The page number (default: 30, max: 30)',
47+
in: 'query',
48+
required: false,
49+
schema: new OA\Schema(type: 'string'),
50+
)]
51+
#[OA\Response(
52+
response: 200,
53+
description: 'OK',
54+
content: new OA\JsonContent(ref: '#/components/schemas/CourseCollection'),
55+
)]
56+
#[OA\Response(ref: '#/components/responses/401', response: 401)]
57+
#[OA\Response(ref: '#/components/responses/403', response: 403)]
58+
public function index(User $user, Gate $gate)
59+
{
60+
$gate->authorize('view', $user);
61+
62+
$courses = QueryBuilder::for($user->enrolledCourses())
63+
->allowedSorts([
64+
'created_at',
65+
])
66+
->jsonPaginate();
67+
68+
return new CourseCollection($courses);
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Courses\Http\Resources;
6+
7+
use Illuminate\Http\Request;
8+
use Illuminate\Http\Resources\Json\ResourceCollection;
9+
use OpenApi\Attributes as OA;
10+
11+
class CourseCollection extends ResourceCollection
12+
{
13+
public $collects = CourseResource::class;
14+
15+
/**
16+
* Transform the resource into an array.
17+
*
18+
* @return array<string, mixed>
19+
*/
20+
#[OA\Schema(
21+
schema: 'CourseCollection',
22+
properties: [
23+
new OA\Property(
24+
property: 'data',
25+
ref: '#/components/schemas/CourseResource',
26+
),
27+
],
28+
type: 'object',
29+
allOf: [
30+
new OA\Property(ref: '#/components/schemas/PaginatorMeta'),
31+
],
32+
)]
33+
public function toArray(Request $request): array
34+
{
35+
return parent::toArray($request);
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Courses\Http\Resources;
6+
7+
use Domain\Courses\Models\Course;
8+
use Illuminate\Http\Request;
9+
use Illuminate\Http\Resources\Json\JsonResource;
10+
use OpenApi\Attributes as OA;
11+
12+
/**
13+
* @mixin Course
14+
*/
15+
class CourseResource extends JsonResource
16+
{
17+
/**
18+
* Transform the resource into an array.
19+
*
20+
* @return array<string, mixed>
21+
*/
22+
#[OA\Schema(
23+
schema: 'CourseResource',
24+
properties: [
25+
new OA\Property(
26+
property: 'uuid',
27+
description: 'The uuid of the course',
28+
type: 'string'
29+
),
30+
new OA\Property(
31+
property: 'title',
32+
description: 'The title the user',
33+
type: 'string'
34+
),
35+
new OA\Property(
36+
property: 'content',
37+
description: 'The content of the course',
38+
type: 'string'
39+
),
40+
new OA\Property(
41+
property: 'created_at',
42+
description: 'The date the course is created',
43+
type: 'string',
44+
format: 'date-time',
45+
),
46+
new OA\Property(
47+
property: 'updated_at',
48+
description: 'The date the course is updated',
49+
type: 'string',
50+
format: 'date-time',
51+
),
52+
],
53+
type: 'object',
54+
)]
55+
public function toArray(Request $request): array
56+
{
57+
return [
58+
'uuid' => $this->uuid,
59+
'title' => $this->title,
60+
'content' => $this->content,
61+
'created_at' => $this->created_at,
62+
'updated_at' => $this->updated_at,
63+
];
64+
}
65+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Courses\Policies;
6+
7+
use Domain\Courses\Models\Course;
8+
use Domain\Users\Models\User;
9+
10+
class CoursePolicy
11+
{
12+
public function view(User $user, Course $course): bool
13+
{
14+
if ($user->enrolledCourses()->where('id', '=', $course->id)->exists()) {
15+
return true;
16+
}
17+
18+
return false;
19+
}
20+
}

app/App/Shared/Providers/AuthServiceProvider.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
namespace App\Shared\Providers;
66

7-
// use Illuminate\Support\Facades\Gate;
7+
use App\Authentication\Policies\UserPolicy;
8+
use App\Courses\Policies\CoursePolicy;
9+
use Domain\Courses\Models\Course;
10+
use Domain\Users\Models\User;
811
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
912

1013
class AuthServiceProvider extends ServiceProvider
@@ -15,6 +18,8 @@ class AuthServiceProvider extends ServiceProvider
1518
* @var array<class-string, class-string>
1619
*/
1720
protected $policies = [
21+
User::class => UserPolicy::class,
22+
Course::class => CoursePolicy::class,
1823
];
1924

2025
public function boot(): void

0 commit comments

Comments
 (0)