Vatsim-Scandinavia / controlcenter

Training Management System created by VATSIM Scandinavia
https://docs.vatsca.org/controlcenter/
GNU General Public License v3.0
16 stars 14 forks source link

Open booking api #901

Closed blt950 closed 6 days ago

blt950 commented 3 months ago

Create a Booking API that is anonymized but open without API keys. Needed for new homepage, to avoid also distributing keys that might have larger scopes.

blt950 commented 3 months ago

I've already started on it here to test https://github.com/Vatsim-Scandinavia/controlcenter/commit/38bd8ae87f4e343732719ad227116a795579eb79

blt950 commented 1 week ago

Well, ChatGPT might have a suggestion here that can be tweaked and do what I wanted in the first place (same endpoint but different data if unauthenticated)

To make the /bookings endpoint return different data if the user has not logged in with an API token, you can adjust the middleware logic to allow unauthenticated requests but handle them differently in the BookingController. Here’s how you can achieve that:

  1. Update the middleware to allow unauthenticated access but mark the request as unauthenticated:

    Modify the ApiToken middleware to set a flag on the request indicating whether the user is authenticated or not, instead of directly returning an unauthorized response.

    <?php
    
    namespace App\Http\Middleware;
    
    use App\Models\ApiKey;
    use Closure;
    use Illuminate\Http\Request;
    
    class ApiToken
    {
       /**
        * Handle an incoming request.
        *
        * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
        * @param  mixed  $editRights
        * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
        */
       public function handle(Request $request, Closure $next, $args = '')
       {
           // Authenticate by searching for the key, check if middleware requires edit rights and compare to key access
           $key = ApiKey::find($request->bearerToken());
    
           if ($key == null || ($args == 'edit' && $key->read_only == true)) {
               // Mark the request as unauthenticated
               $request->attributes->set('authenticated', false);
           } else {
               // Update last used
               $key->update(['last_used_at' => now()]);
               // Mark the request as authenticated
               $request->attributes->set('authenticated', true);
           }
    
           return $next($request);
       }
    }
  2. Handle the request differently in the BookingController:

    In the BookingController, check the request attribute to determine if the user is authenticated or not and return different data accordingly.

    namespace App\Http\Controllers\API;
    
    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    
    class BookingController extends Controller
    {
       public function index(Request $request)
       {
           if ($request->attributes->get('authenticated')) {
               // User is authenticated, return the actual bookings data
               $bookings = $this->getAuthenticatedBookings();
           } else {
               // User is not authenticated, return a different response
               $bookings = $this->getUnauthenticatedBookings();
           }
    
           return response()->json($bookings);
       }
    
       private function getAuthenticatedBookings()
       {
           // Fetch and return the actual bookings data
           return [
               'bookings' => [
                   // ... actual bookings data
               ]
           ];
       }
    
       private function getUnauthenticatedBookings()
       {
           // Return limited or different data for unauthenticated users
           return [
               'message' => 'Please log in to see your bookings.',
               'bookings' => []
           ];
       }
    }
  3. Adjust your routes to apply the middleware:

    Ensure the api-token middleware is applied to the /bookings route.

    Route::group(['middleware' => ['api-token']], function () {
       Route::get('/bookings', [App\Http\Controllers\API\BookingController::class, 'index'])->name('api.booking.index');
    });

With these changes, the /bookings endpoint will return different data depending on whether the user has provided a valid API token. If authenticated, it will return the actual bookings data. If not authenticated, it will return a message indicating that the user needs to log in.