From 777f6bdbafa46fcc0c2380fe89a207edb0eded1a Mon Sep 17 00:00:00 2001 From: smarcet Date: Fri, 13 Mar 2026 22:55:41 -0300 Subject: [PATCH 1/2] chore(swagger): preview openapi doc at gh-pages --- .github/workflows/l5-swagger-generate.yml | 160 ++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 .github/workflows/l5-swagger-generate.yml diff --git a/.github/workflows/l5-swagger-generate.yml b/.github/workflows/l5-swagger-generate.yml new file mode 100644 index 00000000..c9864683 --- /dev/null +++ b/.github/workflows/l5-swagger-generate.yml @@ -0,0 +1,160 @@ +name: OpenAPI generation + +on: + push: + pull_request: +jobs: + openapi-generate: + runs-on: ubuntu-latest + env: + APP_ENV: testing + APP_DEBUG: true + APP_KEY: base64:4vh0op/S1dAsXKQ2bbdCfWRyCI9r8NNIdPXyZWt9PX4= + DEV_EMAIL_TO: smarcet@gmail.com + APP_URL: http://localhost + DB_CONNECTION: mysql + DB_HOST: 127.0.0.1 + DB_PORT: 3306 + DB_DATABASE: idp_test + DB_USERNAME: root + DB_PASSWORD: 1qaz2wsx + REDIS_HOST: 127.0.0.1 + REDIS_PORT: 6379 + REDIS_DB: 0 + REDIS_PASSWORD: 1qaz2wsx + REDIS_DATABASES: 16 + SSL_ENABLED: false + SESSION_DRIVER: redis + PHP_VERSION: 8.3 + OTEL_SDK_DISABLED: true + OTEL_SERVICE_ENABLED: false + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ROOT_PASSWORD: ${{env.DB_PASSWORD}} + MYSQL_DATABASE: ${{env.DB_DATABASE}} + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + steps: + - name: Create Redis + uses: supercharge/redis-github-action@1.8.1 + with: + redis-port: ${{env.REDIS_PORT}} + redis-password: ${{env.REDIS_PASSWORD}} + + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ env.PHP_VERSION }} + extensions: pdo_mysql, mbstring, exif, pcntl, bcmath, sockets, gettext, apcu, redis, igbinary, memcached + + - name: Install dependencies + uses: "ramsey/composer-install@v3" + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.PAT }}"} }' + + - name: Generate OpenAPI docs + run: php artisan l5-swagger:generate + + - name: Build Swagger UI preview + run: | + mkdir -p swagger-ui + cp storage/api-docs/api-docs.json swagger-ui/api-docs.json + cat > swagger-ui/index.html << 'HTMLEOF' + + + + + OpenStackID API - Swagger UI + + + +
+ + + + + HTMLEOF + + - name: Upload Swagger UI artifact + uses: actions/upload-artifact@v4 + with: + name: swagger-ui + path: swagger-ui/ + if-no-files-found: error + + pages-preview: + name: Publish Swagger UI to GitHub Pages + needs: openapi-generate + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + + permissions: + contents: write + issues: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download Swagger UI artifact + uses: actions/download-artifact@v4 + with: + name: swagger-ui + path: swagger-ui + + - name: Build public directory for GitHub Pages + run: | + PR_PATH="openapi/pr-${{ github.event.number }}" + mkdir -p "public/${PR_PATH}" + cp -R swagger-ui/* "public/${PR_PATH}/" + echo "Built GitHub Pages content at public/${PR_PATH}" + + - name: Publish to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./public + keep_files: true + + - name: Comment preview URL on PR + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const prNumber = context.payload.pull_request.number; + const owner = context.repo.owner; + const repo = context.repo.repo; + const baseUrl = `https://${owner}.github.io/${repo}`; + const previewPath = `/openapi/pr-${prNumber}/`; + const url = `${baseUrl}${previewPath}`; + + const body = [ + '📘 **OpenAPI / Swagger preview**', + '', + `➡️ ${url}`, + '', + 'This page is automatically updated on each push to this PR.' + ].join('\n'); + + await github.rest.issues.createComment({ + owner, + repo, + issue_number: prNumber, + body, + }); + From f445be543c0a0a63c4f174276b7bcd04791f9d97 Mon Sep 17 00:00:00 2001 From: smarcet Date: Fri, 13 Mar 2026 23:09:55 -0300 Subject: [PATCH 2/2] fix(swagger): endpoint doc Signed-off-by: smarcet --- .../Api/OAuth2/OAuth2UserApiController.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/OAuth2/OAuth2UserApiController.php b/app/Http/Controllers/Api/OAuth2/OAuth2UserApiController.php index 3a2b27d6..20356e1d 100644 --- a/app/Http/Controllers/Api/OAuth2/OAuth2UserApiController.php +++ b/app/Http/Controllers/Api/OAuth2/OAuth2UserApiController.php @@ -342,14 +342,17 @@ public function get($id) #[OA\Get( path: '/api/v2/users/{id}', summary: 'Get a user by ID', - description: 'Get a user by ID (only for accounts of type "SERVICE")', + description: 'Retrieves user details by their numeric ID.', operationId: 'getUserByIdV2', - tags: ['Users'], + tags: ['Users', 'V2'], security: [ ['OAuth2UserSecurity' => [ IUserScopes::ReadAll, ]], ], + x: [ + 'x-required-client-type' => 'SERVICE', + ], parameters: [ new OA\Parameter( name: 'id', @@ -380,6 +383,10 @@ public function get($id) response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error' ), + new OA\Response( + response: HttpResponse::HTTP_FORBIDDEN, + description: 'Forbidden - Only service accounts are allowed' + ), ] )] public function getV2($id)