diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..30a88e2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "docker" + directory: "/.github/fusionauth" + schedule: + interval: "weekly" diff --git a/.github/fusionauth/.env b/.github/fusionauth/.env new file mode 100644 index 0000000..08cace4 --- /dev/null +++ b/.github/fusionauth/.env @@ -0,0 +1,6 @@ +DATABASE_USERNAME=fusionauth +DATABASE_PASSWORD=hkaLBM3RVnyYeYeqE3WI1w2e4Avpy0Wd5O3s3 +FUSIONAUTH_APP_MEMORY=256M +FUSIONAUTH_APP_RUNTIME_MODE=development +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres diff --git a/.github/fusionauth/docker-compose.yml b/.github/fusionauth/docker-compose.yml new file mode 100644 index 0000000..3563fe4 --- /dev/null +++ b/.github/fusionauth/docker-compose.yml @@ -0,0 +1,53 @@ +version: '3' + +services: + db: + image: postgres:16.0-alpine + environment: + PGDATA: /var/lib/postgresql/data/pgdata + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + healthcheck: + test: [ "CMD-SHELL", "pg_isready -U postgres" ] + interval: 5s + timeout: 5s + retries: 5 + networks: + - db_net + restart: unless-stopped + volumes: + - db_data:/var/lib/postgresql/data + + fusionauth: + image: fusionauth/fusionauth-app:latest + depends_on: + db: + condition: service_healthy + environment: + DATABASE_URL: jdbc:postgresql://db:5432/fusionauth + DATABASE_ROOT_USERNAME: ${POSTGRES_USER} + DATABASE_ROOT_PASSWORD: ${POSTGRES_PASSWORD} + DATABASE_USERNAME: ${DATABASE_USERNAME} + DATABASE_PASSWORD: ${DATABASE_PASSWORD} + FUSIONAUTH_APP_MEMORY: ${FUSIONAUTH_APP_MEMORY} + FUSIONAUTH_APP_RUNTIME_MODE: ${FUSIONAUTH_APP_RUNTIME_MODE} + FUSIONAUTH_APP_SILENT_MODE: true + FUSIONAUTH_APP_URL: http://fusionauth:9011 + FUSIONAUTH_APP_KICKSTART_FILE: /usr/local/fusionauth/kickstart.json + SEARCH_TYPE: database + networks: + - db_net + restart: unless-stopped + ports: + - 9011:9011 + volumes: + - fusionauth_config:/usr/local/fusionauth/config + - ./kickstart.json:/usr/local/fusionauth/kickstart.json + +networks: + db_net: + driver: bridge + +volumes: + db_data: + fusionauth_config: diff --git a/.github/fusionauth/kickstart.json b/.github/fusionauth/kickstart.json new file mode 100644 index 0000000..d557306 --- /dev/null +++ b/.github/fusionauth/kickstart.json @@ -0,0 +1,46 @@ +{ + "variables": { + "applicationid": "e9fdb985-9173-4e01-9d73-ac2d60d1dc8e", + "apiKey": "72a8c464b86c3c9098c33da73f471b8a0352f6e14087ddc3", + "asymmetricKeyId": "#{UUID()}", + "defaultTenantId": "d7d09513-a3f5-401c-9685-34ab6c552453", + "adminEmail": "admin@example.com", + "adminPassword": "password" + }, + "apiKeys": [ + { + "key": "#{apiKey}", + "description": "Unrestricted API key" + } + ], + "requests": [ + { + "method": "POST", + "url": "/api/key/generate/#{asymmetricKeyId}", + "tenantId": "#{defaultTenantId}", + "body": { + "key": { + "algorithm": "RS256", + "name": "For GitHub Actions", + "length": 2048 + } + } + }, + { + "method": "POST", + "url": "/api/user/registration", + "body": { + "user": { + "email": "#{adminEmail}", + "password": "#{adminPassword}" + }, + "registration": { + "applicationId": "#{FUSIONAUTH_APPLICATION_ID}", + "roles": [ + "admin" + ] + } + } + } + ] +} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..8c510ea --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,41 @@ +name: Test Library + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up FusionAuth + working-directory: .github/fusionauth + run: docker compose up -d + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Waiting for FusionAuth App + run: timeout 30 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:9011)" != "200" ]]; do sleep 5; done' || false + + - name: Run test suite + run: composer run test diff --git a/README.md b/README.md index 04cc6cb..ff1fe70 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,208 @@ -## FusionAuth PHP Client ![semver 2.0.0 compliant](http://img.shields.io/badge/semver-2.0.0-brightgreen.svg?style=flat-square) -If you're integrating FusionAuth with a PHP application, this library will speed up your development time. +# FusionAuth PHP Client ![semver 2.0.0 compliant](http://img.shields.io/badge/semver-2.0.0-brightgreen.svg?style=flat-square) -For additional information and documentation on FusionAuth refer to [https://fusionauth.io](https://fusionauth.io). +## Intro -### Example Usage + -#### Install the Code +If you're integrating FusionAuth with a PHP application, this library will speed up your development time. Please also make sure to check our [SDK Usage Suggestions page](https://fusionauth.io/docs/sdks/#usage-suggestions). -To use the client library on your project simply copy the PHP source files from the `src` directory to your project or the following - Composer package. +For additional information and documentation on FusionAuth refer to [https://fusionauth.io](https://fusionauth.io). -Packagist +## Install -* https://packagist.org/packages/fusionauth/fusionauth-client +The most preferred way to use the client library is to install the [`fusionauth/fusionauth-client`](https://packagist.org/packages/fusionauth/fusionauth-client) package via Composer by running the command below at your project root folder. ```bash composer require fusionauth/fusionauth-client ``` -Include composer autoloader +Then, include the `composer` autoloader in your PHP files. -```PHP +```php require __DIR__ . '/vendor/autoload.php'; ``` -#### Create the Client +## Examples -```PHP -$apiKey = "5a826da2-1e3a-49df-85ba-cd88575e4e9d"; -$client = new FusionAuth\FusionAuthClient($apiKey, "http://localhost:9011"); -``` +### Set Up + +First, you have to make sure you have a running FusionAuth instance. If you don't have one already, the easiest way to install FusionAuth is [via Docker](https://fusionauth.io/docs/get-started/download-and-install/docker), but there are [other ways](https://fusionauth.io/docs/get-started/download-and-install). By default, it'll be running on `localhost:9011`. + +Then, you have to [create an API Key](https://fusionauth.io/docs/apis/authentication#managing-api-keys) in the admin UI to allow calling API endpoints. + +You are now ready to use this library! + +### Error Handling -#### Login a user +After every request is made, you need to check for any errors and handle them. To avoid cluttering things up, we'll omit the error handling in the next examples, but you should do something like the following. -```PHP -$applicationId = "68364852-7a38-4e15-8c48-394eceafa601"; +```php +// $result is the response of one of the endpoint invocations from the examples below -$request = array(); -$request["applicationId"] = $applicationId; -$request["loginId"] = "joe@fusionauth.io"; -$request["password"] = "abc123"; -$result = $client->login($request); if (!$result->wasSuccessful()) { - // Error + echo "Error!" . PHP_EOL; + echo "Got HTTP {$result->status}" . PHP_EOL; + if (isset($result->errorResponse->fieldErrors)) { + echo "There are some errors with the payload:" . PHP_EOL; + var_dump($result->errorResponse->fieldErrors); + } + if (isset($result->errorResponse->generalErrors)) { + echo "There are some general errors:" . PHP_EOL; + var_dump($result->errorResponse->generalErrors); + } } +``` + +### Create the Client + +To make requests to the API, first you need to create a `FusionAuthClient` instance with [the API Key created](https://fusionauth.io/docs/apis/authentication#managing-api-keys) and the server address where FusionAuth is running. + +```php +$client = new FusionAuth\FusionAuthClient( + apiKey: "", + baseURL: "http://localhost:9011", // or change this to whatever address FusionAuth is running on +); +``` + +### Create an Application + +To create an [Application](https://fusionauth.io/docs/get-started/core-concepts/applications), use the `createApplication()` method. + +```php +$result = $client->createApplication( + applicationId: null, // Leave this empty to automatically generate the UUID + request: [ + 'application' => [ + 'name' => 'ChangeBank', + ], + ], +); + +// Handle errors as shown in the beginning of the Examples section + +// Otherwise parse the successful response +var_dump($result->successResponse->application); +``` + +[Check the API docs for this endpoint](https://fusionauth.io/docs/apis/applications#create-an-application) + +### Adding Roles to an Existing Application + +To add [roles to an Application](https://fusionauth.io/docs/get-started/core-concepts/applications#roles), use `createApplicationRole()`. + +```php +$result = $client->createApplicationRole( + applicationId: 'd564255e-f767-466b-860d-6dcb63afe4cc', // Existing Application Id + roleId: null, // Leave this empty to automatically generate the UUID + request: [ + 'role' => [ + 'name' => 'customer', + 'description' => 'Default role for regular customers', + 'isDefault' => true, + ], + ], +); + +// Handle errors as shown in the beginning of the Examples section + +// Otherwise parse the successful response +var_dump($result->successResponse->role); +``` + +[Check the API docs for this endpoint](https://fusionauth.io/docs/apis/applications#create-an-application-role) + +### Retrieve Application Details + +To fetch details about an [Application](https://fusionauth.io/docs/get-started/core-concepts/applications), use `retrieveApplication()`. -// Hooray! Success +```php +$result = $client->retrieveApplication( + applicationId: 'd564255e-f767-466b-860d-6dcb63afe4cc', +); + +// Handle errors as shown in the beginning of the Examples section + +// Otherwise parse the successful response +var_dump($result->successResponse->application); +``` + +[Check the API docs for this endpoint](https://fusionauth.io/docs/apis/applications#retrieve-an-application) + +### Delete an Application + +To delete an [Application](https://fusionauth.io/docs/get-started/core-concepts/applications), use `deleteApplication()`. + +```php +$result = $client->deleteApplication( + applicationId: 'd564255e-f767-466b-860d-6dcb63afe4cc', +); + +// Handle errors as shown in the beginning of the Examples section + +// Otherwise parse the successful response +// Note that $result->successResponse will be empty +``` + +[Check the API docs for this endpoint](https://fusionauth.io/docs/apis/applications#delete-an-application) + +### Lock a User + +To [prevent a User from logging in](https://fusionauth.io/docs/get-started/core-concepts/users), use `deactivateUser()`. + +```php +$result = $client->deactivateUser( + 'fa0bc822-793e-45ee-a7f4-04bfb6a28199', +); + +// Handle errors as shown in the beginning of the Examples section + +// Otherwise parse the successful response +``` + +[Check the API docs for this endpoint](https://fusionauth.io/docs/apis/users#delete-a-user) + +### Registering a User + +To [register a User in an Application](https://fusionauth.io/docs/get-started/core-concepts/users#registrations), use `register()`. + +The code below also adds a `customer` role and a custom `appBackgroundColor` property to the User Registration. + +```php +$result = $client->register( + userId: 'fa0bc822-793e-45ee-a7f4-04bfb6a28199', + request: [ + 'registration' => [ + 'applicationId' => 'd564255e-f767-466b-860d-6dcb63afe4cc', + 'roles' => [ + 'customer', + ], + 'data' => [ + 'appBackgroundColor' => '#096324', + ], + ], + ], +); + +// Handle errors as shown in the beginning of the Examples section + +// Otherwise parse the successful response ``` +[Check the API docs for this endpoint](https://fusionauth.io/docs/apis/registrations#create-a-user-registration-for-an-existing-user) + + + ## Questions and support -If you have a question or support issue regarding this client library, we'd love to hear from you. +If you find any bugs in this library, [please open an issue](https://github.com/FusionAuth/fusionauth-php-client/issues). Note that changes to the `FusionAuthClient` class have to be done on the [FusionAuth Client Builder repository](https://github.com/FusionAuth/fusionauth-client-builder/blob/master/src/main/client/php.client.ftl), which is responsible for generating that file. + +But if you have a question or support issue, we'd love to hear from you. -If you have a paid edition with support included, please [open a ticket in your account portal](https://account.fusionauth.io/account/support/). Learn more about [paid editions here](https://fusionauth.io/pricing). +If you have a paid plan with support included, please [open a ticket in your account portal](https://account.fusionauth.io/account/support/). Learn more about [paid plan here](https://fusionauth.io/pricing). Otherwise, please [post your question in the community forum](https://fusionauth.io/community/forum/). @@ -60,7 +210,9 @@ Otherwise, please [post your question in the community forum](https://fusionauth Bug reports and pull requests are welcome on GitHub at https://github.com/FusionAuth/fusionauth-php-client. +Note: if you want to change the `FusionAuthClient` class, you have to do it on the [FusionAuth Client Builder repository](https://github.com/FusionAuth/fusionauth-client-builder/blob/master/src/main/client/php.client.ftl), which is responsible for generating all client libraries we support. + ## License -This code is available as open source under the terms of the [Apache v2.0 License](https://opensource.org/licenses/Apache-2.0). +This code is available as open source under the terms of the [Apache v2.0 License](https://opensource.org/blog/license/apache-2-0). diff --git a/composer.lock b/composer.lock index e5380d2..e64b175 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "94a18de62688fe39c9c7c3715407712c", + "content-hash": "caf15cf149f3cf51556dde19260ed26a", "packages": [], "packages-dev": [ { @@ -68,16 +68,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.0.0", + "version": "v5.0.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc" + "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc", - "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2218c2252c874a4624ab2f613d86ac32d227bc69", + "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69", "shasum": "" }, "require": { @@ -120,9 +120,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.1" }, - "time": "2024-01-07T17:17:35+00:00" + "time": "2024-02-21T19:24:10+00:00" }, { "name": "phar-io/manifest", @@ -558,16 +558,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.8", + "version": "10.5.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "08f4fa74d5fbfff1ef22abffee47aaedcaea227e" + "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/08f4fa74d5fbfff1ef22abffee47aaedcaea227e", - "reference": "08f4fa74d5fbfff1ef22abffee47aaedcaea227e", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4", + "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4", "shasum": "" }, "require": { @@ -639,7 +639,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.8" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.11" }, "funding": [ { @@ -655,7 +655,7 @@ "type": "tidelift" } ], - "time": "2024-01-19T07:07:27+00:00" + "time": "2024-02-25T14:05:00+00:00" }, { "name": "sebastian/cli-parser", diff --git a/phpunit.xml b/phpunit.xml index 72f2048..36033b0 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -21,4 +21,8 @@ src + + + +