diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f2aa69..8786698 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,10 +9,8 @@ jobs: strategy: matrix: php: [8.0, 8.1, 8.2] - laravel: [8.*, 9.*, 10.*, 11.*, 12.*] + laravel: [10.*, 11.*, 12.*] exclude: - - laravel: 8.* - php: 8.2 - laravel: 10.* php: 8.0 - laravel: 11.* @@ -46,4 +44,24 @@ jobs: composer require "illuminate/console:${{ matrix.laravel }}" "illuminate/database:${{ matrix.laravel }}" "illuminate/support:${{ matrix.laravel }}" --no-interaction --no-update composer update - name: Run tests - run: vendor/bin/phpunit \ No newline at end of file + run: vendor/bin/phpunit + + docker: + runs-on: ubuntu-latest + needs: tests + if: github.event_name == 'push' || github.event_name == 'pull_request' + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ghcr.io/${{ github.repository }}:latest \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 8f051e4..f8480f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,12 +20,122 @@ RUN jq '.repositories=[{"type": "path","url": "/laravel-scim-server"}]' ./compos RUN composer require arietimmerman/laravel-scim-server @dev && \ composer require laravel/tinker -RUN touch ./.database.sqlite && \ - echo "DB_CONNECTION=sqlite" >> ./.env && \ - echo "DB_DATABASE=/.database.sqlite" >> ./.env && \ - echo "APP_URL=http://localhost:18123" >> ./.env +RUN touch /example/database.sqlite && \ + echo "DB_CONNECTION=sqlite" >> /example/.env && \ + echo "DB_DATABASE=/example/database.sqlite" >> /example/.env && \ + echo "APP_URL=http://localhost:18123" >> /example/.env + +# Add migration for groups table using heredoc +RUN cat > /example/database/migrations/2021_01_01_000001_create_groups_table.php <<'EOM' +id(); + $table->string('displayName')->unique(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('groups'); + } +}; +EOM + +# Add Group model +RUN cat > app/Models/Group.php <<'EOM' + app/SCIM/CustomSCIMConfig.php <<'EOM' + app/Providers/AppServiceProvider.php <<'EOM' +app->singleton(BaseSCIMConfig::class, CustomSCIMConfig::class); + } + + public function boot(): void + { + // Additional boot logic if needed + } +} +EOM + +# Add Group factory +RUN cat > database/factories/GroupFactory.php <<'EOM' + $this->faker->unique()->company(), + ]; + } +} +EOM + +# Run migrations and seed demo data RUN php artisan migrate && \ - echo "User::factory()->count(100)->create();" | php artisan tinker + echo "User::factory()->count(100)->create(); App\\Models\\Group::factory()->count(10)->create();" | php artisan tinker -CMD php artisan serve --host=0.0.0.0 --port=8000 +CMD ["php","artisan","serve","--host=0.0.0.0","--port=8000"] diff --git a/composer.json b/composer.json index d5fd81a..c738ea7 100644 --- a/composer.json +++ b/composer.json @@ -11,9 +11,9 @@ ], "require": { "php": "^8.0", - "illuminate/database": "^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/console": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/database": "^10.0|^11.0|^12.0", + "illuminate/support": "^10.0|^11.0|^12.0", + "illuminate/console": "^10.0|^11.0|^12.0", "tmilos/scim-schema": "^0.1.0", "tmilos/scim-filter-parser": "^1.3" }, diff --git a/docker-compose.yml b/docker-compose.yml index 0dc043c..12f972e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,7 +5,7 @@ services: ports: # forward xdebug ports - "127.0.0.1:18123:8000" - working_dir: /laravel-scim-server + working_dir: /example environment: - XDEBUG_MODE=debug - XDEBUG_SESSION=1 diff --git a/src/RouteProvider.php b/src/RouteProvider.php index 447ad1c..a98d1bf 100644 --- a/src/RouteProvider.php +++ b/src/RouteProvider.php @@ -1,7 +1,10 @@ group( function () use ($options) { - Route::prefix('v2')->middleware( - [ - // TODO: Not loading this middleware introduces resolve issues. But having it, might slow things down. - \Illuminate\Routing\Middleware\SubstituteBindings::class, - 'ArieTimmerman\Laravel\SCIMServer\Middleware\SCIMHeaders' - ] - )->group( + Route::prefix('v2')->middleware([ + SubstituteBindings::class, + SCIMHeaders::class, + ])->group( function () use ($options) { static::allRoutes($options); } ); - Route::get('v1', '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@wrongVersion'); + Route::get('v1', [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'wrongVersion']); Route::prefix('v1')->group( function () { - Route::fallback('\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@wrongVersion'); + Route::fallback([\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'wrongVersion']); } ); } @@ -44,47 +44,47 @@ function () { public static function meRoutes(array $options = []) { Route::prefix(static::$prefix)->group(function () { - Route::get("/v2/Me", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\MeController@getMe')->name('scim.me.get'); - Route::put('/v2/Me', '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\MeController@replaceMe')->name('scim.me.put'); + Route::get("/v2/Me", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\MeController::class, 'getMe'])->name('scim.me.get'); + Route::put('/v2/Me', [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\MeController::class, 'replaceMe'])->name('scim.me.put'); }); } public static function meRoutePost(array $options = []) { Route::prefix(static::$prefix)->group(function () { - Route::post('/v2/Me', '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\MeController@createMe')->name('scim.me.post'); + Route::post('/v2/Me', [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\MeController::class, 'createMe'])->name('scim.me.post'); }); } public static function publicRoutes(array $options = []) { Route::prefix(static::$prefix)->group(function () { - Route::get("/v2/ServiceProviderConfig", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ServiceProviderController@index')->name('scim.serviceproviderconfig'); + Route::get("/v2/ServiceProviderConfig", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ServiceProviderController::class, 'index'])->name('scim.serviceproviderconfig'); - Route::get("/v2/Schemas", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\SchemaController@index'); - Route::get("/v2/Schemas/{id}", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\SchemaController@show')->name('scim.schemas'); + Route::get("/v2/Schemas", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\SchemaController::class, 'index']); + Route::get("/v2/Schemas/{id}", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\SchemaController::class, 'show'])->name('scim.schemas'); - Route::get("/v2/ResourceTypes", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceTypesController@index'); - Route::get("/v2/ResourceTypes/{id}", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceTypesController@show')->name('scim.resourcetype'); + Route::get("/v2/ResourceTypes", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceTypesController::class, 'index']); + Route::get("/v2/ResourceTypes/{id}", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceTypesController::class, 'show'])->name('scim.resourcetype'); }); } private static function allRoutes(array $options = []) { - Route::post('.search', '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@notImplemented'); + Route::post('.search', [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'notImplemented']); - Route::post("/Bulk", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\BulkController@processBulkRequest'); + Route::post("/Bulk", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\BulkController::class, 'processBulkRequest']); // TODO: Use the attributes parameters ?attributes=userName, excludedAttributes=asdg,asdg (respect "returned" settings "always") - Route::get('/{resourceType}/{resourceObject}', '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@show')->name('scim.resource'); - Route::get("/{resourceType}", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@index')->name('scim.resources'); - Route::post("/{resourceType}/.search", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@search'); - Route::post("/{resourceType}", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@create'); + Route::get('/{resourceType}/{resourceObject}', [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'show'])->name('scim.resource'); + Route::get("/{resourceType}", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'index'])->name('scim.resources'); + Route::post("/{resourceType}/.search", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'search']); + Route::post("/{resourceType}", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'create']); - Route::put("/{resourceType}/{resourceObject}", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@replace'); - Route::patch("/{resourceType}/{resourceObject}", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@update'); - Route::delete("/{resourceType}/{resourceObject}", '\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@delete'); + Route::put("/{resourceType}/{resourceObject}", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'replace']); + Route::patch("/{resourceType}/{resourceObject}", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'update']); + Route::delete("/{resourceType}/{resourceObject}", [\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'delete']); - Route::fallback('\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController@notImplemented'); + Route::fallback([\ArieTimmerman\Laravel\SCIMServer\Http\Controllers\ResourceController::class, 'notImplemented']); } } diff --git a/src/SCIMConfig.php b/src/SCIMConfig.php index bda4c4a..1fd6cb4 100644 --- a/src/SCIMConfig.php +++ b/src/SCIMConfig.php @@ -44,6 +44,11 @@ public function getConfigForResource($name) return @$result[$name]; } + public function getGroupClass() + { + return Group::class; + } + public function getUserConfig() { return [ diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index e2e493a..88aaceb 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -1,4 +1,5 @@ loadMigrationsFrom(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'migrations'); $this->publishes([ - __DIR__.'/../config/scim.php' => config_path('scim.php'), + __DIR__ . '/../config/scim.php' => config_path('scim.php'), ], 'laravel-scim'); // Match everything, except the Me routes @@ -79,7 +80,7 @@ function ($id, $route) { public function register() { $this->mergeConfigFrom( - __DIR__.'/../config/scim.php', + __DIR__ . '/../config/scim.php', 'scim' ); }