From 55bc2e08f8dde302ad457ae1260cef6f6d9b09f8 Mon Sep 17 00:00:00 2001 From: robonen Date: Sat, 28 May 2022 22:55:36 +0700 Subject: [PATCH] User authentication --- .../Http/Controllers/Auth/LoginController.php | 26 ++++++++ .../Controllers/Auth/LogoutController.php | 17 +++++ .../Auth/RegistrationController.php | 30 +++++++++ .../app/Http/Controllers/ReviewController.php | 63 ------------------- .../app/Http/Controllers/UserController.php | 51 +++------------ backend/app/Http/Kernel.php | 2 +- .../app/Http/Requests/Auth/LoginRequest.php | 21 +++++++ .../Requests/Auth/RegistrationRequest.php | 21 +++++++ .../app/Http/Requests/StoreOfferRequest.php | 7 ++- .../app/Http/Requests/StoreOrderRequest.php | 2 - .../app/Http/Requests/UpdateOfferRequest.php | 7 ++- .../app/Http/Requests/UpdateOrderRequest.php | 2 - .../app/Http/Requests/UpdateUserRequest.php | 22 +++++++ .../{ReviewResource.php => UserResource.php} | 2 +- .../app/Models/{Review.php => Feedback.php} | 3 +- backend/app/Models/Offer.php | 4 +- backend/app/Models/Order.php | 4 -- backend/app/Models/User.php | 9 --- .../2014_10_12_000000_create_users_table.php | 4 +- ...01_create_personal_access_tokens_table.php | 36 +++++++++++ .../2022_05_26_030738_create_offers_table.php | 8 ++- ...05_26_035738_create_offer_photos_table.php | 6 +- ...22_05_26_035905_create_feedback_table.php} | 12 ++-- .../2022_05_26_035920_create_orders_table.php | 16 +++-- backend/routes/api.php | 32 +++++++++- 25 files changed, 260 insertions(+), 147 deletions(-) create mode 100644 backend/app/Http/Controllers/Auth/LoginController.php create mode 100644 backend/app/Http/Controllers/Auth/LogoutController.php create mode 100644 backend/app/Http/Controllers/Auth/RegistrationController.php delete mode 100644 backend/app/Http/Controllers/ReviewController.php create mode 100644 backend/app/Http/Requests/Auth/LoginRequest.php create mode 100644 backend/app/Http/Requests/Auth/RegistrationRequest.php create mode 100644 backend/app/Http/Requests/UpdateUserRequest.php rename backend/app/Http/Resources/{ReviewResource.php => UserResource.php} (90%) rename backend/app/Models/{Review.php => Feedback.php} (87%) create mode 100644 backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php rename backend/database/migrations/{2022_05_26_035905_create_reviews_table.php => 2022_05_26_035905_create_feedback_table.php} (66%) diff --git a/backend/app/Http/Controllers/Auth/LoginController.php b/backend/app/Http/Controllers/Auth/LoginController.php new file mode 100644 index 0000000..ff1dde6 --- /dev/null +++ b/backend/app/Http/Controllers/Auth/LoginController.php @@ -0,0 +1,26 @@ +attempt($request->validated())) + abort(401); + + $token = auth()->user()->createToken('web')->plainTextToken; + + return (new UserResource(auth()->user())) + ->additional(['token' => $token]); + } +} diff --git a/backend/app/Http/Controllers/Auth/LogoutController.php b/backend/app/Http/Controllers/Auth/LogoutController.php new file mode 100644 index 0000000..5ae6f18 --- /dev/null +++ b/backend/app/Http/Controllers/Auth/LogoutController.php @@ -0,0 +1,17 @@ +user()->currentAccessToken()->delete(); + } +} diff --git a/backend/app/Http/Controllers/Auth/RegistrationController.php b/backend/app/Http/Controllers/Auth/RegistrationController.php new file mode 100644 index 0000000..c27ab32 --- /dev/null +++ b/backend/app/Http/Controllers/Auth/RegistrationController.php @@ -0,0 +1,30 @@ +validated(); + $credentials['password'] = Hash::make($credentials['password']); + + auth()->login(User::create($credentials)); + + $token = auth()->user()->createToken('web')->plainTextToken; + + return (new UserResource(auth()->user())) + ->additional(['token' => $token]); + } +} diff --git a/backend/app/Http/Controllers/ReviewController.php b/backend/app/Http/Controllers/ReviewController.php deleted file mode 100644 index e99691c..0000000 --- a/backend/app/Http/Controllers/ReviewController.php +++ /dev/null @@ -1,63 +0,0 @@ -user()); } /** * Update the specified resource in storage. * - * @param \Illuminate\Http\Request $request - * @param int $id - * @return \Illuminate\Http\Response + * @param \App\Http\Requests\UpdateUserRequest $request + * @return void */ - public function update(Request $request, $id) + public function update(UpdateUserRequest $request): void { - // - } - - /** - * Remove the specified resource from storage. - * - * @param int $id - * @return \Illuminate\Http\Response - */ - public function destroy($id) - { - // + auth()->user()->update($request->validated()); } } diff --git a/backend/app/Http/Kernel.php b/backend/app/Http/Kernel.php index c3be254..6ead053 100644 --- a/backend/app/Http/Kernel.php +++ b/backend/app/Http/Kernel.php @@ -39,7 +39,7 @@ class Kernel extends HttpKernel ], 'api' => [ - // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, + \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], diff --git a/backend/app/Http/Requests/Auth/LoginRequest.php b/backend/app/Http/Requests/Auth/LoginRequest.php new file mode 100644 index 0000000..9af72c6 --- /dev/null +++ b/backend/app/Http/Requests/Auth/LoginRequest.php @@ -0,0 +1,21 @@ + + */ + public function rules(): array + { + return [ + 'email' => ['required', 'string', 'email', 'exists:users'], + 'password' => ['required', 'string'], + ]; + } +} diff --git a/backend/app/Http/Requests/Auth/RegistrationRequest.php b/backend/app/Http/Requests/Auth/RegistrationRequest.php new file mode 100644 index 0000000..ca18e41 --- /dev/null +++ b/backend/app/Http/Requests/Auth/RegistrationRequest.php @@ -0,0 +1,21 @@ + + */ + public function rules(): array + { + return [ + 'email' => ['required', 'string', 'email', 'unique:users'], + 'password' => ['required', 'string'], + ]; + } +} diff --git a/backend/app/Http/Requests/StoreOfferRequest.php b/backend/app/Http/Requests/StoreOfferRequest.php index b450247..15615dd 100644 --- a/backend/app/Http/Requests/StoreOfferRequest.php +++ b/backend/app/Http/Requests/StoreOfferRequest.php @@ -15,11 +15,12 @@ class StoreOfferRequest extends BaseRequest public function rules(): array { return [ - 'owner_id' => ['required', 'numeric', 'exists:users,id'], + 'user_id' => ['required', 'numeric', 'exists:users,id'], 'name' => ['required', 'string'], 'type' => ['required', new Enum(OrderTypesEnum::class)], - 'price' => ['required', 'numeric'], - 'rooms' => ['required', 'numeric'], + 'price' => ['required', 'numeric', 'min:0.1'], + 'rooms' => ['required', 'numeric', 'min:1'], + 'space' => ['required', 'numeric', 'min:1'], 'yandex_mark' => ['string'], 'location' => ['required', 'string'], 'description' => ['required', 'string'], diff --git a/backend/app/Http/Requests/StoreOrderRequest.php b/backend/app/Http/Requests/StoreOrderRequest.php index 83f8d2e..ee44d82 100644 --- a/backend/app/Http/Requests/StoreOrderRequest.php +++ b/backend/app/Http/Requests/StoreOrderRequest.php @@ -14,8 +14,6 @@ class StoreOrderRequest extends BaseRequest return [ 'offer_id' => ['required', 'numeric', 'exists:offers,id'], 'user_id' => ['required', 'numeric', 'exists:users,id'], - 'start_date' => ['required', 'date', 'after_or_equal:today'], - 'end_date' => ['required', 'date', 'after_or_equal:tomorrow'], 'price' => ['required', 'numeric', 'min:0.1'], 'discount' => ['required', 'numeric', 'min:0'], ]; diff --git a/backend/app/Http/Requests/UpdateOfferRequest.php b/backend/app/Http/Requests/UpdateOfferRequest.php index 8f74124..4e0903e 100644 --- a/backend/app/Http/Requests/UpdateOfferRequest.php +++ b/backend/app/Http/Requests/UpdateOfferRequest.php @@ -15,11 +15,12 @@ class UpdateOfferRequest extends BaseRequest public function rules(): array { return [ - 'owner_id' => ['numeric', 'exists:users,id'], + 'user_id' => ['numeric', 'exists:users,id'], 'name' => ['string'], 'type' => [new Enum(OrderTypesEnum::class)], - 'price' => ['numeric'], - 'rooms' => ['numeric'], + 'price' => ['numeric', 'min:0.1'], + 'rooms' => ['numeric', 'min:1'], + 'space' => ['numeric', 'min:1'], 'yandex_mark' => ['string'], 'location' => ['string'], 'description' => ['string'], diff --git a/backend/app/Http/Requests/UpdateOrderRequest.php b/backend/app/Http/Requests/UpdateOrderRequest.php index 1ff4f25..abf195d 100644 --- a/backend/app/Http/Requests/UpdateOrderRequest.php +++ b/backend/app/Http/Requests/UpdateOrderRequest.php @@ -14,8 +14,6 @@ class UpdateOrderRequest extends BaseRequest return [ 'offer_id' => ['numeric', 'exists:offers,id'], 'user_id' => ['numeric', 'exists:users,id'], - 'start_date' => ['date'], - 'end_date' => ['date'], 'price' => ['numeric', 'min:0.1'], 'discount' => ['numeric', 'min:0.1'], ]; diff --git a/backend/app/Http/Requests/UpdateUserRequest.php b/backend/app/Http/Requests/UpdateUserRequest.php new file mode 100644 index 0000000..8315f86 --- /dev/null +++ b/backend/app/Http/Requests/UpdateUserRequest.php @@ -0,0 +1,22 @@ + + */ + public function rules() + { + return [ + 'first_name' => ['string'], + 'last_name' => ['string'], + 'middle_name' => ['string'], + 'email' => ['string', 'email', 'unique:users'], + 'phone' => ['string'], + ]; + } +} diff --git a/backend/app/Http/Resources/ReviewResource.php b/backend/app/Http/Resources/UserResource.php similarity index 90% rename from backend/app/Http/Resources/ReviewResource.php rename to backend/app/Http/Resources/UserResource.php index f866bbe..7a74549 100644 --- a/backend/app/Http/Resources/ReviewResource.php +++ b/backend/app/Http/Resources/UserResource.php @@ -4,7 +4,7 @@ namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; -class ReviewResource extends JsonResource +class UserResource extends JsonResource { /** * Transform the resource into an array. diff --git a/backend/app/Models/Review.php b/backend/app/Models/Feedback.php similarity index 87% rename from backend/app/Models/Review.php rename to backend/app/Models/Feedback.php index e924c4a..c453313 100644 --- a/backend/app/Models/Review.php +++ b/backend/app/Models/Feedback.php @@ -5,7 +5,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class Review extends Model +class Feedback extends Model { use HasFactory; @@ -15,7 +15,6 @@ class Review extends Model * @var array */ protected $fillable = [ - 'offer_id', 'user_id', 'comment', 'rating', diff --git a/backend/app/Models/Offer.php b/backend/app/Models/Offer.php index 99d752c..edb7327 100644 --- a/backend/app/Models/Offer.php +++ b/backend/app/Models/Offer.php @@ -16,11 +16,12 @@ class Offer extends Model * @var array */ protected $fillable = [ - 'owner_id', + 'user_id', 'name', 'type', 'price', 'rooms', + 'space', 'yandex_mark', 'location', 'description', @@ -34,6 +35,7 @@ class Offer extends Model */ protected $casts = [ 'type' => OrderTypesEnum::class, + 'space' => 'double', 'price' => 'double', 'is_group' => 'boolean', ]; diff --git a/backend/app/Models/Order.php b/backend/app/Models/Order.php index b2606c6..d8c0c20 100644 --- a/backend/app/Models/Order.php +++ b/backend/app/Models/Order.php @@ -17,8 +17,6 @@ class Order extends Model protected $fillable = [ 'offer_id', 'user_id', - 'start_date', - 'end_date', 'price', 'discount', ]; @@ -29,8 +27,6 @@ class Order extends Model * @var array */ protected $casts = [ - 'start_date' => 'datetime', - 'end_date' => 'datetime', 'price' => 'double', 'discount' => 'double', ]; diff --git a/backend/app/Models/User.php b/backend/app/Models/User.php index 0282ad6..0dd1542 100644 --- a/backend/app/Models/User.php +++ b/backend/app/Models/User.php @@ -34,13 +34,4 @@ class User extends Authenticatable protected $hidden = [ 'password', ]; - - /** - * The attributes that should be cast. - * - * @var array - */ -// protected $casts = [ -// 'email_verified_at' => 'datetime', -// ]; } diff --git a/backend/database/migrations/2014_10_12_000000_create_users_table.php b/backend/database/migrations/2014_10_12_000000_create_users_table.php index 6d3255e..02eec63 100644 --- a/backend/database/migrations/2014_10_12_000000_create_users_table.php +++ b/backend/database/migrations/2014_10_12_000000_create_users_table.php @@ -15,8 +15,8 @@ return new class extends Migration { Schema::create('users', function (Blueprint $table) { $table->id(); - $table->string('first_name'); - $table->string('last_name'); + $table->string('first_name')->nullable(); + $table->string('last_name')->nullable(); $table->string('middle_name')->nullable(); $table->string('email')->unique(); $table->string('phone')->unique()->nullable(); diff --git a/backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php new file mode 100644 index 0000000..3ce0002 --- /dev/null +++ b/backend/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -0,0 +1,36 @@ +bigIncrements('id'); + $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('personal_access_tokens'); + } +} diff --git a/backend/database/migrations/2022_05_26_030738_create_offers_table.php b/backend/database/migrations/2022_05_26_030738_create_offers_table.php index 5fa50f5..186ccf1 100644 --- a/backend/database/migrations/2022_05_26_030738_create_offers_table.php +++ b/backend/database/migrations/2022_05_26_030738_create_offers_table.php @@ -16,16 +16,22 @@ return new class extends Migration { Schema::create('offers', function (Blueprint $table) { $table->id(); - $table->foreignId('owner_id'); $table->string('name'); $table->enum('type', OrderTypesEnum::values()); $table->decimal('price'); $table->unsignedSmallInteger('rooms'); + $table->decimal('space'); $table->string('yandex_mark')->nullable(); $table->string('location'); $table->text('description'); $table->boolean('is_group'); $table->timestamps(); + + $table + ->foreignId('user_id') + ->constrained() + ->onDelete('set null') + ->onUpdate('cascade'); }); } diff --git a/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php b/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php index 6e5f8e5..4022a15 100644 --- a/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php +++ b/backend/database/migrations/2022_05_26_035738_create_offer_photos_table.php @@ -15,9 +15,13 @@ return new class extends Migration { Schema::create('offer_photos', function (Blueprint $table) { $table->id(); - $table->foreignId('offer_id'); $table->string('file'); $table->timestamps(); + + $table + ->foreignId('offer_id') + ->constrained() + ->onUpdate('cascade'); }); } diff --git a/backend/database/migrations/2022_05_26_035905_create_reviews_table.php b/backend/database/migrations/2022_05_26_035905_create_feedback_table.php similarity index 66% rename from backend/database/migrations/2022_05_26_035905_create_reviews_table.php rename to backend/database/migrations/2022_05_26_035905_create_feedback_table.php index 62106f4..2c452da 100644 --- a/backend/database/migrations/2022_05_26_035905_create_reviews_table.php +++ b/backend/database/migrations/2022_05_26_035905_create_feedback_table.php @@ -13,13 +13,17 @@ return new class extends Migration */ public function up() { - Schema::create('reviews', function (Blueprint $table) { + Schema::create('feedback', function (Blueprint $table) { $table->id(); - $table->foreignId('offer_id'); - $table->foreignId('user_id'); $table->text('comment'); $table->unsignedFloat('rating'); $table->timestamps(); + + $table + ->foreignId('user_id') + ->constrained() + ->onDelete('cascade') + ->onUpdate('cascade'); }); } @@ -30,6 +34,6 @@ return new class extends Migration */ public function down() { - Schema::dropIfExists('reviews'); + Schema::dropIfExists('feedback'); } }; diff --git a/backend/database/migrations/2022_05_26_035920_create_orders_table.php b/backend/database/migrations/2022_05_26_035920_create_orders_table.php index 8375b27..aa256a6 100644 --- a/backend/database/migrations/2022_05_26_035920_create_orders_table.php +++ b/backend/database/migrations/2022_05_26_035920_create_orders_table.php @@ -15,13 +15,21 @@ return new class extends Migration { Schema::create('orders', function (Blueprint $table) { $table->id(); - $table->foreignId('offer_id'); - $table->foreignId('user_id'); - $table->date('start_date'); - $table->date('end_date'); $table->decimal('price'); $table->decimal('discount'); $table->timestamps(); + + $table + ->foreignId('offer_id') + ->constrained() + ->onDelete('set null') + ->onUpdate('cascade'); + + $table + ->foreignId('user_id') + ->constrained() + ->onDelete('set null') + ->onUpdate('cascade'); }); } diff --git a/backend/routes/api.php b/backend/routes/api.php index 1abbc85..42ae39e 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -1,7 +1,11 @@ group(function() { + + Route::post('registration', RegistrationController::class); + Route::post('login', LoginController::class); + + Route::middleware('auth:sanctum')->group(function() { + Route::post('logout', LogoutController::class); + }); + +}); + +Route::middleware('auth:sanctum')->group(function() { + + Route::prefix('user')->group(function() { + Route::get('', [UserController::class, 'index']); + Route::put('', [UserController::class, 'update']); + }); + + Route::apiResource('orders', OrderController::class); + +}); + +Route::apiResource('offers', OfferController::class); + +// TODO: На главной странице 6 самых дорогих квартир +// TODO: Последние добавленные квартиры + фильтры