From 093f1ce87beac6b0c29fee145a9e6df0338e1d3f Mon Sep 17 00:00:00 2001 From: rcomunica Date: Tue, 30 Sep 2025 00:48:06 -0500 Subject: [PATCH] FEAT | OAuth 2.0 Working - No testing --- .env.example | 5 + app/Http/Controllers/SashaAuthController.php | 106 ++++++++++++++++++ app/Models/User.php | 14 ++- config/services.php | 7 ++ database/factories/UserFactory.php | 2 +- .../0001_01_01_000000_create_users_table.php | 3 +- ...2025_09_25_220024_create_records_table.php | 2 +- ...25_09_26_000807_create_newnesses_table.php | 2 +- ..._28_023709_add_custom_columns_to_users.php | 1 - routes/auth.php | 15 ++- 10 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 app/Http/Controllers/SashaAuthController.php diff --git a/.env.example b/.env.example index 9356624..c2af960 100644 --- a/.env.example +++ b/.env.example @@ -67,3 +67,8 @@ VITE_APP_NAME="${APP_NAME}" ACTIVITY_LOGGER_ENABLED=true + +SASHA_CLIENT_ID="" +SASHA_CLIENT_SECRET="" +SASHA_REDIRECT_URL="" +SASHA_URL="" diff --git a/app/Http/Controllers/SashaAuthController.php b/app/Http/Controllers/SashaAuthController.php new file mode 100644 index 0000000..c0120e3 --- /dev/null +++ b/app/Http/Controllers/SashaAuthController.php @@ -0,0 +1,106 @@ + $guard]); + $request->session()->put('state', $state = Str::random(40)); + $scopes = []; + + switch ($guard) { + case 'student': + $scopes = ["students:read", "teachers:read", "user", "email"]; + break; + case 'teacher': + $scopes = ["students:read", "teachers:read", "user", "email"]; + break; + case 'developer': + $scopes = ["students:read", "teachers:read", "user", "email"]; + break; + default: + $scopes = ["students:read", "teachers:read", "user", "email"]; + break; + } + + // This is the query + $q = [ + 'client_id' => config('services.sasha.client_id'), + 'redirect_uri' => config('services.sasha.redirect'), + 'response_type' => 'code', + 'scope' => implode(" ", $scopes), + 'state' => $state, + // Custom HTTP + 'guard' => $guard + ]; + + // HTTP BUILD WITH QUERY + $query = http_build_query($q); + + + // Notify + Log::info("New user is attempt login in SASHA:"); + Log::info($q); + + return redirect(config('services.sasha.main_url') . '/oauth/authorize?' . $query); + } + + public function handleCallback(Request $request) + { + $response = Http::asForm()->post(config('services.sasha.main_url') . '/oauth/token', [ + 'grant_type' => 'authorization_code', + 'client_id' => config('services.sasha.client_id'), + 'client_secret' => config('services.sasha.client_secret'), + 'redirect_uri' => config('services.sasha.redirect'), + 'code' => $request->code, + ]); + + if (!$response->successful()) { + return redirect('/')->withErrors('No se pudo autenticar con SASHA.'); + } + + $accessToken = $response->json('access_token'); + session([ + 'sasha_access_token' => $accessToken, + ]); + + $userResponse = Http::withToken($accessToken)->get(config('services.sasha.main_url') . '/api/me')->json(); + $sashaUser = $userResponse['data']; + + $user = User::updateOrCreate([ + 'id' => $sashaUser['uuid'], + ], [ + 'id' => $sashaUser['uuid'], + 'name' => $sashaUser["name"], + 'last_name' => $sashaUser["last_name"], + 'email' => $sashaUser['email'], + 'grade' => $sashaUser['grade'], + 'fingerprint' => $sashaUser['fingerprint'], + 'document' => $sashaUser['document'], + 'document_type' => $sashaUser['document_type'], + 'last_login_ip' => $sashaUser["last_login_ip"], + 'last_login_at' => $sashaUser['last_login_at'], + 'password' => Hash::make("somosoeistas"), + 'rol' => UserRol::from($sashaUser["type"] ?? 'student'), + ]); + + Log::info("Se creo o actualizo un usuario"); + Activity::all(); + + Auth::login($user); + + return redirect('/'); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 3e7fddc..4cd6070 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -3,6 +3,8 @@ namespace App\Models; // use Illuminate\Contracts\Auth\MustVerifyEmail; + +use Illuminate\Database\Eloquent\Concerns\HasUuids; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\User as Authenticatable; @@ -13,7 +15,7 @@ class User extends Authenticatable { /** @use HasFactory<\Database\Factories\UserFactory> */ - use HasFactory, Notifiable, TwoFactorAuthenticatable; + use HasFactory, Notifiable, TwoFactorAuthenticatable, HasUuids; /** * The attributes that are mass assignable. @@ -21,9 +23,19 @@ class User extends Authenticatable * @var list */ protected $fillable = [ + 'id', 'name', + 'last_name', 'email', + 'grade', + 'fingerprint', + 'uuid', + 'document', + 'document_type', + 'last_login_ip', + 'last_login_at', 'password', + 'rol' ]; /** diff --git a/config/services.php b/config/services.php index 27a3617..8c98461 100644 --- a/config/services.php +++ b/config/services.php @@ -35,4 +35,11 @@ ], ], + 'sasha' => [ + 'client_id' => env('SASHA_CLIENT_ID'), + 'client_secret' => env('SASHA_CLIENT_SECRET'), + 'redirect' => env('SASHA_REDIRECT_URL'), + 'main_url' => env('SASHA_URL', 'http://localhost:3500'), + ], + ]; diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index a614477..7b2c318 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -26,13 +26,13 @@ public function definition(): array { return [ 'name' => fake()->name(), + 'last_name' => fake()->lastName(), 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => static::$password ??= Hash::make('password'), 'remember_token' => Str::random(10), 'grade' => '1104', 'fingerprint' => fake()->sha256(), - 'UUID' => fake()->uuid(), 'document' => fake()->numberBetween(1000000000, 1999999999), 'document_type' => 'T.I', 'profile_photo_path' => null, diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 9e11d11..4339cea 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -12,8 +12,9 @@ public function up(): void { Schema::create('users', function (Blueprint $table) { - $table->id(); + $table->uuid('id')->primary(); $table->string('name'); + $table->string("last_name"); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); diff --git a/database/migrations/2025_09_25_220024_create_records_table.php b/database/migrations/2025_09_25_220024_create_records_table.php index c2d8e55..73e78a9 100644 --- a/database/migrations/2025_09_25_220024_create_records_table.php +++ b/database/migrations/2025_09_25_220024_create_records_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::create('records', function (Blueprint $table) { $table->id(); - $table->unsignedBigInteger('user_id'); + $table->uuid('user_id'); $table->dateTime("date"); $table->enum('record_type', RecordType::cases()); $table->unsignedBigInteger("journey_id"); diff --git a/database/migrations/2025_09_26_000807_create_newnesses_table.php b/database/migrations/2025_09_26_000807_create_newnesses_table.php index 9cfc12a..68b6091 100644 --- a/database/migrations/2025_09_26_000807_create_newnesses_table.php +++ b/database/migrations/2025_09_26_000807_create_newnesses_table.php @@ -13,7 +13,7 @@ public function up(): void { Schema::create('newnesses', function (Blueprint $table) { $table->id(); - $table->unsignedBigInteger("user_id"); + $table->uuid("user_id"); $table->string("subject"); $table->text("text"); $table->string("slug"); diff --git a/database/migrations/2025_09_28_023709_add_custom_columns_to_users.php b/database/migrations/2025_09_28_023709_add_custom_columns_to_users.php index f09b946..08c5bee 100644 --- a/database/migrations/2025_09_28_023709_add_custom_columns_to_users.php +++ b/database/migrations/2025_09_28_023709_add_custom_columns_to_users.php @@ -16,7 +16,6 @@ public function up(): void $table->enum("rol", UserRol::cases())->nullable(); $table->string("grade")->nullable(); $table->string("fingerprint")->nullable(); - $table->uuid("UUID")->nullable(); // Indentificadores universales $table->integer("document")->unique()->nullable(); $table->string("document_type")->nullable(); diff --git a/routes/auth.php b/routes/auth.php index 3d7863a..ffcda78 100644 --- a/routes/auth.php +++ b/routes/auth.php @@ -1,6 +1,7 @@ group(function () { - Route::get('login', Login::class)->name('login'); - Route::get('register', Register::class)->name('register'); - Route::get('forgot-password', ForgotPassword::class)->name('password.request'); - Route::get('reset-password/{token}', ResetPassword::class)->name('password.reset'); + Route::get( + 'login/{guard}', + [SashaAuthController::class, 'redirectToSasha'] + )->name('login'); + + Route::get('/auth/callback', [SashaAuthController::class, 'handleCallback']); + + // Route::get('register', Register::class)->name('register'); + // Route::get('forgot-password', ForgotPassword::class)->name('password.request'); + // Route::get('reset-password/{token}', ResetPassword::class)->name('password.reset'); }); Route::middleware('auth')->group(function () {