From 3088349f7d9df3a5133c07db0320dd1bba325b5b Mon Sep 17 00:00:00 2001 From: cortzuy Date: Thu, 25 Aug 2022 22:32:24 +0800 Subject: [PATCH 1/2] Create models --- app/Models/Project.php | 17 +++++++ app/Models/Task.php | 23 +++++++++ app/Models/User.php | 45 ++++-------------- app/Models/User_.php | 44 +++++++++++++++++ .../2014_10_12_000000_create_users_table.php | 8 ++-- ...022_08_25_141036_create_projects_table.php | 32 +++++++++++++ .../2022_08_25_141049_create_tasks_table.php | 47 +++++++++++++++++++ 7 files changed, 175 insertions(+), 41 deletions(-) create mode 100644 app/Models/Project.php create mode 100644 app/Models/Task.php create mode 100644 app/Models/User_.php create mode 100644 database/migrations/2022_08_25_141036_create_projects_table.php create mode 100644 database/migrations/2022_08_25_141049_create_tasks_table.php diff --git a/app/Models/Project.php b/app/Models/Project.php new file mode 100644 index 0000000..97bea82 --- /dev/null +++ b/app/Models/Project.php @@ -0,0 +1,17 @@ +belongsTo(Task::class); + } +} diff --git a/app/Models/Task.php b/app/Models/Task.php new file mode 100644 index 0000000..bb198f6 --- /dev/null +++ b/app/Models/Task.php @@ -0,0 +1,23 @@ +hasOne(User::class); + } + + public function projects() + { + return $this->hasOne(Project::class); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 8996368..91fd372 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,43 +2,16 @@ namespace App\Models; -use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Foundation\Auth\User as Authenticatable; -use Illuminate\Notifications\Notifiable; -use Laravel\Sanctum\HasApiTokens; +use Illuminate\Database\Eloquent\Model; +use Laravel\Passport\HasApiTokens; -class User extends Authenticatable +class User extends Model { - use HasApiTokens, HasFactory, Notifiable; - - /** - * The attributes that are mass assignable. - * - * @var array - */ - protected $fillable = [ - 'name', - 'email', - 'password', - ]; - - /** - * The attributes that should be hidden for serialization. - * - * @var array - */ - protected $hidden = [ - 'password', - 'remember_token', - ]; - - /** - * The attributes that should be cast. - * - * @var array - */ - protected $casts = [ - 'email_verified_at' => 'datetime', - ]; + use HasFactory; + + public function Task() + { + return $this->belongsTo(Task::class); + } } diff --git a/app/Models/User_.php b/app/Models/User_.php new file mode 100644 index 0000000..8996368 --- /dev/null +++ b/app/Models/User_.php @@ -0,0 +1,44 @@ + + */ + protected $fillable = [ + 'name', + 'email', + 'password', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'password', + 'remember_token', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'email_verified_at' => 'datetime', + ]; +} diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 621a24e..d6beb0e 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -14,12 +14,10 @@ class CreateUsersTable extends Migration public function up() { Schema::create('users', function (Blueprint $table) { - $table->id(); - $table->string('name'); - $table->string('email')->unique(); - $table->timestamp('email_verified_at')->nullable(); + $table->bigIncrements('id'); + $table->string('username')->unique(); $table->string('password'); - $table->rememberToken(); + $table->string('role'); $table->timestamps(); }); } diff --git a/database/migrations/2022_08_25_141036_create_projects_table.php b/database/migrations/2022_08_25_141036_create_projects_table.php new file mode 100644 index 0000000..b34fa90 --- /dev/null +++ b/database/migrations/2022_08_25_141036_create_projects_table.php @@ -0,0 +1,32 @@ +bigIncrements('id'); + $table->string('name')->unique(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('projects'); + } +} diff --git a/database/migrations/2022_08_25_141049_create_tasks_table.php b/database/migrations/2022_08_25_141049_create_tasks_table.php new file mode 100644 index 0000000..8cb416c --- /dev/null +++ b/database/migrations/2022_08_25_141049_create_tasks_table.php @@ -0,0 +1,47 @@ +bigIncrements('id'); + $table->string('title'); + $table->text('description')->nullable(); + $table->string('status'); + $table->unsignedBigInteger('user_id'); + $table->unsignedBigInteger('project_id'); + $table->timestamps(); + + $table->foreign('user_id') + ->references('id') + ->on('users') + ->onDelete('cascade'); + + $table->foreign('project_id') + ->references('id') + ->on('projects') + ->onDelete('cascade'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('tasks'); + } +} From 063ec90b4f4dd9b61491a97ec3c4b7a195edddec Mon Sep 17 00:00:00 2001 From: cortzuy Date: Thu, 25 Aug 2022 22:48:40 +0800 Subject: [PATCH 2/2] Create REST APIs --- app/Http/Controllers/API/AuthController.php | 57 +++++++++++++++ .../Controllers/API/ProjectController.php | 65 +++++++++++++++++ app/Http/Controllers/API/TaskController.php | 71 +++++++++++++++++++ app/Http/Controllers/API/UserController.php | 67 +++++++++++++++++ app/Http/Resources/ProjectResource.php | 13 ++++ app/Http/Resources/TaskResource.php | 13 ++++ app/Http/Resources/UserResource.php | 13 ++++ app/Providers/AuthServiceProvider.php | 5 +- composer.json | 1 + config/app.php | 1 + config/auth.php | 5 ++ routes/api.php | 13 +++- 12 files changed, 321 insertions(+), 3 deletions(-) create mode 100644 app/Http/Controllers/API/AuthController.php create mode 100644 app/Http/Controllers/API/ProjectController.php create mode 100644 app/Http/Controllers/API/TaskController.php create mode 100644 app/Http/Controllers/API/UserController.php create mode 100644 app/Http/Resources/ProjectResource.php create mode 100644 app/Http/Resources/TaskResource.php create mode 100644 app/Http/Resources/UserResource.php diff --git a/app/Http/Controllers/API/AuthController.php b/app/Http/Controllers/API/AuthController.php new file mode 100644 index 0000000..3a6fc88 --- /dev/null +++ b/app/Http/Controllers/API/AuthController.php @@ -0,0 +1,57 @@ +all(), [ + 'username' => 'required|max:55|unique:users', + 'password' => 'required|min:6' + ]); + + if($validator->fails()){ + return response(['error' => $validator->errors()]); + } + + $user = User::create([ + 'username' => $request->username, + 'password' => Hash::make($request->password), + 'role' => $request->role, + ]); + + $accessToken = $user->createToken('authToken')->accessToken; + + return response([ 'user' => $user, 'access_token' => $accessToken]); + } + + public function login(Request $request) + { + $data = $request->all(); + + $validator = Validator::make($data, [ + 'username' => 'required', + 'password' => 'required|min:6' + ]); + + if($validator->fails()){ + return response(['error' => $validator->errors()]); + } + + if (!auth()->attempt($data)) { + return response(['message' => 'Login credentials are invaild']); + } + + $accessToken = auth()->user()->createToken('authToken')->accessToken; + + return response(['access_token' => $accessToken]); + + } +} diff --git a/app/Http/Controllers/API/ProjectController.php b/app/Http/Controllers/API/ProjectController.php new file mode 100644 index 0000000..9b64952 --- /dev/null +++ b/app/Http/Controllers/API/ProjectController.php @@ -0,0 +1,65 @@ + ProjectResource::collection($Projects)]); + } + + public function store(Request $request) + { + $data = $request->all(); + + $validator = Validator::make($data, [ + 'name' => 'required|max:255', + ]); + + if($validator->fails()){ + return response(['error' => $validator->errors(), 'Validation Error']); + } + + $Project = Project::create($data); + + return response(['Project' => new ProjectResource($Project), 'message' => 'Project created successfully']); + } + + public function show(Project $Project) + { + return response(['Project' => new ProjectResource($Project)]); + } + + public function update(Request $request, Project $Project) + { + $data = $request->all(); + + $validator = Validator::make($data, [ + 'name' => 'required|max:255', + ]); + + if($validator->fails()){ + return response(['error' => $validator->errors(), 'Validation Error']); + } + + $Project->update($data); + + return response(['Project' => new ProjectResource($Project), 'message' => 'Project updated successfully']); + } + + public function destroy(Project $Project) + { + $Project->delete(); + + return response(['message' => 'Project deleted successfully']); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/API/TaskController.php b/app/Http/Controllers/API/TaskController.php new file mode 100644 index 0000000..eb7d798 --- /dev/null +++ b/app/Http/Controllers/API/TaskController.php @@ -0,0 +1,71 @@ + TaskResource::collection($Tasks)]); + } + + public function store(Request $request) + { + $data = $request->all(); + + $validator = Validator::make($data, [ + 'title' => 'required|max:255', + 'status' => 'required', + 'project_id' => 'required', + 'user_id' => 'required', + ]); + + if($validator->fails()){ + return response(['error' => $validator->errors(), 'Validation Error']); + } + + $Task = Task::create($data); + + return response(['Task' => new TaskResource($Task), 'message' => 'Task created successfully']); + } + + public function show(Task $Task) + { + return response(['Task' => new TaskResource($Task)]); + } + + public function update(Request $request, Task $Task) + { + $data = $request->all(); + + $validator = Validator::make($data, [ + 'title' => 'required|max:255', + 'status' => 'required', + 'project_id' => 'required', + 'user_id' => 'required', + ]); + + if($validator->fails()){ + return response(['error' => $validator->errors(), 'Validation Error']); + } + + $Task->update($data); + + return response(['Task' => new TaskResource($Task), 'message' => 'Task updated successfully']); + } + + public function destroy(Task $Task) + { + $Task->delete(); + + return response(['message' => 'Task deleted successfully']); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/API/UserController.php b/app/Http/Controllers/API/UserController.php new file mode 100644 index 0000000..6fcd120 --- /dev/null +++ b/app/Http/Controllers/API/UserController.php @@ -0,0 +1,67 @@ + UserResource::collection($Users)]); + } + + public function store(Request $request) + { + $data = $request->all(); + + $validator = Validator::make($data, [ + 'username' => 'required', + 'password' => 'required|min:6', + ]); + + if($validator->fails()){ + return response(['error' => $validator->errors(), 'Validation Error']); + } + + $User = User::create($data); + + return response(['User' => new UserResource($User), 'message' => 'User created successfully']); + } + + public function show(User $User) + { + return response(['User' => new UserResource($User)]); + } + + public function update(Request $request, User $User) + { + $data = $request->all(); + + $validator = Validator::make($data, [ + 'username' => 'required', + 'password' => 'required|min:6', + ]); + + if($validator->fails()){ + return response(['error' => $validator->errors(), 'Validation Error']); + } + + $User->update($data); + + return response(['User' => new UserResource($User), 'message' => 'User updated successfully']); + } + + public function destroy(User $User) + { + $User->delete(); + + return response(['message' => 'User deleted successfully']); + } +} \ No newline at end of file diff --git a/app/Http/Resources/ProjectResource.php b/app/Http/Resources/ProjectResource.php new file mode 100644 index 0000000..ba96ecf --- /dev/null +++ b/app/Http/Resources/ProjectResource.php @@ -0,0 +1,13 @@ + */ protected $policies = [ - // 'App\Models\Model' => 'App\Policies\ModelPolicy', + 'App\Models\Model' => 'App\Policies\ModelPolicy', ]; /** @@ -24,7 +25,7 @@ class AuthServiceProvider extends ServiceProvider public function boot() { $this->registerPolicies(); - + Passport::routes(); // } } diff --git a/composer.json b/composer.json index 2b0c115..27aee5d 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "fruitcake/laravel-cors": "^2.0", "guzzlehttp/guzzle": "^7.0.1", "laravel/framework": "^8.75", + "laravel/passport": "^10.3", "laravel/sanctum": "^2.11", "laravel/tinker": "^2.5" }, diff --git a/config/app.php b/config/app.php index a8d1a82..28b8bdc 100644 --- a/config/app.php +++ b/config/app.php @@ -161,6 +161,7 @@ Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, + Laravel\Passport\PassportServiceProvider::class, /* * Package Service Providers... diff --git a/config/auth.php b/config/auth.php index d8c6cee..28cd01a 100644 --- a/config/auth.php +++ b/config/auth.php @@ -40,6 +40,11 @@ 'driver' => 'session', 'provider' => 'users', ], + 'api' => [ + 'driver' => 'passport', + 'provider' => 'users', + 'hash' => false, + ], ], /* diff --git a/routes/api.php b/routes/api.php index eb6fa48..7971873 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,6 +2,10 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; +use App\Http\Controllers\API\AuthController; +use App\Http\Controllers\API\ProjectController; +use App\Http\Controllers\API\UserController; +use App\Http\Controllers\API\TaskController; /* |-------------------------------------------------------------------------- @@ -14,6 +18,13 @@ | */ -Route::middleware('auth:sanctum')->get('/user', function (Request $request) { +Route::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); }); + +Route::post('/v1/user/register', [AuthController::class, 'register']); +Route::post('/v1/user/login', [AuthController::class, 'login']); + +Route::apiResource('/v1/project', ProjectController::class)->middleware('auth:api'); +Route::apiResource('/v1/users', UserController::class)->middleware('auth:api'); +Route::apiResource('/v1/tasks', TaskController::class)->middleware('auth:api'); \ No newline at end of file