From d65e435b3ba5a4be81dbd24f08df58b4c8da47eb Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:19:38 +0000 Subject: [PATCH 01/69] hack(tests): add fuzz testing workflow --- .github/workflows/rest-api-fuzzer.yml | 135 +++++++ .../speckle-server.openapi.json | 345 ++++++++++++++++++ 2 files changed, 480 insertions(+) create mode 100644 .github/workflows/rest-api-fuzzer.yml create mode 100644 utils/specifications/speckle-server.openapi.json diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml new file mode 100644 index 0000000000..a69ab6821e --- /dev/null +++ b/.github/workflows/rest-api-fuzzer.yml @@ -0,0 +1,135 @@ +name: REST API Fuzz Test + +on: + workflow_dispatch: + pull_request: # Pushing a new commit to the HEAD ref of a pull request will trigger the “synchronize” event + paths: + - .yarnrc.yml . + - .yarn + - package.json + - '.github/workflows/rest-api-fuzzer.yml' + - 'packages/server/**/*' + - 'packages/shared/**/*' + +env: + BUILD_CONFIGURATION: Release + BUILD_PLATFORM: 'Any CPU' + RESTLER_VERSION: '9.2.4' + PYTHON_VERSION: '3.8' + DOTNET_VERSION: '6.0.x' + +jobs: + + build-restler-fuzzer: + name: Build Restler Fuzzer + runs-on: ubuntu-latest + permissions: + packages: write # publishing container to GitHub registry + steps: + - uses: actions/checkout@v4 + with: + repository: microsoft/restler-fuzzer + ref: ${{ env.RESTLER_VERSION }} + path: 'restler-fuzzer' # The path to clone the repository under {{ github.workspace }} + - name: Print environment variables + run: printenv + + - name: Setup .NET ${{ env.DOTNET_VERSION }} + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Restore NuGet packages + run: dotnet restore src/Restler.sln + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install engine (Python) dependencies + run: | + pip install -r ./restler/requirements.txt + + - name: Build RESTler drop + run: | + python ./build-restler.py --dest_dir ${{ github.workspace }}/restler/restler + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v3 + # - name: Log in to the Container registry + # uses: docker/login-action@v3.3.0 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + # - name: Extract metadata (tags, labels) for Docker + # id: meta + # uses: docker/metadata-action@v5.5.1 + # with: + # tags: type=sha,format=long + # images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + # - name: Build and load preview-service Docker image + # uses: docker/build-push-action@v6 + # with: + # context: ${{ github.workspace }}/restler-fuzzer + # file: ${{ github.workspace }}/restler-fuzzer/Dockerfile # The Dockerfile for the restler-fuzzer + # push: true + # tags: ${{ steps.meta.outputs.tags }} + # cache-from: type=gha + # cache-to: type=gha,mode=max + # outputs: + # tags: ${{ steps.meta.outputs.tags }} + + # compile-fuzzer-syntax: + # name: Compile Fuzzer Syntax + # runs-on: ubuntu-latest + # needs: build-restler-fuzzer + + # steps: + - uses: actions/checkout@v4 + - name: Compile from OpenAPI + # run: docker run --volume ${{ github.workspace }}/restlerConfig:/RESTler/restler/restlerConfig ${{ needs.build-restler-fuzzer.outputs.tags }} compile --api_spec utils/specifications/speckle-server.openapi.json + run: | + ${{ github.workspace }}/restler/restler compile --api_spec utils/specifications/speckle-server.openapi.json + - name: Print the results + run: ls -lat ${{ github.workspace }}/restler/restler/restlerConfig + + # fuzz-rest-api-lite: + # runs-on: ubuntu-latest + # needs: + # - compile-fuzzer-syntax + # timeout-minutes: 15 + + # services: + # postgres: + # # Docker Hub image + # image: postgres:16.4-bookworm@sha256:91f464e7ba0ad91a106c94cff079fb4384139291b8c0502fd36989cf2c788bbb + # env: + # POSTGRES_DB: fuzz_test + # POSTGRES_PASSWORD: fuzz_test + # POSTGRES_USER: fuzz_test + # # Set health checks to wait until postgres has started + # options: >- + # --health-cmd pg_isready + # --health-interval 10s + # --health-timeout 5s + # --health-retries 5 + # ports: + # - 5432:5432 + # # 4. Run the fuzzer in lite mode + # steps: + # - name: Compile from OpenAPI + # run: docker run ${{ needs.build-restler-fuzzer.outputs.tags }} compile --api_spec + # # 5. Print the results + + + + # fuzz-rest-api-full: + # runs-on: ubuntu-latest + # needs: + # - compile-fuzzer-syntax + # timeout-minutes: 45 + # steps: + # - name: Run RESTler Fuzzer + # run: docker run /RESTler/restler/restler.exe fuzz --api_spec --fuzz_mode full + # # 7. Print the results \ No newline at end of file diff --git a/utils/specifications/speckle-server.openapi.json b/utils/specifications/speckle-server.openapi.json new file mode 100644 index 0000000000..927d45b8c9 --- /dev/null +++ b/utils/specifications/speckle-server.openapi.json @@ -0,0 +1,345 @@ +{ + "swagger": "2.0", + "basePath": "/", + "info": { "title": "Speckle.", "version": "dev" }, + "definitions": {}, + "paths": { + "/explorer": { + "get": { + "summary": "GraphQL API Explorer", + "description": "GraphQL API Explorer", + "responses": { + "default": { "description": "Returns the GraphQL API Explorer" } + } + } + }, + "/auth/local/login": { + "post": { + "description": "Login with email and password", + "responses": { + "200": { "description": "User logged in successfully" }, + "401": { "description": "Invalid credentials" } + } + } + }, + "/auth/local/register": { + "post": { + "description": "Register with email and password", + "responses": { + "200": { "description": "User registered successfully" }, + "400": { "description": "Invalid input" }, + "500": { "description": "Server error" } + } + } + }, + "/auth/accesscode": { + "get": { + "description": "Generates an access code for an app.", + "responses": { + "200": { "description": "Returns an access code in the body" }, + "302": { "description": "Redirects with access code in url query" }, + "400": { "description": "Invalid access code" }, + "500": { "description": "Internal error" } + } + }, + "options": { + "description": "Generates a new API token", + "responses": { + "default": { "description": "Options for generating a new API token" } + } + } + }, + "/auth/token": { + "post": { + "description": "Generates a new API token", + "responses": { "200": { "description": "Generates a new API token" } } + } + }, + "/auth/logout": { + "post": { + "description": "Logs a user out by invalidating token and refresh token", + "responses": { + "200": { "description": "Successfully logged out" }, + "400": { "description": "Error while logging out" } + } + } + }, + "/api/stream/{streamId}/blob": { + "post": { + "description": "Upload a new blob to a project (stream)", + "parameters": [{ "in": "path", "name": "streamId", "required": true }], + "responses": { + "200": { + "description": "Successfully uploaded a blob to the project" + } + } + } + }, + "/api/stream/{streamId}/diff": { + "post": { + "description": "Determine the difference (diff) between the provided array of blob Ids and those stored on the server", + "parameters": [{ "in": "path", "name": "streamId", "required": true }], + "responses": { + "200": { + "description": "The difference between the list of blob Ids provided in the body of the request and those stored on the server" + } + } + } + }, + "/api/stream/{streamId}/blob/{blobId}": { + "get": { + "description": "Gets a blob from a project (stream)", + "parameters": [ + { "in": "path", "name": "streamId", "required": true }, + { "in": "path", "name": "blobId", "required": true } + ], + "responses": { + "200": { + "description": "Successfully retrieved a blob from the project" + } + } + }, + "delete": { + "description": "Deletes a blob from a project (stream)", + "parameters": [ + { "in": "path", "name": "streamId", "required": true }, + { "in": "path", "name": "blobId", "required": true } + ], + "responses": { + "204": { + "description": "Successfully deleted a blob from the project" + } + } + } + }, + "/api/stream/{streamId}/blobs": { + "get": { + "description": "Gets all the blobs of a project (stream)", + "parameters": [{ "in": "path", "name": "streamId", "required": true }], + "responses": { + "200": { + "description": "Successfully retrieved all the blobs from the project" + } + } + }, + "delete": { + "description": "Deletes all the blobs from a project (stream)", + "parameters": [{ "in": "path", "name": "streamId", "required": true }], + "responses": { "501": { "description": "Not implemented." } } + } + }, + "/static": { + "get": { + "description": "Static assets", + "responses": { "200": { "description": "An asset was retrieved." } } + } + }, + "/liveness": { + "options": { + "description": "Liveness options", + "responses": { + "200": { "description": "Options for liveness endpoint." } + } + }, + "get": { + "description": "Indicates whether the application is alive.", + "responses": { "200": { "description": "The application is alive." } } + } + }, + "/readiness": { + "options": { + "description": "Readiness endpoint options", + "responses": { "200": { "description": "Options were retrieved." } } + }, + "get": { + "description": "Indicates whether the application is ready to accept traffic", + "responses": { "200": { "description": "The application is ready." } } + } + }, + "/objects/{streamId}": { + "options": { + "description": "The options for this endpoint", + "responses": { "200": { "description": "Options were retrieved." } } + }, + "post": { + "description": "Upload objects to the project (stream)", + "responses": { + "200": { "description": "Objects were successfully uploaded." } + } + } + }, + "/objects/{streamId}/{objectId}": { + "options": { + "description": "Options for downloading an object from a project (stream)", + "responses": { "200": { "description": "Options were retrieved." } } + }, + "get": { + "description": "Download objects from a project (stream)", + "responses": { "200": { "description": "Objects were downloaded." } } + } + }, + "/objects/{streamId}/{objectId}/single": { + "options": { + "description": "Options for downloading a single object from a project (stream)", + "responses": { "200": { "description": "Options were retrieved." } } + }, + "get": { + "description": "Options for downloading a single object from a project (stream)", + "responses": { "200": { "description": "An object was retrieved." } } + } + }, + "/api/diff/{streamId}": { + "options": { + "description": "Options for the endpoint", + "responses": { "200": { "description": "Options were retrieved." } } + }, + "post": { + "description": "Options for getting the diff of objects for a project (stream)", + "responses": { + "200": { "description": "A diff was successfully computed." } + } + } + }, + "/api/getobjects/{streamId}": { + "options": { + "description": "Options for the endpoint", + "responses": { "200": { "description": "Options were retrieved." } } + }, + "post": { + "description": "Get all objects for a project (stream)", + "responses": { + "200": { "description": "All objects were successfully retrieved." } + } + } + }, + "/auth/verifyemail": { + "get": { + "summary": "Verify email", + "description": "Verifies an email address", + "responses": { "302": { "description": "Redirects to the home page." } } + } + }, + "/api/file/{fileType}/{streamId}/{branchName}": { + "post": { + "description": "Uploads a file to a project (stream)", + "responses": { + "200": { + "description": "file successfully uploaded to the project (stream)" + } + } + } + }, + "/metrics": { + "get": { + "summary": "Metrics", + "description": "Returns Prometheus metrics", + "responses": { "200": { "description": "Returns Prometheus metrics" } } + } + }, + "/openapi/html": { + "get": { + "summary": "OpenAPI HTML", + "description": "Returns the OpenAPI documentation in HTML format", + "responses": { + "200": { + "description": "Returns the OpenAPI documentation in HTML format" + } + } + } + }, + "/openapi/json": { + "get": { + "summary": "OpenAPI JSON", + "description": "Returns the OpenAPI documentation in JSON format", + "responses": { + "200": { + "description": "Returns the OpenAPI documentation in JSON format" + } + } + } + }, + "/preview/{streamId}/{angle}": { + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } + }, + "get": { + "description": "Retrieve a preview for the project (stream), at an optional angle", + "responses": { + "200": { "description": "A preview was successfully retrieved." } + } + } + }, + "/preview/{streamId}/branches/{branchName}/{angle}": { + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } + } + }, + "/preview/{streamId}/branches/{branchname}/{angle}": { + "get": { + "description": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", + "responses": { + "200": { "description": "A preview was successfully retrieved." } + } + } + }, + "/preview/{streamId}/commits/{commitId}/{angle}": { + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } + }, + "get": { + "description": "Retrieve a preview for the project (stream) and version (commit), at an optional angle", + "responses": { + "200": { "description": "A preview was successfully retrieved." } + } + } + }, + "/preview/{streamId}/objects/{objectId}/{angle}": { + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } + }, + "get": { + "description": "Retrieve a preview for the project (stream) and object, at an optional angle", + "responses": { + "200": { "description": "A preview was successfully retrieved." } + } + } + }, + "/auth/pwdreset/request": { + "post": { + "description": "Reset a password", + "responses": { + "200": { + "description": "The password reset workflow was successfully started." + } + } + } + }, + "/auth/pwdreset/finalize": { + "get": { + "description": "Finish resetting a password", + "responses": { + "200": { "description": "The password was successfully reset." } + } + } + }, + "/graphql": { + "post": { + "summary": "GraphQL", + "description": "GraphQL endpoint", + "responses": { "default": { "description": "GraphQL endpoint" } } + } + } + } +} From e4bbf381ac70075c24b3dd21375e08296cabd482 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:28:11 +0000 Subject: [PATCH 02/69] fixes --- .github/workflows/rest-api-fuzzer.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index a69ab6821e..3365ebee2d 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -24,12 +24,12 @@ jobs: name: Build Restler Fuzzer runs-on: ubuntu-latest permissions: - packages: write # publishing container to GitHub registry + contents: read steps: - uses: actions/checkout@v4 with: repository: microsoft/restler-fuzzer - ref: ${{ env.RESTLER_VERSION }} + ref: v${{ env.RESTLER_VERSION }} path: 'restler-fuzzer' # The path to clone the repository under {{ github.workspace }} - name: Print environment variables run: printenv @@ -40,7 +40,7 @@ jobs: dotnet-version: ${{ env.DOTNET_VERSION }} - name: Restore NuGet packages - run: dotnet restore src/Restler.sln + run: dotnet restore ${{ github.workspace }}/restler-fuzzer/src/Restler.sln - name: Set up Python ${{ env.PYTHON_VERSION }} uses: actions/setup-python@v4 @@ -49,11 +49,11 @@ jobs: - name: Install engine (Python) dependencies run: | - pip install -r ./restler/requirements.txt + pip install -r ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt - name: Build RESTler drop run: | - python ./build-restler.py --dest_dir ${{ github.workspace }}/restler/restler + python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin/restler # - name: Set up Docker Buildx # uses: docker/setup-buildx-action@v3 # - name: Log in to the Container registry @@ -87,12 +87,14 @@ jobs: # steps: - uses: actions/checkout@v4 + with: + path: 'speckle-server' - name: Compile from OpenAPI # run: docker run --volume ${{ github.workspace }}/restlerConfig:/RESTler/restler/restlerConfig ${{ needs.build-restler-fuzzer.outputs.tags }} compile --api_spec utils/specifications/speckle-server.openapi.json run: | - ${{ github.workspace }}/restler/restler compile --api_spec utils/specifications/speckle-server.openapi.json + ${{ github.workspace }}/bin/restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json - name: Print the results - run: ls -lat ${{ github.workspace }}/restler/restler/restlerConfig + run: ls -lat ${{ github.workspace }}/restlerConfig # fuzz-rest-api-lite: # runs-on: ubuntu-latest From a026354e4c31d5966911d91cf56862eecfa73648 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:31:42 +0000 Subject: [PATCH 03/69] Update path of binary --- .github/workflows/rest-api-fuzzer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 3365ebee2d..cb0cf7f640 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -92,7 +92,7 @@ jobs: - name: Compile from OpenAPI # run: docker run --volume ${{ github.workspace }}/restlerConfig:/RESTler/restler/restlerConfig ${{ needs.build-restler-fuzzer.outputs.tags }} compile --api_spec utils/specifications/speckle-server.openapi.json run: | - ${{ github.workspace }}/bin/restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json + ${{ github.workspace }}/bin/restler/compiler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json - name: Print the results run: ls -lat ${{ github.workspace }}/restlerConfig From e66d2c288b47a10ecdf088d7e7f54994fcaec961 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:34:48 +0000 Subject: [PATCH 04/69] Update binary path again, and add names to steps --- .github/workflows/rest-api-fuzzer.yml | 44 ++++----------------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index cb0cf7f640..7acac6bca9 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -21,18 +21,17 @@ env: jobs: build-restler-fuzzer: - name: Build Restler Fuzzer + name: Fuzz test speckle-server REST API runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@v4 + name: Checkout RESTler Fuzzer with: repository: microsoft/restler-fuzzer ref: v${{ env.RESTLER_VERSION }} path: 'restler-fuzzer' # The path to clone the repository under {{ github.workspace }} - - name: Print environment variables - run: printenv - name: Setup .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 @@ -51,48 +50,17 @@ jobs: run: | pip install -r ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt - - name: Build RESTler drop + - name: Build RESTler run: | python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin/restler - # - name: Set up Docker Buildx - # uses: docker/setup-buildx-action@v3 - # - name: Log in to the Container registry - # uses: docker/login-action@v3.3.0 - # with: - # registry: ${{ env.REGISTRY }} - # username: ${{ github.actor }} - # password: ${{ secrets.GITHUB_TOKEN }} - # - name: Extract metadata (tags, labels) for Docker - # id: meta - # uses: docker/metadata-action@v5.5.1 - # with: - # tags: type=sha,format=long - # images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - # - name: Build and load preview-service Docker image - # uses: docker/build-push-action@v6 - # with: - # context: ${{ github.workspace }}/restler-fuzzer - # file: ${{ github.workspace }}/restler-fuzzer/Dockerfile # The Dockerfile for the restler-fuzzer - # push: true - # tags: ${{ steps.meta.outputs.tags }} - # cache-from: type=gha - # cache-to: type=gha,mode=max - # outputs: - # tags: ${{ steps.meta.outputs.tags }} - # compile-fuzzer-syntax: - # name: Compile Fuzzer Syntax - # runs-on: ubuntu-latest - # needs: build-restler-fuzzer - - # steps: - uses: actions/checkout@v4 + name: Checkout speckle-server with: path: 'speckle-server' - - name: Compile from OpenAPI - # run: docker run --volume ${{ github.workspace }}/restlerConfig:/RESTler/restler/restlerConfig ${{ needs.build-restler-fuzzer.outputs.tags }} compile --api_spec utils/specifications/speckle-server.openapi.json + - name: Compile RESTler grammar from OpenAPI specification run: | - ${{ github.workspace }}/bin/restler/compiler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json + ${{ github.workspace }}/bin/restler/restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json - name: Print the results run: ls -lat ${{ github.workspace }}/restlerConfig From 3e18153bc28e3bf8078e89a0c72b37c83396e6b8 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:36:41 +0000 Subject: [PATCH 05/69] More path fixes, too much nesting --- .github/workflows/rest-api-fuzzer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 7acac6bca9..9fdfe23b6e 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -52,7 +52,7 @@ jobs: - name: Build RESTler run: | - python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin/restler + python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin - uses: actions/checkout@v4 name: Checkout speckle-server From c8b96e43b7f60d6740e010bab667a04551866748 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:39:08 +0000 Subject: [PATCH 06/69] Add debugging output --- .github/workflows/rest-api-fuzzer.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 9fdfe23b6e..935bdcc24d 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -53,11 +53,16 @@ jobs: - name: Build RESTler run: | python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin + - name: Debug the built output + run: | + ls -la ${{ github.workspace }}/bin/restler + ls -la ${{ github.workspace }}/bin/restler/restler - uses: actions/checkout@v4 name: Checkout speckle-server with: path: 'speckle-server' + - name: Compile RESTler grammar from OpenAPI specification run: | ${{ github.workspace }}/bin/restler/restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json From 48b7d2fc020304948c72053c3be394319af2e6d6 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:42:32 +0000 Subject: [PATCH 07/69] it is case-sensitive fml --- .github/workflows/rest-api-fuzzer.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 935bdcc24d..690a2f9eb8 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -56,7 +56,7 @@ jobs: - name: Debug the built output run: | ls -la ${{ github.workspace }}/bin/restler - ls -la ${{ github.workspace }}/bin/restler/restler + ls -la ${{ github.workspace }}/bin/restler/Restler - uses: actions/checkout@v4 name: Checkout speckle-server @@ -65,7 +65,7 @@ jobs: - name: Compile RESTler grammar from OpenAPI specification run: | - ${{ github.workspace }}/bin/restler/restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json + ${{ github.workspace }}/bin/restler/Restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json - name: Print the results run: ls -lat ${{ github.workspace }}/restlerConfig From ea36cd9920295340ec2666fd4dd4e1db5d5c2abb Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:46:02 +0000 Subject: [PATCH 08/69] Restler documentation is inconsistent on the output dir and there are no logs --- .github/workflows/rest-api-fuzzer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 690a2f9eb8..0590beb5f4 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -67,7 +67,7 @@ jobs: run: | ${{ github.workspace }}/bin/restler/Restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json - name: Print the results - run: ls -lat ${{ github.workspace }}/restlerConfig + run: ls -lat ${{ github.workspace }}/Compile # fuzz-rest-api-lite: # runs-on: ubuntu-latest From 8ea40b3c9c54a66f2873e7e6db1eba9544aaace5 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:53:04 +0000 Subject: [PATCH 09/69] Now output the file content to allow configuration --- .github/workflows/rest-api-fuzzer.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 0590beb5f4..478a8c4b43 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -67,7 +67,14 @@ jobs: run: | ${{ github.workspace }}/bin/restler/Restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json - name: Print the results - run: ls -lat ${{ github.workspace }}/Compile + run: | + ls -lat ${{ github.workspace }}/Compile + echo "Engine settings:" + cat ${{ github.workspace }}/Compile/engine_settings.json + echo "Config:" + cat ${{ github.workspace }}/Compile/config.json + echo "Dictionary:" + cat ${{ github.workspace }}/Compile/dict.json # fuzz-rest-api-lite: # runs-on: ubuntu-latest From 968e4e7638107732c2310ee5d58bf03dab8947a0 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 19:21:13 +0000 Subject: [PATCH 10/69] Attempt to run speckle-server and test the API --- .github/workflows/rest-api-fuzzer.yml | 102 +++++++++++++++----------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 478a8c4b43..56bf50f217 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -19,12 +19,42 @@ env: DOTNET_VERSION: '6.0.x' jobs: - build-restler-fuzzer: name: Fuzz test speckle-server REST API runs-on: ubuntu-latest permissions: contents: read + + services: + postgres: + # Docker Hub image + image: postgres:16.4-bookworm@sha256:91f464e7ba0ad91a106c94cff079fb4384139291b8c0502fd36989cf2c788bbb + env: + POSTGRES_DB: fuzz_test + POSTGRES_PASSWORD: fuzz_test + POSTGRES_USER: fuzz_test + # Set health checks to wait until postgres has started + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + redis: + image: redis:7-alpine@sha256:c1e88455c85225310bbea54816e9c3f4b5295815e6dbf80c34d40afc6df28275 + ports: + - 6379:6379 + + minio: + image: minio/minio@sha256:1dce27c494a16bae114774f1cec295493f3613142713130c2d22dd5696be6ad3 + options: >- + --console-address ":9001" + ports: + - 9000:9000 + - 9001:9001 + steps: - uses: actions/checkout@v4 name: Checkout RESTler Fuzzer @@ -68,50 +98,40 @@ jobs: ${{ github.workspace }}/bin/restler/Restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json - name: Print the results run: | - ls -lat ${{ github.workspace }}/Compile + ls -la ${{ github.workspace }}/Compile + echo "" echo "Engine settings:" cat ${{ github.workspace }}/Compile/engine_settings.json + echo "" echo "Config:" cat ${{ github.workspace }}/Compile/config.json + echo "" echo "Dictionary:" cat ${{ github.workspace }}/Compile/dict.json - # fuzz-rest-api-lite: - # runs-on: ubuntu-latest - # needs: - # - compile-fuzzer-syntax - # timeout-minutes: 15 - - # services: - # postgres: - # # Docker Hub image - # image: postgres:16.4-bookworm@sha256:91f464e7ba0ad91a106c94cff079fb4384139291b8c0502fd36989cf2c788bbb - # env: - # POSTGRES_DB: fuzz_test - # POSTGRES_PASSWORD: fuzz_test - # POSTGRES_USER: fuzz_test - # # Set health checks to wait until postgres has started - # options: >- - # --health-cmd pg_isready - # --health-interval 10s - # --health-timeout 5s - # --health-retries 5 - # ports: - # - 5432:5432 - # # 4. Run the fuzzer in lite mode - # steps: - # - name: Compile from OpenAPI - # run: docker run ${{ needs.build-restler-fuzzer.outputs.tags }} compile --api_spec - # # 5. Print the results - - - - # fuzz-rest-api-full: - # runs-on: ubuntu-latest - # needs: - # - compile-fuzzer-syntax - # timeout-minutes: 45 - # steps: - # - name: Run RESTler Fuzzer - # run: docker run /RESTler/restler/restler.exe fuzz --api_spec --fuzz_mode full - # # 7. Print the results \ No newline at end of file + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + - name: Install dependencies + working-directory: packages/server + run: yarn install + - name: Build public packages + working-directory: packages/server + run: yarn build:public + - name: Build speckle-server + working-directory: packages/server + run: yarn build + - name: Run speckle-server + working-directory: packages/server + run: yarn start & + + - name: Run RESTler fuzz test + run: | + ${{ github.workspace }}/bin/restler/Restler test --grammar_file ${{ github.workspace }}/Compile/grammar.py --dictionary_file ${{ github.workspace }}/Compile/dict.json --settings ${{ github.workspace }}/Compile/engine_settings.json --no_ssl + + - name: Print the results + run: | + ls -la ${{ github.workspace }}/Test + find ${{ github.workspace }}/Test -type f -name "speccov.json" From 45674f0b99a87c535a66c6816dd356d744554cdc Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 19:29:05 +0000 Subject: [PATCH 11/69] fix minio service --- .github/workflows/rest-api-fuzzer.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 56bf50f217..832ae5a79a 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -49,11 +49,8 @@ jobs: minio: image: minio/minio@sha256:1dce27c494a16bae114774f1cec295493f3613142713130c2d22dd5696be6ad3 - options: >- - --console-address ":9001" ports: - 9000:9000 - - 9001:9001 steps: - uses: actions/checkout@v4 From bc4ca1732deafc0321adb62926543839685d19a4 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 19:32:18 +0000 Subject: [PATCH 12/69] Fix paths for yarn --- .github/workflows/rest-api-fuzzer.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 832ae5a79a..5c04a2fa25 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -109,19 +109,19 @@ jobs: - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'yarn' - name: Install dependencies - working-directory: packages/server + working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn install - name: Build public packages - working-directory: packages/server + working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn build:public - name: Build speckle-server - working-directory: packages/server + working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn build - name: Run speckle-server - working-directory: packages/server + working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn start & - name: Run RESTler fuzz test From 95fbf4ab413bb781f69931555593a09ea69e234d Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 19:36:57 +0000 Subject: [PATCH 13/69] set cache dependency path --- .github/workflows/rest-api-fuzzer.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 5c04a2fa25..ac0fe362b0 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -111,6 +111,7 @@ jobs: with: node-version: 22 cache: 'yarn' + cache-dependency-path: ${{ github.workspace }}/speckle-server/yarn.lock - name: Install dependencies working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn install From b2ebd47b5ea7500a45cc2dba1c094cb583d5ff0f Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 19:51:36 +0000 Subject: [PATCH 14/69] Add a yarn start to server package.json --- packages/server/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/server/package.json b/packages/server/package.json index 4c74a3f6aa..2cbe823349 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -38,7 +38,8 @@ "migrate": "yarn cli db migrate", "migrate:test": "cross-env NODE_ENV=test ts-node ./modules/cli/index.js db migrate", "gqlgen": "graphql-codegen --config codegen.yml", - "gqlgen:watch": "graphql-codegen --config codegen.yml --watch \"assets/**/*.graphql\"" + "gqlgen:watch": "graphql-codegen --config codegen.yml --watch \"assets/**/*.graphql\"", + "start": "cross-env NODE_ENV=production LOG_PRETTY=true node ./bin/ts-www" }, "dependencies": { "@apollo/client": "^3.7.0", From 8686c0013c7d439ea74bc834cc5ae62b6d00ced9 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:10:05 +0000 Subject: [PATCH 15/69] Caching --- .github/workflows/rest-api-fuzzer.yml | 57 +++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index ac0fe362b0..bf3ac6e870 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -30,9 +30,9 @@ jobs: # Docker Hub image image: postgres:16.4-bookworm@sha256:91f464e7ba0ad91a106c94cff079fb4384139291b8c0502fd36989cf2c788bbb env: - POSTGRES_DB: fuzz_test - POSTGRES_PASSWORD: fuzz_test - POSTGRES_USER: fuzz_test + POSTGRES_DB: speckle + POSTGRES_PASSWORD: speckle + POSTGRES_USER: speckle # Set health checks to wait until postgres has started options: >- --health-cmd pg_isready @@ -53,7 +53,16 @@ jobs: - 9000:9000 steps: + - name: Restore cached Restler + id: cache-restler-restore + uses: actions/cache/restore@v4 + with: + path: | + ${{ github.workspace }}/bin/restler + key: restler-fuzzer-${{ env.RESTLER_VERSION }} + - uses: actions/checkout@v4 + if: steps.cache-restler-restore.outputs.cache-hit != 'true' name: Checkout RESTler Fuzzer with: repository: microsoft/restler-fuzzer @@ -61,39 +70,67 @@ jobs: path: 'restler-fuzzer' # The path to clone the repository under {{ github.workspace }} - name: Setup .NET ${{ env.DOTNET_VERSION }} + if: steps.cache-restler-restore.outputs.cache-hit != 'true' uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} + cache: true + cache-dependency-path: ${{ github.workspace }}/restler-fuzzer/src/Restler.sln - name: Restore NuGet packages + if: steps.cache-restler-restore.outputs.cache-hit != 'true' run: dotnet restore ${{ github.workspace }}/restler-fuzzer/src/Restler.sln - name: Set up Python ${{ env.PYTHON_VERSION }} + if: steps.cache-restler-restore.outputs.cache-hit != 'true' uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' + cache-dependency-path: ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt - name: Install engine (Python) dependencies + if: steps.cache-restler-restore.outputs.cache-hit != 'true' run: | pip install -r ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt - name: Build RESTler + if: steps.cache-restler-restore.outputs.cache-hit != 'true' run: | python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin + - name: Debug the built output run: | ls -la ${{ github.workspace }}/bin/restler ls -la ${{ github.workspace }}/bin/restler/Restler + - name: Save Restler + id: cache-restler-save + uses: actions/cache/save@v4 + with: + path: | + ${{ github.workspace }}/bin/restler + key: ${{ steps.cache-restler-restore.outputs.cache-primary-key }} + - uses: actions/checkout@v4 name: Checkout speckle-server with: path: 'speckle-server' + - name: Restore cached Grammar + id: cache-grammar-restore + uses: actions/cache/restore@v4 + with: + path: | + ${{ github.workspace }}/Compile + key: restler-grammar-${{ hashFiles('speckle-server/utils/specifications/speckle-server.openapi.json') }} + - name: Compile RESTler grammar from OpenAPI specification + if: steps.cache-grammar-restore.outputs.cache-hit != 'true' run: | ${{ github.workspace }}/bin/restler/Restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json - - name: Print the results + + - name: Print the Restler configuration run: | ls -la ${{ github.workspace }}/Compile echo "" @@ -106,6 +143,14 @@ jobs: echo "Dictionary:" cat ${{ github.workspace }}/Compile/dict.json + - name: Save Grammar + id: cache-grammar-save + uses: actions/cache/save@v4 + with: + path: | + ${{ github.workspace }}/Compile + key: ${{ steps.cache-grammar-restore.outputs.cache-primary-key }} + - name: Install Node.js uses: actions/setup-node@v4 with: @@ -121,6 +166,10 @@ jobs: - name: Build speckle-server working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn build + - name: Configure speckle-server + working-directory: ${{ github.workspace }}/speckle-server/packages/server + run: | + cp .env-example .env - name: Run speckle-server working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn start & From 3d20d7a09cfaa68c90350e70c5a2c1e845ecf2cb Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:25:12 +0000 Subject: [PATCH 16/69] configure env vars for fuzz test --- .github/workflows/rest-api-fuzzer.yml | 2 +- setup/fuzzer/.env.fuzzer-example | 35 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 setup/fuzzer/.env.fuzzer-example diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index bf3ac6e870..0865da7303 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -169,7 +169,7 @@ jobs: - name: Configure speckle-server working-directory: ${{ github.workspace }}/speckle-server/packages/server run: | - cp .env-example .env + cp ${{ github.workspace }}/speckle-server/setup/fuzzer/.env.fuzzer-example .env - name: Run speckle-server working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn start & diff --git a/setup/fuzzer/.env.fuzzer-example b/setup/fuzzer/.env.fuzzer-example new file mode 100644 index 0000000000..ac02377b2e --- /dev/null +++ b/setup/fuzzer/.env.fuzzer-example @@ -0,0 +1,35 @@ +# BIND_ADDRESS="127.0.0.1" +PORT=3000 + +CANONICAL_URL="http://127.0.0.1:3000" +SESSION_SECRET="-> FILL IN <-" + +REDIS_URL="redis://127.0.0.1:6379" + +USE_FRONTEND_2=true +FRONTEND_ORIGIN="http://127.0.0.1:8081" + +ONBOARDING_STREAM_URL=https://latest.speckle.systems/projects/843d07eb10 + +ONBOARDING_STREAM_CACHE_BUST_NUMBER=1 + +ENABLE_FE2_MESSAGING=false + +POSTGRES_URL="127.0.0.1" +POSTGRES_USER="fuzz_test" +POSTGRES_PASSWORD="fuzz_test" +POSTGRES_DB="fuzz_test" + +S3_ENDPOINT="http://127.0.0.1:9000" +S3_ACCESS_KEY="minioadmin" +S3_SECRET_KEY="minioadmin" +S3_BUCKET="speckle-server" +S3_CREATE_BUCKET="true" + +EMAIL=false +EMAIL_HOST="127.0.0.1" +EMAIL_FROM="no-reply@example.org" +EMAIL_PORT="1025" + +DISABLE_NOTIFICATIONS_CONSUMPTION=true +STRATEGY_LOCAL=true From a030b22d0e26c07a13f08b128998dcbd56a0c178 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:29:21 +0000 Subject: [PATCH 17/69] Printing results --- .github/workflows/rest-api-fuzzer.yml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 0865da7303..2dc3cb6dd7 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -181,4 +181,24 @@ jobs: - name: Print the results run: | ls -la ${{ github.workspace }}/Test - find ${{ github.workspace }}/Test -type f -name "speccov.json" + echo "" + echo "Engine stderr:" + cat ${{ github.workspace }}/Test/EngineStdErr.txt + echo "" + echo "Engine stdout:" + cat ${{ github.workspace }}/Test/EngineStdOut.txt + echo "" + echo "Results analyzer stderr:" + cat ${{ github.workspace }}/Test/ResultsAnalyzerStdErr.txt + echo "" + echo "Results analyzer stdout:" + cat ${{ github.workspace }}/Test/ResultsAnalyzerStdOut.txt + echo "" + echo "Coverage failures to investigate:" + cat ${{ github.workspace }}/Test/coverage_failures_to_investigate.txt + echo "" + echo "Restler logs:" + cat ${{ github.workspace }}/Test/restler-*.log + echo "" + echo "Coverage report:" + cat "$(find ${{ github.workspace }}/Test -type f -name "speccov.json")" From 272b9fae86dcde4ab1a1813e144a6a7cf332d6ac Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:44:33 +0000 Subject: [PATCH 18/69] caching was too agressive - override default settings --- .github/workflows/rest-api-fuzzer.yml | 30 ++++++++----------- ....fuzzer-example => .env.fuzz-test-example} | 0 setup/fuzzer/settings.restler.json | 6 ++++ 3 files changed, 19 insertions(+), 17 deletions(-) rename setup/fuzzer/{.env.fuzzer-example => .env.fuzz-test-example} (100%) create mode 100644 setup/fuzzer/settings.restler.json diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 2dc3cb6dd7..a58ff87b3e 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -30,9 +30,9 @@ jobs: # Docker Hub image image: postgres:16.4-bookworm@sha256:91f464e7ba0ad91a106c94cff079fb4384139291b8c0502fd36989cf2c788bbb env: - POSTGRES_DB: speckle - POSTGRES_PASSWORD: speckle - POSTGRES_USER: speckle + POSTGRES_DB: fuzz_test + POSTGRES_PASSWORD: fuzz_test + POSTGRES_USER: fuzz_test # Set health checks to wait until postgres has started options: >- --health-cmd pg_isready @@ -53,6 +53,13 @@ jobs: - 9000:9000 steps: + - uses: actions/checkout@v4 + name: Checkout RESTler Fuzzer + with: + repository: microsoft/restler-fuzzer + ref: v${{ env.RESTLER_VERSION }} + path: 'restler-fuzzer' # The path to clone the repository within the {{ github.workspace }} directory + - name: Restore cached Restler id: cache-restler-restore uses: actions/cache/restore@v4 @@ -61,16 +68,7 @@ jobs: ${{ github.workspace }}/bin/restler key: restler-fuzzer-${{ env.RESTLER_VERSION }} - - uses: actions/checkout@v4 - if: steps.cache-restler-restore.outputs.cache-hit != 'true' - name: Checkout RESTler Fuzzer - with: - repository: microsoft/restler-fuzzer - ref: v${{ env.RESTLER_VERSION }} - path: 'restler-fuzzer' # The path to clone the repository under {{ github.workspace }} - - name: Setup .NET ${{ env.DOTNET_VERSION }} - if: steps.cache-restler-restore.outputs.cache-hit != 'true' uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} @@ -78,11 +76,9 @@ jobs: cache-dependency-path: ${{ github.workspace }}/restler-fuzzer/src/Restler.sln - name: Restore NuGet packages - if: steps.cache-restler-restore.outputs.cache-hit != 'true' run: dotnet restore ${{ github.workspace }}/restler-fuzzer/src/Restler.sln - name: Set up Python ${{ env.PYTHON_VERSION }} - if: steps.cache-restler-restore.outputs.cache-hit != 'true' uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} @@ -90,7 +86,6 @@ jobs: cache-dependency-path: ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt - name: Install engine (Python) dependencies - if: steps.cache-restler-restore.outputs.cache-hit != 'true' run: | pip install -r ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt @@ -105,6 +100,7 @@ jobs: ls -la ${{ github.workspace }}/bin/restler/Restler - name: Save Restler + if: steps.cache-restler-restore.outputs.cache-hit != 'true' id: cache-restler-save uses: actions/cache/save@v4 with: @@ -169,14 +165,14 @@ jobs: - name: Configure speckle-server working-directory: ${{ github.workspace }}/speckle-server/packages/server run: | - cp ${{ github.workspace }}/speckle-server/setup/fuzzer/.env.fuzzer-example .env + cp ${{ github.workspace }}/speckle-server/setup/fuzzer/.env.fuzz-test-example .env - name: Run speckle-server working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn start & - name: Run RESTler fuzz test run: | - ${{ github.workspace }}/bin/restler/Restler test --grammar_file ${{ github.workspace }}/Compile/grammar.py --dictionary_file ${{ github.workspace }}/Compile/dict.json --settings ${{ github.workspace }}/Compile/engine_settings.json --no_ssl + ${{ github.workspace }}/bin/restler/Restler test --grammar_file ${{ github.workspace }}/Compile/grammar.py --dictionary_file ${{ github.workspace }}/Compile/dict.json --settings ${{ github.workspace }}/speckle-server/setup/fuzzer/settings.restler.json --no_ssl - name: Print the results run: | diff --git a/setup/fuzzer/.env.fuzzer-example b/setup/fuzzer/.env.fuzz-test-example similarity index 100% rename from setup/fuzzer/.env.fuzzer-example rename to setup/fuzzer/.env.fuzz-test-example diff --git a/setup/fuzzer/settings.restler.json b/setup/fuzzer/settings.restler.json new file mode 100644 index 0000000000..3a0b83ef1e --- /dev/null +++ b/setup/fuzzer/settings.restler.json @@ -0,0 +1,6 @@ +{ + "per_resource_settings": {}, + "max_combinations": 20, + "target_ip": "127.0.0.1", + "target_port": 3000 +} From d0c0c6083b9d534ef34b884ec29340466daa0067 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:54:40 +0000 Subject: [PATCH 19/69] overwrite minio entrypoint --- .github/workflows/rest-api-fuzzer.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index a58ff87b3e..744b07f5fe 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -49,6 +49,8 @@ jobs: minio: image: minio/minio@sha256:1dce27c494a16bae114774f1cec295493f3613142713130c2d22dd5696be6ad3 + options: >- + --entrypoint "/usr/bin/docker-entrypoint.sh server" ports: - 9000:9000 @@ -170,7 +172,7 @@ jobs: working-directory: ${{ github.workspace }}/speckle-server/packages/server run: yarn start & - - name: Run RESTler fuzz test + - name: Run RESTler coverage test run: | ${{ github.workspace }}/bin/restler/Restler test --grammar_file ${{ github.workspace }}/Compile/grammar.py --dictionary_file ${{ github.workspace }}/Compile/dict.json --settings ${{ github.workspace }}/speckle-server/setup/fuzzer/settings.restler.json --no_ssl From e19abdd0ce10df140bdd1ba06d836233cc62bf1b Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:18:38 +0000 Subject: [PATCH 20/69] More bug fixing --- .github/workflows/rest-api-fuzzer.yml | 30 +++++---------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 744b07f5fe..e56ce78dff 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -47,13 +47,6 @@ jobs: ports: - 6379:6379 - minio: - image: minio/minio@sha256:1dce27c494a16bae114774f1cec295493f3613142713130c2d22dd5696be6ad3 - options: >- - --entrypoint "/usr/bin/docker-entrypoint.sh server" - ports: - - 9000:9000 - steps: - uses: actions/checkout@v4 name: Checkout RESTler Fuzzer @@ -62,14 +55,6 @@ jobs: ref: v${{ env.RESTLER_VERSION }} path: 'restler-fuzzer' # The path to clone the repository within the {{ github.workspace }} directory - - name: Restore cached Restler - id: cache-restler-restore - uses: actions/cache/restore@v4 - with: - path: | - ${{ github.workspace }}/bin/restler - key: restler-fuzzer-${{ env.RESTLER_VERSION }} - - name: Setup .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: @@ -92,7 +77,6 @@ jobs: pip install -r ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt - name: Build RESTler - if: steps.cache-restler-restore.outputs.cache-hit != 'true' run: | python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin @@ -101,15 +85,6 @@ jobs: ls -la ${{ github.workspace }}/bin/restler ls -la ${{ github.workspace }}/bin/restler/Restler - - name: Save Restler - if: steps.cache-restler-restore.outputs.cache-hit != 'true' - id: cache-restler-save - uses: actions/cache/save@v4 - with: - path: | - ${{ github.workspace }}/bin/restler - key: ${{ steps.cache-restler-restore.outputs.cache-primary-key }} - - uses: actions/checkout@v4 name: Checkout speckle-server with: @@ -149,6 +124,11 @@ jobs: ${{ github.workspace }}/Compile key: ${{ steps.cache-grammar-restore.outputs.cache-primary-key }} + - name: Minio + # Minio requires a command to be passed to the container, and github action services do not allow commands to be passed to containers. So we create the container manually. + run: | + docker create --name minio -p 9000:9000 --network-alias minio minio/minio@sha256:1dce27c494a16bae114774f1cec295493f3613142713130c2d22dd5696be6ad3 server + - name: Install Node.js uses: actions/setup-node@v4 with: From 2460fb9218cac4e4304242588cd419cd609a817b Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:20:49 +0000 Subject: [PATCH 21/69] remove network alias --- .github/workflows/rest-api-fuzzer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index e56ce78dff..d82ab9f95f 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -127,7 +127,7 @@ jobs: - name: Minio # Minio requires a command to be passed to the container, and github action services do not allow commands to be passed to containers. So we create the container manually. run: | - docker create --name minio -p 9000:9000 --network-alias minio minio/minio@sha256:1dce27c494a16bae114774f1cec295493f3613142713130c2d22dd5696be6ad3 server + docker create --name minio -p 9000:9000 minio/minio@sha256:1dce27c494a16bae114774f1cec295493f3613142713130c2d22dd5696be6ad3 server - name: Install Node.js uses: actions/setup-node@v4 From 6cba30d48f3c4e51b5bbdcf1961a270c6de734f1 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:42:16 +0000 Subject: [PATCH 22/69] Bump OpenAPI specification version and add servers property --- .github/workflows/rest-api-fuzzer.yml | 35 +++++++++++++++---- .../speckle-server.openapi.json | 5 ++- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index d82ab9f95f..c300f4fabf 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -160,23 +160,44 @@ jobs: run: | ls -la ${{ github.workspace }}/Test echo "" - echo "Engine stderr:" + echo "############################################" + echo "# Engine stderr #" + echo "############################################" + echo "" cat ${{ github.workspace }}/Test/EngineStdErr.txt echo "" - echo "Engine stdout:" + echo "############################################" + echo "# Engine stdout #" + echo "############################################" + echo "" cat ${{ github.workspace }}/Test/EngineStdOut.txt echo "" - echo "Results analyzer stderr:" + echo "############################################" + echo "# Results analyzer stderr #" + echo "############################################" + echo "" cat ${{ github.workspace }}/Test/ResultsAnalyzerStdErr.txt echo "" - echo "Results analyzer stdout:" + echo "############################################" + echo "# Results analyzer stdout #" + echo "############################################" + echo "" cat ${{ github.workspace }}/Test/ResultsAnalyzerStdOut.txt echo "" - echo "Coverage failures to investigate:" + echo "############################################" + echo "# Coverage failures to investigate #" + echo "############################################" + echo "" cat ${{ github.workspace }}/Test/coverage_failures_to_investigate.txt echo "" - echo "Restler logs:" + echo "############################################" + echo "# Restler logs #" + echo "############################################" + echo "" cat ${{ github.workspace }}/Test/restler-*.log echo "" - echo "Coverage report:" + echo "############################################" + echo "# Coverage report #" + echo "############################################" + echo "" cat "$(find ${{ github.workspace }}/Test -type f -name "speccov.json")" diff --git a/utils/specifications/speckle-server.openapi.json b/utils/specifications/speckle-server.openapi.json index 927d45b8c9..823de340b4 100644 --- a/utils/specifications/speckle-server.openapi.json +++ b/utils/specifications/speckle-server.openapi.json @@ -1,8 +1,11 @@ { - "swagger": "2.0", + "swagger": "3.1.1", "basePath": "/", "info": { "title": "Speckle.", "version": "dev" }, "definitions": {}, + "servers": [ + { "url": "http://localhost:3000", "description": "Development and Testing server" } + ], "paths": { "/explorer": { "get": { From 198a8ccff523c04c2c953bd6c52faab97bb8d04e Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:54:54 +0000 Subject: [PATCH 23/69] Override host when testing --- .github/workflows/rest-api-fuzzer.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index c300f4fabf..589ed4bdc7 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -154,7 +154,13 @@ jobs: - name: Run RESTler coverage test run: | - ${{ github.workspace }}/bin/restler/Restler test --grammar_file ${{ github.workspace }}/Compile/grammar.py --dictionary_file ${{ github.workspace }}/Compile/dict.json --settings ${{ github.workspace }}/speckle-server/setup/fuzzer/settings.restler.json --no_ssl + ${{ github.workspace }}/bin/restler/Restler test \ + --grammar_file ${{ github.workspace }}/Compile/grammar.py \ + --dictionary_file ${{ github.workspace }}/Compile/dict.json \ + --settings ${{ github.workspace }}/speckle-server/setup/fuzzer/settings.restler.json \ + --no_ssl \ + --target_ip 127.0.0.1 \ + --target_port 3000 - name: Print the results run: | @@ -201,3 +207,8 @@ jobs: echo "############################################" echo "" cat "$(find ${{ github.workspace }}/Test -type f -name "speccov.json")" + + - name: Print Minio logs + if: always() + run: | + docker logs minio From b76f20e64cc5cd093a8a316a8dc95fc934ef1613 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 22:04:24 +0000 Subject: [PATCH 24/69] Swap to docker compose --- .github/workflows/rest-api-fuzzer.yml | 31 ++++----------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 589ed4bdc7..7e62827330 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -25,28 +25,6 @@ jobs: permissions: contents: read - services: - postgres: - # Docker Hub image - image: postgres:16.4-bookworm@sha256:91f464e7ba0ad91a106c94cff079fb4384139291b8c0502fd36989cf2c788bbb - env: - POSTGRES_DB: fuzz_test - POSTGRES_PASSWORD: fuzz_test - POSTGRES_USER: fuzz_test - # Set health checks to wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - - redis: - image: redis:7-alpine@sha256:c1e88455c85225310bbea54816e9c3f4b5295815e6dbf80c34d40afc6df28275 - ports: - - 6379:6379 - steps: - uses: actions/checkout@v4 name: Checkout RESTler Fuzzer @@ -124,10 +102,9 @@ jobs: ${{ github.workspace }}/Compile key: ${{ steps.cache-grammar-restore.outputs.cache-primary-key }} - - name: Minio - # Minio requires a command to be passed to the container, and github action services do not allow commands to be passed to containers. So we create the container manually. + - name: Docker Compose up run: | - docker create --name minio -p 9000:9000 minio/minio@sha256:1dce27c494a16bae114774f1cec295493f3613142713130c2d22dd5696be6ad3 server + docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml up --detach - name: Install Node.js uses: actions/setup-node@v4 @@ -208,7 +185,7 @@ jobs: echo "" cat "$(find ${{ github.workspace }}/Test -type f -name "speccov.json")" - - name: Print Minio logs + - name: Print Docker Compose logs if: always() run: | - docker logs minio + docker compose logs From e68da6ae439fd96242d9358fe64958e067632b92 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 22:05:42 +0000 Subject: [PATCH 25/69] fix postgres creds --- setup/fuzzer/.env.fuzz-test-example | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/fuzzer/.env.fuzz-test-example b/setup/fuzzer/.env.fuzz-test-example index ac02377b2e..7b6202a79a 100644 --- a/setup/fuzzer/.env.fuzz-test-example +++ b/setup/fuzzer/.env.fuzz-test-example @@ -16,9 +16,9 @@ ONBOARDING_STREAM_CACHE_BUST_NUMBER=1 ENABLE_FE2_MESSAGING=false POSTGRES_URL="127.0.0.1" -POSTGRES_USER="fuzz_test" -POSTGRES_PASSWORD="fuzz_test" -POSTGRES_DB="fuzz_test" +POSTGRES_USER="speckle" +POSTGRES_PASSWORD="speckle" +POSTGRES_DB="speckle" S3_ENDPOINT="http://127.0.0.1:9000" S3_ACCESS_KEY="minioadmin" From c8002de40108ca0a29183746cb68dbf8c70ff64e Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 22:18:32 +0000 Subject: [PATCH 26/69] Wait for server to start running, and always print restler output --- .github/workflows/rest-api-fuzzer.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 7e62827330..965cb447a0 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -127,7 +127,9 @@ jobs: cp ${{ github.workspace }}/speckle-server/setup/fuzzer/.env.fuzz-test-example .env - name: Run speckle-server working-directory: ${{ github.workspace }}/speckle-server/packages/server - run: yarn start & + run: | + yarn start & + sleep 20 - name: Run RESTler coverage test run: | @@ -140,6 +142,7 @@ jobs: --target_port 3000 - name: Print the results + if: always() run: | ls -la ${{ github.workspace }}/Test echo "" @@ -188,4 +191,4 @@ jobs: - name: Print Docker Compose logs if: always() run: | - docker compose logs + docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml logs From fe446d5ec80fe76b6e5fb90191d29f888d0361ad Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 22:35:57 +0000 Subject: [PATCH 27/69] Wait until server is responding --- .github/workflows/rest-api-fuzzer.yml | 30 +++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 965cb447a0..e71ef139c4 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -129,17 +129,21 @@ jobs: working-directory: ${{ github.workspace }}/speckle-server/packages/server run: | yarn start & - sleep 20 + until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do + echo "Waiting a further 3 seconds for speckle-server to start..." + sleep 3 + done - name: Run RESTler coverage test run: | + curl --head --fail http://127.0.0.1:3000/readiness ${{ github.workspace }}/bin/restler/Restler test \ - --grammar_file ${{ github.workspace }}/Compile/grammar.py \ - --dictionary_file ${{ github.workspace }}/Compile/dict.json \ - --settings ${{ github.workspace }}/speckle-server/setup/fuzzer/settings.restler.json \ + --grammar_file "${{ github.workspace }}/Compile/grammar.py" \ + --dictionary_file "${{ github.workspace }}/Compile/dict.json" \ + --settings "${{ github.workspace }}/speckle-server/setup/fuzzer/settings.restler.json" \ --no_ssl \ - --target_ip 127.0.0.1 \ - --target_port 3000 + --target_ip "127.0.0.1" \ + --target_port "3000" - name: Print the results if: always() @@ -150,43 +154,43 @@ jobs: echo "# Engine stderr #" echo "############################################" echo "" - cat ${{ github.workspace }}/Test/EngineStdErr.txt + cat ${{ github.workspace }}/Test/EngineStdErr.txt || true echo "" echo "############################################" echo "# Engine stdout #" echo "############################################" echo "" - cat ${{ github.workspace }}/Test/EngineStdOut.txt + cat ${{ github.workspace }}/Test/EngineStdOut.txt || true echo "" echo "############################################" echo "# Results analyzer stderr #" echo "############################################" echo "" - cat ${{ github.workspace }}/Test/ResultsAnalyzerStdErr.txt + cat ${{ github.workspace }}/Test/ResultsAnalyzerStdErr.txt || true echo "" echo "############################################" echo "# Results analyzer stdout #" echo "############################################" echo "" - cat ${{ github.workspace }}/Test/ResultsAnalyzerStdOut.txt + cat ${{ github.workspace }}/Test/ResultsAnalyzerStdOut.txt || true echo "" echo "############################################" echo "# Coverage failures to investigate #" echo "############################################" echo "" - cat ${{ github.workspace }}/Test/coverage_failures_to_investigate.txt + cat ${{ github.workspace }}/Test/coverage_failures_to_investigate.txt || true echo "" echo "############################################" echo "# Restler logs #" echo "############################################" echo "" - cat ${{ github.workspace }}/Test/restler-*.log + cat ${{ github.workspace }}/Test/restler-*.log || true echo "" echo "############################################" echo "# Coverage report #" echo "############################################" echo "" - cat "$(find ${{ github.workspace }}/Test -type f -name "speccov.json")" + cat "$(find ${{ github.workspace }}/Test -type f -name "speccov.json")" || true - name: Print Docker Compose logs if: always() From ca4633696c1c35d3e0cac5ec1a80fb0cf61c28cf Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 30 Dec 2024 22:50:04 +0000 Subject: [PATCH 28/69] Do not fail on decoding of responses being unexpected unicode --- .github/workflows/rest-api-fuzzer.yml | 7 +++++++ setup/fuzzer/settings.restler.json | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index e71ef139c4..c825d362e0 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -127,6 +127,7 @@ jobs: cp ${{ github.workspace }}/speckle-server/setup/fuzzer/.env.fuzz-test-example .env - name: Run speckle-server working-directory: ${{ github.workspace }}/speckle-server/packages/server + timeout-minutes: 1 run: | yarn start & until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do @@ -191,6 +192,12 @@ jobs: echo "############################################" echo "" cat "$(find ${{ github.workspace }}/Test -type f -name "speccov.json")" || true + echo "" + echo "############################################" + echo "# Network testing logs #" + echo "############################################" + echo "" + cat "$(find ${{ github.workspace }}/Test -type f -name "network.testing.*.txt")" || true - name: Print Docker Compose logs if: always() diff --git a/setup/fuzzer/settings.restler.json b/setup/fuzzer/settings.restler.json index 3a0b83ef1e..68f9340260 100644 --- a/setup/fuzzer/settings.restler.json +++ b/setup/fuzzer/settings.restler.json @@ -2,5 +2,6 @@ "per_resource_settings": {}, "max_combinations": 20, "target_ip": "127.0.0.1", - "target_port": 3000 + "target_port": 3000, + "ignore_decoding_failures": true } From f09ce259240ac193e584a21c8dd3048a2e89675a Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 10:45:14 +0000 Subject: [PATCH 29/69] Two step creation of grammar - update openapi specification for images in response body --- .github/workflows/rest-api-fuzzer.yml | 90 ++++++++++++++----- setup/fuzzer/config.restler.json | 23 +++++ setup/fuzzer/dictionary.restler.json | 19 ++++ setup/fuzzer/settings.restler.json | 3 +- .../fuzzer}/speckle-server.openapi.json | 58 ++++++------ 5 files changed, 144 insertions(+), 49 deletions(-) create mode 100644 setup/fuzzer/config.restler.json create mode 100644 setup/fuzzer/dictionary.restler.json rename {utils/specifications => setup/fuzzer}/speckle-server.openapi.json (91%) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index c825d362e0..b71798da06 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -2,14 +2,12 @@ name: REST API Fuzz Test on: workflow_dispatch: - pull_request: # Pushing a new commit to the HEAD ref of a pull request will trigger the “synchronize” event + # schedule: + # - cron: "15 4 3 * *" # Run at 4:15am on the 3rd of every month + pull_request: paths: - - .yarnrc.yml . - - .yarn - - package.json - '.github/workflows/rest-api-fuzzer.yml' - - 'packages/server/**/*' - - 'packages/shared/**/*' + - 'setup/fuzzer/**/*' env: BUILD_CONFIGURATION: Release @@ -68,31 +66,81 @@ jobs: with: path: 'speckle-server' - - name: Restore cached Grammar - id: cache-grammar-restore + - name: Restore cached Restler configuration + id: cache-config-restore uses: actions/cache/restore@v4 with: path: | - ${{ github.workspace }}/Compile - key: restler-grammar-${{ hashFiles('speckle-server/utils/specifications/speckle-server.openapi.json') }} + ${{ github.workspace }}/restlerConfig + key: restler-config-${{ hashFiles('speckle-server/setup/fuzzer/speckle-server.openapi.json') }} - - name: Compile RESTler grammar from OpenAPI specification - if: steps.cache-grammar-restore.outputs.cache-hit != 'true' + - name: Generate RESTler config from OpenAPI specification + if: steps.cache-config-restore.outputs.cache-hit != 'true' run: | - ${{ github.workspace }}/bin/restler/Restler compile --api_spec ${{ github.workspace }}/speckle-server/utils/specifications/speckle-server.openapi.json + ${{ github.workspace }}/bin/restler/Restler generate_config --specs ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle-server.openapi.json - name: Print the Restler configuration run: | - ls -la ${{ github.workspace }}/Compile + ls -la ${{ github.workspace }} + ls -la ${{ github.workspace }}/restlerConfig echo "" - echo "Engine settings:" - cat ${{ github.workspace }}/Compile/engine_settings.json + echo "############################################" + echo "# Engine settings #" + echo "# To customize, copy and save this file to #" + echo "# setup/fuzzer/settings.restler.json #" + echo "############################################" + echo "" + cat ${{ github.workspace }}/restlerConfig/engine_settings.json echo "" - echo "Config:" - cat ${{ github.workspace }}/Compile/config.json + echo "############################################" + echo "# Config #" + echo "# To customize, copy and save this file to #" + echo "# setup/fuzzer/config.restler.json #" + echo "############################################" + echo "" + cat ${{ github.workspace }}/restlerConfig/config.json + echo "" + echo "############################################" + echo "# Dictionary #" + echo "# To customize, copy and save this file to #" + echo "# setup/fuzzer/dictionary.restler.json #" + echo "############################################" + echo "" + cat ${{ github.workspace }}/restlerConfig/dict.json + echo "" + echo "############################################" + echo "# Annotations #" + echo "# To customize, copy and save this file to #" + echo "# setup/fuzzer/annotations.restler.json #" + echo "############################################" echo "" - echo "Dictionary:" - cat ${{ github.workspace }}/Compile/dict.json + cat ${{ github.workspace }}/restlerConfig/annotations.json + + - name: Save Restler Config + id: cache-config-save + uses: actions/cache/save@v4 + with: + path: | + ${{ github.workspace }}/restlerConfig + key: ${{ steps.cache-config-restore.outputs.cache-primary-key }} + + - name: Restore cached Restler grammar + id: cache-grammar-restore + uses: actions/cache/restore@v4 + with: + path: | + ${{ github.workspace }}/Compile + key: restler-grammar-${{ hashFiles('speckle-server/setup/fuzzer/*.json') }} + + - name: Generate RESTler grammar from Restler config + if: steps.cache-grammar-restore.outputs.cache-hit != 'true' + run: | + ${{ github.workspace }}/bin/restler/Restler compile ${{ github.workspace }}/speckle-server/setup/fuzzer/config.restler.json + + - name: Print the contents of the Restler compile directory + run: | + ls -la ${{ github.workspace }} + ls -la ${{ github.workspace }}/Compile - name: Save Grammar id: cache-grammar-save @@ -140,7 +188,7 @@ jobs: curl --head --fail http://127.0.0.1:3000/readiness ${{ github.workspace }}/bin/restler/Restler test \ --grammar_file "${{ github.workspace }}/Compile/grammar.py" \ - --dictionary_file "${{ github.workspace }}/Compile/dict.json" \ + --dictionary_file "${{ github.workspace }}/speckle-server/setup/fuzzer/dictionary.restler.json" \ --settings "${{ github.workspace }}/speckle-server/setup/fuzzer/settings.restler.json" \ --no_ssl \ --target_ip "127.0.0.1" \ diff --git a/setup/fuzzer/config.restler.json b/setup/fuzzer/config.restler.json new file mode 100644 index 0000000000..7648512840 --- /dev/null +++ b/setup/fuzzer/config.restler.json @@ -0,0 +1,23 @@ +{ + "SwaggerSpecFilePath": [ + "/home/runner/work/speckle-server/speckle-server/speckle-server/utils/specifications/speckle-server.openapi.json" + ], + "GrammarOutputDirectoryPath": "/home/runner/work/speckle-server/speckle-server/Compile", + "CustomDictionaryFilePath": "/home/runner/work/speckle-server/speckle-server/Compile/defaultDict.json", + "IncludeOptionalParameters": true, + "UseHeaderExamples": true, + "UsePathExamples": false, + "UseQueryExamples": true, + "UseBodyExamples": true, + "UseAllExamplePayloads": false, + "DiscoverExamples": false, + "ExamplesDirectory": "", + "DataFuzzing": true, + "ReadOnlyFuzz": false, + "ResolveQueryDependencies": true, + "ResolveBodyDependencies": true, + "ResolveHeaderDependencies": false, + "UseRefreshableToken": true, + "AllowGetProducers": false, + "TrackFuzzedParameterNames": false +} diff --git a/setup/fuzzer/dictionary.restler.json b/setup/fuzzer/dictionary.restler.json new file mode 100644 index 0000000000..826669edda --- /dev/null +++ b/setup/fuzzer/dictionary.restler.json @@ -0,0 +1,19 @@ +{ + "restler_fuzzable_string": ["fuzzstring"], + "restler_fuzzable_string_unquoted": [], + "restler_fuzzable_datetime": ["2019-06-26T20:20:39+00:00"], + "restler_fuzzable_datetime_unquoted": [], + "restler_fuzzable_date": ["2019-06-26"], + "restler_fuzzable_date_unquoted": [], + "restler_fuzzable_uuid4": ["566048da-ed19-4cd3-8e0a-b7e0e1ec4d72"], + "restler_fuzzable_uuid4_unquoted": [], + "restler_fuzzable_int": ["1"], + "restler_fuzzable_number": ["1.23"], + "restler_fuzzable_bool": ["true"], + "restler_fuzzable_object": ["{ \"fuzz\": false }"], + "restler_custom_payload": {}, + "restler_custom_payload_unquoted": {}, + "restler_custom_payload_uuid4_suffix": {}, + "restler_custom_payload_header": {}, + "restler_custom_payload_query": {} +} diff --git a/setup/fuzzer/settings.restler.json b/setup/fuzzer/settings.restler.json index 68f9340260..3a0b83ef1e 100644 --- a/setup/fuzzer/settings.restler.json +++ b/setup/fuzzer/settings.restler.json @@ -2,6 +2,5 @@ "per_resource_settings": {}, "max_combinations": 20, "target_ip": "127.0.0.1", - "target_port": 3000, - "ignore_decoding_failures": true + "target_port": 3000 } diff --git a/utils/specifications/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json similarity index 91% rename from utils/specifications/speckle-server.openapi.json rename to setup/fuzzer/speckle-server.openapi.json index 823de340b4..3d8e5c688b 100644 --- a/utils/specifications/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -239,28 +239,6 @@ "responses": { "200": { "description": "Returns Prometheus metrics" } } } }, - "/openapi/html": { - "get": { - "summary": "OpenAPI HTML", - "description": "Returns the OpenAPI documentation in HTML format", - "responses": { - "200": { - "description": "Returns the OpenAPI documentation in HTML format" - } - } - } - }, - "/openapi/json": { - "get": { - "summary": "OpenAPI JSON", - "description": "Returns the OpenAPI documentation in JSON format", - "responses": { - "200": { - "description": "Returns the OpenAPI documentation in JSON format" - } - } - } - }, "/preview/{streamId}/{angle}": { "options": { "description": "Options for the endpoint", @@ -271,7 +249,14 @@ "get": { "description": "Retrieve a preview for the project (stream), at an optional angle", "responses": { - "200": { "description": "A preview was successfully retrieved." } + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } + } + } } } }, @@ -287,7 +272,14 @@ "get": { "description": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", "responses": { - "200": { "description": "A preview was successfully retrieved." } + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } + } + } } } }, @@ -301,7 +293,14 @@ "get": { "description": "Retrieve a preview for the project (stream) and version (commit), at an optional angle", "responses": { - "200": { "description": "A preview was successfully retrieved." } + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } + } + } } } }, @@ -315,7 +314,14 @@ "get": { "description": "Retrieve a preview for the project (stream) and object, at an optional angle", "responses": { - "200": { "description": "A preview was successfully retrieved." } + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } + } + } } } }, From 62abdcb40c852bc1767e7d0883bf13a1bf4974a1 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 10:53:07 +0000 Subject: [PATCH 30/69] Fix restler config --- setup/fuzzer/annotations.restler.json | 3 +++ setup/fuzzer/config.restler.json | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 setup/fuzzer/annotations.restler.json diff --git a/setup/fuzzer/annotations.restler.json b/setup/fuzzer/annotations.restler.json new file mode 100644 index 0000000000..2ce82289a3 --- /dev/null +++ b/setup/fuzzer/annotations.restler.json @@ -0,0 +1,3 @@ +{ + "x-restler-global-annotations": [] +} diff --git a/setup/fuzzer/config.restler.json b/setup/fuzzer/config.restler.json index 7648512840..c7cce303b0 100644 --- a/setup/fuzzer/config.restler.json +++ b/setup/fuzzer/config.restler.json @@ -1,9 +1,11 @@ { "SwaggerSpecFilePath": [ - "/home/runner/work/speckle-server/speckle-server/speckle-server/utils/specifications/speckle-server.openapi.json" + "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/speckle-server.openapi.json" ], "GrammarOutputDirectoryPath": "/home/runner/work/speckle-server/speckle-server/Compile", - "CustomDictionaryFilePath": "/home/runner/work/speckle-server/speckle-server/Compile/defaultDict.json", + "CustomDictionaryFilePath": "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/dictionary.restler.json", + "EngineSettingsFilePath": "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/settings.restler.json", + "AnnotationFilePath": "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/annotations.restler.json", "IncludeOptionalParameters": true, "UseHeaderExamples": true, "UsePathExamples": false, From 76911950c60c424d6bf367cbff0da8d35f9370bf Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:34:47 +0000 Subject: [PATCH 31/69] Add more detail to OpenAPI specification --- setup/fuzzer/settings.restler.json | 3 +- setup/fuzzer/speckle-server.openapi.json | 185 ++++++++++++++++++++++- 2 files changed, 182 insertions(+), 6 deletions(-) diff --git a/setup/fuzzer/settings.restler.json b/setup/fuzzer/settings.restler.json index 3a0b83ef1e..68f9340260 100644 --- a/setup/fuzzer/settings.restler.json +++ b/setup/fuzzer/settings.restler.json @@ -2,5 +2,6 @@ "per_resource_settings": {}, "max_combinations": 20, "target_ip": "127.0.0.1", - "target_port": 3000 + "target_port": 3000, + "ignore_decoding_failures": true } diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index 3d8e5c688b..e0e2db7a7e 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -116,9 +116,16 @@ } }, "/api/stream/{streamId}/blobs": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + } + ], "get": { "description": "Gets all the blobs of a project (stream)", - "parameters": [{ "in": "path", "name": "streamId", "required": true }], "responses": { "200": { "description": "Successfully retrieved all the blobs from the project" @@ -127,7 +134,6 @@ }, "delete": { "description": "Deletes all the blobs from a project (stream)", - "parameters": [{ "in": "path", "name": "streamId", "required": true }], "responses": { "501": { "description": "Not implemented." } } } }, @@ -160,6 +166,14 @@ } }, "/objects/{streamId}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + } + ], "options": { "description": "The options for this endpoint", "responses": { "200": { "description": "Options were retrieved." } } @@ -172,6 +186,20 @@ } }, "/objects/{streamId}/{objectId}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "objectId", + "required": true, + "schema": { "type": "string" } + } + ], "options": { "description": "Options for downloading an object from a project (stream)", "responses": { "200": { "description": "Options were retrieved." } } @@ -182,6 +210,20 @@ } }, "/objects/{streamId}/{objectId}/single": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "objectId", + "required": true, + "schema": { "type": "string" } + } + ], "options": { "description": "Options for downloading a single object from a project (stream)", "responses": { "200": { "description": "Options were retrieved." } } @@ -192,6 +234,14 @@ } }, "/api/diff/{streamId}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + } + ], "options": { "description": "Options for the endpoint", "responses": { "200": { "description": "Options were retrieved." } } @@ -204,6 +254,14 @@ } }, "/api/getobjects/{streamId}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + } + ], "options": { "description": "Options for the endpoint", "responses": { "200": { "description": "Options were retrieved." } } @@ -223,6 +281,26 @@ } }, "/api/file/{fileType}/{streamId}/{branchName}": { + "parameters": [ + { + "in": "path", + "name": "fileType", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "branchName", + "required": true, + "schema": { "type": "string" } + } + ], "post": { "description": "Uploads a file to a project (stream)", "responses": { @@ -240,6 +318,25 @@ } }, "/preview/{streamId}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] + } + } + ], "options": { "description": "Options for the endpoint", "responses": { @@ -261,14 +358,37 @@ } }, "/preview/{streamId}/branches/{branchName}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "branchName", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] + } + } + ], "options": { "description": "Options for the endpoint", "responses": { "200": { "description": "Options successfully retrieved." } } - } - }, - "/preview/{streamId}/branches/{branchname}/{angle}": { + }, "get": { "description": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", "responses": { @@ -284,6 +404,31 @@ } }, "/preview/{streamId}/commits/{commitId}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "commitId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] + } + } + ], "options": { "description": "Options for the endpoint", "responses": { @@ -305,6 +450,31 @@ } }, "/preview/{streamId}/objects/{objectId}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "objectId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] + } + } + ], "options": { "description": "Options for the endpoint", "responses": { @@ -345,6 +515,11 @@ }, "/graphql": { "post": { + "requestBody": { + "content": { + "application/json": {} + } + }, "summary": "GraphQL", "description": "GraphQL endpoint", "responses": { "default": { "description": "GraphQL endpoint" } } From 1b7cd2877b976f5aed66003b78bfac46ce7f1687 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 14:12:46 +0000 Subject: [PATCH 32/69] Update openapi specification and skip unimplemented endpoint --- setup/fuzzer/dictionary.restler.json | 4 +- setup/fuzzer/settings.restler.json | 8 +- setup/fuzzer/speckle-server.openapi.json | 199 +++++++++++++++++++---- 3 files changed, 180 insertions(+), 31 deletions(-) diff --git a/setup/fuzzer/dictionary.restler.json b/setup/fuzzer/dictionary.restler.json index 826669edda..ebdf7e2893 100644 --- a/setup/fuzzer/dictionary.restler.json +++ b/setup/fuzzer/dictionary.restler.json @@ -11,7 +11,9 @@ "restler_fuzzable_number": ["1.23"], "restler_fuzzable_bool": ["true"], "restler_fuzzable_object": ["{ \"fuzz\": false }"], - "restler_custom_payload": {}, + "restler_custom_payload": { + "/graphql/post/Content-Type": ["application/json"] + }, "restler_custom_payload_unquoted": {}, "restler_custom_payload_uuid4_suffix": {}, "restler_custom_payload_header": {}, diff --git a/setup/fuzzer/settings.restler.json b/setup/fuzzer/settings.restler.json index 68f9340260..9076368e86 100644 --- a/setup/fuzzer/settings.restler.json +++ b/setup/fuzzer/settings.restler.json @@ -3,5 +3,11 @@ "max_combinations": 20, "target_ip": "127.0.0.1", "target_port": 3000, - "ignore_decoding_failures": true + "ignore_decoding_failures": true, + "exclude_requests": [ + { + "endpoint": "/api/stream/{streamId}/blobs", + "methods": ["DELETE"] + } + ] } diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index e0e2db7a7e..8e2965342c 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -18,15 +18,32 @@ }, "/auth/local/login": { "post": { + "parameters": [ + { + "in": "query", + "name": "challenge", + "required": true, + "schema": { "type": "string" } + } + ], "description": "Login with email and password", "responses": { "200": { "description": "User logged in successfully" }, + "400": { "description": "Invalid input" }, "401": { "description": "Invalid credentials" } } } }, "/auth/local/register": { "post": { + "parameters": [ + { + "in": "query", + "name": "challenge", + "required": true, + "schema": { "type": "string" } + } + ], "description": "Register with email and password", "responses": { "200": { "description": "User registered successfully" }, @@ -37,6 +54,14 @@ }, "/auth/accesscode": { "get": { + "parameters": [ + { + "in": "query", + "name": "appId", + "required": true, + "schema": { "type": "string" } + } + ], "description": "Generates an access code for an app.", "responses": { "200": { "description": "Returns an access code in the body" }, @@ -55,7 +80,27 @@ "/auth/token": { "post": { "description": "Generates a new API token", - "responses": { "200": { "description": "Generates a new API token" } } + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "appId": { "type": "string" }, + "appSecret": { "type": "string" }, + "accessCode": { "type": "string" }, + "challenge": { "type": "string" }, + "refreshToken": { "type": "string" } + }, + "required": ["appId", "appSecret"] + } + } + } + }, + "responses": { + "200": { "description": "Generates a new API token" }, + "401": { "description": "Unauthorized" } + } } }, "/auth/logout": { @@ -70,18 +115,43 @@ "/api/stream/{streamId}/blob": { "post": { "description": "Upload a new blob to a project (stream)", - "parameters": [{ "in": "path", "name": "streamId", "required": true }], + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + } + ], "responses": { "200": { "description": "Successfully uploaded a blob to the project" - } + }, + "404": { "description": "Stream could not be found" } } } }, - "/api/stream/{streamId}/diff": { + "/api/stream/{streamId}/blob/diff": { "post": { "description": "Determine the difference (diff) between the provided array of blob Ids and those stored on the server", - "parameters": [{ "in": "path", "name": "streamId", "required": true }], + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { "type": "string" } + } + } + } + }, "responses": { "200": { "description": "The difference between the list of blob Ids provided in the body of the request and those stored on the server" @@ -90,28 +160,37 @@ } }, "/api/stream/{streamId}/blob/{blobId}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "blobId", + "required": true, + "schema": { "type": "string" } + } + ], "get": { "description": "Gets a blob from a project (stream)", - "parameters": [ - { "in": "path", "name": "streamId", "required": true }, - { "in": "path", "name": "blobId", "required": true } - ], "responses": { "200": { "description": "Successfully retrieved a blob from the project" - } + }, + "401": { "description": "Unauthorized" }, + "404": { "description": "Stream or blob could not be found." } } }, "delete": { "description": "Deletes a blob from a project (stream)", - "parameters": [ - { "in": "path", "name": "streamId", "required": true }, - { "in": "path", "name": "blobId", "required": true } - ], "responses": { "204": { "description": "Successfully deleted a blob from the project" - } + }, + "404": { "description": "Stream or blob could not be found." } } } }, @@ -129,7 +208,9 @@ "responses": { "200": { "description": "Successfully retrieved all the blobs from the project" - } + }, + "401": { "description": "Unauthorized" }, + "404": { "description": "Stream could not be found." } } }, "delete": { @@ -137,7 +218,7 @@ "responses": { "501": { "description": "Not implemented." } } } }, - "/static": { + "/static/": { "get": { "description": "Static assets", "responses": { "200": { "description": "An asset was retrieved." } } @@ -181,7 +262,8 @@ "post": { "description": "Upload objects to the project (stream)", "responses": { - "200": { "description": "Objects were successfully uploaded." } + "200": { "description": "Objects were successfully uploaded." }, + "401": { "description": "Unauthorized" } } } }, @@ -206,7 +288,10 @@ }, "get": { "description": "Download objects from a project (stream)", - "responses": { "200": { "description": "Objects were downloaded." } } + "responses": { + "200": { "description": "Objects were downloaded." }, + "401": { "description": "Unauthorized" } + } } }, "/objects/{streamId}/{objectId}/single": { @@ -230,7 +315,10 @@ }, "get": { "description": "Options for downloading a single object from a project (stream)", - "responses": { "200": { "description": "An object was retrieved." } } + "responses": { + "200": { "description": "An object was retrieved." }, + "401": { "description": "Unauthorized" } + } } }, "/api/diff/{streamId}": { @@ -248,8 +336,22 @@ }, "post": { "description": "Options for getting the diff of objects for a project (stream)", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "objects": { "type": "array", "items": { "type": "string" } } + }, + "required": ["objects"] + } + } + } + }, "responses": { - "200": { "description": "A diff was successfully computed." } + "200": { "description": "A diff was successfully computed." }, + "401": { "description": "Unauthorized" } } } }, @@ -269,7 +371,8 @@ "post": { "description": "Get all objects for a project (stream)", "responses": { - "200": { "description": "All objects were successfully retrieved." } + "200": { "description": "All objects were successfully retrieved." }, + "401": { "description": "Unauthorized" } } } }, @@ -277,7 +380,23 @@ "get": { "summary": "Verify email", "description": "Verifies an email address", - "responses": { "302": { "description": "Redirects to the home page." } } + "responses": { + "302": { + "description": "Redirects to the home page.", + "headers": { + "Location": { + "schema": { "type": "string" } + } + }, + "parameters": [ + { + "in": "query", + "name": "emailverifiederror", + "schema": { "type": "string" } + } + ] + } + } } }, "/api/file/{fileType}/{streamId}/{branchName}": { @@ -286,7 +405,12 @@ "in": "path", "name": "fileType", "required": true, - "schema": { "type": "string" } + "schema": { + "oneOf": [ + { "type": "string" }, + { "type": "string", "enum": ["autodetect"] } + ] + } }, { "in": "path", @@ -306,6 +430,9 @@ "responses": { "200": { "description": "file successfully uploaded to the project (stream)" + }, + "404": { + "description": "Stream or branch could not be found." } } } @@ -466,10 +593,9 @@ { "in": "path", "name": "angle", - "required": true, "schema": { "oneOf": [ - { "type": "integer", "minimum": 0 }, + { "type": "integer", "minimum": 0, "maximum": 360 }, { "type": "string", "enum": ["all"] } ] } @@ -491,22 +617,37 @@ "schema": { "type": "string", "format": "binary" } } } - } + }, + "403": { "description": "Forbidden" } } } }, "/auth/pwdreset/request": { "post": { "description": "Reset a password", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { "type": "string", "format": "email" } + }, + "required": ["email"] + } + } + } + }, "responses": { "200": { "description": "The password reset workflow was successfully started." - } + }, + "400": { "description": "Invalid input" } } } }, "/auth/pwdreset/finalize": { - "get": { + "post": { "description": "Finish resetting a password", "responses": { "200": { "description": "The password was successfully reset." } From ebbf332f297651a84af2c5af6641e195831aab58 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 15:41:42 +0000 Subject: [PATCH 33/69] Restler should be authenticated; seed the database with data --- .github/workflows/rest-api-fuzzer.yml | 8 + setup/fuzzer/settings.restler.json | 8 +- setup/fuzzer/speckle-server.openapi.json | 2 +- setup/fuzzer/speckle.backup.sql | 973 +++++++++++++++++++++++ setup/fuzzer/token.txt | 1 + 5 files changed, 990 insertions(+), 2 deletions(-) create mode 100644 setup/fuzzer/speckle.backup.sql create mode 100644 setup/fuzzer/token.txt diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index b71798da06..0b05fa62f4 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -154,6 +154,12 @@ jobs: run: | docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml up --detach + - name: Seed the database + run: | + apt-get update + apt-get install --yes --no-install-recommends postgresql-client + PGPASSWORD=speckle psql -h 127.0.0.1 -U speckle -d speckle -p 5432 -w -f ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle.backup.sql + - name: Install Node.js uses: actions/setup-node@v4 with: @@ -198,6 +204,8 @@ jobs: if: always() run: | ls -la ${{ github.workspace }}/Test + ls -la ${{ github.workspace }}/Test/RestlerResults || true + ls -la ${{ github.workspace }}/Test/ResponseBuckets || true echo "" echo "############################################" echo "# Engine stderr #" diff --git a/setup/fuzzer/settings.restler.json b/setup/fuzzer/settings.restler.json index 9076368e86..e15b14a987 100644 --- a/setup/fuzzer/settings.restler.json +++ b/setup/fuzzer/settings.restler.json @@ -9,5 +9,11 @@ "endpoint": "/api/stream/{streamId}/blobs", "methods": ["DELETE"] } - ] + ], + "authentication": { + "token": { + "location": "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/token.txt", + "token_refresh_interval": 300 + } + } } diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index 8e2965342c..dd47a0a9e3 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -66,7 +66,7 @@ "responses": { "200": { "description": "Returns an access code in the body" }, "302": { "description": "Redirects with access code in url query" }, - "400": { "description": "Invalid access code" }, + "400": { "description": "Invalid access code, or the app does not exist" }, "500": { "description": "Internal error" } } }, diff --git a/setup/fuzzer/speckle.backup.sql b/setup/fuzzer/speckle.backup.sql new file mode 100644 index 0000000000..473ff5b71d --- /dev/null +++ b/setup/fuzzer/speckle.backup.sql @@ -0,0 +1,973 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 14.5 +-- Dumped by pg_dump version 16.4 + +-- Started on 2024-12-31 15:27:50 GMT + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- TOC entry 3878 (class 0 OID 16464) +-- Dependencies: 215 +-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.users (id, suuid, "createdAt", name, bio, company, email, verified, avatar, profiles, "passwordDigest", ip) FROM stdin; +bd195995fe 541d6d57-7726-444f-a5ab-baea78144b9d 2024-12-31 15:25:51.318+00 Fuzz Test \N \N fuzztest@example.org f \N \N $2b$10$EjlFakaD7KampuN3Zhf1lO5rCHK7dOizlmMDyT4Cw6JwAs7jouW.2 \N +\. + + +-- +-- TOC entry 3881 (class 0 OID 16500) +-- Dependencies: 218 +-- Data for Name: api_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.api_tokens (id, "tokenDigest", owner, name, "lastChars", revoked, lifespan, "createdAt", "lastUsed") FROM stdin; +d725857cc3 $2b$10$ZkJ9R8//SXclnt/3ZFQNG.c5qRJYjwM/6EbwVRSCU37PVpTa/Nt.G bd195995fe all b58a5a f 3154000000000 2024-12-31 15:26:43.130443+00 2024-12-31 15:26:43.130443+00 +6d4a0f4aea $2b$10$kcT4aItS5Hcas9ty8vPoKOodNiyCmxKSRcHAlxufR0dDzrn3wRrhG bd195995fe Speckle Web Manager-token bb52ff f 3154000000000 2024-12-31 15:25:51.924544+00 2024-12-31 15:26:43.227+00 +\. + + +-- +-- TOC entry 3893 (class 0 OID 16814) +-- Dependencies: 230 +-- Data for Name: server_apps; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_apps (id, secret, name, description, "termsAndConditionsLink", logo, public, "trustByDefault", "authorId", "createdAt", "redirectUrl") FROM stdin; +spklexcel spklexcel Speckle Connector For Excel The Speckle Connector For Excel. For more info, check the docs here: https://speckle.guide/user/excel. \N \N t t \N 2024-12-31 15:20:24.17486+00 https://speckle-excel.netlify.app +explorer explorer Speckle Explorer GraphiQL Playground with authentication. \N \N t t \N 2024-12-31 15:20:24.173284+00 http://127.0.0.1:3000/explorer +sca sca Speckle Connector A Speckle Desktop Connectors. \N \N t t \N 2024-12-31 15:20:24.174077+00 http://localhost:29363 +spklwebapp spklwebapp Speckle Web Manager The Speckle Web Manager is your one-stop place to manage and coordinate your data. \N \N t t \N 2024-12-31 15:20:24.173144+00 http://127.0.0.1:3000 +sdm sdm Speckle Desktop Manager Manages local installations of Speckle connectors, kits and everything else. \N \N t t \N 2024-12-31 15:20:24.174147+00 speckle://account +spklpwerbi spklpwerbi Speckle Connector For PowerBI The Speckle Connector For Excel. For more info check the docs here: https://speckle.guide/user/powerbi.html. \N \N t t \N 2024-12-31 15:20:24.175225+00 https://oauth.powerbi.com/views/oauthredirect.html +spklautoma spklautoma Speckle Automate Our automation platform \N \N t t \N 2024-12-31 15:20:24.175615+00 undefined/authn/callback +\. + + +-- +-- TOC entry 3895 (class 0 OID 16879) +-- Dependencies: 232 +-- Data for Name: authorization_codes; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.authorization_codes (id, "appId", "userId", challenge, "createdAt", lifespan) FROM stdin; +\. + + +-- +-- TOC entry 3929 (class 0 OID 18615) +-- Dependencies: 266 +-- Data for Name: workspaces; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspaces (id, name, description, "createdAt", "updatedAt", logo, "domainBasedMembershipProtectionEnabled", "discoverabilityEnabled", "defaultLogoIndex", "defaultProjectRole", slug) FROM stdin; +\. + + +-- +-- TOC entry 3885 (class 0 OID 16558) +-- Dependencies: 222 +-- Data for Name: streams; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.streams (id, name, description, "isPublic", "clonedFrom", "createdAt", "updatedAt", "allowPublicComments", "isDiscoverable", "workspaceId", "regionKey") FROM stdin; +bddc34ce4b Fuzz's First Project Welcome to Speckle! This is your sample project, designed by Beijia Gu - feel free to do whatever you want with it! t \N 2024-12-31 15:25:52.271+00 2024-12-31 15:25:52.289+00 f t \N \N +\. + + +-- +-- TOC entry 3920 (class 0 OID 18259) +-- Dependencies: 257 +-- Data for Name: automations; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automations (id, name, "projectId", enabled, "createdAt", "updatedAt", "executionEngineAutomationId", "userId", "isTestAutomation") FROM stdin; +\. + + +-- +-- TOC entry 3921 (class 0 OID 18275) +-- Dependencies: 258 +-- Data for Name: automation_revisions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_revisions (id, "automationId", "createdAt", active, "userId", "publicKey") FROM stdin; +\. + + +-- +-- TOC entry 3923 (class 0 OID 18309) +-- Dependencies: 260 +-- Data for Name: automation_runs; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_runs (id, "automationRevisionId", "createdAt", "updatedAt", status, "executionEngineRunId") FROM stdin; +\. + + +-- +-- TOC entry 3925 (class 0 OID 18375) +-- Dependencies: 262 +-- Data for Name: automation_function_runs; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_function_runs (id, "runId", "functionId", "functionReleaseId", elapsed, status, "contextView", "statusMessage", results, "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- TOC entry 3922 (class 0 OID 18293) +-- Dependencies: 259 +-- Data for Name: automation_revision_functions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_revision_functions ("automationRevisionId", "functionId", "functionReleaseId", "functionInputs", id) FROM stdin; +\. + + +-- +-- TOC entry 3927 (class 0 OID 18472) +-- Dependencies: 264 +-- Data for Name: automation_run_triggers; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_run_triggers ("automationRunId", "triggeringId", "triggerType") FROM stdin; +\. + + +-- +-- TOC entry 3926 (class 0 OID 18417) +-- Dependencies: 263 +-- Data for Name: automation_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_tokens ("automationId", "automateToken") FROM stdin; +\. + + +-- +-- TOC entry 3924 (class 0 OID 18351) +-- Dependencies: 261 +-- Data for Name: automation_triggers; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_triggers ("automationRevisionId", "triggerType", "triggeringId") FROM stdin; +\. + + +-- +-- TOC entry 3913 (class 0 OID 17577) +-- Dependencies: 250 +-- Data for Name: blob_storage; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.blob_storage (id, "streamId", "userId", "objectKey", "fileName", "fileType", "fileSize", "uploadStatus", "uploadError", "createdAt", "fileHash") FROM stdin; +\. + + +-- +-- TOC entry 3890 (class 0 OID 16720) +-- Dependencies: 227 +-- Data for Name: branches; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.branches (id, "streamId", "authorId", name, description, "createdAt", "updatedAt") FROM stdin; +cc21a58628 bddc34ce4b bd195995fe main default branch 2024-12-31 15:25:52.277+00 2024-12-31 15:25:52.277+00 +833dcf6df1 bddc34ce4b bd195995fe fuzzy \N 2024-12-31 15:26:00.401+00 2024-12-31 15:26:00.401+00 +\. + + +-- +-- TOC entry 3889 (class 0 OID 16647) +-- Dependencies: 226 +-- Data for Name: commits; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.commits (id, "referencedObject", author, message, "createdAt", "sourceApplication", "totalChildrenCount", parents) FROM stdin; +\. + + +-- +-- TOC entry 3891 (class 0 OID 16761) +-- Dependencies: 228 +-- Data for Name: branch_commits; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.branch_commits ("branchId", "commitId") FROM stdin; +\. + + +-- +-- TOC entry 3907 (class 0 OID 17422) +-- Dependencies: 244 +-- Data for Name: comments; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.comments (id, "streamId", "authorId", "createdAt", "updatedAt", text, screenshot, data, archived, "parentComment") FROM stdin; +\. + + +-- +-- TOC entry 3908 (class 0 OID 17483) +-- Dependencies: 245 +-- Data for Name: comment_links; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.comment_links ("commentId", "resourceId", "resourceType") FROM stdin; +\. + + +-- +-- TOC entry 3909 (class 0 OID 17494) +-- Dependencies: 246 +-- Data for Name: comment_views; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.comment_views ("commentId", "userId", "viewedAt") FROM stdin; +\. + + +-- +-- TOC entry 3906 (class 0 OID 17380) +-- Dependencies: 243 +-- Data for Name: email_verifications; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.email_verifications (id, email, "createdAt") FROM stdin; +608666d4fd018d334500 fuzztest@example.org 2024-12-31 15:25:51.356+00 +\. + + +-- +-- TOC entry 3905 (class 0 OID 17352) +-- Dependencies: 242 +-- Data for Name: file_uploads; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.file_uploads (id, "streamId", "branchName", "userId", "fileName", "fileType", "fileSize", "uploadComplete", "uploadDate", "convertedStatus", "convertedLastUpdate", "convertedMessage", "convertedCommitId") FROM stdin; +\. + + +-- +-- TOC entry 3928 (class 0 OID 18532) +-- Dependencies: 265 +-- Data for Name: gendo_ai_renders; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.gendo_ai_renders (id, "userId", "projectId", "modelId", "versionId", "createdAt", "updatedAt", "gendoGenerationId", status, prompt, camera, "baseImage", "responseImage") FROM stdin; +\. + + +-- +-- TOC entry 3941 (class 0 OID 18948) +-- Dependencies: 278 +-- Data for Name: gendo_user_credits; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.gendo_user_credits ("userId", "resetDate", used) FROM stdin; +\. + + +-- +-- TOC entry 3874 (class 0 OID 16396) +-- Dependencies: 211 +-- Data for Name: knex_migrations; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.knex_migrations (id, name, batch, migration_time) FROM stdin; +1 000-core.js 1 2024-12-31 15:20:17.258+00 +2 2020-05-29-apps.js 1 2024-12-31 15:20:17.33+00 +3 20201222100048_add_sourceapp_to_commits.js 1 2024-12-31 15:20:17.332+00 +4 20201222101522_add_totalchildrencount_to_commits.js 1 2024-12-31 15:20:17.335+00 +5 20201223120532_add_commit_parents_simplification.js 1 2024-12-31 15:20:17.34+00 +6 20201230111428_add_scopes_public_field.js 1 2024-12-31 15:20:17.342+00 +7 20210225130308_add_roles_public_field.js 1 2024-12-31 15:20:17.344+00 +8 20210303185834_invites.js 1 2024-12-31 15:20:17.356+00 +9 20210304111614_pwdreset.js 1 2024-12-31 15:20:17.365+00 +10 20210314101154_add_invitefield_to_serverinfo.js 1 2024-12-31 15:20:17.37+00 +11 20210322190000_add_streamid_to_objects.js 1 2024-12-31 15:20:17.433+00 +12 20210426200000-previews.js 1 2024-12-31 15:20:17.458+00 +13 20210603160000_optional_user_references.js 1 2024-12-31 15:20:17.471+00 +14 20210616173000_stream_activity.js 1 2024-12-31 15:20:17.486+00 +15 20210701180000-webhooks.js 1 2024-12-31 15:20:17.518+00 +16 20210915130000-fileuploads.js 1 2024-12-31 15:20:17.53+00 +17 20211119105730_de_duplicate_users.js 1 2024-12-31 15:20:17.541+00 +18 20220118181256-email-verifications.js 1 2024-12-31 15:20:17.554+00 +19 20220222173000_comments.js 1 2024-12-31 15:20:17.593+00 +20 20220315140000_ratelimit.js 1 2024-12-31 15:20:17.611+00 +21 20220318121405_add_stream_favorites.js 1 2024-12-31 15:20:17.637+00 +22 20220412150558_stream-public-comments.js 1 2024-12-31 15:20:17.64+00 +23 202206030936_add_asset_storage.js 1 2024-12-31 15:20:17.649+00 +24 202206231429_add_file_hash_to_blobs.js 1 2024-12-31 15:20:17.657+00 +25 20220629110918_server_invites_rework.js 1 2024-12-31 15:20:17.678+00 +26 20220707135553_make_users_email_not_nullable.js 1 2024-12-31 15:20:17.688+00 +27 20220722092821_add_invite_token_field.js 1 2024-12-31 15:20:17.697+00 +28 20220722110643_fix_comments_delete_cascade.js 1 2024-12-31 15:20:17.706+00 +29 20220727091536_blobs-id-length-removal.js 1 2024-12-31 15:20:17.708+00 +30 20220803104832_ts_test.js 1 2024-12-31 15:20:17.709+00 +31 20220819091523_add_stream_discoverable_field.js 1 2024-12-31 15:20:17.712+00 +32 20220823100915_migrate_streams_to_lower_precision_timestamps.js 1 2024-12-31 15:20:17.741+00 +33 20220825082631_drop_email_verifications_used_col.js 1 2024-12-31 15:20:17.769+00 +34 20220825123323_usernotificationpreferences.js 1 2024-12-31 15:20:17.78+00 +35 20220829102231_add_server_access_requests_table.js 1 2024-12-31 15:20:17.792+00 +36 20220921084935_fix_branch_nullability.js 1 2024-12-31 15:20:17.797+00 +37 20220929141717_scheduled_tasks.js 1 2024-12-31 15:20:17.801+00 +38 20221104104921_webhooks_drop_stream_fk.js 1 2024-12-31 15:20:17.803+00 +39 20221122133014_add_user_onboarding_data.js 1 2024-12-31 15:20:17.805+00 +40 20221213124322_migrate_more_table_precisions.js 1 2024-12-31 15:20:17.849+00 +41 20230316091225_create_users_meta_table.js 1 2024-12-31 15:20:17.856+00 +42 20230316132827_remove_user_is_onboarding_complete_col.js 1 2024-12-31 15:20:17.858+00 +43 20230330082209_stricter_file_uploads_schema.js 1 2024-12-31 15:20:17.909+00 +44 20230517122919_clean_up_invalid_stream_invites.js 1 2024-12-31 15:20:17.915+00 +45 20230713094611_create_streams_meta_table.js 1 2024-12-31 15:20:17.935+00 +46 20230727150957_serverGuestMode.js 1 2024-12-31 15:20:17.94+00 +47 20230818075729_add_invite_server_role_support.js 1 2024-12-31 15:20:17.943+00 +48 20230905162038_automations.js 1 2024-12-31 15:20:17.966+00 +49 20230907131636_migrate_invites_to_lower_precision_timestamps.js 1 2024-12-31 15:20:17.986+00 +50 20230912114629_automations_tables_normalization.js 1 2024-12-31 15:20:18.023+00 +51 20230914071540_make_function_run_results_nullable.js 1 2024-12-31 15:20:18.028+00 +52 20230919080704_add_webhook_config_timestamps.js 1 2024-12-31 15:20:18.031+00 +53 20230920130032_fix_project_delete_cascade.js 1 2024-12-31 15:20:18.051+00 +54 20231025100054_automation_function_name_and_logo.js 1 2024-12-31 15:20:18.056+00 +55 20240109101048_create_token_resource_access_table.js 1 2024-12-31 15:20:18.073+00 +56 20240304143445_rename_tables.js 1 2024-12-31 15:20:18.078+00 +57 20240305120620_automate.js 1 2024-12-31 15:20:18.125+00 +58 20240321092858_triggers.js 1 2024-12-31 15:20:18.161+00 +59 20240404075414_revision_active.js 1 2024-12-31 15:20:18.166+00 +60 20240404173455_automation_token.js 1 2024-12-31 15:20:18.2+00 +61 20240507075055_add_function_run_timestamps.js 1 2024-12-31 15:20:18.21+00 +62 20240507140149_add_encryption_support.js 1 2024-12-31 15:20:18.216+00 +63 20240522130000_gendo.js 1 2024-12-31 15:20:18.229+00 +64 20240523192300_add_is_test_automation_column.js 1 2024-12-31 15:20:18.232+00 +65 20240620105859_drop_beta_tables.js 1 2024-12-31 15:20:18.242+00 +66 20240621174016_workspaces.js 1 2024-12-31 15:20:18.262+00 +67 20240628112300_dropCreatorId.js 1 2024-12-31 15:20:18.264+00 +68 20240703084247_user-emails.js 1 2024-12-31 15:20:18.276+00 +69 20240710154658_user_emails_backfill.js 1 2024-12-31 15:20:18.28+00 +70 20240716094858_generalized_invite_record_resources.js 1 2024-12-31 15:20:18.283+00 +71 20240716134617_migrate_to_resources_array.js 1 2024-12-31 15:20:18.295+00 +72 20240801000000_logos.js 1 2024-12-31 15:20:18.297+00 +73 20240802212846_cascadeDeleteWorkspaceProjects.js 1 2024-12-31 15:20:18.31+00 +74 20240806160740_workspace_domains.js 1 2024-12-31 15:20:18.334+00 +75 20240807174901_add_column_domainBasedMembershipProtection.js 1 2024-12-31 15:20:18.337+00 +76 20240808091944_add_workspace_discovery_flag.js 1 2024-12-31 15:20:18.34+00 +77 20240808140602_add_invite_updated_at.js 1 2024-12-31 15:20:18.346+00 +78 20240813125251_workspaceAclWithTimestamps.js 1 2024-12-31 15:20:18.349+00 +79 20240820131619_fallbackWorkspaceLogo.js 1 2024-12-31 15:20:18.351+00 +80 20240910163614_add_column_defaultProjectRole.js 1 2024-12-31 15:20:18.354+00 +81 20240912134548_add_workspace_slug.js 1 2024-12-31 15:20:18.366+00 +82 20240926112407_copy_workspace_slug.js 1 2024-12-31 15:20:18.37+00 +83 20240930141322_workspace_sso.js 1 2024-12-31 15:20:18.399+00 +84 20241014092507_workspace_sso_expiration.js 1 2024-12-31 15:20:18.402+00 +85 20241018132400_workspace_checkout.js 1 2024-12-31 15:20:18.436+00 +86 20241031081827_create_regions_table.js 1 2024-12-31 15:20:18.442+00 +87 20241101055531_project_region.js 1 2024-12-31 15:20:18.446+00 +88 20241102055157_project_region_nofk.js 1 2024-12-31 15:20:18.449+00 +89 20241105070219_create_workspace_regions_table.js 1 2024-12-31 15:20:18.462+00 +90 20241105144301_cascade_delete_workspace_plans.js 1 2024-12-31 15:20:18.468+00 +91 20241120063859_cascade_delete_checkout_session.js 1 2024-12-31 15:20:18.475+00 +92 20241120140402_gendo_credits.js 1 2024-12-31 15:20:18.481+00 +93 20241126084242_workspace_plan_rename.js 1 2024-12-31 15:20:18.484+00 +94 20241126142602_workspace_plan_date.js 1 2024-12-31 15:20:18.485+00 +95 20241128153315_workspace_creation_state.js 1 2024-12-31 15:20:18.491+00 +96 20241202183039_workspace_start_trial.js 1 2024-12-31 15:20:18.493+00 +97 20241203212110_cascade_delete_automations.js 1 2024-12-31 15:20:18.508+00 +98 20241230115552_object_size.js 1 2024-12-31 15:20:18.51+00 +99 20241230141235_object_size_backfill.js 1 2024-12-31 15:20:18.513+00 +\. + + +-- +-- TOC entry 3876 (class 0 OID 16403) +-- Dependencies: 213 +-- Data for Name: knex_migrations_lock; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.knex_migrations_lock (index, is_locked) FROM stdin; +1 0 +\. + + +-- +-- TOC entry 3888 (class 0 OID 16605) +-- Dependencies: 225 +-- Data for Name: object_children_closure; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.object_children_closure (parent, child, "minDepth", "streamId") FROM stdin; +\. + + +-- +-- TOC entry 3900 (class 0 OID 17202) +-- Dependencies: 237 +-- Data for Name: object_preview; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.object_preview ("streamId", "objectId", "previewStatus", priority, "lastUpdate", preview) FROM stdin; +\. + + +-- +-- TOC entry 3887 (class 0 OID 16596) +-- Dependencies: 224 +-- Data for Name: objects; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.objects (id, "speckleType", "totalChildrenCount", "totalChildrenCountByDepth", "createdAt", data, "streamId", "sizeBytes") FROM stdin; +\. + + +-- +-- TOC entry 3882 (class 0 OID 16518) +-- Dependencies: 219 +-- Data for Name: personal_api_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.personal_api_tokens ("tokenId", "userId") FROM stdin; +d725857cc3 bd195995fe +\. + + +-- +-- TOC entry 3901 (class 0 OID 17231) +-- Dependencies: 238 +-- Data for Name: previews; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.previews (id, data) FROM stdin; +\. + + +-- +-- TOC entry 3899 (class 0 OID 17000) +-- Dependencies: 236 +-- Data for Name: pwdreset_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.pwdreset_tokens (id, email, "createdAt") FROM stdin; +\. + + +-- +-- TOC entry 3910 (class 0 OID 17518) +-- Dependencies: 247 +-- Data for Name: ratelimit_actions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.ratelimit_actions ("timestamp", action, source) FROM stdin; +\. + + +-- +-- TOC entry 3896 (class 0 OID 16904) +-- Dependencies: 233 +-- Data for Name: refresh_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.refresh_tokens (id, "tokenDigest", "appId", "userId", "createdAt", lifespan) FROM stdin; +ce9fc7efef $2b$10$pAAsDpjNndfRi4fs0uvCh.p5k.WVPXWfZklUgwbBtBIm6PFU0bFrS spklwebapp bd195995fe 2024-12-31 15:25:51.990884+00 15770000000 +\. + + +-- +-- TOC entry 3939 (class 0 OID 18884) +-- Dependencies: 276 +-- Data for Name: regions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.regions (key, name, description, "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- TOC entry 3916 (class 0 OID 17800) +-- Dependencies: 253 +-- Data for Name: scheduled_tasks; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.scheduled_tasks ("taskName", "lockExpiresAt") FROM stdin; +\. + + +-- +-- TOC entry 3883 (class 0 OID 16533) +-- Dependencies: 220 +-- Data for Name: scopes; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.scopes (name, description, public) FROM stdin; +apps:read See created or authorized applications. f +apps:write Register new applications. f +streams:read Read your streams, and any associated information (branches, commits, objects). t +streams:write Create streams on your behalf, and any associated data (branches, commits, objects). t +profile:read Read your profile information. t +profile:email Read the email address you registered with. t +profile:delete Delete the account with all associated data. f +users:read Read other users' profiles. t +server:stats Request server stats from the API. Only works in conjunction with a "server:admin" role. t +users:email Access the emails of other users. f +server:setup Edit server information. Note: Only server admins will be able to use this token. f +tokens:read Access API tokens. f +tokens:write Create and delete API tokens. f +users:invite Invite others to join this server. f +workspace:create Required for the creation of a workspace t +workspace:update Required for editing workspace information t +workspace:read Required for reading workspace data t +workspace:delete Required for deleting workspaces t +workspace:billing Scope for managing workspace billing f +\. + + +-- +-- TOC entry 3915 (class 0 OID 17765) +-- Dependencies: 252 +-- Data for Name: server_access_requests; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_access_requests (id, "requesterId", "resourceType", "resourceId", "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- TOC entry 3879 (class 0 OID 16477) +-- Dependencies: 216 +-- Data for Name: user_roles; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_roles (name, description, "resourceTarget", "aclTableName", weight, public) FROM stdin; +server:admin Holds supreme autocratic authority, not restricted by written laws, legislature, or customs. server server_acl 1000 f +server:user Has normal access to the server. server server_acl 100 f +server:guest Has limited access to the server. server server_acl 50 f +server:archived-user No longer has access to the server. server server_acl 10 f +stream:owner Owners have full access, including deletion rights & access control. streams stream_acl 1000 t +stream:contributor Contributors can create new branches and commits, but they cannot edit stream details or manage collaborators. streams stream_acl 500 t +stream:reviewer Reviewers can only view (read) the data from this stream. streams stream_acl 100 t +workspace:guest An external guest member of the workspace with limited rights workspaces workspace_acl 50 t +workspace:admin Has root on the workspace workspaces workspace_acl 1000 t +workspace:member A regular member of the workspace workspaces workspace_acl 100 t +\. + + +-- +-- TOC entry 3880 (class 0 OID 16485) +-- Dependencies: 217 +-- Data for Name: server_acl; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_acl ("userId", role) FROM stdin; +bd195995fe server:admin +\. + + +-- +-- TOC entry 3894 (class 0 OID 16850) +-- Dependencies: 231 +-- Data for Name: server_apps_scopes; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_apps_scopes ("appId", "scopeName") FROM stdin; +spklwebapp apps:read +spklwebapp apps:write +spklwebapp streams:read +spklwebapp streams:write +spklwebapp profile:read +spklwebapp profile:email +spklwebapp profile:delete +spklwebapp users:read +spklwebapp server:stats +spklwebapp users:email +spklwebapp server:setup +spklwebapp tokens:read +spklwebapp tokens:write +spklwebapp users:invite +spklwebapp workspace:create +spklwebapp workspace:update +spklwebapp workspace:read +spklwebapp workspace:delete +spklwebapp workspace:billing +explorer apps:read +explorer apps:write +explorer streams:read +explorer streams:write +explorer profile:read +explorer profile:email +explorer profile:delete +explorer users:read +explorer server:stats +explorer users:email +sdm streams:read +explorer server:setup +sdm streams:write +explorer tokens:read +sdm profile:read +explorer tokens:write +sdm profile:email +explorer users:invite +sdm users:read +sca streams:read +explorer workspace:create +sca streams:write +sca profile:read +sca profile:email +explorer workspace:update +sca users:read +explorer workspace:read +sca users:invite +explorer workspace:delete +explorer workspace:billing +sdm users:invite +spklexcel streams:read +spklexcel streams:write +spklexcel profile:read +spklexcel profile:email +spklexcel users:read +spklexcel users:invite +spklpwerbi streams:read +spklpwerbi profile:read +spklpwerbi profile:email +spklpwerbi users:read +spklpwerbi users:invite +spklautoma profile:email +spklautoma profile:read +spklautoma users:read +spklautoma tokens:write +spklautoma streams:read +spklautoma streams:write +\. + + +-- +-- TOC entry 3877 (class 0 OID 16451) +-- Dependencies: 214 +-- Data for Name: server_config; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_config (id, name, company, description, "adminContact", "termsOfService", "canonicalUrl", completed, "inviteOnly", "guestModeEnabled") FROM stdin; +0 My new Speckle Server Unknown Company This a community deployment of a Speckle Server. n/a n/a \N f f f +\. + + +-- +-- TOC entry 3898 (class 0 OID 16982) +-- Dependencies: 235 +-- Data for Name: server_invites; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_invites (id, target, "inviterId", "createdAt", message, token, resource, "updatedAt") FROM stdin; +\. + + +-- +-- TOC entry 3933 (class 0 OID 18777) +-- Dependencies: 270 +-- Data for Name: sso_providers; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.sso_providers (id, "providerType", "encryptedProviderData", "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- TOC entry 3886 (class 0 OID 16574) +-- Dependencies: 223 +-- Data for Name: stream_acl; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.stream_acl ("userId", "resourceId", role) FROM stdin; +bd195995fe bddc34ce4b stream:owner +\. + + +-- +-- TOC entry 3902 (class 0 OID 17265) +-- Dependencies: 239 +-- Data for Name: stream_activity; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.stream_activity ("streamId", "time", "resourceType", "resourceId", "actionType", "userId", info, message) FROM stdin; +\N 2024-12-31 15:25:51.702927+00 user bd195995fe user_create bd195995fe {"user": {"id": "bd195995fe", "ip": null, "bio": null, "name": "Fuzz Test", "email": "fuzztest@example.org", "suuid": "541d6d57-7726-444f-a5ab-baea78144b9d", "avatar": null, "company": null, "profiles": null, "verified": false, "createdAt": "2024-12-31T15:25:51.318Z", "passwordDigest": "$2b$10$EjlFakaD7KampuN3Zhf1lO5rCHK7dOizlmMDyT4Cw6JwAs7jouW.2"}} User created +bddc34ce4b 2024-12-31 15:25:52.2804+00 stream bddc34ce4b stream_create bd195995fe {"input": {"id": "bddc34ce4b", "name": "Rectangular Edifice", "isPublic": true, "createdAt": "2024-12-31T15:25:52.271Z", "regionKey": null, "updatedAt": "2024-12-31T15:25:52.271Z", "clonedFrom": null, "description": "", "workspaceId": null, "isDiscoverable": true, "allowPublicComments": false}} Stream Rectangular Edifice created +bddc34ce4b 2024-12-31 15:26:00.404984+00 branch 833dcf6df1 branch_create bd195995fe {"branch": {"id": "833dcf6df1", "name": "fuzzy", "authorId": "bd195995fe", "streamId": "bddc34ce4b", "createdAt": "2024-12-31T15:26:00.401Z", "updatedAt": "2024-12-31T15:26:00.401Z", "description": null}} Branch created: fuzzy (833dcf6df1) +\. + + +-- +-- TOC entry 3892 (class 0 OID 16779) +-- Dependencies: 229 +-- Data for Name: stream_commits; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.stream_commits ("streamId", "commitId") FROM stdin; +\. + + +-- +-- TOC entry 3911 (class 0 OID 17536) +-- Dependencies: 248 +-- Data for Name: stream_favorites; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.stream_favorites ("streamId", "userId", "createdAt", cursor) FROM stdin; +\. + + +-- +-- TOC entry 3918 (class 0 OID 17989) +-- Dependencies: 255 +-- Data for Name: streams_meta; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.streams_meta ("streamId", key, value, "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- TOC entry 3919 (class 0 OID 18247) +-- Dependencies: 256 +-- Data for Name: token_resource_access; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.token_resource_access ("tokenId", "resourceId", "resourceType") FROM stdin; +\. + + +-- +-- TOC entry 3884 (class 0 OID 16540) +-- Dependencies: 221 +-- Data for Name: token_scopes; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.token_scopes ("tokenId", "scopeName") FROM stdin; +6d4a0f4aea apps:read +6d4a0f4aea apps:write +6d4a0f4aea streams:read +6d4a0f4aea streams:write +6d4a0f4aea profile:read +6d4a0f4aea profile:email +6d4a0f4aea profile:delete +6d4a0f4aea users:read +6d4a0f4aea server:stats +6d4a0f4aea users:email +6d4a0f4aea server:setup +6d4a0f4aea tokens:read +6d4a0f4aea tokens:write +6d4a0f4aea users:invite +6d4a0f4aea workspace:create +6d4a0f4aea workspace:update +6d4a0f4aea workspace:read +6d4a0f4aea workspace:delete +6d4a0f4aea workspace:billing +d725857cc3 streams:read +d725857cc3 streams:write +d725857cc3 profile:read +d725857cc3 profile:email +d725857cc3 users:read +d725857cc3 server:stats +d725857cc3 workspace:create +d725857cc3 workspace:update +d725857cc3 workspace:read +d725857cc3 workspace:delete +\. + + +-- +-- TOC entry 3931 (class 0 OID 18679) +-- Dependencies: 268 +-- Data for Name: user_emails; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_emails (id, email, "primary", verified, "userId", "createdAt", "updatedAt") FROM stdin; +c6c27a75d3 fuzztest@example.org t f bd195995fe 2024-12-31 15:25:51.332+00 2024-12-31 15:25:51.332+00 +\. + + +-- +-- TOC entry 3914 (class 0 OID 17746) +-- Dependencies: 251 +-- Data for Name: user_notification_preferences; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_notification_preferences ("userId", preferences) FROM stdin; +\. + + +-- +-- TOC entry 3897 (class 0 OID 16931) +-- Dependencies: 234 +-- Data for Name: user_server_app_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_server_app_tokens ("appId", "userId", "tokenId") FROM stdin; +spklwebapp bd195995fe 6d4a0f4aea +\. + + +-- +-- TOC entry 3934 (class 0 OID 18784) +-- Dependencies: 271 +-- Data for Name: user_sso_sessions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_sso_sessions ("userId", "providerId", "createdAt", "validUntil") FROM stdin; +\. + + +-- +-- TOC entry 3917 (class 0 OID 17914) +-- Dependencies: 254 +-- Data for Name: users_meta; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.users_meta ("userId", key, value, "createdAt", "updatedAt") FROM stdin; +bd195995fe isOnboardingFinished true 2024-12-31 15:25:52.382+00 2024-12-31 15:25:52.382+00 +\. + + +-- +-- TOC entry 3903 (class 0 OID 17279) +-- Dependencies: 240 +-- Data for Name: webhooks_config; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.webhooks_config (id, "streamId", url, description, triggers, secret, enabled, "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- TOC entry 3904 (class 0 OID 17304) +-- Dependencies: 241 +-- Data for Name: webhooks_events; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.webhooks_events (id, "webhookId", status, "statusInfo", "lastUpdate", payload) FROM stdin; +\. + + +-- +-- TOC entry 3930 (class 0 OID 18640) +-- Dependencies: 267 +-- Data for Name: workspace_acl; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_acl ("userId", "workspaceId", role, "createdAt") FROM stdin; +\. + + +-- +-- TOC entry 3937 (class 0 OID 18851) +-- Dependencies: 274 +-- Data for Name: workspace_checkout_sessions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_checkout_sessions ("workspaceId", id, url, "workspacePlan", "paymentStatus", "billingInterval", "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- TOC entry 3942 (class 0 OID 18964) +-- Dependencies: 279 +-- Data for Name: workspace_creation_state; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_creation_state ("workspaceId", completed, state) FROM stdin; +\. + + +-- +-- TOC entry 3932 (class 0 OID 18727) +-- Dependencies: 269 +-- Data for Name: workspace_domains; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_domains (id, domain, verified, "createdAt", "updatedAt", "createdByUserId", "workspaceId") FROM stdin; +\. + + +-- +-- TOC entry 3936 (class 0 OID 18836) +-- Dependencies: 273 +-- Data for Name: workspace_plans; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_plans ("workspaceId", name, status, "createdAt") FROM stdin; +\. + + +-- +-- TOC entry 3940 (class 0 OID 18903) +-- Dependencies: 277 +-- Data for Name: workspace_regions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_regions ("workspaceId", "regionKey", "createdAt") FROM stdin; +\. + + +-- +-- TOC entry 3935 (class 0 OID 18808) +-- Dependencies: 272 +-- Data for Name: workspace_sso_providers; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_sso_providers ("workspaceId", "providerId") FROM stdin; +\. + + +-- +-- TOC entry 3938 (class 0 OID 18868) +-- Dependencies: 275 +-- Data for Name: workspace_subscriptions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_subscriptions ("workspaceId", "createdAt", "updatedAt", "currentBillingCycleEnd", "billingInterval", "subscriptionData") FROM stdin; +\. + + +-- +-- TOC entry 3948 (class 0 OID 0) +-- Dependencies: 210 +-- Name: knex_migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle +-- + +SELECT pg_catalog.setval('public.knex_migrations_id_seq', 99, true); + + +-- +-- TOC entry 3949 (class 0 OID 0) +-- Dependencies: 212 +-- Name: knex_migrations_lock_index_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle +-- + +SELECT pg_catalog.setval('public.knex_migrations_lock_index_seq', 1, true); + + +-- +-- TOC entry 3950 (class 0 OID 0) +-- Dependencies: 249 +-- Name: stream_favorites_cursor_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle +-- + +SELECT pg_catalog.setval('public.stream_favorites_cursor_seq', 1, false); + + +-- Completed on 2024-12-31 15:27:50 GMT + +-- +-- PostgreSQL database dump complete +-- + diff --git a/setup/fuzzer/token.txt b/setup/fuzzer/token.txt new file mode 100644 index 0000000000..d9a3276b16 --- /dev/null +++ b/setup/fuzzer/token.txt @@ -0,0 +1 @@ +d725857cc3a13391d2ac209f24e4177606bdb58a5a \ No newline at end of file From 0d3ac1c4703c5b4a0d2da363ac46858d0df7c5d7 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 15:45:43 +0000 Subject: [PATCH 34/69] sudo is required --- .github/workflows/rest-api-fuzzer.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 0b05fa62f4..3b7f22afa0 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -156,8 +156,8 @@ jobs: - name: Seed the database run: | - apt-get update - apt-get install --yes --no-install-recommends postgresql-client + sudo apt-get update + sudo apt-get install --yes --no-install-recommends postgresql-client PGPASSWORD=speckle psql -h 127.0.0.1 -U speckle -d speckle -p 5432 -w -f ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle.backup.sql - name: Install Node.js From dbf2c0780734c467d79ed9cae92b3c29a4e56342 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 16:08:34 +0000 Subject: [PATCH 35/69] Token file should match Restler format --- setup/fuzzer/token.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/fuzzer/token.txt b/setup/fuzzer/token.txt index d9a3276b16..11189c3fdc 100644 --- a/setup/fuzzer/token.txt +++ b/setup/fuzzer/token.txt @@ -1 +1,2 @@ -d725857cc3a13391d2ac209f24e4177606bdb58a5a \ No newline at end of file +{u'app1': {}} +ApiTokenTag: d725857cc3a13391d2ac209f24e4177606bdb58a5a \ No newline at end of file From d0c828761161d4016186ae9e0bc8738d7e93dc31 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 16:25:39 +0000 Subject: [PATCH 36/69] Fix seeding of database --- .github/workflows/rest-api-fuzzer.yml | 2 +- setup/fuzzer/speckle.backup.sql | 147 +------------------------- 2 files changed, 3 insertions(+), 146 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 3b7f22afa0..1e95d0abcf 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -158,7 +158,7 @@ jobs: run: | sudo apt-get update sudo apt-get install --yes --no-install-recommends postgresql-client - PGPASSWORD=speckle psql -h 127.0.0.1 -U speckle -d speckle -p 5432 -w -f ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle.backup.sql + PGPASSWORD=speckle psql -h 127.0.0.1 -U speckle -d speckle -p 5432 -w < ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle.backup.sql - name: Install Node.js uses: actions/setup-node@v4 diff --git a/setup/fuzzer/speckle.backup.sql b/setup/fuzzer/speckle.backup.sql index 473ff5b71d..02dc84475f 100644 --- a/setup/fuzzer/speckle.backup.sql +++ b/setup/fuzzer/speckle.backup.sql @@ -3,13 +3,12 @@ -- -- Dumped from database version 14.5 --- Dumped by pg_dump version 16.4 - --- Started on 2024-12-31 15:27:50 GMT +-- Dumped by pg_dump version 17.2 SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; +SET transaction_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); @@ -19,8 +18,6 @@ SET client_min_messages = warning; SET row_security = off; -- --- TOC entry 3878 (class 0 OID 16464) --- Dependencies: 215 -- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -30,8 +27,6 @@ bd195995fe 541d6d57-7726-444f-a5ab-baea78144b9d 2024-12-31 15:25:51.318+00 Fuzz -- --- TOC entry 3881 (class 0 OID 16500) --- Dependencies: 218 -- Data for Name: api_tokens; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -42,8 +37,6 @@ d725857cc3 $2b$10$ZkJ9R8//SXclnt/3ZFQNG.c5qRJYjwM/6EbwVRSCU37PVpTa/Nt.G bd195995 -- --- TOC entry 3893 (class 0 OID 16814) --- Dependencies: 230 -- Data for Name: server_apps; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -59,8 +52,6 @@ spklautoma spklautoma Speckle Automate Our automation platform \N \N t t \N 2024 -- --- TOC entry 3895 (class 0 OID 16879) --- Dependencies: 232 -- Data for Name: authorization_codes; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -69,8 +60,6 @@ COPY public.authorization_codes (id, "appId", "userId", challenge, "createdAt", -- --- TOC entry 3929 (class 0 OID 18615) --- Dependencies: 266 -- Data for Name: workspaces; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -79,8 +68,6 @@ COPY public.workspaces (id, name, description, "createdAt", "updatedAt", logo, " -- --- TOC entry 3885 (class 0 OID 16558) --- Dependencies: 222 -- Data for Name: streams; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -90,8 +77,6 @@ bddc34ce4b Fuzz's First Project Welcome to Speckle! This is your sample project, -- --- TOC entry 3920 (class 0 OID 18259) --- Dependencies: 257 -- Data for Name: automations; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -100,8 +85,6 @@ COPY public.automations (id, name, "projectId", enabled, "createdAt", "updatedAt -- --- TOC entry 3921 (class 0 OID 18275) --- Dependencies: 258 -- Data for Name: automation_revisions; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -110,8 +93,6 @@ COPY public.automation_revisions (id, "automationId", "createdAt", active, "user -- --- TOC entry 3923 (class 0 OID 18309) --- Dependencies: 260 -- Data for Name: automation_runs; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -120,8 +101,6 @@ COPY public.automation_runs (id, "automationRevisionId", "createdAt", "updatedAt -- --- TOC entry 3925 (class 0 OID 18375) --- Dependencies: 262 -- Data for Name: automation_function_runs; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -130,8 +109,6 @@ COPY public.automation_function_runs (id, "runId", "functionId", "functionReleas -- --- TOC entry 3922 (class 0 OID 18293) --- Dependencies: 259 -- Data for Name: automation_revision_functions; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -140,8 +117,6 @@ COPY public.automation_revision_functions ("automationRevisionId", "functionId", -- --- TOC entry 3927 (class 0 OID 18472) --- Dependencies: 264 -- Data for Name: automation_run_triggers; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -150,8 +125,6 @@ COPY public.automation_run_triggers ("automationRunId", "triggeringId", "trigger -- --- TOC entry 3926 (class 0 OID 18417) --- Dependencies: 263 -- Data for Name: automation_tokens; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -160,8 +133,6 @@ COPY public.automation_tokens ("automationId", "automateToken") FROM stdin; -- --- TOC entry 3924 (class 0 OID 18351) --- Dependencies: 261 -- Data for Name: automation_triggers; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -170,8 +141,6 @@ COPY public.automation_triggers ("automationRevisionId", "triggerType", "trigger -- --- TOC entry 3913 (class 0 OID 17577) --- Dependencies: 250 -- Data for Name: blob_storage; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -180,8 +149,6 @@ COPY public.blob_storage (id, "streamId", "userId", "objectKey", "fileName", "fi -- --- TOC entry 3890 (class 0 OID 16720) --- Dependencies: 227 -- Data for Name: branches; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -192,8 +159,6 @@ cc21a58628 bddc34ce4b bd195995fe main default branch 2024-12-31 15:25:52.277+00 -- --- TOC entry 3889 (class 0 OID 16647) --- Dependencies: 226 -- Data for Name: commits; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -202,8 +167,6 @@ COPY public.commits (id, "referencedObject", author, message, "createdAt", "sour -- --- TOC entry 3891 (class 0 OID 16761) --- Dependencies: 228 -- Data for Name: branch_commits; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -212,8 +175,6 @@ COPY public.branch_commits ("branchId", "commitId") FROM stdin; -- --- TOC entry 3907 (class 0 OID 17422) --- Dependencies: 244 -- Data for Name: comments; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -222,8 +183,6 @@ COPY public.comments (id, "streamId", "authorId", "createdAt", "updatedAt", text -- --- TOC entry 3908 (class 0 OID 17483) --- Dependencies: 245 -- Data for Name: comment_links; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -232,8 +191,6 @@ COPY public.comment_links ("commentId", "resourceId", "resourceType") FROM stdin -- --- TOC entry 3909 (class 0 OID 17494) --- Dependencies: 246 -- Data for Name: comment_views; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -242,8 +199,6 @@ COPY public.comment_views ("commentId", "userId", "viewedAt") FROM stdin; -- --- TOC entry 3906 (class 0 OID 17380) --- Dependencies: 243 -- Data for Name: email_verifications; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -253,8 +208,6 @@ COPY public.email_verifications (id, email, "createdAt") FROM stdin; -- --- TOC entry 3905 (class 0 OID 17352) --- Dependencies: 242 -- Data for Name: file_uploads; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -263,8 +216,6 @@ COPY public.file_uploads (id, "streamId", "branchName", "userId", "fileName", "f -- --- TOC entry 3928 (class 0 OID 18532) --- Dependencies: 265 -- Data for Name: gendo_ai_renders; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -273,8 +224,6 @@ COPY public.gendo_ai_renders (id, "userId", "projectId", "modelId", "versionId", -- --- TOC entry 3941 (class 0 OID 18948) --- Dependencies: 278 -- Data for Name: gendo_user_credits; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -283,8 +232,6 @@ COPY public.gendo_user_credits ("userId", "resetDate", used) FROM stdin; -- --- TOC entry 3874 (class 0 OID 16396) --- Dependencies: 211 -- Data for Name: knex_migrations; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -392,8 +339,6 @@ COPY public.knex_migrations (id, name, batch, migration_time) FROM stdin; -- --- TOC entry 3876 (class 0 OID 16403) --- Dependencies: 213 -- Data for Name: knex_migrations_lock; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -403,8 +348,6 @@ COPY public.knex_migrations_lock (index, is_locked) FROM stdin; -- --- TOC entry 3888 (class 0 OID 16605) --- Dependencies: 225 -- Data for Name: object_children_closure; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -413,8 +356,6 @@ COPY public.object_children_closure (parent, child, "minDepth", "streamId") FROM -- --- TOC entry 3900 (class 0 OID 17202) --- Dependencies: 237 -- Data for Name: object_preview; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -423,8 +364,6 @@ COPY public.object_preview ("streamId", "objectId", "previewStatus", priority, " -- --- TOC entry 3887 (class 0 OID 16596) --- Dependencies: 224 -- Data for Name: objects; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -433,8 +372,6 @@ COPY public.objects (id, "speckleType", "totalChildrenCount", "totalChildrenCoun -- --- TOC entry 3882 (class 0 OID 16518) --- Dependencies: 219 -- Data for Name: personal_api_tokens; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -444,8 +381,6 @@ d725857cc3 bd195995fe -- --- TOC entry 3901 (class 0 OID 17231) --- Dependencies: 238 -- Data for Name: previews; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -454,8 +389,6 @@ COPY public.previews (id, data) FROM stdin; -- --- TOC entry 3899 (class 0 OID 17000) --- Dependencies: 236 -- Data for Name: pwdreset_tokens; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -464,8 +397,6 @@ COPY public.pwdreset_tokens (id, email, "createdAt") FROM stdin; -- --- TOC entry 3910 (class 0 OID 17518) --- Dependencies: 247 -- Data for Name: ratelimit_actions; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -474,8 +405,6 @@ COPY public.ratelimit_actions ("timestamp", action, source) FROM stdin; -- --- TOC entry 3896 (class 0 OID 16904) --- Dependencies: 233 -- Data for Name: refresh_tokens; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -485,8 +414,6 @@ ce9fc7efef $2b$10$pAAsDpjNndfRi4fs0uvCh.p5k.WVPXWfZklUgwbBtBIm6PFU0bFrS spklweba -- --- TOC entry 3939 (class 0 OID 18884) --- Dependencies: 276 -- Data for Name: regions; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -495,8 +422,6 @@ COPY public.regions (key, name, description, "createdAt", "updatedAt") FROM stdi -- --- TOC entry 3916 (class 0 OID 17800) --- Dependencies: 253 -- Data for Name: scheduled_tasks; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -505,8 +430,6 @@ COPY public.scheduled_tasks ("taskName", "lockExpiresAt") FROM stdin; -- --- TOC entry 3883 (class 0 OID 16533) --- Dependencies: 220 -- Data for Name: scopes; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -534,8 +457,6 @@ workspace:billing Scope for managing workspace billing f -- --- TOC entry 3915 (class 0 OID 17765) --- Dependencies: 252 -- Data for Name: server_access_requests; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -544,8 +465,6 @@ COPY public.server_access_requests (id, "requesterId", "resourceType", "resource -- --- TOC entry 3879 (class 0 OID 16477) --- Dependencies: 216 -- Data for Name: user_roles; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -564,8 +483,6 @@ workspace:member A regular member of the workspace workspaces workspace_acl 100 -- --- TOC entry 3880 (class 0 OID 16485) --- Dependencies: 217 -- Data for Name: server_acl; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -575,8 +492,6 @@ bd195995fe server:admin -- --- TOC entry 3894 (class 0 OID 16850) --- Dependencies: 231 -- Data for Name: server_apps_scopes; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -652,8 +567,6 @@ spklautoma streams:write -- --- TOC entry 3877 (class 0 OID 16451) --- Dependencies: 214 -- Data for Name: server_config; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -663,8 +576,6 @@ COPY public.server_config (id, name, company, description, "adminContact", "term -- --- TOC entry 3898 (class 0 OID 16982) --- Dependencies: 235 -- Data for Name: server_invites; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -673,8 +584,6 @@ COPY public.server_invites (id, target, "inviterId", "createdAt", message, token -- --- TOC entry 3933 (class 0 OID 18777) --- Dependencies: 270 -- Data for Name: sso_providers; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -683,8 +592,6 @@ COPY public.sso_providers (id, "providerType", "encryptedProviderData", "created -- --- TOC entry 3886 (class 0 OID 16574) --- Dependencies: 223 -- Data for Name: stream_acl; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -694,8 +601,6 @@ bd195995fe bddc34ce4b stream:owner -- --- TOC entry 3902 (class 0 OID 17265) --- Dependencies: 239 -- Data for Name: stream_activity; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -707,8 +612,6 @@ bddc34ce4b 2024-12-31 15:26:00.404984+00 branch 833dcf6df1 branch_create bd19599 -- --- TOC entry 3892 (class 0 OID 16779) --- Dependencies: 229 -- Data for Name: stream_commits; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -717,8 +620,6 @@ COPY public.stream_commits ("streamId", "commitId") FROM stdin; -- --- TOC entry 3911 (class 0 OID 17536) --- Dependencies: 248 -- Data for Name: stream_favorites; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -727,8 +628,6 @@ COPY public.stream_favorites ("streamId", "userId", "createdAt", cursor) FROM st -- --- TOC entry 3918 (class 0 OID 17989) --- Dependencies: 255 -- Data for Name: streams_meta; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -737,8 +636,6 @@ COPY public.streams_meta ("streamId", key, value, "createdAt", "updatedAt") FROM -- --- TOC entry 3919 (class 0 OID 18247) --- Dependencies: 256 -- Data for Name: token_resource_access; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -747,8 +644,6 @@ COPY public.token_resource_access ("tokenId", "resourceId", "resourceType") FROM -- --- TOC entry 3884 (class 0 OID 16540) --- Dependencies: 221 -- Data for Name: token_scopes; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -786,8 +681,6 @@ d725857cc3 workspace:delete -- --- TOC entry 3931 (class 0 OID 18679) --- Dependencies: 268 -- Data for Name: user_emails; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -797,8 +690,6 @@ c6c27a75d3 fuzztest@example.org t f bd195995fe 2024-12-31 15:25:51.332+00 2024-1 -- --- TOC entry 3914 (class 0 OID 17746) --- Dependencies: 251 -- Data for Name: user_notification_preferences; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -807,8 +698,6 @@ COPY public.user_notification_preferences ("userId", preferences) FROM stdin; -- --- TOC entry 3897 (class 0 OID 16931) --- Dependencies: 234 -- Data for Name: user_server_app_tokens; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -818,8 +707,6 @@ spklwebapp bd195995fe 6d4a0f4aea -- --- TOC entry 3934 (class 0 OID 18784) --- Dependencies: 271 -- Data for Name: user_sso_sessions; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -828,8 +715,6 @@ COPY public.user_sso_sessions ("userId", "providerId", "createdAt", "validUntil" -- --- TOC entry 3917 (class 0 OID 17914) --- Dependencies: 254 -- Data for Name: users_meta; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -839,8 +724,6 @@ bd195995fe isOnboardingFinished true 2024-12-31 15:25:52.382+00 2024-12-31 15:25 -- --- TOC entry 3903 (class 0 OID 17279) --- Dependencies: 240 -- Data for Name: webhooks_config; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -849,8 +732,6 @@ COPY public.webhooks_config (id, "streamId", url, description, triggers, secret, -- --- TOC entry 3904 (class 0 OID 17304) --- Dependencies: 241 -- Data for Name: webhooks_events; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -859,8 +740,6 @@ COPY public.webhooks_events (id, "webhookId", status, "statusInfo", "lastUpdate" -- --- TOC entry 3930 (class 0 OID 18640) --- Dependencies: 267 -- Data for Name: workspace_acl; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -869,8 +748,6 @@ COPY public.workspace_acl ("userId", "workspaceId", role, "createdAt") FROM stdi -- --- TOC entry 3937 (class 0 OID 18851) --- Dependencies: 274 -- Data for Name: workspace_checkout_sessions; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -879,8 +756,6 @@ COPY public.workspace_checkout_sessions ("workspaceId", id, url, "workspacePlan" -- --- TOC entry 3942 (class 0 OID 18964) --- Dependencies: 279 -- Data for Name: workspace_creation_state; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -889,8 +764,6 @@ COPY public.workspace_creation_state ("workspaceId", completed, state) FROM stdi -- --- TOC entry 3932 (class 0 OID 18727) --- Dependencies: 269 -- Data for Name: workspace_domains; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -899,8 +772,6 @@ COPY public.workspace_domains (id, domain, verified, "createdAt", "updatedAt", " -- --- TOC entry 3936 (class 0 OID 18836) --- Dependencies: 273 -- Data for Name: workspace_plans; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -909,8 +780,6 @@ COPY public.workspace_plans ("workspaceId", name, status, "createdAt") FROM stdi -- --- TOC entry 3940 (class 0 OID 18903) --- Dependencies: 277 -- Data for Name: workspace_regions; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -919,8 +788,6 @@ COPY public.workspace_regions ("workspaceId", "regionKey", "createdAt") FROM std -- --- TOC entry 3935 (class 0 OID 18808) --- Dependencies: 272 -- Data for Name: workspace_sso_providers; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -929,8 +796,6 @@ COPY public.workspace_sso_providers ("workspaceId", "providerId") FROM stdin; -- --- TOC entry 3938 (class 0 OID 18868) --- Dependencies: 275 -- Data for Name: workspace_subscriptions; Type: TABLE DATA; Schema: public; Owner: speckle -- @@ -939,8 +804,6 @@ COPY public.workspace_subscriptions ("workspaceId", "createdAt", "updatedAt", "c -- --- TOC entry 3948 (class 0 OID 0) --- Dependencies: 210 -- Name: knex_migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle -- @@ -948,8 +811,6 @@ SELECT pg_catalog.setval('public.knex_migrations_id_seq', 99, true); -- --- TOC entry 3949 (class 0 OID 0) --- Dependencies: 212 -- Name: knex_migrations_lock_index_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle -- @@ -957,16 +818,12 @@ SELECT pg_catalog.setval('public.knex_migrations_lock_index_seq', 1, true); -- --- TOC entry 3950 (class 0 OID 0) --- Dependencies: 249 -- Name: stream_favorites_cursor_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle -- SELECT pg_catalog.setval('public.stream_favorites_cursor_seq', 1, false); --- Completed on 2024-12-31 15:27:50 GMT - -- -- PostgreSQL database dump complete -- From beb60efc8ef8c6b5a8a5227839b6a6df4d469871 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:25:37 +0000 Subject: [PATCH 37/69] Run from docker image, not source --- .github/workflows/rest-api-fuzzer.yml | 26 +- setup/fuzzer/.env.fuzz-test-example | 35 --- setup/fuzzer/docker-compose-speckle.yml | 52 ++++ setup/fuzzer/speckle.backup.sql | 338 ++++++++++++------------ setup/fuzzer/token.txt | 2 +- 5 files changed, 225 insertions(+), 228 deletions(-) delete mode 100644 setup/fuzzer/.env.fuzz-test-example create mode 100644 setup/fuzzer/docker-compose-speckle.yml diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 1e95d0abcf..b22f13d1f8 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -160,34 +160,15 @@ jobs: sudo apt-get install --yes --no-install-recommends postgresql-client PGPASSWORD=speckle psql -h 127.0.0.1 -U speckle -d speckle -p 5432 -w < ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle.backup.sql - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: 'yarn' - cache-dependency-path: ${{ github.workspace }}/speckle-server/yarn.lock - - name: Install dependencies - working-directory: ${{ github.workspace }}/speckle-server/packages/server - run: yarn install - - name: Build public packages - working-directory: ${{ github.workspace }}/speckle-server/packages/server - run: yarn build:public - - name: Build speckle-server - working-directory: ${{ github.workspace }}/speckle-server/packages/server - run: yarn build - name: Configure speckle-server - working-directory: ${{ github.workspace }}/speckle-server/packages/server + working-directory: ${{ github.workspace }} run: | cp ${{ github.workspace }}/speckle-server/setup/fuzzer/.env.fuzz-test-example .env - name: Run speckle-server - working-directory: ${{ github.workspace }}/speckle-server/packages/server + working-directory: ${{ github.workspace }} timeout-minutes: 1 run: | - yarn start & - until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do - echo "Waiting a further 3 seconds for speckle-server to start..." - sleep 3 - done + docker compose --file ${{ github.workspace }}/speckle-server/setup/fuzzer/docker-compose-speckle.yml up --detach - name: Run RESTler coverage test run: | @@ -259,3 +240,4 @@ jobs: if: always() run: | docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml logs + docker compose --file ${{ github.workspace }}/speckle-server/setup/fuzzer/docker-compose-speckle.yml logs diff --git a/setup/fuzzer/.env.fuzz-test-example b/setup/fuzzer/.env.fuzz-test-example deleted file mode 100644 index 7b6202a79a..0000000000 --- a/setup/fuzzer/.env.fuzz-test-example +++ /dev/null @@ -1,35 +0,0 @@ -# BIND_ADDRESS="127.0.0.1" -PORT=3000 - -CANONICAL_URL="http://127.0.0.1:3000" -SESSION_SECRET="-> FILL IN <-" - -REDIS_URL="redis://127.0.0.1:6379" - -USE_FRONTEND_2=true -FRONTEND_ORIGIN="http://127.0.0.1:8081" - -ONBOARDING_STREAM_URL=https://latest.speckle.systems/projects/843d07eb10 - -ONBOARDING_STREAM_CACHE_BUST_NUMBER=1 - -ENABLE_FE2_MESSAGING=false - -POSTGRES_URL="127.0.0.1" -POSTGRES_USER="speckle" -POSTGRES_PASSWORD="speckle" -POSTGRES_DB="speckle" - -S3_ENDPOINT="http://127.0.0.1:9000" -S3_ACCESS_KEY="minioadmin" -S3_SECRET_KEY="minioadmin" -S3_BUCKET="speckle-server" -S3_CREATE_BUCKET="true" - -EMAIL=false -EMAIL_HOST="127.0.0.1" -EMAIL_FROM="no-reply@example.org" -EMAIL_PORT="1025" - -DISABLE_NOTIFICATIONS_CONSUMPTION=true -STRATEGY_LOCAL=true diff --git a/setup/fuzzer/docker-compose-speckle.yml b/setup/fuzzer/docker-compose-speckle.yml new file mode 100644 index 0000000000..e1649f2bba --- /dev/null +++ b/setup/fuzzer/docker-compose-speckle.yml @@ -0,0 +1,52 @@ +version: '2.4' +services: + speckle-server: + platform: linux/amd64 + image: speckle/speckle-server:latest + restart: always + ports: + - '0.0.0.0:3000:3000' + healthcheck: + test: + - CMD + - /nodejs/bin/node + - -e + - "try { require('node:http').request({headers: {'Content-Type': 'application/json'}, port:3000, hostname:'127.0.0.1', path:'/readiness', method: 'GET', timeout: 2000 }, (res) => { body = ''; res.on('data', (chunk) => {body += chunk;}); res.on('end', () => {process.exit(res.statusCode != 200 || body.toLowerCase().includes('error'));}); }).end(); } catch { process.exit(1); }" + interval: 10s + timeout: 10s + retries: 3 + start_period: 90s + environment: + PORT: 3000 + + CANONICAL_URL: 'http://127.0.0.1:3000' + SESSION_SECRET: '-> FILL IN <-' + + REDIS_URL: 'redis://redis:6379' + + USE_FRONTEND_2: true + FRONTEND_ORIGIN: 'http://127.0.0.1:8081' + + ENABLE_FE2_MESSAGING: false + + POSTGRES_URL: 'postgres' + POSTGRES_USER: 'speckle' + POSTGRES_PASSWORD: 'speckle' + POSTGRES_DB: 'speckle' + + S3_ENDPOINT: 'http://minio:9000' + S3_ACCESS_KEY: 'minioadmin' + S3_SECRET_KEY: 'minioadmin' + S3_BUCKET: 'speckle-server' + S3_CREATE_BUCKET: 'true' + + EMAIL: false + + DISABLE_NOTIFICATIONS_CONSUMPTION: true + STRATEGY_LOCAL: true + networks: + - speckle-server_default + +networks: + speckle-server_default: + external: true diff --git a/setup/fuzzer/speckle.backup.sql b/setup/fuzzer/speckle.backup.sql index 02dc84475f..75cb9c3868 100644 --- a/setup/fuzzer/speckle.backup.sql +++ b/setup/fuzzer/speckle.backup.sql @@ -22,7 +22,7 @@ SET row_security = off; -- COPY public.users (id, suuid, "createdAt", name, bio, company, email, verified, avatar, profiles, "passwordDigest", ip) FROM stdin; -bd195995fe 541d6d57-7726-444f-a5ab-baea78144b9d 2024-12-31 15:25:51.318+00 Fuzz Test \N \N fuzztest@example.org f \N \N $2b$10$EjlFakaD7KampuN3Zhf1lO5rCHK7dOizlmMDyT4Cw6JwAs7jouW.2 \N +3fb61f0d69 6bff2a82-30db-4d5e-b4a6-78dbb07f0b2b 2024-12-31 17:15:25.885+00 Fuzz Test \N \N fuzztest@example.org f \N \N $2b$10$n9TiIOXO8PagZ8azbKyGk.fa6u2iju7mgEtDwyiBnRRZGaNLlMUQS \N \. @@ -31,8 +31,8 @@ bd195995fe 541d6d57-7726-444f-a5ab-baea78144b9d 2024-12-31 15:25:51.318+00 Fuzz -- COPY public.api_tokens (id, "tokenDigest", owner, name, "lastChars", revoked, lifespan, "createdAt", "lastUsed") FROM stdin; -d725857cc3 $2b$10$ZkJ9R8//SXclnt/3ZFQNG.c5qRJYjwM/6EbwVRSCU37PVpTa/Nt.G bd195995fe all b58a5a f 3154000000000 2024-12-31 15:26:43.130443+00 2024-12-31 15:26:43.130443+00 -6d4a0f4aea $2b$10$kcT4aItS5Hcas9ty8vPoKOodNiyCmxKSRcHAlxufR0dDzrn3wRrhG bd195995fe Speckle Web Manager-token bb52ff f 3154000000000 2024-12-31 15:25:51.924544+00 2024-12-31 15:26:43.227+00 +314504c3d0 $2b$10$xOYgfOmq1XHXO0dPCctlk.l38qxEsyZZk4q6YstaGJFdK4RBVk5QK 3fb61f0d69 all 8b1a70 f 3154000000000 2024-12-31 17:16:19.315306+00 2024-12-31 17:16:19.315306+00 +d018e9f40e $2b$10$NNwurjMss/m8/8HV7vROIetVRWPaKgN57iPv0j92HztsritKnZU4W 3fb61f0d69 Speckle Web Manager-token 54da62 f 3154000000000 2024-12-31 17:15:26.482142+00 2024-12-31 17:17:23.802+00 \. @@ -41,13 +41,13 @@ d725857cc3 $2b$10$ZkJ9R8//SXclnt/3ZFQNG.c5qRJYjwM/6EbwVRSCU37PVpTa/Nt.G bd195995 -- COPY public.server_apps (id, secret, name, description, "termsAndConditionsLink", logo, public, "trustByDefault", "authorId", "createdAt", "redirectUrl") FROM stdin; -spklexcel spklexcel Speckle Connector For Excel The Speckle Connector For Excel. For more info, check the docs here: https://speckle.guide/user/excel. \N \N t t \N 2024-12-31 15:20:24.17486+00 https://speckle-excel.netlify.app -explorer explorer Speckle Explorer GraphiQL Playground with authentication. \N \N t t \N 2024-12-31 15:20:24.173284+00 http://127.0.0.1:3000/explorer -sca sca Speckle Connector A Speckle Desktop Connectors. \N \N t t \N 2024-12-31 15:20:24.174077+00 http://localhost:29363 -spklwebapp spklwebapp Speckle Web Manager The Speckle Web Manager is your one-stop place to manage and coordinate your data. \N \N t t \N 2024-12-31 15:20:24.173144+00 http://127.0.0.1:3000 -sdm sdm Speckle Desktop Manager Manages local installations of Speckle connectors, kits and everything else. \N \N t t \N 2024-12-31 15:20:24.174147+00 speckle://account -spklpwerbi spklpwerbi Speckle Connector For PowerBI The Speckle Connector For Excel. For more info check the docs here: https://speckle.guide/user/powerbi.html. \N \N t t \N 2024-12-31 15:20:24.175225+00 https://oauth.powerbi.com/views/oauthredirect.html -spklautoma spklautoma Speckle Automate Our automation platform \N \N t t \N 2024-12-31 15:20:24.175615+00 undefined/authn/callback +spklexcel spklexcel Speckle Connector For Excel The Speckle Connector For Excel. For more info, check the docs here: https://speckle.guide/user/excel. \N \N t t \N 2024-12-31 17:13:26.847617+00 https://speckle-excel.netlify.app +spklwebapp spklwebapp Speckle Web Manager The Speckle Web Manager is your one-stop place to manage and coordinate your data. \N \N t t \N 2024-12-31 17:13:26.846065+00 http://127.0.0.1:3000 +spklautoma spklautoma Speckle Automate Our automation platform \N \N t t \N 2024-12-31 17:13:26.848538+00 undefined/authn/callback +explorer explorer Speckle Explorer GraphiQL Playground with authentication. \N \N t t \N 2024-12-31 17:13:26.846596+00 http://127.0.0.1:3000/explorer +sdm sdm Speckle Desktop Manager Manages local installations of Speckle connectors, kits and everything else. \N \N t t \N 2024-12-31 17:13:26.847991+00 speckle://account +sca sca Speckle Connector A Speckle Desktop Connectors. \N \N t t \N 2024-12-31 17:13:26.846334+00 http://localhost:29363 +spklpwerbi spklpwerbi Speckle Connector For PowerBI The Speckle Connector For Excel. For more info check the docs here: https://speckle.guide/user/powerbi.html. \N \N t t \N 2024-12-31 17:13:26.847174+00 https://oauth.powerbi.com/views/oauthredirect.html \. @@ -72,7 +72,7 @@ COPY public.workspaces (id, name, description, "createdAt", "updatedAt", logo, " -- COPY public.streams (id, name, description, "isPublic", "clonedFrom", "createdAt", "updatedAt", "allowPublicComments", "isDiscoverable", "workspaceId", "regionKey") FROM stdin; -bddc34ce4b Fuzz's First Project Welcome to Speckle! This is your sample project, designed by Beijia Gu - feel free to do whatever you want with it! t \N 2024-12-31 15:25:52.271+00 2024-12-31 15:25:52.289+00 f t \N \N +47d8fd9d36 Fuzz's First Project Welcome to Speckle! This is your sample project, designed by Beijia Gu - feel free to do whatever you want with it! t \N 2024-12-31 17:15:26.845+00 2024-12-31 17:15:26.872+00 f t \N \N \. @@ -153,8 +153,8 @@ COPY public.blob_storage (id, "streamId", "userId", "objectKey", "fileName", "fi -- COPY public.branches (id, "streamId", "authorId", name, description, "createdAt", "updatedAt") FROM stdin; -cc21a58628 bddc34ce4b bd195995fe main default branch 2024-12-31 15:25:52.277+00 2024-12-31 15:25:52.277+00 -833dcf6df1 bddc34ce4b bd195995fe fuzzy \N 2024-12-31 15:26:00.401+00 2024-12-31 15:26:00.401+00 +c4f249efcd 47d8fd9d36 3fb61f0d69 main default branch 2024-12-31 17:15:26.855+00 2024-12-31 17:15:26.855+00 +3c4ce908af 47d8fd9d36 3fb61f0d69 fuzzy \N 2024-12-31 17:17:23.699+00 2024-12-31 17:17:23.699+00 \. @@ -203,7 +203,7 @@ COPY public.comment_views ("commentId", "userId", "viewedAt") FROM stdin; -- COPY public.email_verifications (id, email, "createdAt") FROM stdin; -608666d4fd018d334500 fuzztest@example.org 2024-12-31 15:25:51.356+00 +6ff3e4d864195cabc2dd fuzztest@example.org 2024-12-31 17:15:25.924+00 \. @@ -236,105 +236,103 @@ COPY public.gendo_user_credits ("userId", "resetDate", used) FROM stdin; -- COPY public.knex_migrations (id, name, batch, migration_time) FROM stdin; -1 000-core.js 1 2024-12-31 15:20:17.258+00 -2 2020-05-29-apps.js 1 2024-12-31 15:20:17.33+00 -3 20201222100048_add_sourceapp_to_commits.js 1 2024-12-31 15:20:17.332+00 -4 20201222101522_add_totalchildrencount_to_commits.js 1 2024-12-31 15:20:17.335+00 -5 20201223120532_add_commit_parents_simplification.js 1 2024-12-31 15:20:17.34+00 -6 20201230111428_add_scopes_public_field.js 1 2024-12-31 15:20:17.342+00 -7 20210225130308_add_roles_public_field.js 1 2024-12-31 15:20:17.344+00 -8 20210303185834_invites.js 1 2024-12-31 15:20:17.356+00 -9 20210304111614_pwdreset.js 1 2024-12-31 15:20:17.365+00 -10 20210314101154_add_invitefield_to_serverinfo.js 1 2024-12-31 15:20:17.37+00 -11 20210322190000_add_streamid_to_objects.js 1 2024-12-31 15:20:17.433+00 -12 20210426200000-previews.js 1 2024-12-31 15:20:17.458+00 -13 20210603160000_optional_user_references.js 1 2024-12-31 15:20:17.471+00 -14 20210616173000_stream_activity.js 1 2024-12-31 15:20:17.486+00 -15 20210701180000-webhooks.js 1 2024-12-31 15:20:17.518+00 -16 20210915130000-fileuploads.js 1 2024-12-31 15:20:17.53+00 -17 20211119105730_de_duplicate_users.js 1 2024-12-31 15:20:17.541+00 -18 20220118181256-email-verifications.js 1 2024-12-31 15:20:17.554+00 -19 20220222173000_comments.js 1 2024-12-31 15:20:17.593+00 -20 20220315140000_ratelimit.js 1 2024-12-31 15:20:17.611+00 -21 20220318121405_add_stream_favorites.js 1 2024-12-31 15:20:17.637+00 -22 20220412150558_stream-public-comments.js 1 2024-12-31 15:20:17.64+00 -23 202206030936_add_asset_storage.js 1 2024-12-31 15:20:17.649+00 -24 202206231429_add_file_hash_to_blobs.js 1 2024-12-31 15:20:17.657+00 -25 20220629110918_server_invites_rework.js 1 2024-12-31 15:20:17.678+00 -26 20220707135553_make_users_email_not_nullable.js 1 2024-12-31 15:20:17.688+00 -27 20220722092821_add_invite_token_field.js 1 2024-12-31 15:20:17.697+00 -28 20220722110643_fix_comments_delete_cascade.js 1 2024-12-31 15:20:17.706+00 -29 20220727091536_blobs-id-length-removal.js 1 2024-12-31 15:20:17.708+00 -30 20220803104832_ts_test.js 1 2024-12-31 15:20:17.709+00 -31 20220819091523_add_stream_discoverable_field.js 1 2024-12-31 15:20:17.712+00 -32 20220823100915_migrate_streams_to_lower_precision_timestamps.js 1 2024-12-31 15:20:17.741+00 -33 20220825082631_drop_email_verifications_used_col.js 1 2024-12-31 15:20:17.769+00 -34 20220825123323_usernotificationpreferences.js 1 2024-12-31 15:20:17.78+00 -35 20220829102231_add_server_access_requests_table.js 1 2024-12-31 15:20:17.792+00 -36 20220921084935_fix_branch_nullability.js 1 2024-12-31 15:20:17.797+00 -37 20220929141717_scheduled_tasks.js 1 2024-12-31 15:20:17.801+00 -38 20221104104921_webhooks_drop_stream_fk.js 1 2024-12-31 15:20:17.803+00 -39 20221122133014_add_user_onboarding_data.js 1 2024-12-31 15:20:17.805+00 -40 20221213124322_migrate_more_table_precisions.js 1 2024-12-31 15:20:17.849+00 -41 20230316091225_create_users_meta_table.js 1 2024-12-31 15:20:17.856+00 -42 20230316132827_remove_user_is_onboarding_complete_col.js 1 2024-12-31 15:20:17.858+00 -43 20230330082209_stricter_file_uploads_schema.js 1 2024-12-31 15:20:17.909+00 -44 20230517122919_clean_up_invalid_stream_invites.js 1 2024-12-31 15:20:17.915+00 -45 20230713094611_create_streams_meta_table.js 1 2024-12-31 15:20:17.935+00 -46 20230727150957_serverGuestMode.js 1 2024-12-31 15:20:17.94+00 -47 20230818075729_add_invite_server_role_support.js 1 2024-12-31 15:20:17.943+00 -48 20230905162038_automations.js 1 2024-12-31 15:20:17.966+00 -49 20230907131636_migrate_invites_to_lower_precision_timestamps.js 1 2024-12-31 15:20:17.986+00 -50 20230912114629_automations_tables_normalization.js 1 2024-12-31 15:20:18.023+00 -51 20230914071540_make_function_run_results_nullable.js 1 2024-12-31 15:20:18.028+00 -52 20230919080704_add_webhook_config_timestamps.js 1 2024-12-31 15:20:18.031+00 -53 20230920130032_fix_project_delete_cascade.js 1 2024-12-31 15:20:18.051+00 -54 20231025100054_automation_function_name_and_logo.js 1 2024-12-31 15:20:18.056+00 -55 20240109101048_create_token_resource_access_table.js 1 2024-12-31 15:20:18.073+00 -56 20240304143445_rename_tables.js 1 2024-12-31 15:20:18.078+00 -57 20240305120620_automate.js 1 2024-12-31 15:20:18.125+00 -58 20240321092858_triggers.js 1 2024-12-31 15:20:18.161+00 -59 20240404075414_revision_active.js 1 2024-12-31 15:20:18.166+00 -60 20240404173455_automation_token.js 1 2024-12-31 15:20:18.2+00 -61 20240507075055_add_function_run_timestamps.js 1 2024-12-31 15:20:18.21+00 -62 20240507140149_add_encryption_support.js 1 2024-12-31 15:20:18.216+00 -63 20240522130000_gendo.js 1 2024-12-31 15:20:18.229+00 -64 20240523192300_add_is_test_automation_column.js 1 2024-12-31 15:20:18.232+00 -65 20240620105859_drop_beta_tables.js 1 2024-12-31 15:20:18.242+00 -66 20240621174016_workspaces.js 1 2024-12-31 15:20:18.262+00 -67 20240628112300_dropCreatorId.js 1 2024-12-31 15:20:18.264+00 -68 20240703084247_user-emails.js 1 2024-12-31 15:20:18.276+00 -69 20240710154658_user_emails_backfill.js 1 2024-12-31 15:20:18.28+00 -70 20240716094858_generalized_invite_record_resources.js 1 2024-12-31 15:20:18.283+00 -71 20240716134617_migrate_to_resources_array.js 1 2024-12-31 15:20:18.295+00 -72 20240801000000_logos.js 1 2024-12-31 15:20:18.297+00 -73 20240802212846_cascadeDeleteWorkspaceProjects.js 1 2024-12-31 15:20:18.31+00 -74 20240806160740_workspace_domains.js 1 2024-12-31 15:20:18.334+00 -75 20240807174901_add_column_domainBasedMembershipProtection.js 1 2024-12-31 15:20:18.337+00 -76 20240808091944_add_workspace_discovery_flag.js 1 2024-12-31 15:20:18.34+00 -77 20240808140602_add_invite_updated_at.js 1 2024-12-31 15:20:18.346+00 -78 20240813125251_workspaceAclWithTimestamps.js 1 2024-12-31 15:20:18.349+00 -79 20240820131619_fallbackWorkspaceLogo.js 1 2024-12-31 15:20:18.351+00 -80 20240910163614_add_column_defaultProjectRole.js 1 2024-12-31 15:20:18.354+00 -81 20240912134548_add_workspace_slug.js 1 2024-12-31 15:20:18.366+00 -82 20240926112407_copy_workspace_slug.js 1 2024-12-31 15:20:18.37+00 -83 20240930141322_workspace_sso.js 1 2024-12-31 15:20:18.399+00 -84 20241014092507_workspace_sso_expiration.js 1 2024-12-31 15:20:18.402+00 -85 20241018132400_workspace_checkout.js 1 2024-12-31 15:20:18.436+00 -86 20241031081827_create_regions_table.js 1 2024-12-31 15:20:18.442+00 -87 20241101055531_project_region.js 1 2024-12-31 15:20:18.446+00 -88 20241102055157_project_region_nofk.js 1 2024-12-31 15:20:18.449+00 -89 20241105070219_create_workspace_regions_table.js 1 2024-12-31 15:20:18.462+00 -90 20241105144301_cascade_delete_workspace_plans.js 1 2024-12-31 15:20:18.468+00 -91 20241120063859_cascade_delete_checkout_session.js 1 2024-12-31 15:20:18.475+00 -92 20241120140402_gendo_credits.js 1 2024-12-31 15:20:18.481+00 -93 20241126084242_workspace_plan_rename.js 1 2024-12-31 15:20:18.484+00 -94 20241126142602_workspace_plan_date.js 1 2024-12-31 15:20:18.485+00 -95 20241128153315_workspace_creation_state.js 1 2024-12-31 15:20:18.491+00 -96 20241202183039_workspace_start_trial.js 1 2024-12-31 15:20:18.493+00 -97 20241203212110_cascade_delete_automations.js 1 2024-12-31 15:20:18.508+00 -98 20241230115552_object_size.js 1 2024-12-31 15:20:18.51+00 -99 20241230141235_object_size_backfill.js 1 2024-12-31 15:20:18.513+00 +1 000-core.js 1 2024-12-31 17:13:23.07+00 +2 2020-05-29-apps.js 1 2024-12-31 17:13:23.168+00 +3 20201222100048_add_sourceapp_to_commits.js 1 2024-12-31 17:13:23.177+00 +4 20201222101522_add_totalchildrencount_to_commits.js 1 2024-12-31 17:13:23.18+00 +5 20201223120532_add_commit_parents_simplification.js 1 2024-12-31 17:13:23.184+00 +6 20201230111428_add_scopes_public_field.js 1 2024-12-31 17:13:23.185+00 +7 20210225130308_add_roles_public_field.js 1 2024-12-31 17:13:23.19+00 +8 20210303185834_invites.js 1 2024-12-31 17:13:23.207+00 +9 20210304111614_pwdreset.js 1 2024-12-31 17:13:23.213+00 +10 20210314101154_add_invitefield_to_serverinfo.js 1 2024-12-31 17:13:23.216+00 +11 20210322190000_add_streamid_to_objects.js 1 2024-12-31 17:13:23.303+00 +12 20210426200000-previews.js 1 2024-12-31 17:13:23.311+00 +13 20210603160000_optional_user_references.js 1 2024-12-31 17:13:23.315+00 +14 20210616173000_stream_activity.js 1 2024-12-31 17:13:23.322+00 +15 20210701180000-webhooks.js 1 2024-12-31 17:13:23.333+00 +16 20210915130000-fileuploads.js 1 2024-12-31 17:13:23.338+00 +17 20211119105730_de_duplicate_users.js 1 2024-12-31 17:13:23.34+00 +18 20220118181256-email-verifications.js 1 2024-12-31 17:13:23.345+00 +19 20220222173000_comments.js 1 2024-12-31 17:13:23.364+00 +20 20220315140000_ratelimit.js 1 2024-12-31 17:13:23.369+00 +21 20220318121405_add_stream_favorites.js 1 2024-12-31 17:13:23.375+00 +22 20220412150558_stream-public-comments.js 1 2024-12-31 17:13:23.376+00 +23 202206030936_add_asset_storage.js 1 2024-12-31 17:13:23.381+00 +24 202206231429_add_file_hash_to_blobs.js 1 2024-12-31 17:13:23.382+00 +25 20220629110918_server_invites_rework.js 1 2024-12-31 17:13:23.398+00 +26 20220707135553_make_users_email_not_nullable.js 1 2024-12-31 17:13:23.406+00 +27 20220722092821_add_invite_token_field.js 1 2024-12-31 17:13:23.41+00 +28 20220722110643_fix_comments_delete_cascade.js 1 2024-12-31 17:13:23.419+00 +29 20220727091536_blobs-id-length-removal.js 1 2024-12-31 17:13:23.421+00 +30 20220803104832_ts_test.js 1 2024-12-31 17:13:23.422+00 +31 20220819091523_add_stream_discoverable_field.js 1 2024-12-31 17:13:23.423+00 +32 20220823100915_migrate_streams_to_lower_precision_timestamps.js 1 2024-12-31 17:13:23.447+00 +33 20220825082631_drop_email_verifications_used_col.js 1 2024-12-31 17:13:23.457+00 +34 20220825123323_usernotificationpreferences.js 1 2024-12-31 17:13:23.461+00 +35 20220829102231_add_server_access_requests_table.js 1 2024-12-31 17:13:23.468+00 +36 20220921084935_fix_branch_nullability.js 1 2024-12-31 17:13:23.472+00 +37 20220929141717_scheduled_tasks.js 1 2024-12-31 17:13:23.475+00 +38 20221104104921_webhooks_drop_stream_fk.js 1 2024-12-31 17:13:23.476+00 +39 20221122133014_add_user_onboarding_data.js 1 2024-12-31 17:13:23.477+00 +40 20221213124322_migrate_more_table_precisions.js 1 2024-12-31 17:13:23.508+00 +41 20230316091225_create_users_meta_table.js 1 2024-12-31 17:13:23.516+00 +42 20230316132827_remove_user_is_onboarding_complete_col.js 1 2024-12-31 17:13:23.518+00 +43 20230330082209_stricter_file_uploads_schema.js 1 2024-12-31 17:13:23.534+00 +44 20230517122919_clean_up_invalid_stream_invites.js 1 2024-12-31 17:13:23.537+00 +45 20230713094611_create_streams_meta_table.js 1 2024-12-31 17:13:23.541+00 +46 20230727150957_serverGuestMode.js 1 2024-12-31 17:13:23.542+00 +47 20230818075729_add_invite_server_role_support.js 1 2024-12-31 17:13:23.543+00 +48 20230905162038_automations.js 1 2024-12-31 17:13:23.551+00 +49 20230907131636_migrate_invites_to_lower_precision_timestamps.js 1 2024-12-31 17:13:23.56+00 +50 20230912114629_automations_tables_normalization.js 1 2024-12-31 17:13:23.583+00 +51 20230914071540_make_function_run_results_nullable.js 1 2024-12-31 17:13:23.586+00 +52 20230919080704_add_webhook_config_timestamps.js 1 2024-12-31 17:13:23.587+00 +53 20230920130032_fix_project_delete_cascade.js 1 2024-12-31 17:13:23.595+00 +54 20231025100054_automation_function_name_and_logo.js 1 2024-12-31 17:13:23.596+00 +55 20240109101048_create_token_resource_access_table.js 1 2024-12-31 17:13:23.601+00 +56 20240304143445_rename_tables.js 1 2024-12-31 17:13:23.605+00 +57 20240305120620_automate.js 1 2024-12-31 17:13:23.635+00 +58 20240321092858_triggers.js 1 2024-12-31 17:13:23.656+00 +59 20240404075414_revision_active.js 1 2024-12-31 17:13:23.658+00 +60 20240404173455_automation_token.js 1 2024-12-31 17:13:23.674+00 +61 20240507075055_add_function_run_timestamps.js 1 2024-12-31 17:13:23.676+00 +62 20240507140149_add_encryption_support.js 1 2024-12-31 17:13:23.685+00 +63 20240522130000_gendo.js 1 2024-12-31 17:13:23.697+00 +64 20240523192300_add_is_test_automation_column.js 1 2024-12-31 17:13:23.699+00 +65 20240620105859_drop_beta_tables.js 1 2024-12-31 17:13:23.714+00 +66 20240621174016_workspaces.js 1 2024-12-31 17:13:23.739+00 +67 20240628112300_dropCreatorId.js 1 2024-12-31 17:13:23.742+00 +68 20240703084247_user-emails.js 1 2024-12-31 17:13:23.759+00 +69 20240710154658_user_emails_backfill.js 1 2024-12-31 17:13:23.765+00 +70 20240716094858_generalized_invite_record_resources.js 1 2024-12-31 17:13:23.778+00 +71 20240716134617_migrate_to_resources_array.js 1 2024-12-31 17:13:23.802+00 +72 20240801000000_logos.js 1 2024-12-31 17:13:23.808+00 +73 20240802212846_cascadeDeleteWorkspaceProjects.js 1 2024-12-31 17:13:23.818+00 +74 20240806160740_workspace_domains.js 1 2024-12-31 17:13:23.842+00 +75 20240807174901_add_column_domainBasedMembershipProtection.js 1 2024-12-31 17:13:23.845+00 +76 20240808091944_add_workspace_discovery_flag.js 1 2024-12-31 17:13:23.848+00 +77 20240808140602_add_invite_updated_at.js 1 2024-12-31 17:13:23.852+00 +78 20240813125251_workspaceAclWithTimestamps.js 1 2024-12-31 17:13:23.857+00 +79 20240820131619_fallbackWorkspaceLogo.js 1 2024-12-31 17:13:23.864+00 +80 20240910163614_add_column_defaultProjectRole.js 1 2024-12-31 17:13:23.869+00 +81 20240912134548_add_workspace_slug.js 1 2024-12-31 17:13:23.889+00 +82 20240926112407_copy_workspace_slug.js 1 2024-12-31 17:13:23.892+00 +83 20240930141322_workspace_sso.js 1 2024-12-31 17:13:23.911+00 +84 20241014092507_workspace_sso_expiration.js 1 2024-12-31 17:13:23.913+00 +85 20241018132400_workspace_checkout.js 1 2024-12-31 17:13:23.955+00 +86 20241031081827_create_regions_table.js 1 2024-12-31 17:13:23.964+00 +87 20241101055531_project_region.js 1 2024-12-31 17:13:23.972+00 +88 20241102055157_project_region_nofk.js 1 2024-12-31 17:13:23.978+00 +89 20241105070219_create_workspace_regions_table.js 1 2024-12-31 17:13:23.996+00 +90 20241105144301_cascade_delete_workspace_plans.js 1 2024-12-31 17:13:24.005+00 +91 20241120063859_cascade_delete_checkout_session.js 1 2024-12-31 17:13:24.016+00 +92 20241120140402_gendo_credits.js 1 2024-12-31 17:13:24.028+00 +93 20241126084242_workspace_plan_rename.js 1 2024-12-31 17:13:24.041+00 +94 20241126142602_workspace_plan_date.js 1 2024-12-31 17:13:24.045+00 +95 20241128153315_workspace_creation_state.js 1 2024-12-31 17:13:24.063+00 +96 20241202183039_workspace_start_trial.js 1 2024-12-31 17:13:24.07+00 +97 20241203212110_cascade_delete_automations.js 1 2024-12-31 17:13:24.097+00 \. @@ -367,7 +365,7 @@ COPY public.object_preview ("streamId", "objectId", "previewStatus", priority, " -- Data for Name: objects; Type: TABLE DATA; Schema: public; Owner: speckle -- -COPY public.objects (id, "speckleType", "totalChildrenCount", "totalChildrenCountByDepth", "createdAt", data, "streamId", "sizeBytes") FROM stdin; +COPY public.objects (id, "speckleType", "totalChildrenCount", "totalChildrenCountByDepth", "createdAt", data, "streamId") FROM stdin; \. @@ -376,7 +374,7 @@ COPY public.objects (id, "speckleType", "totalChildrenCount", "totalChildrenCoun -- COPY public.personal_api_tokens ("tokenId", "userId") FROM stdin; -d725857cc3 bd195995fe +314504c3d0 3fb61f0d69 \. @@ -409,7 +407,7 @@ COPY public.ratelimit_actions ("timestamp", action, source) FROM stdin; -- COPY public.refresh_tokens (id, "tokenDigest", "appId", "userId", "createdAt", lifespan) FROM stdin; -ce9fc7efef $2b$10$pAAsDpjNndfRi4fs0uvCh.p5k.WVPXWfZklUgwbBtBIm6PFU0bFrS spklwebapp bd195995fe 2024-12-31 15:25:51.990884+00 15770000000 +b9eeee1b67 $2b$10$V9el87hGEUU43t/7R45qlegPxj8J6hfVKfjWwC4ueUwDGqNgInet. spklwebapp 3fb61f0d69 2024-12-31 17:15:26.550566+00 15770000000 \. @@ -476,9 +474,9 @@ server:archived-user No longer has access to the server. server server_acl 10 f stream:owner Owners have full access, including deletion rights & access control. streams stream_acl 1000 t stream:contributor Contributors can create new branches and commits, but they cannot edit stream details or manage collaborators. streams stream_acl 500 t stream:reviewer Reviewers can only view (read) the data from this stream. streams stream_acl 100 t -workspace:guest An external guest member of the workspace with limited rights workspaces workspace_acl 50 t workspace:admin Has root on the workspace workspaces workspace_acl 1000 t workspace:member A regular member of the workspace workspaces workspace_acl 100 t +workspace:guest An external guest member of the workspace with limited rights workspaces workspace_acl 50 t \. @@ -487,7 +485,7 @@ workspace:member A regular member of the workspace workspaces workspace_acl 100 -- COPY public.server_acl ("userId", role) FROM stdin; -bd195995fe server:admin +3fb61f0d69 server:admin \. @@ -525,44 +523,44 @@ explorer profile:delete explorer users:read explorer server:stats explorer users:email -sdm streams:read explorer server:setup -sdm streams:write explorer tokens:read -sdm profile:read explorer tokens:write -sdm profile:email explorer users:invite -sdm users:read -sca streams:read explorer workspace:create +explorer workspace:update +explorer workspace:read +explorer workspace:delete +explorer workspace:billing +sca streams:read sca streams:write sca profile:read sca profile:email -explorer workspace:update sca users:read -explorer workspace:read sca users:invite -explorer workspace:delete -explorer workspace:billing -sdm users:invite +spklpwerbi streams:read +spklpwerbi profile:read +spklpwerbi profile:email +spklpwerbi users:read +spklpwerbi users:invite spklexcel streams:read spklexcel streams:write spklexcel profile:read spklexcel profile:email spklexcel users:read spklexcel users:invite -spklpwerbi streams:read -spklpwerbi profile:read -spklpwerbi profile:email -spklpwerbi users:read -spklpwerbi users:invite spklautoma profile:email spklautoma profile:read spklautoma users:read spklautoma tokens:write spklautoma streams:read spklautoma streams:write +sdm streams:read +sdm streams:write +sdm profile:read +sdm profile:email +sdm users:read +sdm users:invite \. @@ -596,7 +594,7 @@ COPY public.sso_providers (id, "providerType", "encryptedProviderData", "created -- COPY public.stream_acl ("userId", "resourceId", role) FROM stdin; -bd195995fe bddc34ce4b stream:owner +3fb61f0d69 47d8fd9d36 stream:owner \. @@ -605,9 +603,9 @@ bd195995fe bddc34ce4b stream:owner -- COPY public.stream_activity ("streamId", "time", "resourceType", "resourceId", "actionType", "userId", info, message) FROM stdin; -\N 2024-12-31 15:25:51.702927+00 user bd195995fe user_create bd195995fe {"user": {"id": "bd195995fe", "ip": null, "bio": null, "name": "Fuzz Test", "email": "fuzztest@example.org", "suuid": "541d6d57-7726-444f-a5ab-baea78144b9d", "avatar": null, "company": null, "profiles": null, "verified": false, "createdAt": "2024-12-31T15:25:51.318Z", "passwordDigest": "$2b$10$EjlFakaD7KampuN3Zhf1lO5rCHK7dOizlmMDyT4Cw6JwAs7jouW.2"}} User created -bddc34ce4b 2024-12-31 15:25:52.2804+00 stream bddc34ce4b stream_create bd195995fe {"input": {"id": "bddc34ce4b", "name": "Rectangular Edifice", "isPublic": true, "createdAt": "2024-12-31T15:25:52.271Z", "regionKey": null, "updatedAt": "2024-12-31T15:25:52.271Z", "clonedFrom": null, "description": "", "workspaceId": null, "isDiscoverable": true, "allowPublicComments": false}} Stream Rectangular Edifice created -bddc34ce4b 2024-12-31 15:26:00.404984+00 branch 833dcf6df1 branch_create bd195995fe {"branch": {"id": "833dcf6df1", "name": "fuzzy", "authorId": "bd195995fe", "streamId": "bddc34ce4b", "createdAt": "2024-12-31T15:26:00.401Z", "updatedAt": "2024-12-31T15:26:00.401Z", "description": null}} Branch created: fuzzy (833dcf6df1) +\N 2024-12-31 17:15:26.189971+00 user 3fb61f0d69 user_create 3fb61f0d69 {"user": {"id": "3fb61f0d69", "ip": null, "bio": null, "name": "Fuzz Test", "email": "fuzztest@example.org", "suuid": "6bff2a82-30db-4d5e-b4a6-78dbb07f0b2b", "avatar": null, "company": null, "profiles": null, "verified": false, "createdAt": "2024-12-31T17:15:25.885Z", "passwordDigest": "$2b$10$n9TiIOXO8PagZ8azbKyGk.fa6u2iju7mgEtDwyiBnRRZGaNLlMUQS"}} User created +47d8fd9d36 2024-12-31 17:15:26.86193+00 stream 47d8fd9d36 stream_create 3fb61f0d69 {"input": {"id": "47d8fd9d36", "name": "Shiny Edifice", "isPublic": true, "createdAt": "2024-12-31T17:15:26.845Z", "regionKey": null, "updatedAt": "2024-12-31T17:15:26.845Z", "clonedFrom": null, "description": "", "workspaceId": null, "isDiscoverable": true, "allowPublicComments": false}} Stream Shiny Edifice created +47d8fd9d36 2024-12-31 17:17:23.701158+00 branch 3c4ce908af branch_create 3fb61f0d69 {"branch": {"id": "3c4ce908af", "name": "fuzzy", "authorId": "3fb61f0d69", "streamId": "47d8fd9d36", "createdAt": "2024-12-31T17:17:23.699Z", "updatedAt": "2024-12-31T17:17:23.699Z", "description": null}} Branch created: fuzzy (3c4ce908af) \. @@ -648,35 +646,35 @@ COPY public.token_resource_access ("tokenId", "resourceId", "resourceType") FROM -- COPY public.token_scopes ("tokenId", "scopeName") FROM stdin; -6d4a0f4aea apps:read -6d4a0f4aea apps:write -6d4a0f4aea streams:read -6d4a0f4aea streams:write -6d4a0f4aea profile:read -6d4a0f4aea profile:email -6d4a0f4aea profile:delete -6d4a0f4aea users:read -6d4a0f4aea server:stats -6d4a0f4aea users:email -6d4a0f4aea server:setup -6d4a0f4aea tokens:read -6d4a0f4aea tokens:write -6d4a0f4aea users:invite -6d4a0f4aea workspace:create -6d4a0f4aea workspace:update -6d4a0f4aea workspace:read -6d4a0f4aea workspace:delete -6d4a0f4aea workspace:billing -d725857cc3 streams:read -d725857cc3 streams:write -d725857cc3 profile:read -d725857cc3 profile:email -d725857cc3 users:read -d725857cc3 server:stats -d725857cc3 workspace:create -d725857cc3 workspace:update -d725857cc3 workspace:read -d725857cc3 workspace:delete +d018e9f40e apps:read +d018e9f40e apps:write +d018e9f40e streams:read +d018e9f40e streams:write +d018e9f40e profile:read +d018e9f40e profile:email +d018e9f40e profile:delete +d018e9f40e users:read +d018e9f40e server:stats +d018e9f40e users:email +d018e9f40e server:setup +d018e9f40e tokens:read +d018e9f40e tokens:write +d018e9f40e users:invite +d018e9f40e workspace:create +d018e9f40e workspace:update +d018e9f40e workspace:read +d018e9f40e workspace:delete +d018e9f40e workspace:billing +314504c3d0 streams:read +314504c3d0 streams:write +314504c3d0 profile:read +314504c3d0 profile:email +314504c3d0 users:read +314504c3d0 server:stats +314504c3d0 workspace:create +314504c3d0 workspace:update +314504c3d0 workspace:read +314504c3d0 workspace:delete \. @@ -685,7 +683,7 @@ d725857cc3 workspace:delete -- COPY public.user_emails (id, email, "primary", verified, "userId", "createdAt", "updatedAt") FROM stdin; -c6c27a75d3 fuzztest@example.org t f bd195995fe 2024-12-31 15:25:51.332+00 2024-12-31 15:25:51.332+00 +fe2c9e7e8a fuzztest@example.org t f 3fb61f0d69 2024-12-31 17:15:25.903+00 2024-12-31 17:15:25.903+00 \. @@ -702,7 +700,7 @@ COPY public.user_notification_preferences ("userId", preferences) FROM stdin; -- COPY public.user_server_app_tokens ("appId", "userId", "tokenId") FROM stdin; -spklwebapp bd195995fe 6d4a0f4aea +spklwebapp 3fb61f0d69 d018e9f40e \. @@ -719,7 +717,7 @@ COPY public.user_sso_sessions ("userId", "providerId", "createdAt", "validUntil" -- COPY public.users_meta ("userId", key, value, "createdAt", "updatedAt") FROM stdin; -bd195995fe isOnboardingFinished true 2024-12-31 15:25:52.382+00 2024-12-31 15:25:52.382+00 +3fb61f0d69 isOnboardingFinished true 2024-12-31 17:15:26.963+00 2024-12-31 17:15:26.964+00 \. diff --git a/setup/fuzzer/token.txt b/setup/fuzzer/token.txt index 11189c3fdc..b9d8db4757 100644 --- a/setup/fuzzer/token.txt +++ b/setup/fuzzer/token.txt @@ -1,2 +1,2 @@ {u'app1': {}} -ApiTokenTag: d725857cc3a13391d2ac209f24e4177606bdb58a5a \ No newline at end of file +ApiTokenTag: 314504c3d01038e2013fb5b1f5d0344422168b1a70 From 5aab55114fb237858e3a13e9c5bf31b9948ad732 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:29:25 +0000 Subject: [PATCH 38/69] remove obsolete step --- .github/workflows/rest-api-fuzzer.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index b22f13d1f8..8c0e058989 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -150,7 +150,7 @@ jobs: ${{ github.workspace }}/Compile key: ${{ steps.cache-grammar-restore.outputs.cache-primary-key }} - - name: Docker Compose up + - name: Deploy dependencies (docker compose) run: | docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml up --detach @@ -160,11 +160,7 @@ jobs: sudo apt-get install --yes --no-install-recommends postgresql-client PGPASSWORD=speckle psql -h 127.0.0.1 -U speckle -d speckle -p 5432 -w < ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle.backup.sql - - name: Configure speckle-server - working-directory: ${{ github.workspace }} - run: | - cp ${{ github.workspace }}/speckle-server/setup/fuzzer/.env.fuzz-test-example .env - - name: Run speckle-server + - name: Deploy speckle-server (docker compose) working-directory: ${{ github.workspace }} timeout-minutes: 1 run: | From 0d5a1c5ff6901b31240d075b4742ed3aaf11b38b Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:22:52 +0000 Subject: [PATCH 39/69] fix migrations in pg dump backup --- setup/fuzzer/speckle.backup.sql | 3503 +++++++++++++++++++++++++++---- setup/fuzzer/token.txt | 2 +- 2 files changed, 3049 insertions(+), 456 deletions(-) diff --git a/setup/fuzzer/speckle.backup.sql b/setup/fuzzer/speckle.backup.sql index 75cb9c3868..fe7c87c45f 100644 --- a/setup/fuzzer/speckle.backup.sql +++ b/setup/fuzzer/speckle.backup.sql @@ -2,7 +2,7 @@ -- PostgreSQL database dump -- --- Dumped from database version 14.5 +-- Dumped from database version 16.4 -- Dumped by pg_dump version 17.2 SET statement_timeout = 0; @@ -17,809 +17,3402 @@ SET xmloption = content; SET client_min_messages = warning; SET row_security = off; +-- +-- Name: pgcrypto; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public; + + +-- +-- Name: EXTENSION pgcrypto; Type: COMMENT; Schema: -; Owner: +-- + +COMMENT ON EXTENSION pgcrypto IS 'cryptographic functions'; + + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: api_tokens; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.api_tokens ( + id character varying(10) NOT NULL, + "tokenDigest" character varying(255), + owner character varying(10) NOT NULL, + name character varying(512), + "lastChars" character varying(6), + revoked boolean DEFAULT false, + lifespan bigint DEFAULT '3154000000000'::bigint, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP, + "lastUsed" timestamp with time zone DEFAULT CURRENT_TIMESTAMP +); + + +ALTER TABLE public.api_tokens OWNER TO speckle; + +-- +-- Name: authorization_codes; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.authorization_codes ( + id character varying(255) NOT NULL, + "appId" character varying(255), + "userId" character varying(255), + challenge character varying(255) NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP, + lifespan bigint DEFAULT '600000'::bigint +); + + +ALTER TABLE public.authorization_codes OWNER TO speckle; + +-- +-- Name: automation_function_runs; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.automation_function_runs ( + id text NOT NULL, + "runId" text NOT NULL, + "functionId" text NOT NULL, + "functionReleaseId" text NOT NULL, + elapsed real NOT NULL, + status text NOT NULL, + "contextView" text, + "statusMessage" text, + results jsonb, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.automation_function_runs OWNER TO speckle; + +-- +-- Name: automation_revision_functions; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.automation_revision_functions ( + "automationRevisionId" text NOT NULL, + "functionId" text NOT NULL, + "functionReleaseId" text NOT NULL, + "functionInputs" text, + id text DEFAULT gen_random_uuid() NOT NULL +); + + +ALTER TABLE public.automation_revision_functions OWNER TO speckle; + +-- +-- Name: automation_revisions; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.automation_revisions ( + id text NOT NULL, + "automationId" text, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + active boolean DEFAULT false NOT NULL, + "userId" text, + "publicKey" character varying(255) NOT NULL +); + + +ALTER TABLE public.automation_revisions OWNER TO speckle; + +-- +-- Name: automation_run_triggers; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.automation_run_triggers ( + "automationRunId" text NOT NULL, + "triggeringId" text NOT NULL, + "triggerType" text NOT NULL +); + + +ALTER TABLE public.automation_run_triggers OWNER TO speckle; + +-- +-- Name: automation_runs; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.automation_runs ( + id text NOT NULL, + "automationRevisionId" text NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + status character varying(255) NOT NULL, + "executionEngineRunId" text +); + + +ALTER TABLE public.automation_runs OWNER TO speckle; + +-- +-- Name: automation_tokens; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.automation_tokens ( + "automationId" text NOT NULL, + "automateToken" text NOT NULL +); + + +ALTER TABLE public.automation_tokens OWNER TO speckle; + +-- +-- Name: automation_triggers; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.automation_triggers ( + "automationRevisionId" text NOT NULL, + "triggerType" text NOT NULL, + "triggeringId" text NOT NULL +); + + +ALTER TABLE public.automation_triggers OWNER TO speckle; + +-- +-- Name: automations; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.automations ( + id text NOT NULL, + name text NOT NULL, + "projectId" text, + enabled boolean NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "executionEngineAutomationId" text DEFAULT ''::text, + "userId" text, + "isTestAutomation" boolean DEFAULT false NOT NULL +); + + +ALTER TABLE public.automations OWNER TO speckle; + +-- +-- Name: blob_storage; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.blob_storage ( + id character varying(255) NOT NULL, + "streamId" character varying(10) NOT NULL, + "userId" character varying(10), + "objectKey" character varying(255), + "fileName" character varying(255) NOT NULL, + "fileType" character varying(255) NOT NULL, + "fileSize" integer, + "uploadStatus" integer DEFAULT 0 NOT NULL, + "uploadError" character varying(255), + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + "fileHash" character varying(255) +); + + +ALTER TABLE public.blob_storage OWNER TO speckle; + +-- +-- Name: branch_commits; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.branch_commits ( + "branchId" character varying(10) NOT NULL, + "commitId" character varying(255) NOT NULL +); + + +ALTER TABLE public.branch_commits OWNER TO speckle; + +-- +-- Name: branches; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.branches ( + id character varying(10) NOT NULL, + "streamId" character varying(10) NOT NULL, + "authorId" character varying(10), + name character varying(512) NOT NULL, + description character varying(65536), + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP +); + + +ALTER TABLE public.branches OWNER TO speckle; + +-- +-- Name: comment_links; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.comment_links ( + "commentId" character varying(10), + "resourceId" character varying(255) NOT NULL, + "resourceType" character varying(255) NOT NULL, + CONSTRAINT "comment_links_resourceType_check" CHECK ((("resourceType")::text = ANY ((ARRAY['stream'::character varying, 'commit'::character varying, 'object'::character varying, 'comment'::character varying])::text[]))) +); + + +ALTER TABLE public.comment_links OWNER TO speckle; + +-- +-- Name: comment_views; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.comment_views ( + "commentId" character varying(10) NOT NULL, + "userId" character varying(10) NOT NULL, + "viewedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP +); + + +ALTER TABLE public.comment_views OWNER TO speckle; + +-- +-- Name: comments; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.comments ( + id character varying(10) NOT NULL, + "streamId" character varying(10) NOT NULL, + "authorId" character varying(10) NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + text text, + screenshot text, + data jsonb, + archived boolean DEFAULT false NOT NULL, + "parentComment" character varying(10) DEFAULT NULL::character varying +); + + +ALTER TABLE public.comments OWNER TO speckle; + +-- +-- Name: commits; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.commits ( + id character varying(10) NOT NULL, + "referencedObject" character varying(255) NOT NULL, + author character varying(10), + message character varying(65536) DEFAULT 'no message'::character varying, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + "sourceApplication" character varying(1024), + "totalChildrenCount" integer, + parents text[] +); + + +ALTER TABLE public.commits OWNER TO speckle; + +-- +-- Name: email_verifications; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.email_verifications ( + id character varying(255) NOT NULL, + email character varying(255), + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP +); + + +ALTER TABLE public.email_verifications OWNER TO speckle; + +-- +-- Name: file_uploads; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.file_uploads ( + id character varying(255) NOT NULL, + "streamId" character varying(10), + "branchName" character varying(255) NOT NULL, + "userId" character varying(255) NOT NULL, + "fileName" character varying(255) NOT NULL, + "fileType" character varying(255) NOT NULL, + "fileSize" integer, + "uploadComplete" boolean DEFAULT false NOT NULL, + "uploadDate" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + "convertedStatus" integer DEFAULT 0 NOT NULL, + "convertedLastUpdate" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + "convertedMessage" character varying(255), + "convertedCommitId" character varying(255) +); + + +ALTER TABLE public.file_uploads OWNER TO speckle; + +-- +-- Name: gendo_ai_renders; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.gendo_ai_renders ( + id text NOT NULL, + "userId" text, + "projectId" text, + "modelId" text, + "versionId" text, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "gendoGenerationId" text, + status text NOT NULL, + prompt text NOT NULL, + camera jsonb NOT NULL, + "baseImage" text NOT NULL, + "responseImage" text +); + + +ALTER TABLE public.gendo_ai_renders OWNER TO speckle; + +-- +-- Name: gendo_user_credits; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.gendo_user_credits ( + "userId" character varying(255) NOT NULL, + "resetDate" timestamp(3) with time zone NOT NULL, + used integer NOT NULL +); + + +ALTER TABLE public.gendo_user_credits OWNER TO speckle; + +-- +-- Name: knex_migrations; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.knex_migrations ( + id integer NOT NULL, + name character varying(255), + batch integer, + migration_time timestamp with time zone +); + + +ALTER TABLE public.knex_migrations OWNER TO speckle; + +-- +-- Name: knex_migrations_id_seq; Type: SEQUENCE; Schema: public; Owner: speckle +-- + +CREATE SEQUENCE public.knex_migrations_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER SEQUENCE public.knex_migrations_id_seq OWNER TO speckle; + +-- +-- Name: knex_migrations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: speckle +-- + +ALTER SEQUENCE public.knex_migrations_id_seq OWNED BY public.knex_migrations.id; + + +-- +-- Name: knex_migrations_lock; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.knex_migrations_lock ( + index integer NOT NULL, + is_locked integer +); + + +ALTER TABLE public.knex_migrations_lock OWNER TO speckle; + +-- +-- Name: knex_migrations_lock_index_seq; Type: SEQUENCE; Schema: public; Owner: speckle +-- + +CREATE SEQUENCE public.knex_migrations_lock_index_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER SEQUENCE public.knex_migrations_lock_index_seq OWNER TO speckle; + +-- +-- Name: knex_migrations_lock_index_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: speckle +-- + +ALTER SEQUENCE public.knex_migrations_lock_index_seq OWNED BY public.knex_migrations_lock.index; + + +-- +-- Name: object_children_closure; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.object_children_closure ( + parent character varying(255) NOT NULL, + child character varying(255) NOT NULL, + "minDepth" integer DEFAULT 1 NOT NULL, + "streamId" character varying(10) NOT NULL +); + + +ALTER TABLE public.object_children_closure OWNER TO speckle; + +-- +-- Name: object_preview; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.object_preview ( + "streamId" character varying(10) NOT NULL, + "objectId" character varying(255) NOT NULL, + "previewStatus" integer DEFAULT 0 NOT NULL, + priority integer DEFAULT 1 NOT NULL, + "lastUpdate" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + preview jsonb +); + + +ALTER TABLE public.object_preview OWNER TO speckle; + +-- +-- Name: objects; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.objects ( + id character varying(255) NOT NULL, + "speckleType" character varying(1024) DEFAULT 'Base'::character varying NOT NULL, + "totalChildrenCount" integer, + "totalChildrenCountByDepth" jsonb, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP, + data jsonb, + "streamId" character varying(10) NOT NULL +); + + +ALTER TABLE public.objects OWNER TO speckle; + +-- +-- Name: personal_api_tokens; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.personal_api_tokens ( + "tokenId" character varying(255), + "userId" character varying(255) +); + + +ALTER TABLE public.personal_api_tokens OWNER TO speckle; + +-- +-- Name: previews; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.previews ( + id character varying(255) NOT NULL, + data bytea +); + + +ALTER TABLE public.previews OWNER TO speckle; + +-- +-- Name: pwdreset_tokens; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.pwdreset_tokens ( + id character varying(255) DEFAULT gen_random_uuid() NOT NULL, + email character varying(256) NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP +); + + +ALTER TABLE public.pwdreset_tokens OWNER TO speckle; + +-- +-- Name: ratelimit_actions; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.ratelimit_actions ( + "timestamp" timestamp with time zone DEFAULT CURRENT_TIMESTAMP, + action character varying(255) NOT NULL, + source character varying(255) NOT NULL +); + + +ALTER TABLE public.ratelimit_actions OWNER TO speckle; + +-- +-- Name: refresh_tokens; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.refresh_tokens ( + id character varying(255) NOT NULL, + "tokenDigest" character varying(255) NOT NULL, + "appId" character varying(255), + "userId" character varying(255), + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP, + lifespan bigint DEFAULT '15770000000'::bigint +); + + +ALTER TABLE public.refresh_tokens OWNER TO speckle; + +-- +-- Name: regions; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.regions ( + key character varying(255) NOT NULL, + name character varying(255) NOT NULL, + description text, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.regions OWNER TO speckle; + +-- +-- Name: scheduled_tasks; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.scheduled_tasks ( + "taskName" character varying(255) NOT NULL, + "lockExpiresAt" timestamp(3) with time zone NOT NULL +); + + +ALTER TABLE public.scheduled_tasks OWNER TO speckle; + +-- +-- Name: scopes; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.scopes ( + name character varying(512) NOT NULL, + description character varying(512) NOT NULL, + public boolean DEFAULT true +); + + +ALTER TABLE public.scopes OWNER TO speckle; + +-- +-- Name: server_access_requests; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.server_access_requests ( + id character varying(10) NOT NULL, + "requesterId" character varying(10) NOT NULL, + "resourceType" character varying(255) NOT NULL, + "resourceId" character varying(255), + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.server_access_requests OWNER TO speckle; + +-- +-- Name: server_acl; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.server_acl ( + "userId" character varying(10) NOT NULL, + role character varying(255) NOT NULL +); + + +ALTER TABLE public.server_acl OWNER TO speckle; + +-- +-- Name: server_apps; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.server_apps ( + id character varying(10) NOT NULL, + secret character varying(10), + name character varying(256) NOT NULL, + description character varying(512), + "termsAndConditionsLink" character varying(256), + logo character varying(524288), + public boolean DEFAULT false, + "trustByDefault" boolean DEFAULT false, + "authorId" character varying(255), + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP, + "redirectUrl" character varying(100) NOT NULL +); + + +ALTER TABLE public.server_apps OWNER TO speckle; + +-- +-- Name: server_apps_scopes; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.server_apps_scopes ( + "appId" character varying(255) NOT NULL, + "scopeName" character varying(255) NOT NULL +); + + +ALTER TABLE public.server_apps_scopes OWNER TO speckle; + +-- +-- Name: server_config; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.server_config ( + id integer DEFAULT 0 NOT NULL, + name character varying(255) DEFAULT 'My new Speckle Server'::character varying, + company character varying(255) DEFAULT 'Unknown Company'::character varying, + description character varying(255) DEFAULT 'This a community deployment of a Speckle Server.'::character varying, + "adminContact" character varying(255) DEFAULT 'n/a'::character varying, + "termsOfService" character varying(255) DEFAULT 'n/a'::character varying, + "canonicalUrl" character varying(255), + completed boolean DEFAULT false, + "inviteOnly" boolean DEFAULT false, + "guestModeEnabled" boolean DEFAULT false NOT NULL +); + + +ALTER TABLE public.server_config OWNER TO speckle; + +-- +-- Name: server_invites; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.server_invites ( + id character varying(255) DEFAULT gen_random_uuid() NOT NULL, + target character varying(256) NOT NULL, + "inviterId" character varying(256) NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + message character varying(1024), + token character varying(256) DEFAULT ''::character varying NOT NULL, + resource jsonb DEFAULT '{}'::jsonb NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.server_invites OWNER TO speckle; + +-- +-- Name: sso_providers; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.sso_providers ( + id text NOT NULL, + "providerType" text NOT NULL, + "encryptedProviderData" text NOT NULL, + "createdAt" timestamp(3) with time zone NOT NULL, + "updatedAt" timestamp(3) with time zone NOT NULL +); + + +ALTER TABLE public.sso_providers OWNER TO speckle; + +-- +-- Name: stream_acl; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.stream_acl ( + "userId" character varying(10) NOT NULL, + "resourceId" character varying(10) NOT NULL, + role character varying(255) NOT NULL +); + + +ALTER TABLE public.stream_acl OWNER TO speckle; + +-- +-- Name: stream_activity; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.stream_activity ( + "streamId" character varying(10), + "time" timestamp with time zone DEFAULT CURRENT_TIMESTAMP, + "resourceType" character varying(255), + "resourceId" character varying(255), + "actionType" character varying(255), + "userId" character varying(255), + info jsonb, + message character varying(255) +); + + +ALTER TABLE public.stream_activity OWNER TO speckle; + +-- +-- Name: stream_commits; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.stream_commits ( + "streamId" character varying(10) NOT NULL, + "commitId" character varying(255) NOT NULL +); + + +ALTER TABLE public.stream_commits OWNER TO speckle; + +-- +-- Name: stream_favorites; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.stream_favorites ( + "streamId" character varying(10) NOT NULL, + "userId" character varying(10) NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + cursor integer NOT NULL +); + + +ALTER TABLE public.stream_favorites OWNER TO speckle; + +-- +-- Name: stream_favorites_cursor_seq; Type: SEQUENCE; Schema: public; Owner: speckle +-- + +CREATE SEQUENCE public.stream_favorites_cursor_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER SEQUENCE public.stream_favorites_cursor_seq OWNER TO speckle; + +-- +-- Name: stream_favorites_cursor_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: speckle +-- + +ALTER SEQUENCE public.stream_favorites_cursor_seq OWNED BY public.stream_favorites.cursor; + + +-- +-- Name: streams; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.streams ( + id character varying(10) NOT NULL, + name character varying(512) DEFAULT 'Unnamed Stream'::character varying NOT NULL, + description character varying(65536), + "isPublic" boolean DEFAULT true, + "clonedFrom" character varying(10), + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + "allowPublicComments" boolean DEFAULT false, + "isDiscoverable" boolean DEFAULT false NOT NULL, + "workspaceId" character varying(255), + "regionKey" text +); + + +ALTER TABLE public.streams OWNER TO speckle; + +-- +-- Name: streams_meta; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.streams_meta ( + "streamId" character varying(10) NOT NULL, + key character varying(255) NOT NULL, + value json, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.streams_meta OWNER TO speckle; + +-- +-- Name: token_resource_access; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.token_resource_access ( + "tokenId" character varying(10) NOT NULL, + "resourceId" character varying(255) NOT NULL, + "resourceType" character varying(255) NOT NULL +); + + +ALTER TABLE public.token_resource_access OWNER TO speckle; + +-- +-- Name: token_scopes; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.token_scopes ( + "tokenId" character varying(255) NOT NULL, + "scopeName" character varying(255) NOT NULL +); + + +ALTER TABLE public.token_scopes OWNER TO speckle; + +-- +-- Name: user_emails; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.user_emails ( + id character varying(255) NOT NULL, + email character varying(255) NOT NULL, + "primary" boolean DEFAULT false, + verified boolean DEFAULT false, + "userId" character varying(255) NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.user_emails OWNER TO speckle; + +-- +-- Name: user_notification_preferences; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.user_notification_preferences ( + "userId" character varying(10) NOT NULL, + preferences jsonb NOT NULL +); + + +ALTER TABLE public.user_notification_preferences OWNER TO speckle; + +-- +-- Name: user_roles; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.user_roles ( + name character varying(256) NOT NULL, + description character varying(256) NOT NULL, + "resourceTarget" character varying(256) NOT NULL, + "aclTableName" character varying(256) NOT NULL, + weight integer DEFAULT 100 NOT NULL, + public boolean DEFAULT true +); + + +ALTER TABLE public.user_roles OWNER TO speckle; + +-- +-- Name: user_server_app_tokens; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.user_server_app_tokens ( + "appId" character varying(255) NOT NULL, + "userId" character varying(255) NOT NULL, + "tokenId" character varying(255) NOT NULL +); + + +ALTER TABLE public.user_server_app_tokens OWNER TO speckle; + +-- +-- Name: user_sso_sessions; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.user_sso_sessions ( + "userId" character varying(255) NOT NULL, + "providerId" character varying(255) NOT NULL, + "createdAt" timestamp(3) with time zone NOT NULL, + "validUntil" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.user_sso_sessions OWNER TO speckle; + +-- +-- Name: users; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.users ( + id character varying(10) NOT NULL, + suuid character varying(255) DEFAULT gen_random_uuid(), + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP, + name character varying(512) NOT NULL, + bio character varying(2048), + company character varying(512), + email character varying(255) NOT NULL, + verified boolean DEFAULT false, + avatar character varying(524288), + profiles jsonb, + "passwordDigest" character varying(255), + ip character varying(50) +); + + +ALTER TABLE public.users OWNER TO speckle; + +-- +-- Name: users_meta; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.users_meta ( + "userId" character varying(10) NOT NULL, + key character varying(255) NOT NULL, + value json, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.users_meta OWNER TO speckle; + +-- +-- Name: webhooks_config; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.webhooks_config ( + id character varying(255) NOT NULL, + "streamId" character varying(10), + url text, + description text, + triggers jsonb, + secret character varying(255), + enabled boolean DEFAULT true, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.webhooks_config OWNER TO speckle; + +-- +-- Name: webhooks_events; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.webhooks_events ( + id character varying(255) NOT NULL, + "webhookId" character varying(255), + status integer DEFAULT 0 NOT NULL, + "statusInfo" text DEFAULT 'Pending'::text NOT NULL, + "lastUpdate" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + payload text +); + + +ALTER TABLE public.webhooks_events OWNER TO speckle; + +-- +-- Name: workspace_acl; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.workspace_acl ( + "userId" text NOT NULL, + "workspaceId" text NOT NULL, + role text NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.workspace_acl OWNER TO speckle; + +-- +-- Name: workspace_checkout_sessions; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.workspace_checkout_sessions ( + "workspaceId" text NOT NULL, + id text NOT NULL, + url text NOT NULL, + "workspacePlan" text NOT NULL, + "paymentStatus" text NOT NULL, + "billingInterval" text NOT NULL, + "createdAt" timestamp(3) with time zone NOT NULL, + "updatedAt" timestamp(3) with time zone NOT NULL +); + + +ALTER TABLE public.workspace_checkout_sessions OWNER TO speckle; + +-- +-- Name: workspace_creation_state; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.workspace_creation_state ( + "workspaceId" text NOT NULL, + completed boolean NOT NULL, + state jsonb NOT NULL +); + + +ALTER TABLE public.workspace_creation_state OWNER TO speckle; + +-- +-- Name: workspace_domains; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.workspace_domains ( + id text NOT NULL, + domain text NOT NULL, + verified boolean NOT NULL, + "createdAt" timestamp(3) with time zone NOT NULL, + "updatedAt" timestamp(3) with time zone NOT NULL, + "createdByUserId" text, + "workspaceId" text +); + + +ALTER TABLE public.workspace_domains OWNER TO speckle; + +-- +-- Name: workspace_plans; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.workspace_plans ( + "workspaceId" text NOT NULL, + name text NOT NULL, + status text NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.workspace_plans OWNER TO speckle; + +-- +-- Name: workspace_regions; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.workspace_regions ( + "workspaceId" text NOT NULL, + "regionKey" character varying(255) NOT NULL, + "createdAt" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +ALTER TABLE public.workspace_regions OWNER TO speckle; + +-- +-- Name: workspace_sso_providers; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.workspace_sso_providers ( + "workspaceId" character varying(255) NOT NULL, + "providerId" character varying(255) NOT NULL +); + + +ALTER TABLE public.workspace_sso_providers OWNER TO speckle; + +-- +-- Name: workspace_subscriptions; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.workspace_subscriptions ( + "workspaceId" text NOT NULL, + "createdAt" timestamp(3) with time zone NOT NULL, + "updatedAt" timestamp(3) with time zone NOT NULL, + "currentBillingCycleEnd" timestamp(3) with time zone NOT NULL, + "billingInterval" text NOT NULL, + "subscriptionData" jsonb NOT NULL +); + + +ALTER TABLE public.workspace_subscriptions OWNER TO speckle; + +-- +-- Name: workspaces; Type: TABLE; Schema: public; Owner: speckle +-- + +CREATE TABLE public.workspaces ( + id text NOT NULL, + name text NOT NULL, + description text, + "createdAt" timestamp(3) with time zone NOT NULL, + "updatedAt" timestamp(3) with time zone NOT NULL, + logo text, + "domainBasedMembershipProtectionEnabled" boolean DEFAULT false, + "discoverabilityEnabled" boolean DEFAULT false, + "defaultLogoIndex" integer DEFAULT 0 NOT NULL, + "defaultProjectRole" text DEFAULT 'stream:contributor'::text NOT NULL, + slug text DEFAULT "substring"(md5((random())::text), 0, 15) NOT NULL, + CONSTRAINT "workspaces_defaultProjectRole_check" CHECK (("defaultProjectRole" = ANY (ARRAY['stream:reviewer'::text, 'stream:contributor'::text]))) +); + + +ALTER TABLE public.workspaces OWNER TO speckle; + +-- +-- Name: knex_migrations id; Type: DEFAULT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.knex_migrations ALTER COLUMN id SET DEFAULT nextval('public.knex_migrations_id_seq'::regclass); + + +-- +-- Name: knex_migrations_lock index; Type: DEFAULT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.knex_migrations_lock ALTER COLUMN index SET DEFAULT nextval('public.knex_migrations_lock_index_seq'::regclass); + + +-- +-- Name: stream_favorites cursor; Type: DEFAULT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.stream_favorites ALTER COLUMN cursor SET DEFAULT nextval('public.stream_favorites_cursor_seq'::regclass); + + +-- +-- Data for Name: api_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.api_tokens (id, "tokenDigest", owner, name, "lastChars", revoked, lifespan, "createdAt", "lastUsed") FROM stdin; +103b2cf861 $2b$10$sXlCE3EMfJ1uJbRE0B/W7.yVmq6uhbTaQk4hv9Pr1da.nb6bxKz4i 97553902db all f08d12 f 3154000000000 2024-12-31 18:20:52.507493+00 2024-12-31 18:20:52.507493+00 +76dcc62da6 $2b$10$/ogEcKpuc4tIl7/C6Z7xSOY9UpFmg/I1LczjsE74Pu7dNI6l20oDi 97553902db Speckle Web Manager-token cf8995 f 3154000000000 2024-12-31 18:20:13.022497+00 2024-12-31 18:20:52.602+00 +\. + + +-- +-- Data for Name: authorization_codes; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.authorization_codes (id, "appId", "userId", challenge, "createdAt", lifespan) FROM stdin; +\. + + +-- +-- Data for Name: automation_function_runs; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_function_runs (id, "runId", "functionId", "functionReleaseId", elapsed, status, "contextView", "statusMessage", results, "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- Data for Name: automation_revision_functions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_revision_functions ("automationRevisionId", "functionId", "functionReleaseId", "functionInputs", id) FROM stdin; +\. + + +-- +-- Data for Name: automation_revisions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_revisions (id, "automationId", "createdAt", active, "userId", "publicKey") FROM stdin; +\. + + +-- +-- Data for Name: automation_run_triggers; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_run_triggers ("automationRunId", "triggeringId", "triggerType") FROM stdin; +\. + + +-- +-- Data for Name: automation_runs; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_runs (id, "automationRevisionId", "createdAt", "updatedAt", status, "executionEngineRunId") FROM stdin; +\. + + +-- +-- Data for Name: automation_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_tokens ("automationId", "automateToken") FROM stdin; +\. + + +-- +-- Data for Name: automation_triggers; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automation_triggers ("automationRevisionId", "triggerType", "triggeringId") FROM stdin; +\. + + +-- +-- Data for Name: automations; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.automations (id, name, "projectId", enabled, "createdAt", "updatedAt", "executionEngineAutomationId", "userId", "isTestAutomation") FROM stdin; +\. + + +-- +-- Data for Name: blob_storage; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.blob_storage (id, "streamId", "userId", "objectKey", "fileName", "fileType", "fileSize", "uploadStatus", "uploadError", "createdAt", "fileHash") FROM stdin; +\. + + +-- +-- Data for Name: branch_commits; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.branch_commits ("branchId", "commitId") FROM stdin; +\. + + +-- +-- Data for Name: branches; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.branches (id, "streamId", "authorId", name, description, "createdAt", "updatedAt") FROM stdin; +12d47076c2 815704124b 97553902db main default branch 2024-12-31 18:20:13.449+00 2024-12-31 18:20:13.449+00 +eb9f7ac487 815704124b 97553902db fuzzy \N 2024-12-31 18:20:22.054+00 2024-12-31 18:20:22.054+00 +\. + + +-- +-- Data for Name: comment_links; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.comment_links ("commentId", "resourceId", "resourceType") FROM stdin; +\. + + +-- +-- Data for Name: comment_views; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.comment_views ("commentId", "userId", "viewedAt") FROM stdin; +\. + + +-- +-- Data for Name: comments; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.comments (id, "streamId", "authorId", "createdAt", "updatedAt", text, screenshot, data, archived, "parentComment") FROM stdin; +\. + + +-- +-- Data for Name: commits; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.commits (id, "referencedObject", author, message, "createdAt", "sourceApplication", "totalChildrenCount", parents) FROM stdin; +\. + + +-- +-- Data for Name: email_verifications; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.email_verifications (id, email, "createdAt") FROM stdin; +26e9f15af9c55a268ff6 fuzztest@example.org 2024-12-31 18:20:12.443+00 +\. + + +-- +-- Data for Name: file_uploads; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.file_uploads (id, "streamId", "branchName", "userId", "fileName", "fileType", "fileSize", "uploadComplete", "uploadDate", "convertedStatus", "convertedLastUpdate", "convertedMessage", "convertedCommitId") FROM stdin; +\. + + +-- +-- Data for Name: gendo_ai_renders; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.gendo_ai_renders (id, "userId", "projectId", "modelId", "versionId", "createdAt", "updatedAt", "gendoGenerationId", status, prompt, camera, "baseImage", "responseImage") FROM stdin; +\. + + +-- +-- Data for Name: gendo_user_credits; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.gendo_user_credits ("userId", "resetDate", used) FROM stdin; +\. + + +-- +-- Data for Name: knex_migrations; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.knex_migrations (id, name, batch, migration_time) FROM stdin; +28 000-core.js 1 2024-12-31 18:18:10.955+00 +29 2020-05-29-apps.js 1 2024-12-31 18:18:11.025+00 +30 20201222100048_add_sourceapp_to_commits.js 1 2024-12-31 18:18:11.028+00 +31 20201222101522_add_totalchildrencount_to_commits.js 1 2024-12-31 18:18:11.032+00 +32 20201223120532_add_commit_parents_simplification.js 1 2024-12-31 18:18:11.043+00 +33 20201230111428_add_scopes_public_field.js 1 2024-12-31 18:18:11.047+00 +34 20210225130308_add_roles_public_field.js 1 2024-12-31 18:18:11.052+00 +35 20210303185834_invites.js 1 2024-12-31 18:18:11.065+00 +36 20210304111614_pwdreset.js 1 2024-12-31 18:18:11.075+00 +37 20210314101154_add_invitefield_to_serverinfo.js 1 2024-12-31 18:18:11.078+00 +38 20210322190000_add_streamid_to_objects.js 1 2024-12-31 18:18:11.129+00 +39 20210426200000-previews.js 1 2024-12-31 18:18:11.148+00 +40 20210603160000_optional_user_references.js 1 2024-12-31 18:18:11.16+00 +41 20210616173000_stream_activity.js 1 2024-12-31 18:18:11.169+00 +42 20210701180000-webhooks.js 1 2024-12-31 18:18:11.193+00 +43 20210915130000-fileuploads.js 1 2024-12-31 18:18:11.205+00 +44 20211119105730_de_duplicate_users.js 1 2024-12-31 18:18:11.208+00 +45 20220118181256-email-verifications.js 1 2024-12-31 18:18:11.218+00 +46 20220222173000_comments.js 1 2024-12-31 18:18:11.246+00 +47 20220315140000_ratelimit.js 1 2024-12-31 18:18:11.261+00 +48 20220318121405_add_stream_favorites.js 1 2024-12-31 18:18:11.277+00 +49 20220412150558_stream-public-comments.js 1 2024-12-31 18:18:11.28+00 +50 202206030936_add_asset_storage.js 1 2024-12-31 18:18:11.286+00 +51 202206231429_add_file_hash_to_blobs.js 1 2024-12-31 18:18:11.289+00 +52 20220629110918_server_invites_rework.js 1 2024-12-31 18:18:11.303+00 +53 20220707135553_make_users_email_not_nullable.js 1 2024-12-31 18:18:11.31+00 +54 20220722092821_add_invite_token_field.js 1 2024-12-31 18:18:11.317+00 +55 20220722110643_fix_comments_delete_cascade.js 1 2024-12-31 18:18:11.328+00 +56 20220727091536_blobs-id-length-removal.js 1 2024-12-31 18:18:11.331+00 +57 20220803104832_ts_test.js 1 2024-12-31 18:18:11.332+00 +58 20220819091523_add_stream_discoverable_field.js 1 2024-12-31 18:18:11.333+00 +59 20220823100915_migrate_streams_to_lower_precision_timestamps.js 1 2024-12-31 18:18:11.349+00 +60 20220825082631_drop_email_verifications_used_col.js 1 2024-12-31 18:18:11.359+00 +61 20220825123323_usernotificationpreferences.js 1 2024-12-31 18:18:11.367+00 +62 20220829102231_add_server_access_requests_table.js 1 2024-12-31 18:18:11.379+00 +63 20220921084935_fix_branch_nullability.js 1 2024-12-31 18:18:11.385+00 +64 20220929141717_scheduled_tasks.js 1 2024-12-31 18:18:11.389+00 +65 20221104104921_webhooks_drop_stream_fk.js 1 2024-12-31 18:18:11.392+00 +66 20221122133014_add_user_onboarding_data.js 1 2024-12-31 18:18:11.394+00 +67 20221213124322_migrate_more_table_precisions.js 1 2024-12-31 18:18:11.43+00 +68 20230316091225_create_users_meta_table.js 1 2024-12-31 18:18:11.438+00 +69 20230316132827_remove_user_is_onboarding_complete_col.js 1 2024-12-31 18:18:11.442+00 +70 20230330082209_stricter_file_uploads_schema.js 1 2024-12-31 18:18:11.469+00 +71 20230517122919_clean_up_invalid_stream_invites.js 1 2024-12-31 18:18:11.472+00 +72 20230713094611_create_streams_meta_table.js 1 2024-12-31 18:18:11.478+00 +73 20230727150957_serverGuestMode.js 1 2024-12-31 18:18:11.48+00 +74 20230818075729_add_invite_server_role_support.js 1 2024-12-31 18:18:11.482+00 +75 20230905162038_automations.js 1 2024-12-31 18:18:11.498+00 +76 20230907131636_migrate_invites_to_lower_precision_timestamps.js 1 2024-12-31 18:18:11.511+00 +77 20230912114629_automations_tables_normalization.js 1 2024-12-31 18:18:11.538+00 +78 20230914071540_make_function_run_results_nullable.js 1 2024-12-31 18:18:11.542+00 +79 20230919080704_add_webhook_config_timestamps.js 1 2024-12-31 18:18:11.545+00 +80 20230920130032_fix_project_delete_cascade.js 1 2024-12-31 18:18:11.555+00 +81 20231025100054_automation_function_name_and_logo.js 1 2024-12-31 18:18:11.557+00 +82 20240109101048_create_token_resource_access_table.js 1 2024-12-31 18:18:11.565+00 +83 20240304143445_rename_tables.js 1 2024-12-31 18:18:11.573+00 +84 20240305120620_automate.js 1 2024-12-31 18:18:11.616+00 +85 20240321092858_triggers.js 1 2024-12-31 18:18:11.65+00 +86 20240404075414_revision_active.js 1 2024-12-31 18:18:11.654+00 +87 20240404173455_automation_token.js 1 2024-12-31 18:18:11.686+00 +88 20240507075055_add_function_run_timestamps.js 1 2024-12-31 18:18:11.691+00 +89 20240507140149_add_encryption_support.js 1 2024-12-31 18:18:11.7+00 +90 20240522130000_gendo.js 1 2024-12-31 18:18:11.722+00 +91 20240523192300_add_is_test_automation_column.js 1 2024-12-31 18:18:11.727+00 +92 20240620105859_drop_beta_tables.js 1 2024-12-31 18:18:11.743+00 +93 20240621174016_workspaces.js 1 2024-12-31 18:18:11.774+00 +94 20240628112300_dropCreatorId.js 1 2024-12-31 18:18:11.779+00 +95 20240703084247_user-emails.js 1 2024-12-31 18:18:11.793+00 +96 20240710154658_user_emails_backfill.js 1 2024-12-31 18:18:11.8+00 +97 20240716094858_generalized_invite_record_resources.js 1 2024-12-31 18:18:11.805+00 +98 20240716134617_migrate_to_resources_array.js 1 2024-12-31 18:18:11.82+00 +99 20240801000000_logos.js 1 2024-12-31 18:18:11.824+00 +100 20240802212846_cascadeDeleteWorkspaceProjects.js 1 2024-12-31 18:18:11.83+00 +101 20240806160740_workspace_domains.js 1 2024-12-31 18:18:11.846+00 +102 20240807174901_add_column_domainBasedMembershipProtection.js 1 2024-12-31 18:18:11.849+00 +103 20240808091944_add_workspace_discovery_flag.js 1 2024-12-31 18:18:11.851+00 +104 20240808140602_add_invite_updated_at.js 1 2024-12-31 18:18:11.854+00 +105 20240813125251_workspaceAclWithTimestamps.js 1 2024-12-31 18:18:11.859+00 +106 20240820131619_fallbackWorkspaceLogo.js 1 2024-12-31 18:18:11.861+00 +107 20240910163614_add_column_defaultProjectRole.js 1 2024-12-31 18:18:11.865+00 +108 20240912134548_add_workspace_slug.js 1 2024-12-31 18:18:11.875+00 +109 20240926112407_copy_workspace_slug.js 1 2024-12-31 18:18:11.877+00 +110 20240930141322_workspace_sso.js 1 2024-12-31 18:18:11.901+00 +111 20241014092507_workspace_sso_expiration.js 1 2024-12-31 18:18:11.905+00 +112 20241018132400_workspace_checkout.js 1 2024-12-31 18:18:11.928+00 +113 20241031081827_create_regions_table.js 1 2024-12-31 18:18:11.938+00 +114 20241101055531_project_region.js 1 2024-12-31 18:18:11.944+00 +115 20241102055157_project_region_nofk.js 1 2024-12-31 18:18:11.948+00 +116 20241105070219_create_workspace_regions_table.js 1 2024-12-31 18:18:11.96+00 +117 20241105144301_cascade_delete_workspace_plans.js 1 2024-12-31 18:18:11.965+00 +118 20241120063859_cascade_delete_checkout_session.js 1 2024-12-31 18:18:11.975+00 +119 20241120140402_gendo_credits.js 1 2024-12-31 18:18:11.98+00 +120 20241126084242_workspace_plan_rename.js 1 2024-12-31 18:18:11.985+00 +121 20241126142602_workspace_plan_date.js 1 2024-12-31 18:18:11.99+00 +122 20241128153315_workspace_creation_state.js 1 2024-12-31 18:18:12.018+00 +123 20241202183039_workspace_start_trial.js 1 2024-12-31 18:18:12.02+00 +124 20241203212110_cascade_delete_automations.js 1 2024-12-31 18:18:12.034+00 +\. + + +-- +-- Data for Name: knex_migrations_lock; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.knex_migrations_lock (index, is_locked) FROM stdin; +1 0 +\. + + +-- +-- Data for Name: object_children_closure; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.object_children_closure (parent, child, "minDepth", "streamId") FROM stdin; +\. + + +-- +-- Data for Name: object_preview; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.object_preview ("streamId", "objectId", "previewStatus", priority, "lastUpdate", preview) FROM stdin; +\. + + +-- +-- Data for Name: objects; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.objects (id, "speckleType", "totalChildrenCount", "totalChildrenCountByDepth", "createdAt", data, "streamId") FROM stdin; +\. + + +-- +-- Data for Name: personal_api_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.personal_api_tokens ("tokenId", "userId") FROM stdin; +103b2cf861 97553902db +\. + + +-- +-- Data for Name: previews; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.previews (id, data) FROM stdin; +\. + + +-- +-- Data for Name: pwdreset_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.pwdreset_tokens (id, email, "createdAt") FROM stdin; +\. + + +-- +-- Data for Name: ratelimit_actions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.ratelimit_actions ("timestamp", action, source) FROM stdin; +\. + + +-- +-- Data for Name: refresh_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.refresh_tokens (id, "tokenDigest", "appId", "userId", "createdAt", lifespan) FROM stdin; +2ae2e16b37 $2b$10$5vBmyUXjCAcE5YEJIa6sJebJkN9ouvOJQUWvoa9vtZhuBDkXSN6KG spklwebapp 97553902db 2024-12-31 18:20:13.099546+00 15770000000 +\. + + +-- +-- Data for Name: regions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.regions (key, name, description, "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- Data for Name: scheduled_tasks; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.scheduled_tasks ("taskName", "lockExpiresAt") FROM stdin; +\. + + +-- +-- Data for Name: scopes; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.scopes (name, description, public) FROM stdin; +apps:read See created or authorized applications. f +apps:write Register new applications. f +streams:read Read your streams, and any associated information (branches, commits, objects). t +streams:write Create streams on your behalf, and any associated data (branches, commits, objects). t +profile:read Read your profile information. t +profile:email Read the email address you registered with. t +profile:delete Delete the account with all associated data. f +users:read Read other users' profiles. t +server:stats Request server stats from the API. Only works in conjunction with a "server:admin" role. t +users:email Access the emails of other users. f +server:setup Edit server information. Note: Only server admins will be able to use this token. f +tokens:read Access API tokens. f +tokens:write Create and delete API tokens. f +users:invite Invite others to join this server. f +workspace:create Required for the creation of a workspace t +workspace:update Required for editing workspace information t +workspace:read Required for reading workspace data t +workspace:delete Required for deleting workspaces t +workspace:billing Scope for managing workspace billing f +\. + + +-- +-- Data for Name: server_access_requests; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_access_requests (id, "requesterId", "resourceType", "resourceId", "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- Data for Name: server_acl; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_acl ("userId", role) FROM stdin; +97553902db server:admin +\. + + +-- +-- Data for Name: server_apps; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_apps (id, secret, name, description, "termsAndConditionsLink", logo, public, "trustByDefault", "authorId", "createdAt", "redirectUrl") FROM stdin; +spklwebapp spklwebapp Speckle Web Manager The Speckle Web Manager is your one-stop place to manage and coordinate your data. \N \N t t \N 2024-12-31 18:19:22.529507+00 http://127.0.0.1:3000 +spklpwerbi spklpwerbi Speckle Connector For PowerBI The Speckle Connector For Excel. For more info check the docs here: https://speckle.guide/user/powerbi.html. \N \N t t \N 2024-12-31 18:19:22.529538+00 https://oauth.powerbi.com/views/oauthredirect.html +spklexcel spklexcel Speckle Connector For Excel The Speckle Connector For Excel. For more info, check the docs here: https://speckle.guide/user/excel. \N \N t t \N 2024-12-31 18:19:22.53074+00 https://speckle-excel.netlify.app +sca sca Speckle Connector A Speckle Desktop Connectors. \N \N t t \N 2024-12-31 18:19:22.531507+00 http://localhost:29363 +sdm sdm Speckle Desktop Manager Manages local installations of Speckle connectors, kits and everything else. \N \N t t \N 2024-12-31 18:19:22.529487+00 speckle://account +spklautoma spklautoma Speckle Automate Our automation platform \N \N t t \N 2024-12-31 18:19:22.531456+00 undefined/authn/callback +explorer explorer Speckle Explorer GraphiQL Playground with authentication. \N \N t t \N 2024-12-31 18:19:22.529498+00 http://127.0.0.1:3000/explorer +\. + + +-- +-- Data for Name: server_apps_scopes; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_apps_scopes ("appId", "scopeName") FROM stdin; +spklpwerbi streams:read +spklpwerbi profile:read +spklpwerbi profile:email +spklpwerbi users:read +spklpwerbi users:invite +explorer apps:read +sdm streams:read +explorer apps:write +sdm streams:write +sdm profile:read +sdm profile:email +sdm users:read +spklwebapp apps:read +explorer streams:read +explorer streams:write +explorer profile:read +explorer profile:email +explorer profile:delete +sdm users:invite +spklwebapp apps:write +explorer users:read +explorer server:stats +explorer users:email +explorer server:setup +explorer tokens:read +explorer tokens:write +explorer users:invite +spklwebapp streams:read +spklwebapp streams:write +spklwebapp profile:read +spklwebapp profile:email +spklwebapp profile:delete +spklwebapp users:read +spklwebapp server:stats +explorer workspace:create +spklwebapp users:email +explorer workspace:update +spklwebapp server:setup +explorer workspace:read +explorer workspace:delete +explorer workspace:billing +spklwebapp tokens:read +spklwebapp tokens:write +spklwebapp users:invite +spklwebapp workspace:create +spklwebapp workspace:update +spklwebapp workspace:read +spklwebapp workspace:delete +spklwebapp workspace:billing +spklexcel streams:read +spklexcel streams:write +spklexcel profile:read +spklexcel profile:email +spklexcel users:read +spklexcel users:invite +sca streams:read +sca streams:write +sca profile:read +sca profile:email +sca users:read +sca users:invite +spklautoma profile:email +spklautoma profile:read +spklautoma users:read +spklautoma tokens:write +spklautoma streams:read +spklautoma streams:write +\. + + +-- +-- Data for Name: server_config; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_config (id, name, company, description, "adminContact", "termsOfService", "canonicalUrl", completed, "inviteOnly", "guestModeEnabled") FROM stdin; +0 My new Speckle Server Unknown Company This a community deployment of a Speckle Server. n/a n/a \N f f f +\. + + +-- +-- Data for Name: server_invites; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.server_invites (id, target, "inviterId", "createdAt", message, token, resource, "updatedAt") FROM stdin; +\. + + +-- +-- Data for Name: sso_providers; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.sso_providers (id, "providerType", "encryptedProviderData", "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- Data for Name: stream_acl; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.stream_acl ("userId", "resourceId", role) FROM stdin; +97553902db 815704124b stream:owner +\. + + +-- +-- Data for Name: stream_activity; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.stream_activity ("streamId", "time", "resourceType", "resourceId", "actionType", "userId", info, message) FROM stdin; +\N 2024-12-31 18:20:12.778522+00 user 97553902db user_create 97553902db {"user": {"id": "97553902db", "ip": null, "bio": null, "name": "Fuzz Test", "email": "fuzztest@example.org", "suuid": "c6efe652-18c1-4a31-9f61-3c45a5e2cb23", "avatar": null, "company": null, "profiles": null, "verified": false, "createdAt": "2024-12-31T18:20:12.399Z", "passwordDigest": "$2b$10$M3DQYaqxyrc9.B2rHwEfLOi.y7u55eFvm20E1fiKF23FxhO0DEFpe"}} User created +815704124b 2024-12-31 18:20:13.452134+00 stream 815704124b stream_create 97553902db {"input": {"id": "815704124b", "name": "Tall Pyramid", "isPublic": true, "createdAt": "2024-12-31T18:20:13.443Z", "regionKey": null, "updatedAt": "2024-12-31T18:20:13.443Z", "clonedFrom": null, "description": "", "workspaceId": null, "isDiscoverable": true, "allowPublicComments": false}} Stream Tall Pyramid created +815704124b 2024-12-31 18:20:22.057942+00 branch eb9f7ac487 branch_create 97553902db {"branch": {"id": "eb9f7ac487", "name": "fuzzy", "authorId": "97553902db", "streamId": "815704124b", "createdAt": "2024-12-31T18:20:22.054Z", "updatedAt": "2024-12-31T18:20:22.054Z", "description": null}} Branch created: fuzzy (eb9f7ac487) +\. + + +-- +-- Data for Name: stream_commits; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.stream_commits ("streamId", "commitId") FROM stdin; +\. + + +-- +-- Data for Name: stream_favorites; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.stream_favorites ("streamId", "userId", "createdAt", cursor) FROM stdin; +\. + + +-- +-- Data for Name: streams; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.streams (id, name, description, "isPublic", "clonedFrom", "createdAt", "updatedAt", "allowPublicComments", "isDiscoverable", "workspaceId", "regionKey") FROM stdin; +815704124b Fuzz's First Project Welcome to Speckle! This is your sample project, designed by Beijia Gu - feel free to do whatever you want with it! t \N 2024-12-31 18:20:13.443+00 2024-12-31 18:20:13.463+00 f t \N \N +\. + + +-- +-- Data for Name: streams_meta; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.streams_meta ("streamId", key, value, "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- Data for Name: token_resource_access; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.token_resource_access ("tokenId", "resourceId", "resourceType") FROM stdin; +\. + + +-- +-- Data for Name: token_scopes; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.token_scopes ("tokenId", "scopeName") FROM stdin; +76dcc62da6 apps:read +76dcc62da6 apps:write +76dcc62da6 streams:read +76dcc62da6 streams:write +76dcc62da6 profile:read +76dcc62da6 profile:email +76dcc62da6 profile:delete +76dcc62da6 users:read +76dcc62da6 server:stats +76dcc62da6 users:email +76dcc62da6 server:setup +76dcc62da6 tokens:read +76dcc62da6 tokens:write +76dcc62da6 users:invite +76dcc62da6 workspace:create +76dcc62da6 workspace:update +76dcc62da6 workspace:read +76dcc62da6 workspace:delete +76dcc62da6 workspace:billing +103b2cf861 streams:read +103b2cf861 streams:write +103b2cf861 profile:read +103b2cf861 profile:email +103b2cf861 users:read +103b2cf861 server:stats +103b2cf861 workspace:create +103b2cf861 workspace:update +103b2cf861 workspace:read +103b2cf861 workspace:delete +\. + + +-- +-- Data for Name: user_emails; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_emails (id, email, "primary", verified, "userId", "createdAt", "updatedAt") FROM stdin; +e0cb32df74 fuzztest@example.org t f 97553902db 2024-12-31 18:20:12.416+00 2024-12-31 18:20:12.416+00 +\. + + +-- +-- Data for Name: user_notification_preferences; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_notification_preferences ("userId", preferences) FROM stdin; +\. + + +-- +-- Data for Name: user_roles; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_roles (name, description, "resourceTarget", "aclTableName", weight, public) FROM stdin; +server:admin Holds supreme autocratic authority, not restricted by written laws, legislature, or customs. server server_acl 1000 f +server:user Has normal access to the server. server server_acl 100 f +server:guest Has limited access to the server. server server_acl 50 f +server:archived-user No longer has access to the server. server server_acl 10 f +stream:owner Owners have full access, including deletion rights & access control. streams stream_acl 1000 t +stream:contributor Contributors can create new branches and commits, but they cannot edit stream details or manage collaborators. streams stream_acl 500 t +stream:reviewer Reviewers can only view (read) the data from this stream. streams stream_acl 100 t +workspace:admin Has root on the workspace workspaces workspace_acl 1000 t +workspace:member A regular member of the workspace workspaces workspace_acl 100 t +workspace:guest An external guest member of the workspace with limited rights workspaces workspace_acl 50 t +\. + + +-- +-- Data for Name: user_server_app_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_server_app_tokens ("appId", "userId", "tokenId") FROM stdin; +spklwebapp 97553902db 76dcc62da6 +\. + + +-- +-- Data for Name: user_sso_sessions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.user_sso_sessions ("userId", "providerId", "createdAt", "validUntil") FROM stdin; +\. + + -- -- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: speckle -- -COPY public.users (id, suuid, "createdAt", name, bio, company, email, verified, avatar, profiles, "passwordDigest", ip) FROM stdin; -3fb61f0d69 6bff2a82-30db-4d5e-b4a6-78dbb07f0b2b 2024-12-31 17:15:25.885+00 Fuzz Test \N \N fuzztest@example.org f \N \N $2b$10$n9TiIOXO8PagZ8azbKyGk.fa6u2iju7mgEtDwyiBnRRZGaNLlMUQS \N -\. +COPY public.users (id, suuid, "createdAt", name, bio, company, email, verified, avatar, profiles, "passwordDigest", ip) FROM stdin; +97553902db c6efe652-18c1-4a31-9f61-3c45a5e2cb23 2024-12-31 18:20:12.399+00 Fuzz Test \N \N fuzztest@example.org f \N \N $2b$10$M3DQYaqxyrc9.B2rHwEfLOi.y7u55eFvm20E1fiKF23FxhO0DEFpe \N +\. + + +-- +-- Data for Name: users_meta; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.users_meta ("userId", key, value, "createdAt", "updatedAt") FROM stdin; +97553902db isOnboardingFinished true 2024-12-31 18:20:13.547+00 2024-12-31 18:20:13.547+00 +\. + + +-- +-- Data for Name: webhooks_config; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.webhooks_config (id, "streamId", url, description, triggers, secret, enabled, "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- Data for Name: webhooks_events; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.webhooks_events (id, "webhookId", status, "statusInfo", "lastUpdate", payload) FROM stdin; +\. + + +-- +-- Data for Name: workspace_acl; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_acl ("userId", "workspaceId", role, "createdAt") FROM stdin; +\. + + +-- +-- Data for Name: workspace_checkout_sessions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_checkout_sessions ("workspaceId", id, url, "workspacePlan", "paymentStatus", "billingInterval", "createdAt", "updatedAt") FROM stdin; +\. + + +-- +-- Data for Name: workspace_creation_state; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_creation_state ("workspaceId", completed, state) FROM stdin; +\. + + +-- +-- Data for Name: workspace_domains; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_domains (id, domain, verified, "createdAt", "updatedAt", "createdByUserId", "workspaceId") FROM stdin; +\. + + +-- +-- Data for Name: workspace_plans; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_plans ("workspaceId", name, status, "createdAt") FROM stdin; +\. + + +-- +-- Data for Name: workspace_regions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_regions ("workspaceId", "regionKey", "createdAt") FROM stdin; +\. + + +-- +-- Data for Name: workspace_sso_providers; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_sso_providers ("workspaceId", "providerId") FROM stdin; +\. + + +-- +-- Data for Name: workspace_subscriptions; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspace_subscriptions ("workspaceId", "createdAt", "updatedAt", "currentBillingCycleEnd", "billingInterval", "subscriptionData") FROM stdin; +\. + + +-- +-- Data for Name: workspaces; Type: TABLE DATA; Schema: public; Owner: speckle +-- + +COPY public.workspaces (id, name, description, "createdAt", "updatedAt", logo, "domainBasedMembershipProtectionEnabled", "discoverabilityEnabled", "defaultLogoIndex", "defaultProjectRole", slug) FROM stdin; +\. + + +-- +-- Name: knex_migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle +-- + +SELECT pg_catalog.setval('public.knex_migrations_id_seq', 124, true); + + +-- +-- Name: knex_migrations_lock_index_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle +-- + +SELECT pg_catalog.setval('public.knex_migrations_lock_index_seq', 1, true); + + +-- +-- Name: stream_favorites_cursor_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle +-- + +SELECT pg_catalog.setval('public.stream_favorites_cursor_seq', 1, false); + + +-- +-- Name: api_tokens api_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.api_tokens + ADD CONSTRAINT api_tokens_pkey PRIMARY KEY (id); + + +-- +-- Name: api_tokens api_tokens_tokendigest_unique; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.api_tokens + ADD CONSTRAINT api_tokens_tokendigest_unique UNIQUE ("tokenDigest"); + + +-- +-- Name: authorization_codes authorization_codes_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.authorization_codes + ADD CONSTRAINT authorization_codes_pkey PRIMARY KEY (id); + + +-- +-- Name: automation_function_runs automation_function_run_id_pk; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_function_runs + ADD CONSTRAINT automation_function_run_id_pk PRIMARY KEY (id); + + +-- +-- Name: automations automation_id_pk; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automations + ADD CONSTRAINT automation_id_pk PRIMARY KEY (id); + + +-- +-- Name: automation_revision_functions automation_revision_functions_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_revision_functions + ADD CONSTRAINT automation_revision_functions_pkey PRIMARY KEY (id); + + +-- +-- Name: automation_revisions automation_revisions_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_revisions + ADD CONSTRAINT automation_revisions_pkey PRIMARY KEY (id); + + +-- +-- Name: automation_run_triggers automation_run_triggers_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_run_triggers + ADD CONSTRAINT automation_run_triggers_pkey PRIMARY KEY ("automationRunId", "triggeringId"); + + +-- +-- Name: automation_runs automation_runs_primary; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_runs + ADD CONSTRAINT automation_runs_primary PRIMARY KEY (id); + + +-- +-- Name: automation_tokens automation_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_tokens + ADD CONSTRAINT automation_tokens_pkey PRIMARY KEY ("automationId"); + + +-- +-- Name: automation_triggers automation_triggers_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_triggers + ADD CONSTRAINT automation_triggers_pkey PRIMARY KEY ("automationRevisionId", "triggerType", "triggeringId"); + + +-- +-- Name: blob_storage blob_storage_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.blob_storage + ADD CONSTRAINT blob_storage_pkey PRIMARY KEY (id, "streamId"); + + +-- +-- Name: branch_commits branch_commits_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.branch_commits + ADD CONSTRAINT branch_commits_pkey PRIMARY KEY ("branchId", "commitId"); + + +-- +-- Name: branches branches_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.branches + ADD CONSTRAINT branches_pkey PRIMARY KEY (id); + + +-- +-- Name: branches branches_streamid_name_unique; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.branches + ADD CONSTRAINT branches_streamid_name_unique UNIQUE ("streamId", name); + + +-- +-- Name: comment_views comment_views_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.comment_views + ADD CONSTRAINT comment_views_pkey PRIMARY KEY ("commentId", "userId"); + + +-- +-- Name: comments comments_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.comments + ADD CONSTRAINT comments_pkey PRIMARY KEY (id); + + +-- +-- Name: commits commits_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.commits + ADD CONSTRAINT commits_pkey PRIMARY KEY (id); + + +-- +-- Name: email_verifications email_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.email_verifications + ADD CONSTRAINT email_verifications_pkey PRIMARY KEY (id); + + +-- +-- Name: file_uploads file_uploads_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.file_uploads + ADD CONSTRAINT file_uploads_pkey PRIMARY KEY (id); + + +-- +-- Name: gendo_ai_renders gendo_ai_renders_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.gendo_ai_renders + ADD CONSTRAINT gendo_ai_renders_pkey PRIMARY KEY (id); + + +-- +-- Name: gendo_user_credits gendo_user_credits_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.gendo_user_credits + ADD CONSTRAINT gendo_user_credits_pkey PRIMARY KEY ("userId"); + + +-- +-- Name: knex_migrations_lock knex_migrations_lock_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.knex_migrations_lock + ADD CONSTRAINT knex_migrations_lock_pkey PRIMARY KEY (index); + + +-- +-- Name: knex_migrations knex_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.knex_migrations + ADD CONSTRAINT knex_migrations_pkey PRIMARY KEY (id); + + +-- +-- Name: object_children_closure obj_parent_child_index; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.object_children_closure + ADD CONSTRAINT obj_parent_child_index UNIQUE ("streamId", parent, child); + + +-- +-- Name: object_preview object_preview_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.object_preview + ADD CONSTRAINT object_preview_pkey PRIMARY KEY ("streamId", "objectId"); + + +-- +-- Name: objects objects_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.objects + ADD CONSTRAINT objects_pkey PRIMARY KEY ("streamId", id); + + +-- +-- Name: previews previews_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.previews + ADD CONSTRAINT previews_pkey PRIMARY KEY (id); + + +-- +-- Name: pwdreset_tokens pwdreset_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.pwdreset_tokens + ADD CONSTRAINT pwdreset_tokens_pkey PRIMARY KEY (id); + + +-- +-- Name: refresh_tokens refresh_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.refresh_tokens + ADD CONSTRAINT refresh_tokens_pkey PRIMARY KEY (id); + + +-- +-- Name: regions regions_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.regions + ADD CONSTRAINT regions_pkey PRIMARY KEY (key); + + +-- +-- Name: scheduled_tasks scheduled_tasks_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.scheduled_tasks + ADD CONSTRAINT scheduled_tasks_pkey PRIMARY KEY ("taskName"); + + +-- +-- Name: scopes scopes_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.scopes + ADD CONSTRAINT scopes_pkey PRIMARY KEY (name); + + +-- +-- Name: server_access_requests server_access_requests_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.server_access_requests + ADD CONSTRAINT server_access_requests_pkey PRIMARY KEY (id); + + +-- +-- Name: server_access_requests server_access_requests_requesterid_resourceid_resourcetype_uniq; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.server_access_requests + ADD CONSTRAINT server_access_requests_requesterid_resourceid_resourcetype_uniq UNIQUE ("requesterId", "resourceId", "resourceType"); + + +-- +-- Name: server_acl server_acl_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.server_acl + ADD CONSTRAINT server_acl_pkey PRIMARY KEY ("userId"); + + +-- +-- Name: server_apps server_apps_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.server_apps + ADD CONSTRAINT server_apps_pkey PRIMARY KEY (id); + + +-- +-- Name: server_invites server_invites_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.server_invites + ADD CONSTRAINT server_invites_pkey PRIMARY KEY (id); + + +-- +-- Name: sso_providers sso_providers_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.sso_providers + ADD CONSTRAINT sso_providers_pkey PRIMARY KEY (id); + + +-- +-- Name: stream_acl stream_acl_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.stream_acl + ADD CONSTRAINT stream_acl_pkey PRIMARY KEY ("userId", "resourceId"); + + +-- +-- Name: stream_acl stream_acl_userid_resourceid_unique; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.stream_acl + ADD CONSTRAINT stream_acl_userid_resourceid_unique UNIQUE ("userId", "resourceId"); + + +-- +-- Name: stream_commits stream_commits_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.stream_commits + ADD CONSTRAINT stream_commits_pkey PRIMARY KEY ("streamId", "commitId"); + + +-- +-- Name: stream_favorites stream_favorites_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.stream_favorites + ADD CONSTRAINT stream_favorites_pkey PRIMARY KEY ("userId", "streamId"); + + +-- +-- Name: streams_meta streams_meta_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.streams_meta + ADD CONSTRAINT streams_meta_pkey PRIMARY KEY ("streamId", key); + + +-- +-- Name: streams streams_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.streams + ADD CONSTRAINT streams_pkey PRIMARY KEY (id); + + +-- +-- Name: user_emails user_emails_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.user_emails + ADD CONSTRAINT user_emails_pkey PRIMARY KEY (id); + + +-- +-- Name: user_emails user_emails_userid_email_unique; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.user_emails + ADD CONSTRAINT user_emails_userid_email_unique UNIQUE ("userId", email); + + +-- +-- Name: user_notification_preferences user_notification_preferences_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.user_notification_preferences + ADD CONSTRAINT user_notification_preferences_pkey PRIMARY KEY ("userId"); + + +-- +-- Name: user_roles user_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.user_roles + ADD CONSTRAINT user_roles_pkey PRIMARY KEY (name); + + +-- +-- Name: user_sso_sessions user_sso_sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.user_sso_sessions + ADD CONSTRAINT user_sso_sessions_pkey PRIMARY KEY ("userId", "providerId"); + + +-- +-- Name: users users_email_unique; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_email_unique UNIQUE (email); + + +-- +-- Name: users_meta users_meta_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.users_meta + ADD CONSTRAINT users_meta_pkey PRIMARY KEY ("userId", key); + + +-- +-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_pkey PRIMARY KEY (id); + + +-- +-- Name: webhooks_config webhooks_config_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.webhooks_config + ADD CONSTRAINT webhooks_config_pkey PRIMARY KEY (id); + + +-- +-- Name: webhooks_events webhooks_events_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.webhooks_events + ADD CONSTRAINT webhooks_events_pkey PRIMARY KEY (id); + + +-- +-- Name: workspace_acl workspace_acl_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspace_acl + ADD CONSTRAINT workspace_acl_pkey PRIMARY KEY ("userId", "workspaceId"); + + +-- +-- Name: workspace_checkout_sessions workspace_checkout_sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspace_checkout_sessions + ADD CONSTRAINT workspace_checkout_sessions_pkey PRIMARY KEY ("workspaceId"); + + +-- +-- Name: workspace_creation_state workspace_creation_state_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspace_creation_state + ADD CONSTRAINT workspace_creation_state_pkey PRIMARY KEY ("workspaceId"); + + +-- +-- Name: workspace_domains workspace_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspace_domains + ADD CONSTRAINT workspace_domains_pkey PRIMARY KEY (id); + + +-- +-- Name: workspace_domains workspace_domains_workspaceid_domain_unique; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspace_domains + ADD CONSTRAINT workspace_domains_workspaceid_domain_unique UNIQUE ("workspaceId", domain); + + +-- +-- Name: workspace_plans workspace_plans_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspace_plans + ADD CONSTRAINT workspace_plans_pkey PRIMARY KEY ("workspaceId"); + + +-- +-- Name: workspace_regions workspace_regions_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspace_regions + ADD CONSTRAINT workspace_regions_pkey PRIMARY KEY ("workspaceId", "regionKey"); + + +-- +-- Name: workspace_sso_providers workspace_sso_providers_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspace_sso_providers + ADD CONSTRAINT workspace_sso_providers_pkey PRIMARY KEY ("workspaceId"); + + +-- +-- Name: workspace_subscriptions workspace_subscriptions_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspace_subscriptions + ADD CONSTRAINT workspace_subscriptions_pkey PRIMARY KEY ("workspaceId"); + + +-- +-- Name: workspaces workspaces_pkey; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspaces + ADD CONSTRAINT workspaces_pkey PRIMARY KEY (id); + + +-- +-- Name: workspaces workspaces_slug_unique; Type: CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.workspaces + ADD CONSTRAINT workspaces_slug_unique UNIQUE (slug); + + +-- +-- Name: automation_function_runs_runid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX automation_function_runs_runid_index ON public.automation_function_runs USING btree ("runId"); + + +-- +-- Name: automation_revisions_automationid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX automation_revisions_automationid_index ON public.automation_revisions USING btree ("automationId"); + + +-- +-- Name: automation_run_triggers_triggertype_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX automation_run_triggers_triggertype_index ON public.automation_run_triggers USING btree ("triggerType"); + + +-- +-- Name: automations_projectid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX automations_projectid_index ON public.automations USING btree ("projectId"); + + +-- +-- Name: comments_authorid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX comments_authorid_index ON public.comments USING btree ("authorId"); + + +-- +-- Name: comments_streamid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX comments_streamid_index ON public.comments USING btree ("streamId"); + + +-- +-- Name: email_verifications_email_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX email_verifications_email_index ON public.email_verifications USING btree (email); + + +-- +-- Name: file_uploads_streamid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX file_uploads_streamid_index ON public.file_uploads USING btree ("streamId"); + + +-- +-- Name: full_pcd_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX full_pcd_index ON public.object_children_closure USING btree ("streamId", parent, "minDepth"); + + +-- +-- Name: gendo_ai_renders_gendogenerationid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX gendo_ai_renders_gendogenerationid_index ON public.gendo_ai_renders USING btree ("gendoGenerationId"); -- --- Data for Name: api_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: object_children_closure_streamid_child_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.api_tokens (id, "tokenDigest", owner, name, "lastChars", revoked, lifespan, "createdAt", "lastUsed") FROM stdin; -314504c3d0 $2b$10$xOYgfOmq1XHXO0dPCctlk.l38qxEsyZZk4q6YstaGJFdK4RBVk5QK 3fb61f0d69 all 8b1a70 f 3154000000000 2024-12-31 17:16:19.315306+00 2024-12-31 17:16:19.315306+00 -d018e9f40e $2b$10$NNwurjMss/m8/8HV7vROIetVRWPaKgN57iPv0j92HztsritKnZU4W 3fb61f0d69 Speckle Web Manager-token 54da62 f 3154000000000 2024-12-31 17:15:26.482142+00 2024-12-31 17:17:23.802+00 -\. +CREATE INDEX object_children_closure_streamid_child_index ON public.object_children_closure USING btree ("streamId", child); -- --- Data for Name: server_apps; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: object_children_closure_streamid_mindepth_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.server_apps (id, secret, name, description, "termsAndConditionsLink", logo, public, "trustByDefault", "authorId", "createdAt", "redirectUrl") FROM stdin; -spklexcel spklexcel Speckle Connector For Excel The Speckle Connector For Excel. For more info, check the docs here: https://speckle.guide/user/excel. \N \N t t \N 2024-12-31 17:13:26.847617+00 https://speckle-excel.netlify.app -spklwebapp spklwebapp Speckle Web Manager The Speckle Web Manager is your one-stop place to manage and coordinate your data. \N \N t t \N 2024-12-31 17:13:26.846065+00 http://127.0.0.1:3000 -spklautoma spklautoma Speckle Automate Our automation platform \N \N t t \N 2024-12-31 17:13:26.848538+00 undefined/authn/callback -explorer explorer Speckle Explorer GraphiQL Playground with authentication. \N \N t t \N 2024-12-31 17:13:26.846596+00 http://127.0.0.1:3000/explorer -sdm sdm Speckle Desktop Manager Manages local installations of Speckle connectors, kits and everything else. \N \N t t \N 2024-12-31 17:13:26.847991+00 speckle://account -sca sca Speckle Connector A Speckle Desktop Connectors. \N \N t t \N 2024-12-31 17:13:26.846334+00 http://localhost:29363 -spklpwerbi spklpwerbi Speckle Connector For PowerBI The Speckle Connector For Excel. For more info check the docs here: https://speckle.guide/user/powerbi.html. \N \N t t \N 2024-12-31 17:13:26.847174+00 https://oauth.powerbi.com/views/oauthredirect.html -\. +CREATE INDEX object_children_closure_streamid_mindepth_index ON public.object_children_closure USING btree ("streamId", "minDepth"); -- --- Data for Name: authorization_codes; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: object_children_closure_streamid_parent_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.authorization_codes (id, "appId", "userId", challenge, "createdAt", lifespan) FROM stdin; -\. +CREATE INDEX object_children_closure_streamid_parent_index ON public.object_children_closure USING btree ("streamId", parent); -- --- Data for Name: workspaces; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: object_preview_previewstatus_priority_lastupdate_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.workspaces (id, name, description, "createdAt", "updatedAt", logo, "domainBasedMembershipProtectionEnabled", "discoverabilityEnabled", "defaultLogoIndex", "defaultProjectRole", slug) FROM stdin; -\. +CREATE INDEX object_preview_previewstatus_priority_lastupdate_index ON public.object_preview USING btree ("previewStatus", priority, "lastUpdate"); -- --- Data for Name: streams; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: objects_id_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.streams (id, name, description, "isPublic", "clonedFrom", "createdAt", "updatedAt", "allowPublicComments", "isDiscoverable", "workspaceId", "regionKey") FROM stdin; -47d8fd9d36 Fuzz's First Project Welcome to Speckle! This is your sample project, designed by Beijia Gu - feel free to do whatever you want with it! t \N 2024-12-31 17:15:26.845+00 2024-12-31 17:15:26.872+00 f t \N \N -\. +CREATE INDEX objects_id_index ON public.objects USING btree (id); -- --- Data for Name: automations; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: objects_streamid_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.automations (id, name, "projectId", enabled, "createdAt", "updatedAt", "executionEngineAutomationId", "userId", "isTestAutomation") FROM stdin; -\. +CREATE INDEX objects_streamid_index ON public.objects USING btree ("streamId"); -- --- Data for Name: automation_revisions; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: ratelimit_query_idx; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.automation_revisions (id, "automationId", "createdAt", active, "userId", "publicKey") FROM stdin; -\. +CREATE INDEX ratelimit_query_idx ON public.ratelimit_actions USING btree (source, action, "timestamp"); -- --- Data for Name: automation_runs; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_access_requests_resourcetype_resourceid_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.automation_runs (id, "automationRevisionId", "createdAt", "updatedAt", status, "executionEngineRunId") FROM stdin; -\. +CREATE INDEX server_access_requests_resourcetype_resourceid_index ON public.server_access_requests USING btree ("resourceType", "resourceId"); -- --- Data for Name: automation_function_runs; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_apps_scopes_appid_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.automation_function_runs (id, "runId", "functionId", "functionReleaseId", elapsed, status, "contextView", "statusMessage", results, "createdAt", "updatedAt") FROM stdin; -\. +CREATE INDEX server_apps_scopes_appid_index ON public.server_apps_scopes USING btree ("appId"); -- --- Data for Name: automation_revision_functions; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_apps_scopes_scopename_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.automation_revision_functions ("automationRevisionId", "functionId", "functionReleaseId", "functionInputs", id) FROM stdin; -\. +CREATE INDEX server_apps_scopes_scopename_index ON public.server_apps_scopes USING btree ("scopeName"); -- --- Data for Name: automation_run_triggers; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_config_id_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.automation_run_triggers ("automationRunId", "triggeringId", "triggerType") FROM stdin; -\. +CREATE INDEX server_config_id_index ON public.server_config USING btree (id); -- --- Data for Name: automation_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_invites_resource_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.automation_tokens ("automationId", "automateToken") FROM stdin; -\. +CREATE INDEX server_invites_resource_index ON public.server_invites USING btree (resource); -- --- Data for Name: automation_triggers; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_invites_target_resource_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.automation_triggers ("automationRevisionId", "triggerType", "triggeringId") FROM stdin; -\. +CREATE INDEX server_invites_target_resource_index ON public.server_invites USING btree (target, resource); -- --- Data for Name: blob_storage; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_invites_token_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.blob_storage (id, "streamId", "userId", "objectKey", "fileName", "fileType", "fileSize", "uploadStatus", "uploadError", "createdAt", "fileHash") FROM stdin; -\. +CREATE INDEX server_invites_token_index ON public.server_invites USING btree (token); -- --- Data for Name: branches; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: stream_activity_resourceid_time_index; Type: INDEX; Schema: public; Owner: speckle -- -COPY public.branches (id, "streamId", "authorId", name, description, "createdAt", "updatedAt") FROM stdin; -c4f249efcd 47d8fd9d36 3fb61f0d69 main default branch 2024-12-31 17:15:26.855+00 2024-12-31 17:15:26.855+00 -3c4ce908af 47d8fd9d36 3fb61f0d69 fuzzy \N 2024-12-31 17:17:23.699+00 2024-12-31 17:17:23.699+00 -\. +CREATE INDEX stream_activity_resourceid_time_index ON public.stream_activity USING btree ("resourceId", "time"); + + +-- +-- Name: stream_activity_streamid_time_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX stream_activity_streamid_time_index ON public.stream_activity USING btree ("streamId", "time"); + + +-- +-- Name: stream_activity_userid_time_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX stream_activity_userid_time_index ON public.stream_activity USING btree ("userId", "time"); + + +-- +-- Name: token_resource_access_tokenid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX token_resource_access_tokenid_index ON public.token_resource_access USING btree ("tokenId"); + + +-- +-- Name: token_scope_combined_idx; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX token_scope_combined_idx ON public.token_scopes USING btree ("tokenId", "scopeName"); + + +-- +-- Name: token_scopes_scopename_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX token_scopes_scopename_index ON public.token_scopes USING btree ("scopeName"); + + +-- +-- Name: token_scopes_tokenid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX token_scopes_tokenid_index ON public.token_scopes USING btree ("tokenId"); + + +-- +-- Name: user_server_app_tokens_appid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX user_server_app_tokens_appid_index ON public.user_server_app_tokens USING btree ("appId"); + + +-- +-- Name: user_server_app_tokens_tokenid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX user_server_app_tokens_tokenid_index ON public.user_server_app_tokens USING btree ("tokenId"); + + +-- +-- Name: user_server_app_tokens_userid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX user_server_app_tokens_userid_index ON public.user_server_app_tokens USING btree ("userId"); + + +-- +-- Name: users_suuid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX users_suuid_index ON public.users USING btree (suuid); + + +-- +-- Name: webhooks_config_streamid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX webhooks_config_streamid_index ON public.webhooks_config USING btree ("streamId"); + + +-- +-- Name: webhooks_events_status_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX webhooks_events_status_index ON public.webhooks_events USING btree (status); + + +-- +-- Name: webhooks_events_webhookid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX webhooks_events_webhookid_index ON public.webhooks_events USING btree ("webhookId"); + + +-- +-- Name: workspace_checkout_sessions_id_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX workspace_checkout_sessions_id_index ON public.workspace_checkout_sessions USING btree (id); + + +-- +-- Name: workspace_domains_domain_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX workspace_domains_domain_index ON public.workspace_domains USING btree (domain); + + +-- +-- Name: workspace_domains_workspaceid_index; Type: INDEX; Schema: public; Owner: speckle +-- + +CREATE INDEX workspace_domains_workspaceid_index ON public.workspace_domains USING btree ("workspaceId"); + + +-- +-- Name: api_tokens api_tokens_owner_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.api_tokens + ADD CONSTRAINT api_tokens_owner_foreign FOREIGN KEY (owner) REFERENCES public.users(id) ON DELETE CASCADE; + + +-- +-- Name: authorization_codes authorization_codes_appid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.authorization_codes + ADD CONSTRAINT authorization_codes_appid_foreign FOREIGN KEY ("appId") REFERENCES public.server_apps(id) ON DELETE CASCADE; + + +-- +-- Name: authorization_codes authorization_codes_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.authorization_codes + ADD CONSTRAINT authorization_codes_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; + + +-- +-- Name: automation_function_runs automation_function_runs_runid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_function_runs + ADD CONSTRAINT automation_function_runs_runid_foreign FOREIGN KEY ("runId") REFERENCES public.automation_runs(id) ON DELETE CASCADE; + + +-- +-- Name: automation_revision_functions automation_revision_functions_automationrevisionid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_revision_functions + ADD CONSTRAINT automation_revision_functions_automationrevisionid_foreign FOREIGN KEY ("automationRevisionId") REFERENCES public.automation_revisions(id) ON DELETE CASCADE; + + +-- +-- Name: automation_revisions automation_revisions_automationid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_revisions + ADD CONSTRAINT automation_revisions_automationid_foreign FOREIGN KEY ("automationId") REFERENCES public.automations(id) ON DELETE CASCADE; + + +-- +-- Name: automation_revisions automation_revisions_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_revisions + ADD CONSTRAINT automation_revisions_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE SET NULL; + + +-- +-- Name: automation_run_triggers automation_run_triggers_automationrunid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_run_triggers + ADD CONSTRAINT automation_run_triggers_automationrunid_foreign FOREIGN KEY ("automationRunId") REFERENCES public.automation_runs(id) ON DELETE CASCADE; + + +-- +-- Name: automation_runs automation_runs_automationrevisionid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_runs + ADD CONSTRAINT automation_runs_automationrevisionid_foreign FOREIGN KEY ("automationRevisionId") REFERENCES public.automation_revisions(id) ON DELETE CASCADE; + + +-- +-- Name: automation_tokens automation_tokens_automationid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_tokens + ADD CONSTRAINT automation_tokens_automationid_foreign FOREIGN KEY ("automationId") REFERENCES public.automations(id) ON DELETE CASCADE; + + +-- +-- Name: automation_triggers automation_triggers_automationrevisionid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automation_triggers + ADD CONSTRAINT automation_triggers_automationrevisionid_foreign FOREIGN KEY ("automationRevisionId") REFERENCES public.automation_revisions(id) ON DELETE CASCADE; + + +-- +-- Name: automations automations_projectid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automations + ADD CONSTRAINT automations_projectid_foreign FOREIGN KEY ("projectId") REFERENCES public.streams(id) ON DELETE CASCADE; + + +-- +-- Name: automations automations_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.automations + ADD CONSTRAINT automations_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE SET NULL; + + +-- +-- Name: branch_commits branch_commits_branchid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.branch_commits + ADD CONSTRAINT branch_commits_branchid_foreign FOREIGN KEY ("branchId") REFERENCES public.branches(id) ON DELETE CASCADE; + + +-- +-- Name: branch_commits branch_commits_commitid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.branch_commits + ADD CONSTRAINT branch_commits_commitid_foreign FOREIGN KEY ("commitId") REFERENCES public.commits(id) ON DELETE CASCADE; + + +-- +-- Name: branches branches_authorid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.branches + ADD CONSTRAINT branches_authorid_foreign FOREIGN KEY ("authorId") REFERENCES public.users(id) ON DELETE SET NULL; + + +-- +-- Name: branches branches_streamid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.branches + ADD CONSTRAINT branches_streamid_foreign FOREIGN KEY ("streamId") REFERENCES public.streams(id) ON DELETE CASCADE; + + +-- +-- Name: comment_links comment_links_commentid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.comment_links + ADD CONSTRAINT comment_links_commentid_foreign FOREIGN KEY ("commentId") REFERENCES public.comments(id) ON DELETE CASCADE; + + +-- +-- Name: comment_views comment_views_commentid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.comment_views + ADD CONSTRAINT comment_views_commentid_foreign FOREIGN KEY ("commentId") REFERENCES public.comments(id) ON DELETE CASCADE; + + +-- +-- Name: comment_views comment_views_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.comment_views + ADD CONSTRAINT comment_views_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; + + +-- +-- Name: comments comments_authorid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.comments + ADD CONSTRAINT comments_authorid_foreign FOREIGN KEY ("authorId") REFERENCES public.users(id) ON DELETE CASCADE; + + +-- +-- Name: comments comments_parentcomment_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.comments + ADD CONSTRAINT comments_parentcomment_foreign FOREIGN KEY ("parentComment") REFERENCES public.comments(id) ON DELETE CASCADE; + + +-- +-- Name: comments comments_streamid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.comments + ADD CONSTRAINT comments_streamid_foreign FOREIGN KEY ("streamId") REFERENCES public.streams(id) ON DELETE CASCADE; + + +-- +-- Name: commits commits_author_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.commits + ADD CONSTRAINT commits_author_foreign FOREIGN KEY (author) REFERENCES public.users(id) ON DELETE SET NULL; + + +-- +-- Name: file_uploads file_uploads_streamid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle +-- + +ALTER TABLE ONLY public.file_uploads + ADD CONSTRAINT file_uploads_streamid_foreign FOREIGN KEY ("streamId") REFERENCES public.streams(id) ON DELETE CASCADE; -- --- Data for Name: commits; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: gendo_ai_renders gendo_ai_renders_modelid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.commits (id, "referencedObject", author, message, "createdAt", "sourceApplication", "totalChildrenCount", parents) FROM stdin; -\. +ALTER TABLE ONLY public.gendo_ai_renders + ADD CONSTRAINT gendo_ai_renders_modelid_foreign FOREIGN KEY ("modelId") REFERENCES public.branches(id) ON DELETE CASCADE; -- --- Data for Name: branch_commits; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: gendo_ai_renders gendo_ai_renders_projectid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.branch_commits ("branchId", "commitId") FROM stdin; -\. +ALTER TABLE ONLY public.gendo_ai_renders + ADD CONSTRAINT gendo_ai_renders_projectid_foreign FOREIGN KEY ("projectId") REFERENCES public.streams(id) ON DELETE CASCADE; -- --- Data for Name: comments; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: gendo_ai_renders gendo_ai_renders_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.comments (id, "streamId", "authorId", "createdAt", "updatedAt", text, screenshot, data, archived, "parentComment") FROM stdin; -\. +ALTER TABLE ONLY public.gendo_ai_renders + ADD CONSTRAINT gendo_ai_renders_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: comment_links; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: gendo_ai_renders gendo_ai_renders_versionid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.comment_links ("commentId", "resourceId", "resourceType") FROM stdin; -\. +ALTER TABLE ONLY public.gendo_ai_renders + ADD CONSTRAINT gendo_ai_renders_versionid_foreign FOREIGN KEY ("versionId") REFERENCES public.commits(id) ON DELETE CASCADE; -- --- Data for Name: comment_views; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: gendo_user_credits gendo_user_credits_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.comment_views ("commentId", "userId", "viewedAt") FROM stdin; -\. +ALTER TABLE ONLY public.gendo_user_credits + ADD CONSTRAINT gendo_user_credits_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: email_verifications; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: object_children_closure object_children_closure_streamid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.email_verifications (id, email, "createdAt") FROM stdin; -6ff3e4d864195cabc2dd fuzztest@example.org 2024-12-31 17:15:25.924+00 -\. +ALTER TABLE ONLY public.object_children_closure + ADD CONSTRAINT object_children_closure_streamid_foreign FOREIGN KEY ("streamId") REFERENCES public.streams(id) ON DELETE CASCADE; -- --- Data for Name: file_uploads; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: object_preview object_preview_streamid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.file_uploads (id, "streamId", "branchName", "userId", "fileName", "fileType", "fileSize", "uploadComplete", "uploadDate", "convertedStatus", "convertedLastUpdate", "convertedMessage", "convertedCommitId") FROM stdin; -\. +ALTER TABLE ONLY public.object_preview + ADD CONSTRAINT object_preview_streamid_foreign FOREIGN KEY ("streamId") REFERENCES public.streams(id) ON DELETE CASCADE; -- --- Data for Name: gendo_ai_renders; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: objects objects_streamid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.gendo_ai_renders (id, "userId", "projectId", "modelId", "versionId", "createdAt", "updatedAt", "gendoGenerationId", status, prompt, camera, "baseImage", "responseImage") FROM stdin; -\. +ALTER TABLE ONLY public.objects + ADD CONSTRAINT objects_streamid_foreign FOREIGN KEY ("streamId") REFERENCES public.streams(id) ON DELETE CASCADE; -- --- Data for Name: gendo_user_credits; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: personal_api_tokens personal_api_tokens_tokenid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.gendo_user_credits ("userId", "resetDate", used) FROM stdin; -\. +ALTER TABLE ONLY public.personal_api_tokens + ADD CONSTRAINT personal_api_tokens_tokenid_foreign FOREIGN KEY ("tokenId") REFERENCES public.api_tokens(id) ON DELETE CASCADE; -- --- Data for Name: knex_migrations; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: personal_api_tokens personal_api_tokens_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.knex_migrations (id, name, batch, migration_time) FROM stdin; -1 000-core.js 1 2024-12-31 17:13:23.07+00 -2 2020-05-29-apps.js 1 2024-12-31 17:13:23.168+00 -3 20201222100048_add_sourceapp_to_commits.js 1 2024-12-31 17:13:23.177+00 -4 20201222101522_add_totalchildrencount_to_commits.js 1 2024-12-31 17:13:23.18+00 -5 20201223120532_add_commit_parents_simplification.js 1 2024-12-31 17:13:23.184+00 -6 20201230111428_add_scopes_public_field.js 1 2024-12-31 17:13:23.185+00 -7 20210225130308_add_roles_public_field.js 1 2024-12-31 17:13:23.19+00 -8 20210303185834_invites.js 1 2024-12-31 17:13:23.207+00 -9 20210304111614_pwdreset.js 1 2024-12-31 17:13:23.213+00 -10 20210314101154_add_invitefield_to_serverinfo.js 1 2024-12-31 17:13:23.216+00 -11 20210322190000_add_streamid_to_objects.js 1 2024-12-31 17:13:23.303+00 -12 20210426200000-previews.js 1 2024-12-31 17:13:23.311+00 -13 20210603160000_optional_user_references.js 1 2024-12-31 17:13:23.315+00 -14 20210616173000_stream_activity.js 1 2024-12-31 17:13:23.322+00 -15 20210701180000-webhooks.js 1 2024-12-31 17:13:23.333+00 -16 20210915130000-fileuploads.js 1 2024-12-31 17:13:23.338+00 -17 20211119105730_de_duplicate_users.js 1 2024-12-31 17:13:23.34+00 -18 20220118181256-email-verifications.js 1 2024-12-31 17:13:23.345+00 -19 20220222173000_comments.js 1 2024-12-31 17:13:23.364+00 -20 20220315140000_ratelimit.js 1 2024-12-31 17:13:23.369+00 -21 20220318121405_add_stream_favorites.js 1 2024-12-31 17:13:23.375+00 -22 20220412150558_stream-public-comments.js 1 2024-12-31 17:13:23.376+00 -23 202206030936_add_asset_storage.js 1 2024-12-31 17:13:23.381+00 -24 202206231429_add_file_hash_to_blobs.js 1 2024-12-31 17:13:23.382+00 -25 20220629110918_server_invites_rework.js 1 2024-12-31 17:13:23.398+00 -26 20220707135553_make_users_email_not_nullable.js 1 2024-12-31 17:13:23.406+00 -27 20220722092821_add_invite_token_field.js 1 2024-12-31 17:13:23.41+00 -28 20220722110643_fix_comments_delete_cascade.js 1 2024-12-31 17:13:23.419+00 -29 20220727091536_blobs-id-length-removal.js 1 2024-12-31 17:13:23.421+00 -30 20220803104832_ts_test.js 1 2024-12-31 17:13:23.422+00 -31 20220819091523_add_stream_discoverable_field.js 1 2024-12-31 17:13:23.423+00 -32 20220823100915_migrate_streams_to_lower_precision_timestamps.js 1 2024-12-31 17:13:23.447+00 -33 20220825082631_drop_email_verifications_used_col.js 1 2024-12-31 17:13:23.457+00 -34 20220825123323_usernotificationpreferences.js 1 2024-12-31 17:13:23.461+00 -35 20220829102231_add_server_access_requests_table.js 1 2024-12-31 17:13:23.468+00 -36 20220921084935_fix_branch_nullability.js 1 2024-12-31 17:13:23.472+00 -37 20220929141717_scheduled_tasks.js 1 2024-12-31 17:13:23.475+00 -38 20221104104921_webhooks_drop_stream_fk.js 1 2024-12-31 17:13:23.476+00 -39 20221122133014_add_user_onboarding_data.js 1 2024-12-31 17:13:23.477+00 -40 20221213124322_migrate_more_table_precisions.js 1 2024-12-31 17:13:23.508+00 -41 20230316091225_create_users_meta_table.js 1 2024-12-31 17:13:23.516+00 -42 20230316132827_remove_user_is_onboarding_complete_col.js 1 2024-12-31 17:13:23.518+00 -43 20230330082209_stricter_file_uploads_schema.js 1 2024-12-31 17:13:23.534+00 -44 20230517122919_clean_up_invalid_stream_invites.js 1 2024-12-31 17:13:23.537+00 -45 20230713094611_create_streams_meta_table.js 1 2024-12-31 17:13:23.541+00 -46 20230727150957_serverGuestMode.js 1 2024-12-31 17:13:23.542+00 -47 20230818075729_add_invite_server_role_support.js 1 2024-12-31 17:13:23.543+00 -48 20230905162038_automations.js 1 2024-12-31 17:13:23.551+00 -49 20230907131636_migrate_invites_to_lower_precision_timestamps.js 1 2024-12-31 17:13:23.56+00 -50 20230912114629_automations_tables_normalization.js 1 2024-12-31 17:13:23.583+00 -51 20230914071540_make_function_run_results_nullable.js 1 2024-12-31 17:13:23.586+00 -52 20230919080704_add_webhook_config_timestamps.js 1 2024-12-31 17:13:23.587+00 -53 20230920130032_fix_project_delete_cascade.js 1 2024-12-31 17:13:23.595+00 -54 20231025100054_automation_function_name_and_logo.js 1 2024-12-31 17:13:23.596+00 -55 20240109101048_create_token_resource_access_table.js 1 2024-12-31 17:13:23.601+00 -56 20240304143445_rename_tables.js 1 2024-12-31 17:13:23.605+00 -57 20240305120620_automate.js 1 2024-12-31 17:13:23.635+00 -58 20240321092858_triggers.js 1 2024-12-31 17:13:23.656+00 -59 20240404075414_revision_active.js 1 2024-12-31 17:13:23.658+00 -60 20240404173455_automation_token.js 1 2024-12-31 17:13:23.674+00 -61 20240507075055_add_function_run_timestamps.js 1 2024-12-31 17:13:23.676+00 -62 20240507140149_add_encryption_support.js 1 2024-12-31 17:13:23.685+00 -63 20240522130000_gendo.js 1 2024-12-31 17:13:23.697+00 -64 20240523192300_add_is_test_automation_column.js 1 2024-12-31 17:13:23.699+00 -65 20240620105859_drop_beta_tables.js 1 2024-12-31 17:13:23.714+00 -66 20240621174016_workspaces.js 1 2024-12-31 17:13:23.739+00 -67 20240628112300_dropCreatorId.js 1 2024-12-31 17:13:23.742+00 -68 20240703084247_user-emails.js 1 2024-12-31 17:13:23.759+00 -69 20240710154658_user_emails_backfill.js 1 2024-12-31 17:13:23.765+00 -70 20240716094858_generalized_invite_record_resources.js 1 2024-12-31 17:13:23.778+00 -71 20240716134617_migrate_to_resources_array.js 1 2024-12-31 17:13:23.802+00 -72 20240801000000_logos.js 1 2024-12-31 17:13:23.808+00 -73 20240802212846_cascadeDeleteWorkspaceProjects.js 1 2024-12-31 17:13:23.818+00 -74 20240806160740_workspace_domains.js 1 2024-12-31 17:13:23.842+00 -75 20240807174901_add_column_domainBasedMembershipProtection.js 1 2024-12-31 17:13:23.845+00 -76 20240808091944_add_workspace_discovery_flag.js 1 2024-12-31 17:13:23.848+00 -77 20240808140602_add_invite_updated_at.js 1 2024-12-31 17:13:23.852+00 -78 20240813125251_workspaceAclWithTimestamps.js 1 2024-12-31 17:13:23.857+00 -79 20240820131619_fallbackWorkspaceLogo.js 1 2024-12-31 17:13:23.864+00 -80 20240910163614_add_column_defaultProjectRole.js 1 2024-12-31 17:13:23.869+00 -81 20240912134548_add_workspace_slug.js 1 2024-12-31 17:13:23.889+00 -82 20240926112407_copy_workspace_slug.js 1 2024-12-31 17:13:23.892+00 -83 20240930141322_workspace_sso.js 1 2024-12-31 17:13:23.911+00 -84 20241014092507_workspace_sso_expiration.js 1 2024-12-31 17:13:23.913+00 -85 20241018132400_workspace_checkout.js 1 2024-12-31 17:13:23.955+00 -86 20241031081827_create_regions_table.js 1 2024-12-31 17:13:23.964+00 -87 20241101055531_project_region.js 1 2024-12-31 17:13:23.972+00 -88 20241102055157_project_region_nofk.js 1 2024-12-31 17:13:23.978+00 -89 20241105070219_create_workspace_regions_table.js 1 2024-12-31 17:13:23.996+00 -90 20241105144301_cascade_delete_workspace_plans.js 1 2024-12-31 17:13:24.005+00 -91 20241120063859_cascade_delete_checkout_session.js 1 2024-12-31 17:13:24.016+00 -92 20241120140402_gendo_credits.js 1 2024-12-31 17:13:24.028+00 -93 20241126084242_workspace_plan_rename.js 1 2024-12-31 17:13:24.041+00 -94 20241126142602_workspace_plan_date.js 1 2024-12-31 17:13:24.045+00 -95 20241128153315_workspace_creation_state.js 1 2024-12-31 17:13:24.063+00 -96 20241202183039_workspace_start_trial.js 1 2024-12-31 17:13:24.07+00 -97 20241203212110_cascade_delete_automations.js 1 2024-12-31 17:13:24.097+00 -\. +ALTER TABLE ONLY public.personal_api_tokens + ADD CONSTRAINT personal_api_tokens_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: knex_migrations_lock; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: refresh_tokens refresh_tokens_appid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.knex_migrations_lock (index, is_locked) FROM stdin; -1 0 -\. +ALTER TABLE ONLY public.refresh_tokens + ADD CONSTRAINT refresh_tokens_appid_foreign FOREIGN KEY ("appId") REFERENCES public.server_apps(id) ON DELETE CASCADE; -- --- Data for Name: object_children_closure; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: refresh_tokens refresh_tokens_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.object_children_closure (parent, child, "minDepth", "streamId") FROM stdin; -\. +ALTER TABLE ONLY public.refresh_tokens + ADD CONSTRAINT refresh_tokens_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: object_preview; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_access_requests server_access_requests_requesterid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.object_preview ("streamId", "objectId", "previewStatus", priority, "lastUpdate", preview) FROM stdin; -\. +ALTER TABLE ONLY public.server_access_requests + ADD CONSTRAINT server_access_requests_requesterid_foreign FOREIGN KEY ("requesterId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: objects; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_acl server_acl_role_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.objects (id, "speckleType", "totalChildrenCount", "totalChildrenCountByDepth", "createdAt", data, "streamId") FROM stdin; -\. +ALTER TABLE ONLY public.server_acl + ADD CONSTRAINT server_acl_role_foreign FOREIGN KEY (role) REFERENCES public.user_roles(name) ON DELETE CASCADE; -- --- Data for Name: personal_api_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_acl server_acl_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.personal_api_tokens ("tokenId", "userId") FROM stdin; -314504c3d0 3fb61f0d69 -\. +ALTER TABLE ONLY public.server_acl + ADD CONSTRAINT server_acl_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: previews; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_apps server_apps_authorid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.previews (id, data) FROM stdin; -\. +ALTER TABLE ONLY public.server_apps + ADD CONSTRAINT server_apps_authorid_foreign FOREIGN KEY ("authorId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: pwdreset_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_apps_scopes server_apps_scopes_appid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.pwdreset_tokens (id, email, "createdAt") FROM stdin; -\. +ALTER TABLE ONLY public.server_apps_scopes + ADD CONSTRAINT server_apps_scopes_appid_foreign FOREIGN KEY ("appId") REFERENCES public.server_apps(id) ON DELETE CASCADE; -- --- Data for Name: ratelimit_actions; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_apps_scopes server_apps_scopes_scopename_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.ratelimit_actions ("timestamp", action, source) FROM stdin; -\. +ALTER TABLE ONLY public.server_apps_scopes + ADD CONSTRAINT server_apps_scopes_scopename_foreign FOREIGN KEY ("scopeName") REFERENCES public.scopes(name) ON DELETE CASCADE; -- --- Data for Name: refresh_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: server_invites server_invites_inviterid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.refresh_tokens (id, "tokenDigest", "appId", "userId", "createdAt", lifespan) FROM stdin; -b9eeee1b67 $2b$10$V9el87hGEUU43t/7R45qlegPxj8J6hfVKfjWwC4ueUwDGqNgInet. spklwebapp 3fb61f0d69 2024-12-31 17:15:26.550566+00 15770000000 -\. +ALTER TABLE ONLY public.server_invites + ADD CONSTRAINT server_invites_inviterid_foreign FOREIGN KEY ("inviterId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: regions; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: stream_acl stream_acl_resourceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.regions (key, name, description, "createdAt", "updatedAt") FROM stdin; -\. +ALTER TABLE ONLY public.stream_acl + ADD CONSTRAINT stream_acl_resourceid_foreign FOREIGN KEY ("resourceId") REFERENCES public.streams(id) ON DELETE CASCADE; -- --- Data for Name: scheduled_tasks; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: stream_acl stream_acl_role_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.scheduled_tasks ("taskName", "lockExpiresAt") FROM stdin; -\. +ALTER TABLE ONLY public.stream_acl + ADD CONSTRAINT stream_acl_role_foreign FOREIGN KEY (role) REFERENCES public.user_roles(name) ON DELETE CASCADE; -- --- Data for Name: scopes; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: stream_acl stream_acl_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.scopes (name, description, public) FROM stdin; -apps:read See created or authorized applications. f -apps:write Register new applications. f -streams:read Read your streams, and any associated information (branches, commits, objects). t -streams:write Create streams on your behalf, and any associated data (branches, commits, objects). t -profile:read Read your profile information. t -profile:email Read the email address you registered with. t -profile:delete Delete the account with all associated data. f -users:read Read other users' profiles. t -server:stats Request server stats from the API. Only works in conjunction with a "server:admin" role. t -users:email Access the emails of other users. f -server:setup Edit server information. Note: Only server admins will be able to use this token. f -tokens:read Access API tokens. f -tokens:write Create and delete API tokens. f -users:invite Invite others to join this server. f -workspace:create Required for the creation of a workspace t -workspace:update Required for editing workspace information t -workspace:read Required for reading workspace data t -workspace:delete Required for deleting workspaces t -workspace:billing Scope for managing workspace billing f -\. +ALTER TABLE ONLY public.stream_acl + ADD CONSTRAINT stream_acl_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: server_access_requests; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: stream_commits stream_commits_commitid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.server_access_requests (id, "requesterId", "resourceType", "resourceId", "createdAt", "updatedAt") FROM stdin; -\. +ALTER TABLE ONLY public.stream_commits + ADD CONSTRAINT stream_commits_commitid_foreign FOREIGN KEY ("commitId") REFERENCES public.commits(id) ON DELETE CASCADE; -- --- Data for Name: user_roles; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: stream_commits stream_commits_streamid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.user_roles (name, description, "resourceTarget", "aclTableName", weight, public) FROM stdin; -server:admin Holds supreme autocratic authority, not restricted by written laws, legislature, or customs. server server_acl 1000 f -server:user Has normal access to the server. server server_acl 100 f -server:guest Has limited access to the server. server server_acl 50 f -server:archived-user No longer has access to the server. server server_acl 10 f -stream:owner Owners have full access, including deletion rights & access control. streams stream_acl 1000 t -stream:contributor Contributors can create new branches and commits, but they cannot edit stream details or manage collaborators. streams stream_acl 500 t -stream:reviewer Reviewers can only view (read) the data from this stream. streams stream_acl 100 t -workspace:admin Has root on the workspace workspaces workspace_acl 1000 t -workspace:member A regular member of the workspace workspaces workspace_acl 100 t -workspace:guest An external guest member of the workspace with limited rights workspaces workspace_acl 50 t -\. +ALTER TABLE ONLY public.stream_commits + ADD CONSTRAINT stream_commits_streamid_foreign FOREIGN KEY ("streamId") REFERENCES public.streams(id) ON DELETE CASCADE; -- --- Data for Name: server_acl; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: stream_favorites stream_favorites_streamid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.server_acl ("userId", role) FROM stdin; -3fb61f0d69 server:admin -\. +ALTER TABLE ONLY public.stream_favorites + ADD CONSTRAINT stream_favorites_streamid_foreign FOREIGN KEY ("streamId") REFERENCES public.streams(id) ON DELETE CASCADE; -- --- Data for Name: server_apps_scopes; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: stream_favorites stream_favorites_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.server_apps_scopes ("appId", "scopeName") FROM stdin; -spklwebapp apps:read -spklwebapp apps:write -spklwebapp streams:read -spklwebapp streams:write -spklwebapp profile:read -spklwebapp profile:email -spklwebapp profile:delete -spklwebapp users:read -spklwebapp server:stats -spklwebapp users:email -spklwebapp server:setup -spklwebapp tokens:read -spklwebapp tokens:write -spklwebapp users:invite -spklwebapp workspace:create -spklwebapp workspace:update -spklwebapp workspace:read -spklwebapp workspace:delete -spklwebapp workspace:billing -explorer apps:read -explorer apps:write -explorer streams:read -explorer streams:write -explorer profile:read -explorer profile:email -explorer profile:delete -explorer users:read -explorer server:stats -explorer users:email -explorer server:setup -explorer tokens:read -explorer tokens:write -explorer users:invite -explorer workspace:create -explorer workspace:update -explorer workspace:read -explorer workspace:delete -explorer workspace:billing -sca streams:read -sca streams:write -sca profile:read -sca profile:email -sca users:read -sca users:invite -spklpwerbi streams:read -spklpwerbi profile:read -spklpwerbi profile:email -spklpwerbi users:read -spklpwerbi users:invite -spklexcel streams:read -spklexcel streams:write -spklexcel profile:read -spklexcel profile:email -spklexcel users:read -spklexcel users:invite -spklautoma profile:email -spklautoma profile:read -spklautoma users:read -spklautoma tokens:write -spklautoma streams:read -spklautoma streams:write -sdm streams:read -sdm streams:write -sdm profile:read -sdm profile:email -sdm users:read -sdm users:invite -\. +ALTER TABLE ONLY public.stream_favorites + ADD CONSTRAINT stream_favorites_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: server_config; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: streams streams_clonedfrom_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.server_config (id, name, company, description, "adminContact", "termsOfService", "canonicalUrl", completed, "inviteOnly", "guestModeEnabled") FROM stdin; -0 My new Speckle Server Unknown Company This a community deployment of a Speckle Server. n/a n/a \N f f f -\. +ALTER TABLE ONLY public.streams + ADD CONSTRAINT streams_clonedfrom_foreign FOREIGN KEY ("clonedFrom") REFERENCES public.streams(id); -- --- Data for Name: server_invites; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: streams_meta streams_meta_streamid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.server_invites (id, target, "inviterId", "createdAt", message, token, resource, "updatedAt") FROM stdin; -\. +ALTER TABLE ONLY public.streams_meta + ADD CONSTRAINT streams_meta_streamid_foreign FOREIGN KEY ("streamId") REFERENCES public.streams(id) ON DELETE CASCADE; -- --- Data for Name: sso_providers; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: streams streams_workspaceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.sso_providers (id, "providerType", "encryptedProviderData", "createdAt", "updatedAt") FROM stdin; -\. +ALTER TABLE ONLY public.streams + ADD CONSTRAINT streams_workspaceid_foreign FOREIGN KEY ("workspaceId") REFERENCES public.workspaces(id) ON DELETE CASCADE; -- --- Data for Name: stream_acl; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: token_resource_access token_resource_access_tokenid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.stream_acl ("userId", "resourceId", role) FROM stdin; -3fb61f0d69 47d8fd9d36 stream:owner -\. +ALTER TABLE ONLY public.token_resource_access + ADD CONSTRAINT token_resource_access_tokenid_foreign FOREIGN KEY ("tokenId") REFERENCES public.api_tokens(id) ON DELETE CASCADE; -- --- Data for Name: stream_activity; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: token_scopes token_scopes_scopename_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.stream_activity ("streamId", "time", "resourceType", "resourceId", "actionType", "userId", info, message) FROM stdin; -\N 2024-12-31 17:15:26.189971+00 user 3fb61f0d69 user_create 3fb61f0d69 {"user": {"id": "3fb61f0d69", "ip": null, "bio": null, "name": "Fuzz Test", "email": "fuzztest@example.org", "suuid": "6bff2a82-30db-4d5e-b4a6-78dbb07f0b2b", "avatar": null, "company": null, "profiles": null, "verified": false, "createdAt": "2024-12-31T17:15:25.885Z", "passwordDigest": "$2b$10$n9TiIOXO8PagZ8azbKyGk.fa6u2iju7mgEtDwyiBnRRZGaNLlMUQS"}} User created -47d8fd9d36 2024-12-31 17:15:26.86193+00 stream 47d8fd9d36 stream_create 3fb61f0d69 {"input": {"id": "47d8fd9d36", "name": "Shiny Edifice", "isPublic": true, "createdAt": "2024-12-31T17:15:26.845Z", "regionKey": null, "updatedAt": "2024-12-31T17:15:26.845Z", "clonedFrom": null, "description": "", "workspaceId": null, "isDiscoverable": true, "allowPublicComments": false}} Stream Shiny Edifice created -47d8fd9d36 2024-12-31 17:17:23.701158+00 branch 3c4ce908af branch_create 3fb61f0d69 {"branch": {"id": "3c4ce908af", "name": "fuzzy", "authorId": "3fb61f0d69", "streamId": "47d8fd9d36", "createdAt": "2024-12-31T17:17:23.699Z", "updatedAt": "2024-12-31T17:17:23.699Z", "description": null}} Branch created: fuzzy (3c4ce908af) -\. +ALTER TABLE ONLY public.token_scopes + ADD CONSTRAINT token_scopes_scopename_foreign FOREIGN KEY ("scopeName") REFERENCES public.scopes(name) ON DELETE CASCADE; -- --- Data for Name: stream_commits; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: token_scopes token_scopes_tokenid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.stream_commits ("streamId", "commitId") FROM stdin; -\. +ALTER TABLE ONLY public.token_scopes + ADD CONSTRAINT token_scopes_tokenid_foreign FOREIGN KEY ("tokenId") REFERENCES public.api_tokens(id) ON DELETE CASCADE; -- --- Data for Name: stream_favorites; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: user_emails user_emails_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.stream_favorites ("streamId", "userId", "createdAt", cursor) FROM stdin; -\. +ALTER TABLE ONLY public.user_emails + ADD CONSTRAINT user_emails_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: streams_meta; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: user_notification_preferences user_notification_preferences_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.streams_meta ("streamId", key, value, "createdAt", "updatedAt") FROM stdin; -\. +ALTER TABLE ONLY public.user_notification_preferences + ADD CONSTRAINT user_notification_preferences_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: token_resource_access; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: user_server_app_tokens user_server_app_tokens_appid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.token_resource_access ("tokenId", "resourceId", "resourceType") FROM stdin; -\. +ALTER TABLE ONLY public.user_server_app_tokens + ADD CONSTRAINT user_server_app_tokens_appid_foreign FOREIGN KEY ("appId") REFERENCES public.server_apps(id) ON DELETE CASCADE; -- --- Data for Name: token_scopes; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: user_server_app_tokens user_server_app_tokens_tokenid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.token_scopes ("tokenId", "scopeName") FROM stdin; -d018e9f40e apps:read -d018e9f40e apps:write -d018e9f40e streams:read -d018e9f40e streams:write -d018e9f40e profile:read -d018e9f40e profile:email -d018e9f40e profile:delete -d018e9f40e users:read -d018e9f40e server:stats -d018e9f40e users:email -d018e9f40e server:setup -d018e9f40e tokens:read -d018e9f40e tokens:write -d018e9f40e users:invite -d018e9f40e workspace:create -d018e9f40e workspace:update -d018e9f40e workspace:read -d018e9f40e workspace:delete -d018e9f40e workspace:billing -314504c3d0 streams:read -314504c3d0 streams:write -314504c3d0 profile:read -314504c3d0 profile:email -314504c3d0 users:read -314504c3d0 server:stats -314504c3d0 workspace:create -314504c3d0 workspace:update -314504c3d0 workspace:read -314504c3d0 workspace:delete -\. +ALTER TABLE ONLY public.user_server_app_tokens + ADD CONSTRAINT user_server_app_tokens_tokenid_foreign FOREIGN KEY ("tokenId") REFERENCES public.api_tokens(id) ON DELETE CASCADE; -- --- Data for Name: user_emails; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: user_server_app_tokens user_server_app_tokens_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.user_emails (id, email, "primary", verified, "userId", "createdAt", "updatedAt") FROM stdin; -fe2c9e7e8a fuzztest@example.org t f 3fb61f0d69 2024-12-31 17:15:25.903+00 2024-12-31 17:15:25.903+00 -\. +ALTER TABLE ONLY public.user_server_app_tokens + ADD CONSTRAINT user_server_app_tokens_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: user_notification_preferences; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: user_sso_sessions user_sso_sessions_providerid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.user_notification_preferences ("userId", preferences) FROM stdin; -\. +ALTER TABLE ONLY public.user_sso_sessions + ADD CONSTRAINT user_sso_sessions_providerid_foreign FOREIGN KEY ("providerId") REFERENCES public.sso_providers(id) ON DELETE CASCADE; -- --- Data for Name: user_server_app_tokens; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: user_sso_sessions user_sso_sessions_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.user_server_app_tokens ("appId", "userId", "tokenId") FROM stdin; -spklwebapp 3fb61f0d69 d018e9f40e -\. +ALTER TABLE ONLY public.user_sso_sessions + ADD CONSTRAINT user_sso_sessions_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: user_sso_sessions; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: users_meta users_meta_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.user_sso_sessions ("userId", "providerId", "createdAt", "validUntil") FROM stdin; -\. +ALTER TABLE ONLY public.users_meta + ADD CONSTRAINT users_meta_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: users_meta; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: webhooks_events webhooks_events_webhookid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.users_meta ("userId", key, value, "createdAt", "updatedAt") FROM stdin; -3fb61f0d69 isOnboardingFinished true 2024-12-31 17:15:26.963+00 2024-12-31 17:15:26.964+00 -\. +ALTER TABLE ONLY public.webhooks_events + ADD CONSTRAINT webhooks_events_webhookid_foreign FOREIGN KEY ("webhookId") REFERENCES public.webhooks_config(id) ON DELETE CASCADE; -- --- Data for Name: webhooks_config; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_acl workspace_acl_role_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.webhooks_config (id, "streamId", url, description, triggers, secret, enabled, "createdAt", "updatedAt") FROM stdin; -\. +ALTER TABLE ONLY public.workspace_acl + ADD CONSTRAINT workspace_acl_role_foreign FOREIGN KEY (role) REFERENCES public.user_roles(name) ON DELETE CASCADE; -- --- Data for Name: webhooks_events; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_acl workspace_acl_userid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.webhooks_events (id, "webhookId", status, "statusInfo", "lastUpdate", payload) FROM stdin; -\. +ALTER TABLE ONLY public.workspace_acl + ADD CONSTRAINT workspace_acl_userid_foreign FOREIGN KEY ("userId") REFERENCES public.users(id) ON DELETE CASCADE; -- --- Data for Name: workspace_acl; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_acl workspace_acl_workspaceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.workspace_acl ("userId", "workspaceId", role, "createdAt") FROM stdin; -\. +ALTER TABLE ONLY public.workspace_acl + ADD CONSTRAINT workspace_acl_workspaceid_foreign FOREIGN KEY ("workspaceId") REFERENCES public.workspaces(id) ON DELETE CASCADE; -- --- Data for Name: workspace_checkout_sessions; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_checkout_sessions workspace_checkout_sessions_workspaceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.workspace_checkout_sessions ("workspaceId", id, url, "workspacePlan", "paymentStatus", "billingInterval", "createdAt", "updatedAt") FROM stdin; -\. +ALTER TABLE ONLY public.workspace_checkout_sessions + ADD CONSTRAINT workspace_checkout_sessions_workspaceid_foreign FOREIGN KEY ("workspaceId") REFERENCES public.workspaces(id) ON DELETE CASCADE; -- --- Data for Name: workspace_creation_state; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_creation_state workspace_creation_state_workspaceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.workspace_creation_state ("workspaceId", completed, state) FROM stdin; -\. +ALTER TABLE ONLY public.workspace_creation_state + ADD CONSTRAINT workspace_creation_state_workspaceid_foreign FOREIGN KEY ("workspaceId") REFERENCES public.workspaces(id) ON DELETE CASCADE; -- --- Data for Name: workspace_domains; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_domains workspace_domains_createdbyuserid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.workspace_domains (id, domain, verified, "createdAt", "updatedAt", "createdByUserId", "workspaceId") FROM stdin; -\. +ALTER TABLE ONLY public.workspace_domains + ADD CONSTRAINT workspace_domains_createdbyuserid_foreign FOREIGN KEY ("createdByUserId") REFERENCES public.users(id) ON DELETE SET NULL; -- --- Data for Name: workspace_plans; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_domains workspace_domains_workspaceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.workspace_plans ("workspaceId", name, status, "createdAt") FROM stdin; -\. +ALTER TABLE ONLY public.workspace_domains + ADD CONSTRAINT workspace_domains_workspaceid_foreign FOREIGN KEY ("workspaceId") REFERENCES public.workspaces(id) ON DELETE CASCADE; -- --- Data for Name: workspace_regions; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_plans workspace_plans_workspaceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.workspace_regions ("workspaceId", "regionKey", "createdAt") FROM stdin; -\. +ALTER TABLE ONLY public.workspace_plans + ADD CONSTRAINT workspace_plans_workspaceid_foreign FOREIGN KEY ("workspaceId") REFERENCES public.workspaces(id) ON DELETE CASCADE; -- --- Data for Name: workspace_sso_providers; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_regions workspace_regions_regionkey_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.workspace_sso_providers ("workspaceId", "providerId") FROM stdin; -\. +ALTER TABLE ONLY public.workspace_regions + ADD CONSTRAINT workspace_regions_regionkey_foreign FOREIGN KEY ("regionKey") REFERENCES public.regions(key) ON DELETE CASCADE; -- --- Data for Name: workspace_subscriptions; Type: TABLE DATA; Schema: public; Owner: speckle +-- Name: workspace_regions workspace_regions_workspaceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -COPY public.workspace_subscriptions ("workspaceId", "createdAt", "updatedAt", "currentBillingCycleEnd", "billingInterval", "subscriptionData") FROM stdin; -\. +ALTER TABLE ONLY public.workspace_regions + ADD CONSTRAINT workspace_regions_workspaceid_foreign FOREIGN KEY ("workspaceId") REFERENCES public.workspaces(id) ON DELETE CASCADE; -- --- Name: knex_migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle +-- Name: workspace_sso_providers workspace_sso_providers_providerid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -SELECT pg_catalog.setval('public.knex_migrations_id_seq', 99, true); +ALTER TABLE ONLY public.workspace_sso_providers + ADD CONSTRAINT workspace_sso_providers_providerid_foreign FOREIGN KEY ("providerId") REFERENCES public.sso_providers(id) ON DELETE CASCADE; -- --- Name: knex_migrations_lock_index_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle +-- Name: workspace_sso_providers workspace_sso_providers_workspaceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -SELECT pg_catalog.setval('public.knex_migrations_lock_index_seq', 1, true); +ALTER TABLE ONLY public.workspace_sso_providers + ADD CONSTRAINT workspace_sso_providers_workspaceid_foreign FOREIGN KEY ("workspaceId") REFERENCES public.workspaces(id) ON DELETE CASCADE; -- --- Name: stream_favorites_cursor_seq; Type: SEQUENCE SET; Schema: public; Owner: speckle +-- Name: workspace_subscriptions workspace_subscriptions_workspaceid_foreign; Type: FK CONSTRAINT; Schema: public; Owner: speckle -- -SELECT pg_catalog.setval('public.stream_favorites_cursor_seq', 1, false); +ALTER TABLE ONLY public.workspace_subscriptions + ADD CONSTRAINT workspace_subscriptions_workspaceid_foreign FOREIGN KEY ("workspaceId") REFERENCES public.workspaces(id) ON DELETE CASCADE; -- diff --git a/setup/fuzzer/token.txt b/setup/fuzzer/token.txt index b9d8db4757..58ebc4f21f 100644 --- a/setup/fuzzer/token.txt +++ b/setup/fuzzer/token.txt @@ -1,2 +1,2 @@ {u'app1': {}} -ApiTokenTag: 314504c3d01038e2013fb5b1f5d0344422168b1a70 +ApiTokenTag: 103b2cf86168ec87fc6ec88978455667feb0f08d12 From ea22d5bad163079de1d9563f677d2887a8820d09 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:27:05 +0000 Subject: [PATCH 40/69] wait until server is ready --- .github/workflows/rest-api-fuzzer.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 8c0e058989..0c8c31ca85 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -168,7 +168,11 @@ jobs: - name: Run RESTler coverage test run: | - curl --head --fail http://127.0.0.1:3000/readiness + until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do + echo "Waiting a further 3 seconds for speckle-server to start..." + sleep 3 + done + ${{ github.workspace }}/bin/restler/Restler test \ --grammar_file "${{ github.workspace }}/Compile/grammar.py" \ --dictionary_file "${{ github.workspace }}/speckle-server/setup/fuzzer/dictionary.restler.json" \ From b13b5471fb21bad9d8ad9d7ae87d63f1621e2c69 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:33:52 +0000 Subject: [PATCH 41/69] Fix token --- .gitguardian.yml | 2 ++ setup/fuzzer/token.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitguardian.yml b/.gitguardian.yml index e34613f775..e8a65a0a89 100644 --- a/.gitguardian.yml +++ b/.gitguardian.yml @@ -29,5 +29,7 @@ secret: name: setup/keycloak/speckle-realm.json - secret for dev keycloak - match: 2e1b3675a4049cd39fe6db081735f747730969071528270800f00fa98720d198 name: setup/keycloak/speckle-realm.json - algorithm name + - match: 164797a0ebc32f504e2dbaf48bec77969456bc301829039b34dc6787a1f5b0f3 + name: setup/fuzzer/token.txt - fuzz test token version: 2 diff --git a/setup/fuzzer/token.txt b/setup/fuzzer/token.txt index 58ebc4f21f..c80a63dc84 100644 --- a/setup/fuzzer/token.txt +++ b/setup/fuzzer/token.txt @@ -1,2 +1,2 @@ {u'app1': {}} -ApiTokenTag: 103b2cf86168ec87fc6ec88978455667feb0f08d12 +Authorization: Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12 From 3d5a049e192ba31adffb22e5ab9d5200512eda7e Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Wed, 1 Jan 2025 18:29:03 +0000 Subject: [PATCH 42/69] Update OpenAPI specification --- setup/fuzzer/speckle-server.openapi.json | 785 +++++++++++++++-------- 1 file changed, 503 insertions(+), 282 deletions(-) diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index dd47a0a9e3..eaf968b3bd 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -30,7 +30,20 @@ "responses": { "200": { "description": "User logged in successfully" }, "400": { "description": "Invalid input" }, - "401": { "description": "Invalid credentials" } + "401": { + "description": "Invalid credentials", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "err": { "type": "boolean" }, + "message": { "type": "string" } + } + } + } + } + } } } }, @@ -44,11 +57,36 @@ "schema": { "type": "string" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { "type": "string", "format": "email" }, + "password": { "type": "string" } + }, + "required": ["email", "password"] + } + } + } + }, "description": "Register with email and password", "responses": { "200": { "description": "User registered successfully" }, - "400": { "description": "Invalid input" }, - "500": { "description": "Server error" } + "400": { + "description": "Invalid input", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "err": { "type": "string" } + } + } + } + } + } } } }, @@ -66,7 +104,16 @@ "responses": { "200": { "description": "Returns an access code in the body" }, "302": { "description": "Redirects with access code in url query" }, - "400": { "description": "Invalid access code, or the app does not exist" }, + "400": { + "description": "Invalid access code, or the app does not exist", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, "500": { "description": "Internal error" } } }, @@ -99,7 +146,19 @@ }, "responses": { "200": { "description": "Generates a new API token" }, - "401": { "description": "Unauthorized" } + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "err": { "type": "string" } + } + } + } + } + } } } }, @@ -108,7 +167,14 @@ "description": "Logs a user out by invalidating token and refresh token", "responses": { "200": { "description": "Successfully logged out" }, - "400": { "description": "Error while logging out" } + "400": { + "description": "Error while logging out", + "content": { + "text/html": { + "schema": { "type": "string" } + } + } + } } } }, @@ -127,7 +193,21 @@ "200": { "description": "Successfully uploaded a blob to the project" }, - "404": { "description": "Stream could not be found" } + "404": { + "description": "Stream could not be found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + } + } + } + } + } } } }, @@ -155,6 +235,21 @@ "responses": { "200": { "description": "The difference between the list of blob Ids provided in the body of the request and those stored on the server" + }, + "404": { + "description": "Stream could not be found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + } + } + } + } } } } @@ -190,7 +285,21 @@ "204": { "description": "Successfully deleted a blob from the project" }, - "404": { "description": "Stream or blob could not be found." } + "404": { + "description": "Stream or blob could not be found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + } + } + } + } + } } } }, @@ -210,7 +319,17 @@ "description": "Successfully retrieved all the blobs from the project" }, "401": { "description": "Unauthorized" }, - "404": { "description": "Stream could not be found." } + "404": { + "description": "Stream could not be found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { "error": { "type": "string" } } + } + } + } + } } }, "delete": { @@ -218,10 +337,25 @@ "responses": { "501": { "description": "Not implemented." } } } }, - "/static/": { + "/static": { "get": { "description": "Static assets", - "responses": { "200": { "description": "An asset was retrieved." } } + "responses": { + "200": { "description": "An asset was retrieved." }, + "301": { + "description": "Redirects to the home page.", + "headers": { + "Location": { + "schema": { "type": "string", "format": "uri" } + } + }, + "content": { + "text/html": { + "schema": { "type": "string" } + } + } + } + } } }, "/liveness": { @@ -290,7 +424,8 @@ "description": "Download objects from a project (stream)", "responses": { "200": { "description": "Objects were downloaded." }, - "401": { "description": "Unauthorized" } + "401": { "description": "Unauthorized" }, + "404": { "description": "Stream or Object was not found." } } } }, @@ -317,7 +452,8 @@ "description": "Options for downloading a single object from a project (stream)", "responses": { "200": { "description": "An object was retrieved." }, - "401": { "description": "Unauthorized" } + "401": { "description": "Unauthorized" }, + "404": { "description": "Stream or Object was not found" } } } }, @@ -351,319 +487,404 @@ }, "responses": { "200": { "description": "A diff was successfully computed." }, - "401": { "description": "Unauthorized" } - } - } - }, - "/api/getobjects/{streamId}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - } - ], - "options": { - "description": "Options for the endpoint", - "responses": { "200": { "description": "Options were retrieved." } } - }, - "post": { - "description": "Get all objects for a project (stream)", - "responses": { - "200": { "description": "All objects were successfully retrieved." }, - "401": { "description": "Unauthorized" } - } - } - }, - "/auth/verifyemail": { - "get": { - "summary": "Verify email", - "description": "Verifies an email address", - "responses": { - "302": { - "description": "Redirects to the home page.", + "401": { + "description": "Unauthorized", "headers": { - "Location": { - "schema": { "type": "string" } - } - }, - "parameters": [ - { - "in": "query", - "name": "emailverifiederror", - "schema": { "type": "string" } + "X-RateLimit-Remaining": { + "schema": { "type": "integer" } } - ] + } } } - } - }, - "/api/file/{fileType}/{streamId}/{branchName}": { - "parameters": [ - { - "in": "path", - "name": "fileType", - "required": true, - "schema": { - "oneOf": [ - { "type": "string" }, - { "type": "string", "enum": ["autodetect"] } - ] + }, + "/api/getobjects/{streamId}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } } + ], + "options": { + "description": "Options for the endpoint", + "responses": { "200": { "description": "Options were retrieved." } } }, - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "branchName", - "required": true, - "schema": { "type": "string" } + "post": { + "description": "Get all objects for a project (stream)", + "responses": { + "200": { "description": "All objects were successfully retrieved." }, + "401": { "description": "Unauthorized" }, + "404": { + "description": "Stream was not found.", + "headers": { + "X-RateLimit-Remaining": { + "schema": { "type": "integer" } + } + } + } + } } - ], - "post": { - "description": "Uploads a file to a project (stream)", - "responses": { - "200": { - "description": "file successfully uploaded to the project (stream)" - }, - "404": { - "description": "Stream or branch could not be found." + }, + "/auth/verifyemail": { + "get": { + "summary": "Verify email", + "description": "Verifies an email address", + "parameters": [ + { + "in": "query", + "name": "t", + "required": true, + "schema": { "type": "string" } + } + ], + "responses": { + "302": { + "description": "Redirects to the home page.", + "headers": { + "Location": { + "schema": { "type": "string", "format": "uri" } + } + } + } } } - } - }, - "/metrics": { - "get": { - "summary": "Metrics", - "description": "Returns Prometheus metrics", - "responses": { "200": { "description": "Returns Prometheus metrics" } } - } - }, - "/preview/{streamId}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "angle", - "required": true, - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0 }, - { "type": "string", "enum": ["all"] } - ] + }, + "/api/file/{fileType}/{streamId}/{branchName}": { + "parameters": [ + { + "in": "path", + "name": "fileType", + "required": true, + "schema": { + "oneOf": [ + { "type": "string" }, + { "type": "string", "enum": ["autodetect"] } + ] + } + }, + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "branchName", + "required": true, + "schema": { "type": "string" } + } + ], + "post": { + "description": "Uploads a file to a project (stream)", + "responses": { + "200": { + "description": "file successfully uploaded to the project (stream)" + }, + "404": { + "description": "Stream or branch could not be found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + } + } + } + } + } } } - ], - "options": { - "description": "Options for the endpoint", - "responses": { - "200": { "description": "Options successfully retrieved." } + }, + "/metrics": { + "get": { + "summary": "Metrics", + "description": "Returns Prometheus metrics", + "responses": { "200": { "description": "Returns Prometheus metrics" } } } }, - "get": { - "description": "Retrieve a preview for the project (stream), at an optional angle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } + "/preview/{streamId}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] + } + } + ], + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } + }, + "get": { + "description": "Retrieve a preview for the project (stream), at an optional angle", + "responses": { + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } } } } } - } - }, - "/preview/{streamId}/branches/{branchName}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "branchName", - "required": true, - "schema": { "type": "string" } + }, + "/preview/{streamId}/branches/{branchName}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "branchName", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] + } + } + ], + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } }, - { - "in": "path", - "name": "angle", - "required": true, - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0 }, - { "type": "string", "enum": ["all"] } - ] + "get": { + "description": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", + "responses": { + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } + } + } } } - ], - "options": { - "description": "Options for the endpoint", - "responses": { - "200": { "description": "Options successfully retrieved." } - } }, - "get": { - "description": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } + "/preview/{streamId}/commits/{commitId}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "commitId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] + } + } + ], + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } + }, + "get": { + "description": "Retrieve a preview for the project (stream) and version (commit), at an optional angle", + "responses": { + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } } } } } - } - }, - "/preview/{streamId}/commits/{commitId}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "commitId", - "required": true, - "schema": { "type": "string" } + }, + "/preview/{streamId}/objects/{objectId}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "objectId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0, "maximum": 360 }, + { "type": "string", "enum": ["all"] } + ] + } + } + ], + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } }, - { - "in": "path", - "name": "angle", - "required": true, - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0 }, - { "type": "string", "enum": ["all"] } - ] + "get": { + "description": "Retrieve a preview for the project (stream) and object, at an optional angle", + "responses": { + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } + } + }, + "403": { "description": "Forbidden" } } } - ], - "options": { - "description": "Options for the endpoint", - "responses": { - "200": { "description": "Options successfully retrieved." } - } }, - "get": { - "description": "Retrieve a preview for the project (stream) and version (commit), at an optional angle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", + "/auth/pwdreset/request": { + "post": { + "description": "Reset a password", + "requestBody": { "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { "type": "string", "format": "email" } + }, + "required": ["email"] + } + } + } + }, + "responses": { + "200": { + "description": "The password reset workflow was successfully started." + }, + "400": { + "description": "Invalid input", + "content": { + "text/html": { + "schema": { "type": "string" } + } } } } } - } - }, - "/preview/{streamId}/objects/{objectId}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "objectId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "angle", - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0, "maximum": 360 }, - { "type": "string", "enum": ["all"] } - ] - } - } - ], - "options": { - "description": "Options for the endpoint", - "responses": { - "200": { "description": "Options successfully retrieved." } - } }, - "get": { - "description": "Retrieve a preview for the project (stream) and object, at an optional angle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", + "/auth/pwdreset/finalize": { + "post": { + "description": "Finish resetting a password", + "requestBody": { "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } + "application/json": { + "schema": { + "type": "object", + "properties": { + "tokenId": { "type": "string" }, + "password": { "type": "string" } + }, + "required": ["tokenId", "password"] + } } } }, - "403": { "description": "Forbidden" } - } - } - }, - "/auth/pwdreset/request": { - "post": { - "description": "Reset a password", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { "type": "string", "format": "email" } - }, - "required": ["email"] + "responses": { + "200": { "description": "The password was successfully reset." }, + "400": { + "description": "Invalid input", + "content": { + "text/html": { + "schema": { "type": "string" } + } } } } - }, - "responses": { - "200": { - "description": "The password reset workflow was successfully started." - }, - "400": { "description": "Invalid input" } - } - } - }, - "/auth/pwdreset/finalize": { - "post": { - "description": "Finish resetting a password", - "responses": { - "200": { "description": "The password was successfully reset." } } - } - }, - "/graphql": { - "post": { - "requestBody": { - "content": { - "application/json": {} + }, + "/graphql": { + "post": { + "requestBody": { + "content": { + "application/json": {} + } + }, + "summary": "GraphQL", + "description": "GraphQL endpoint", + "responses": { + "400": { + "description": "Invalid input", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "message": { "type": "string" }, + "extensions": { + "type": "object", + "properties": { + "code": { "type": "string" } + } + } + } + } + } + } + } + } + } + } } - }, - "summary": "GraphQL", - "description": "GraphQL endpoint", - "responses": { "default": { "description": "GraphQL endpoint" } } + } } } } From fb2a22de2b9d58f9d3fe25e2c248e0b2c9c23b9c Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Wed, 1 Jan 2025 19:23:59 +0000 Subject: [PATCH 43/69] Fix indentation of openapi spec --- .github/workflows/rest-api-fuzzer.yml | 5 +- setup/fuzzer/speckle-server.openapi.json | 655 +++++++++++------------ 2 files changed, 330 insertions(+), 330 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 0c8c31ca85..4737c4fa4e 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -138,9 +138,10 @@ jobs: ${{ github.workspace }}/bin/restler/Restler compile ${{ github.workspace }}/speckle-server/setup/fuzzer/config.restler.json - name: Print the contents of the Restler compile directory + if: always() run: | - ls -la ${{ github.workspace }} - ls -la ${{ github.workspace }}/Compile + ls -la ${{ github.workspace }} || true + ls -la ${{ github.workspace }}/Compile || true - name: Save Grammar id: cache-grammar-save diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index eaf968b3bd..e7f6818bf2 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -1,11 +1,10 @@ { - "swagger": "3.1.1", - "basePath": "/", - "info": { "title": "Speckle.", "version": "dev" }, - "definitions": {}, - "servers": [ - { "url": "http://localhost:3000", "description": "Development and Testing server" } - ], + "openapi": "3.1.1", + "info": { + "title": "Speckle.", + "version": "dev", + "license": { "name": "Apache 2.0" } + }, "paths": { "/explorer": { "get": { @@ -18,6 +17,7 @@ }, "/auth/local/login": { "post": { + "summary": "Login with email and password", "parameters": [ { "in": "query", @@ -26,7 +26,6 @@ "schema": { "type": "string" } } ], - "description": "Login with email and password", "responses": { "200": { "description": "User logged in successfully" }, "400": { "description": "Invalid input" }, @@ -71,7 +70,7 @@ } } }, - "description": "Register with email and password", + "summary": "Register with email and password", "responses": { "200": { "description": "User registered successfully" }, "400": { @@ -496,102 +495,102 @@ } } } + } + }, + "/api/getobjects/{streamId}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + } + ], + "options": { + "description": "Options for the endpoint", + "responses": { "200": { "description": "Options were retrieved." } } }, - "/api/getobjects/{streamId}": { + "post": { + "description": "Get all objects for a project (stream)", + "responses": { + "200": { "description": "All objects were successfully retrieved." }, + "401": { "description": "Unauthorized" }, + "404": { + "description": "Stream was not found.", + "headers": { + "X-RateLimit-Remaining": { + "schema": { "type": "integer" } + } + } + } + } + } + }, + "/auth/verifyemail": { + "get": { + "summary": "Verify email", + "description": "Verifies an email address", "parameters": [ { - "in": "path", - "name": "streamId", + "in": "query", + "name": "t", "required": true, "schema": { "type": "string" } } ], - "options": { - "description": "Options for the endpoint", - "responses": { "200": { "description": "Options were retrieved." } } - }, - "post": { - "description": "Get all objects for a project (stream)", - "responses": { - "200": { "description": "All objects were successfully retrieved." }, - "401": { "description": "Unauthorized" }, - "404": { - "description": "Stream was not found.", - "headers": { - "X-RateLimit-Remaining": { - "schema": { "type": "integer" } - } + "responses": { + "302": { + "description": "Redirects to the home page.", + "headers": { + "Location": { + "schema": { "type": "string", "format": "uri" } } } } } - }, - "/auth/verifyemail": { - "get": { - "summary": "Verify email", - "description": "Verifies an email address", - "parameters": [ - { - "in": "query", - "name": "t", - "required": true, - "schema": { "type": "string" } - } - ], - "responses": { - "302": { - "description": "Redirects to the home page.", - "headers": { - "Location": { - "schema": { "type": "string", "format": "uri" } - } - } - } + } + }, + "/api/file/{fileType}/{streamId}/{branchName}": { + "parameters": [ + { + "in": "path", + "name": "fileType", + "required": true, + "schema": { + "oneOf": [ + { "type": "string" }, + { "type": "string", "enum": ["autodetect"] } + ] } + }, + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "branchName", + "required": true, + "schema": { "type": "string" } } - }, - "/api/file/{fileType}/{streamId}/{branchName}": { - "parameters": [ - { - "in": "path", - "name": "fileType", - "required": true, - "schema": { - "oneOf": [ - { "type": "string" }, - { "type": "string", "enum": ["autodetect"] } - ] - } - }, - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } + ], + "post": { + "description": "Uploads a file to a project (stream)", + "responses": { + "200": { + "description": "file successfully uploaded to the project (stream)" }, - { - "in": "path", - "name": "branchName", - "required": true, - "schema": { "type": "string" } - } - ], - "post": { - "description": "Uploads a file to a project (stream)", - "responses": { - "200": { - "description": "file successfully uploaded to the project (stream)" - }, - "404": { - "description": "Stream or branch could not be found.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "string" - } + "404": { + "description": "Stream or branch could not be found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" } } } @@ -599,281 +598,281 @@ } } } - }, - "/metrics": { - "get": { - "summary": "Metrics", - "description": "Returns Prometheus metrics", - "responses": { "200": { "description": "Returns Prometheus metrics" } } + } + }, + "/metrics": { + "get": { + "summary": "Metrics", + "description": "Returns Prometheus metrics", + "responses": { "200": { "description": "Returns Prometheus metrics" } } + } + }, + "/preview/{streamId}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] + } + } + ], + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } } }, - "/preview/{streamId}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "angle", - "required": true, - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0 }, - { "type": "string", "enum": ["all"] } - ] + "get": { + "description": "Retrieve a preview for the project (stream), at an optional angle", + "responses": { + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } } } - ], - "options": { - "description": "Options for the endpoint", - "responses": { - "200": { "description": "Options successfully retrieved." } - } + } + } + }, + "/preview/{streamId}/branches/{branchName}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } }, - "get": { - "description": "Retrieve a preview for the project (stream), at an optional angle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } - } - } - } + { + "in": "path", + "name": "branchName", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] } } + ], + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } }, - "/preview/{streamId}/branches/{branchName}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "branchName", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "angle", - "required": true, - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0 }, - { "type": "string", "enum": ["all"] } - ] + "get": { + "description": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", + "responses": { + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } } } - ], - "options": { - "description": "Options for the endpoint", - "responses": { - "200": { "description": "Options successfully retrieved." } - } + } + } + }, + "/preview/{streamId}/commits/{commitId}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } }, - "get": { - "description": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } - } - } - } + { + "in": "path", + "name": "commitId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "required": true, + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0 }, + { "type": "string", "enum": ["all"] } + ] } } + ], + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } }, - "/preview/{streamId}/commits/{commitId}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "commitId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "angle", - "required": true, - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0 }, - { "type": "string", "enum": ["all"] } - ] + "get": { + "description": "Retrieve a preview for the project (stream) and version (commit), at an optional angle", + "responses": { + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } } } - ], - "options": { - "description": "Options for the endpoint", - "responses": { - "200": { "description": "Options successfully retrieved." } - } + } + } + }, + "/preview/{streamId}/objects/{objectId}/{angle}": { + "parameters": [ + { + "in": "path", + "name": "streamId", + "required": true, + "schema": { "type": "string" } }, - "get": { - "description": "Retrieve a preview for the project (stream) and version (commit), at an optional angle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } - } - } - } + { + "in": "path", + "name": "objectId", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "path", + "name": "angle", + "schema": { + "oneOf": [ + { "type": "integer", "minimum": 0, "maximum": 360 }, + { "type": "string", "enum": ["all"] } + ] } } + ], + "options": { + "description": "Options for the endpoint", + "responses": { + "200": { "description": "Options successfully retrieved." } + } }, - "/preview/{streamId}/objects/{objectId}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "objectId", - "required": true, - "schema": { "type": "string" } + "get": { + "description": "Retrieve a preview for the project (stream) and object, at an optional angle", + "responses": { + "200": { + "description": "A preview was successfully retrieved.", + "content": { + "image/png": { + "schema": { "type": "string", "format": "binary" } + } + } }, - { - "in": "path", - "name": "angle", - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0, "maximum": 360 }, - { "type": "string", "enum": ["all"] } - ] + "403": { "description": "Forbidden" } + } + } + }, + "/auth/pwdreset/request": { + "post": { + "description": "Reset a password", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { "type": "string", "format": "email" } + }, + "required": ["email"] + } } } - ], - "options": { - "description": "Options for the endpoint", - "responses": { - "200": { "description": "Options successfully retrieved." } - } }, - "get": { - "description": "Retrieve a preview for the project (stream) and object, at an optional angle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } - } + "responses": { + "200": { + "description": "The password reset workflow was successfully started." + }, + "400": { + "description": "Invalid input", + "content": { + "text/html": { + "schema": { "type": "string" } } - }, - "403": { "description": "Forbidden" } + } } } - }, - "/auth/pwdreset/request": { - "post": { - "description": "Reset a password", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { "type": "string", "format": "email" } - }, - "required": ["email"] - } + } + }, + "/auth/pwdreset/finalize": { + "post": { + "description": "Finish resetting a password", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "tokenId": { "type": "string" }, + "password": { "type": "string" } + }, + "required": ["tokenId", "password"] } } - }, - "responses": { - "200": { - "description": "The password reset workflow was successfully started." - }, - "400": { - "description": "Invalid input", - "content": { - "text/html": { - "schema": { "type": "string" } - } + } + }, + "responses": { + "200": { "description": "The password was successfully reset." }, + "400": { + "description": "Invalid input", + "content": { + "text/html": { + "schema": { "type": "string" } } } } } - }, - "/auth/pwdreset/finalize": { - "post": { - "description": "Finish resetting a password", - "requestBody": { + } + }, + "/graphql": { + "post": { + "requestBody": { + "content": { + "application/json": {} + } + }, + "summary": "GraphQL", + "description": "GraphQL endpoint", + "responses": { + "400": { + "description": "Invalid input", "content": { "application/json": { "schema": { "type": "object", "properties": { - "tokenId": { "type": "string" }, - "password": { "type": "string" } - }, - "required": ["tokenId", "password"] - } - } - } - }, - "responses": { - "200": { "description": "The password was successfully reset." }, - "400": { - "description": "Invalid input", - "content": { - "text/html": { - "schema": { "type": "string" } - } - } - } - } - } - }, - "/graphql": { - "post": { - "requestBody": { - "content": { - "application/json": {} - } - }, - "summary": "GraphQL", - "description": "GraphQL endpoint", - "responses": { - "400": { - "description": "Invalid input", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "type": "object", - "properties": { - "message": { "type": "string" }, - "extensions": { - "type": "object", - "properties": { - "code": { "type": "string" } - } + "errors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "message": { "type": "string" }, + "extensions": { + "type": "object", + "properties": { + "code": { "type": "string" } } } } From 7e2e079b76575876dd2f72472906ced319be2544 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 10:53:34 +0000 Subject: [PATCH 44/69] Upload test results as an artifact --- .github/workflows/rest-api-fuzzer.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 4737c4fa4e..6e4a424008 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -237,6 +237,16 @@ jobs: echo "" cat "$(find ${{ github.workspace }}/Test -type f -name "network.testing.*.txt")" || true + - uses: actions/upload-artifact@v4 + name: Store the Test output + if: always() + with: + name: fuzz-test-rest-api-output + path: ${{ github.workspace }}/Test + if-no-files-found: error + retention-days: 5 + overwrite: true + - name: Print Docker Compose logs if: always() run: | From 2cda8d8a9c99b7a0208ecc639b8f450f29622e8a Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:46:22 +0000 Subject: [PATCH 45/69] Attempt to improve test coverage --- .github/workflows/rest-api-fuzzer.yml | 12 ------------ setup/fuzzer/dictionary.restler.json | 3 ++- setup/fuzzer/speckle-server.openapi.json | 5 +++-- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 6e4a424008..923bdf57b2 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -224,18 +224,6 @@ jobs: echo "############################################" echo "" cat ${{ github.workspace }}/Test/restler-*.log || true - echo "" - echo "############################################" - echo "# Coverage report #" - echo "############################################" - echo "" - cat "$(find ${{ github.workspace }}/Test -type f -name "speccov.json")" || true - echo "" - echo "############################################" - echo "# Network testing logs #" - echo "############################################" - echo "" - cat "$(find ${{ github.workspace }}/Test -type f -name "network.testing.*.txt")" || true - uses: actions/upload-artifact@v4 name: Store the Test output diff --git a/setup/fuzzer/dictionary.restler.json b/setup/fuzzer/dictionary.restler.json index ebdf7e2893..874f1e52f7 100644 --- a/setup/fuzzer/dictionary.restler.json +++ b/setup/fuzzer/dictionary.restler.json @@ -12,7 +12,8 @@ "restler_fuzzable_bool": ["true"], "restler_fuzzable_object": ["{ \"fuzz\": false }"], "restler_custom_payload": { - "/graphql/post/Content-Type": ["application/json"] + "/graphql/post/Content-Type": "application/json", + "streamId": "815704124b" }, "restler_custom_payload_unquoted": {}, "restler_custom_payload_uuid4_suffix": {}, diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index e7f6818bf2..d483dae545 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -63,9 +63,10 @@ "type": "object", "properties": { "email": { "type": "string", "format": "email" }, - "password": { "type": "string" } + "password": { "type": "string" }, + "name": { "type": "string" } }, - "required": ["email", "password"] + "required": ["email", "password", "name"] } } } From c00c3bb6e17f52a5e0e009ab7630061db1b16106 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:51:04 +0000 Subject: [PATCH 46/69] Print compile logs --- .github/workflows/rest-api-fuzzer.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 923bdf57b2..df806a7aa4 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -142,6 +142,7 @@ jobs: run: | ls -la ${{ github.workspace }} || true ls -la ${{ github.workspace }}/Compile || true + cat $(find ${{ github.workspace }}/Compile -type f -name "*.log") || true - name: Save Grammar id: cache-grammar-save From 5791e5afda542ebdc7d280049d0a0540ce55f487 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:58:36 +0000 Subject: [PATCH 47/69] Cache the restler binary and do not attempt to save cache if cache hit --- .github/workflows/rest-api-fuzzer.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index df806a7aa4..751a2a06f9 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -52,15 +52,34 @@ jobs: run: | pip install -r ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt + - name: Restore cached Restler binaries + id: cache-restler-bin-restore + uses: actions/cache/restore@v4 + with: + path: | + ${{ github.workspace }}/bin/restler + key: restler-binaries-${{ env.RESTLER_VERSION }} + - name: Build RESTler + if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' run: | python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin + python -m compileall -b /bin/restler - name: Debug the built output run: | ls -la ${{ github.workspace }}/bin/restler ls -la ${{ github.workspace }}/bin/restler/Restler + - name: Save Restler binaries to cache + if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' + id: cache-restler-bin-save + uses: actions/cache/save@v4 + with: + path: | + ${{ github.workspace }}/bin/restler + key: ${{ steps.cache-restler-bin-restore.outputs.cache-primary-key }} + - uses: actions/checkout@v4 name: Checkout speckle-server with: @@ -117,6 +136,7 @@ jobs: cat ${{ github.workspace }}/restlerConfig/annotations.json - name: Save Restler Config + if: steps.cache-config-restore.outputs.cache-hit != 'true' id: cache-config-save uses: actions/cache/save@v4 with: @@ -145,6 +165,7 @@ jobs: cat $(find ${{ github.workspace }}/Compile -type f -name "*.log") || true - name: Save Grammar + if: steps.cache-grammar-restore.outputs.cache-hit != 'true' id: cache-grammar-save uses: actions/cache/save@v4 with: From 1f6bb11201188984767a675d764d0e6fe0c68a7c Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:00:48 +0000 Subject: [PATCH 48/69] Attempt to fix dictionary --- setup/fuzzer/dictionary.restler.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/fuzzer/dictionary.restler.json b/setup/fuzzer/dictionary.restler.json index 874f1e52f7..71c2aa157b 100644 --- a/setup/fuzzer/dictionary.restler.json +++ b/setup/fuzzer/dictionary.restler.json @@ -12,8 +12,8 @@ "restler_fuzzable_bool": ["true"], "restler_fuzzable_object": ["{ \"fuzz\": false }"], "restler_custom_payload": { - "/graphql/post/Content-Type": "application/json", - "streamId": "815704124b" + "/graphql/post/Content-Type": ["application/json"], + "streamId": ["815704124b"] }, "restler_custom_payload_unquoted": {}, "restler_custom_payload_uuid4_suffix": {}, From 6ff569b13e0bd86d10f1e309218fef7a086d7c31 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:45:31 +0000 Subject: [PATCH 49/69] Update OpenAPI specification --- setup/fuzzer/speckle-server.openapi.json | 212 ++++++++++++++++++----- 1 file changed, 165 insertions(+), 47 deletions(-) diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index d483dae545..23782ad433 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -3,21 +3,36 @@ "info": { "title": "Speckle.", "version": "dev", - "license": { "name": "Apache 2.0" } + "license": { + "name": "Apache 2.0", + "url": "https://github.com/specklesystems/speckle-server?tab=License-1-ov-file#readme" + } }, + "servers": [ + { + "url": "https://app.speckle.systems" + } + ], "paths": { "/explorer": { "get": { + "operationId": "getExplorer", + "security": [], "summary": "GraphQL API Explorer", "description": "GraphQL API Explorer", "responses": { - "default": { "description": "Returns the GraphQL API Explorer" } + "200": { + "description": "Returns the GraphQL API Explorer", + "content": { "text/html": { "schema": { "type": "string" } } } + } } } }, "/auth/local/login": { "post": { "summary": "Login with email and password", + "operationId": "postAuthLocalLogin", + "security": [], "parameters": [ { "in": "query", @@ -48,6 +63,9 @@ }, "/auth/local/register": { "post": { + "summary": "Register with email and password", + "security": [], + "operationId": "postAuthLocalRegister", "parameters": [ { "in": "query", @@ -71,7 +89,6 @@ } } }, - "summary": "Register with email and password", "responses": { "200": { "description": "User registered successfully" }, "400": { @@ -100,7 +117,9 @@ "schema": { "type": "string" } } ], - "description": "Generates an access code for an app.", + "summary": "Generates an access code for an app.", + "security": [], + "operationId": "getAuthAccesscode", "responses": { "200": { "description": "Returns an access code in the body" }, "302": { "description": "Redirects with access code in url query" }, @@ -118,15 +137,20 @@ } }, "options": { - "description": "Generates a new API token", + "summary": "Generates a new API token", + "security": [], + "operationId": "optionsAuthAccesscode", "responses": { - "default": { "description": "Options for generating a new API token" } + "200": { "description": "Options for generating a new API token" }, + "404": { "description": "Not found" } } } }, "/auth/token": { "post": { - "description": "Generates a new API token", + "summary": "Generates a new API token", + "security": [], + "operationId": "postAuthToken", "requestBody": { "content": { "application/json": { @@ -164,7 +188,9 @@ }, "/auth/logout": { "post": { - "description": "Logs a user out by invalidating token and refresh token", + "summary": "Logs a user out by invalidating token and refresh token", + "security": [], + "operationId": "postAuthLogout", "responses": { "200": { "description": "Successfully logged out" }, "400": { @@ -180,7 +206,9 @@ }, "/api/stream/{streamId}/blob": { "post": { - "description": "Upload a new blob to a project (stream)", + "summary": "Upload a new blob to a project (stream)", + "security": [{ "BearerAuth": [] }], + "operationId": "postStreamBlobNew", "parameters": [ { "in": "path", @@ -213,7 +241,9 @@ }, "/api/stream/{streamId}/blob/diff": { "post": { - "description": "Determine the difference (diff) between the provided array of blob Ids and those stored on the server", + "summary": "Determine the difference (diff) between the provided array of blob Ids and those stored on the server", + "security": [{ "BearerAuth": [] }], + "operationId": "postStreamBlobDiff", "parameters": [ { "in": "path", @@ -270,7 +300,9 @@ } ], "get": { - "description": "Gets a blob from a project (stream)", + "summary": "Gets a blob from a project (stream)", + "security": [{ "BearerAuth": [] }], + "operationId": "getStreamBlob", "responses": { "200": { "description": "Successfully retrieved a blob from the project" @@ -280,7 +312,9 @@ } }, "delete": { - "description": "Deletes a blob from a project (stream)", + "summary": "Deletes a blob from a project (stream)", + "operationId": "deleteStreamBlob", + "security": [{ "BearerAuth": [] }], "responses": { "204": { "description": "Successfully deleted a blob from the project" @@ -313,7 +347,9 @@ } ], "get": { - "description": "Gets all the blobs of a project (stream)", + "summary": "Gets all the blobs of a project (stream)", + "operationId": "getStreamBlobs", + "security": [{ "BearerAuth": [] }], "responses": { "200": { "description": "Successfully retrieved all the blobs from the project" @@ -333,13 +369,17 @@ } }, "delete": { - "description": "Deletes all the blobs from a project (stream)", + "summary": "Deletes all the blobs from a project (stream)", + "operationId": "deleteStreamBlobs", + "security": [{ "BearerAuth": [] }], "responses": { "501": { "description": "Not implemented." } } } }, "/static": { "get": { - "description": "Static assets", + "summary": "Static assets", + "security": [], + "operationId": "getStatic", "responses": { "200": { "description": "An asset was retrieved." }, "301": { @@ -360,23 +400,31 @@ }, "/liveness": { "options": { - "description": "Liveness options", + "summary": "Liveness options", + "security": [], + "operationId": "optionsLiveness", "responses": { "200": { "description": "Options for liveness endpoint." } } }, "get": { - "description": "Indicates whether the application is alive.", + "summary": "Indicates whether the application is alive.", + "security": [], + "operationId": "getLiveness", "responses": { "200": { "description": "The application is alive." } } } }, "/readiness": { "options": { - "description": "Readiness endpoint options", + "summary": "Readiness endpoint options", + "security": [], + "operationId": "optionsReadiness", "responses": { "200": { "description": "Options were retrieved." } } }, "get": { - "description": "Indicates whether the application is ready to accept traffic", + "summary": "Indicates whether the application is ready to accept traffic", + "security": [], + "operationId": "getReadiness", "responses": { "200": { "description": "The application is ready." } } } }, @@ -390,11 +438,18 @@ } ], "options": { - "description": "The options for this endpoint", - "responses": { "200": { "description": "Options were retrieved." } } + "summary": "The options for this endpoint", + "security": [], + "operationId": "optionsObjects", + "responses": { + "200": { "description": "Options were retrieved." }, + "404": { "description": "Not found" } + } }, "post": { - "description": "Upload objects to the project (stream)", + "summary": "Upload objects to the project (stream)", + "security": [{ "BearerAuth": [] }], + "operationId": "postObjects", "responses": { "200": { "description": "Objects were successfully uploaded." }, "401": { "description": "Unauthorized" } @@ -417,11 +472,18 @@ } ], "options": { - "description": "Options for downloading an object from a project (stream)", - "responses": { "200": { "description": "Options were retrieved." } } + "summary": "Options for downloading an object from a project (stream)", + "security": [], + "operationId": "optionsObject", + "responses": { + "200": { "description": "Options were retrieved." }, + "404": { "description": "Not found" } + } }, "get": { - "description": "Download objects from a project (stream)", + "summary": "Download objects from a project (stream)", + "security": [{ "BearerAuth": [] }], + "operationId": "getObject", "responses": { "200": { "description": "Objects were downloaded." }, "401": { "description": "Unauthorized" }, @@ -445,11 +507,18 @@ } ], "options": { - "description": "Options for downloading a single object from a project (stream)", - "responses": { "200": { "description": "Options were retrieved." } } + "summary": "Options for downloading a single object from a project (stream)", + "security": [], + "operationId": "optionsObjectSingle", + "responses": { + "200": { "description": "Options were retrieved." }, + "404": { "description": "Not found" } + } }, "get": { - "description": "Options for downloading a single object from a project (stream)", + "summary": "Options for downloading a single object from a project (stream)", + "security": [{ "BearerAuth": [] }], + "operationId": "getObjectSingle", "responses": { "200": { "description": "An object was retrieved." }, "401": { "description": "Unauthorized" }, @@ -467,11 +536,18 @@ } ], "options": { - "description": "Options for the endpoint", - "responses": { "200": { "description": "Options were retrieved." } } + "summary": "Options for the endpoint", + "security": [], + "operationId": "optionsDiff", + "responses": { + "200": { "description": "Options were retrieved." }, + "404": { "description": "Not found" } + } }, "post": { - "description": "Options for getting the diff of objects for a project (stream)", + "summary": "Options for getting the diff of objects for a project (stream)", + "security": [{ "BearerAuth": [] }], + "operationId": "postDiff", "requestBody": { "content": { "application/json": { @@ -508,11 +584,18 @@ } ], "options": { - "description": "Options for the endpoint", - "responses": { "200": { "description": "Options were retrieved." } } + "summary": "Options for the endpoint", + "security": [], + "operationId": "optionsGetobjects", + "responses": { + "200": { "description": "Options were retrieved." }, + "404": { "description": "Not found" } + } }, "post": { - "description": "Get all objects for a project (stream)", + "summary": "Get all objects for a project (stream)", + "security": [{ "BearerAuth": [] }], + "operationId": "postGetobjects", "responses": { "200": { "description": "All objects were successfully retrieved." }, "401": { "description": "Unauthorized" }, @@ -530,6 +613,8 @@ "/auth/verifyemail": { "get": { "summary": "Verify email", + "security": [], + "operationId": "getAuthVerifyemail", "description": "Verifies an email address", "parameters": [ { @@ -578,7 +663,9 @@ } ], "post": { - "description": "Uploads a file to a project (stream)", + "summary": "Uploads a file to a project (stream)", + "security": [{ "BearerAuth": [] }], + "operationId": "postFileBranch", "responses": { "200": { "description": "file successfully uploaded to the project (stream)" @@ -604,6 +691,8 @@ "/metrics": { "get": { "summary": "Metrics", + "security": [], + "operationId": "getMetrics", "description": "Returns Prometheus metrics", "responses": { "200": { "description": "Returns Prometheus metrics" } } } @@ -629,13 +718,17 @@ } ], "options": { - "description": "Options for the endpoint", + "summary": "Options for the endpoint", + "security": [], + "operationId": "optionsPreviewAngle", "responses": { "200": { "description": "Options successfully retrieved." } } }, "get": { - "description": "Retrieve a preview for the project (stream), at an optional angle", + "summary": "Retrieve a preview for the project (stream), at an optional angle", + "security": [{ "BearerAuth": [] }], + "operationId": "getPreviewAngle", "responses": { "200": { "description": "A preview was successfully retrieved.", @@ -675,13 +768,17 @@ } ], "options": { - "description": "Options for the endpoint", + "summary": "Options for the endpoint", + "security": [], + "operationId": "optionsPreviewBranchAngle", "responses": { "200": { "description": "Options successfully retrieved." } } }, "get": { - "description": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", + "summary": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", + "security": [{ "BearerAuth": [] }], + "operationId": "getPreviewBranchAngle", "responses": { "200": { "description": "A preview was successfully retrieved.", @@ -721,13 +818,17 @@ } ], "options": { - "description": "Options for the endpoint", + "summary": "Options for the endpoint", + "security": [], + "operationId": "optionsPreviewCommitAngle", "responses": { "200": { "description": "Options successfully retrieved." } } }, "get": { - "description": "Retrieve a preview for the project (stream) and version (commit), at an optional angle", + "summary": "Retrieve a preview for the project (stream) and version (commit), at an optional angle", + "security": [{ "BearerAuth": [] }], + "operationId": "getPreviewCommitAngle", "responses": { "200": { "description": "A preview was successfully retrieved.", @@ -766,13 +867,17 @@ } ], "options": { - "description": "Options for the endpoint", + "summary": "Options for the endpoint", + "security": [], + "operationId": "optionsPreviewObjectAngle", "responses": { "200": { "description": "Options successfully retrieved." } } }, "get": { - "description": "Retrieve a preview for the project (stream) and object, at an optional angle", + "summary": "Retrieve a preview for the project (stream) and object, at an optional angle", + "security": [{ "BearerAuth": [] }], + "operationId": "getPreviewObjectAngle", "responses": { "200": { "description": "A preview was successfully retrieved.", @@ -788,7 +893,9 @@ }, "/auth/pwdreset/request": { "post": { - "description": "Reset a password", + "summary": "Reset a password", + "security": [], + "operationId": "postAuthPasswordresetRequest", "requestBody": { "content": { "application/json": { @@ -819,7 +926,9 @@ }, "/auth/pwdreset/finalize": { "post": { - "description": "Finish resetting a password", + "summary": "Finish resetting a password", + "security": [], + "operationId": "postAuthPasswordresetFinalize", "requestBody": { "content": { "application/json": { @@ -849,13 +958,14 @@ }, "/graphql": { "post": { + "summary": "GraphQL", + "security": [{ "BearerAuth": [] }], + "operationId": "postGraphql", "requestBody": { "content": { "application/json": {} } }, - "summary": "GraphQL", - "description": "GraphQL endpoint", "responses": { "400": { "description": "Invalid input", @@ -887,5 +997,13 @@ } } } + }, + "components": { + "securitySchemes": { + "BearerAuth": { + "type": "http", + "scheme": "bearer" + } + } } } From 5f864673ce6dc179bf9390536c03b8a7eadcd9d6 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:55:34 +0000 Subject: [PATCH 50/69] provide proper path to compiler --- .github/workflows/rest-api-fuzzer.yml | 2 +- setup/fuzzer/dictionary.restler.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 751a2a06f9..a5cb96511b 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -64,7 +64,7 @@ jobs: if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' run: | python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin - python -m compileall -b /bin/restler + python -m compileall -b ${{ github.workspace }}/bin/restler - name: Debug the built output run: | diff --git a/setup/fuzzer/dictionary.restler.json b/setup/fuzzer/dictionary.restler.json index 71c2aa157b..5ecb49fabe 100644 --- a/setup/fuzzer/dictionary.restler.json +++ b/setup/fuzzer/dictionary.restler.json @@ -12,7 +12,7 @@ "restler_fuzzable_bool": ["true"], "restler_fuzzable_object": ["{ \"fuzz\": false }"], "restler_custom_payload": { - "/graphql/post/Content-Type": ["application/json"], + "/graphql/post/content-type": ["application/json"], "streamId": ["815704124b"] }, "restler_custom_payload_unquoted": {}, From 080a478c436a099c36a1235f649da66409e124eb Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 13:34:11 +0000 Subject: [PATCH 51/69] Bust cache to retry building --- .github/workflows/rest-api-fuzzer.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index a5cb96511b..406c48e7e2 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -24,6 +24,11 @@ jobs: contents: read steps: + - uses: actions/checkout@v4 + name: Checkout speckle-server + with: + path: 'speckle-server' + - uses: actions/checkout@v4 name: Checkout RESTler Fuzzer with: @@ -58,7 +63,7 @@ jobs: with: path: | ${{ github.workspace }}/bin/restler - key: restler-binaries-${{ env.RESTLER_VERSION }} + key: restler-binaries-${{ env.RESTLER_VERSION }}-${{ hashFiles('speckle-server/.github/workflows/rest-api-fuzzer.yml') }} - name: Build RESTler if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' @@ -80,11 +85,6 @@ jobs: ${{ github.workspace }}/bin/restler key: ${{ steps.cache-restler-bin-restore.outputs.cache-primary-key }} - - uses: actions/checkout@v4 - name: Checkout speckle-server - with: - path: 'speckle-server' - - name: Restore cached Restler configuration id: cache-config-restore uses: actions/cache/restore@v4 From a3e17b83fbbc67776507768572427b3c6ff6e8e1 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:07:40 +0000 Subject: [PATCH 52/69] feat(server): allow ratelimiting to be explicitly disabled - allows rate limiter to be enabled or disabled explicitly - previously implied based on whether NODE_ENV is 'test', which may not be desired behaviour - example .env file for testing now explicitly disables it --- packages/server/.env.test-example | 3 +- .../modules/core/services/ratelimiter.ts | 8 ++- .../modules/shared/helpers/envHelper.ts | 50 +++++++++---------- .../speckle-server/templates/_helpers.tpl | 4 ++ utils/helm/speckle-server/values.schema.json | 5 ++ utils/helm/speckle-server/values.yaml | 2 + 6 files changed, 44 insertions(+), 28 deletions(-) diff --git a/packages/server/.env.test-example b/packages/server/.env.test-example index 47dd87c134..106f853bd4 100644 --- a/packages/server/.env.test-example +++ b/packages/server/.env.test-example @@ -6,4 +6,5 @@ PORT=0 POSTGRES_URL=postgres://speckle:speckle@127.0.0.1/speckle2_test POSTGRES_USER='' MULTI_REGION_CONFIG_PATH="multiregion.test.json" -#RUN_TESTS_IN_MULTIREGION_MODE=true \ No newline at end of file +#RUN_TESTS_IN_MULTIREGION_MODE=true +RATELIMITER_ENABLED='false' diff --git a/packages/server/modules/core/services/ratelimiter.ts b/packages/server/modules/core/services/ratelimiter.ts index 4e67d1344d..549b62167e 100644 --- a/packages/server/modules/core/services/ratelimiter.ts +++ b/packages/server/modules/core/services/ratelimiter.ts @@ -2,7 +2,7 @@ import express from 'express' import { getRedisUrl, getIntFromEnv, - isTestEnv + getBooleanFromEnv } from '@/modules/shared/helpers/envHelper' import { BurstyRateLimiter, @@ -55,6 +55,10 @@ export type RateLimiterMapping = { export type RateLimitAction = keyof typeof LIMITS +export const isRateLimiterEnabled = (): boolean => { + return getBooleanFromEnv('RATELIMITER_ENABLED', true) +} + export const LIMITS = { ALL_REQUESTS: { regularOptions: { @@ -307,7 +311,7 @@ export const createRateLimiterMiddleware = ( res: express.Response, next: express.NextFunction ) => { - if (isTestEnv()) return next() + if (!isRateLimiterEnabled()) return next() const path = getRequestPath(req) || '' const action = getActionForPath(path, req.method) const source = getSourceFromRequest(req) diff --git a/packages/server/modules/shared/helpers/envHelper.ts b/packages/server/modules/shared/helpers/envHelper.ts index 09fb36a24d..b58af83653 100644 --- a/packages/server/modules/shared/helpers/envHelper.ts +++ b/packages/server/modules/shared/helpers/envHelper.ts @@ -3,6 +3,31 @@ import { trimEnd } from 'lodash' import * as Environment from '@speckle/shared/dist/commonjs/environment/index.js' import { ensureError } from '@speckle/shared' +export function getStringFromEnv( + envVarKey: string, + options?: Partial<{ + /** + * If set to true, wont throw if the env var is not set + */ + unsafe: boolean + }> +): string { + const envVar = process.env[envVarKey] + if (!envVar) { + if (options?.unsafe) return '' + throw new MisconfiguredEnvironmentError(`${envVarKey} env var not configured`) + } + return envVar +} + +export function getIntFromEnv(envVarKey: string, aDefault = '0'): number { + return parseInt(process.env[envVarKey] || aDefault) +} + +export function getBooleanFromEnv(envVarKey: string, aDefault = false): boolean { + return ['1', 'true', true].includes(process.env[envVarKey] || aDefault.toString()) +} + export function getSessionSecret() { if (!process.env.SESSION_SECRET) { throw new MisconfiguredEnvironmentError('SESSION_SECRET env var not configured') @@ -45,31 +70,6 @@ export function getMaximumObjectSizeMB() { return getIntFromEnv('MAX_OBJECT_SIZE_MB', '100') } -export function getIntFromEnv(envVarKey: string, aDefault = '0'): number { - return parseInt(process.env[envVarKey] || aDefault) -} - -export function getBooleanFromEnv(envVarKey: string, aDefault = false): boolean { - return ['1', 'true', true].includes(process.env[envVarKey] || aDefault.toString()) -} - -export function getStringFromEnv( - envVarKey: string, - options?: Partial<{ - /** - * If set to true, wont throw if the env var is not set - */ - unsafe: boolean - }> -): string { - const envVar = process.env[envVarKey] - if (!envVar) { - if (options?.unsafe) return '' - throw new MisconfiguredEnvironmentError(`${envVarKey} env var not configured`) - } - return envVar -} - /** * Whether the server is supposed to serve frontend 2.0 */ diff --git a/utils/helm/speckle-server/templates/_helpers.tpl b/utils/helm/speckle-server/templates/_helpers.tpl index 5ae88fca36..22158af8fc 100644 --- a/utils/helm/speckle-server/templates/_helpers.tpl +++ b/utils/helm/speckle-server/templates/_helpers.tpl @@ -964,6 +964,10 @@ Generate the environment variables for Speckle server and Speckle objects deploy {{- end }} # Rate Limiting + +- name: RATELIMITER_ENABLED + value: "{{ .Values.server.ratelimiting.enabled }}" + {{- if .Values.server.ratelimiting.all_requests }} - name: RATELIMIT_ALL_REQUESTS value: "{{ .Values.server.ratelimiting.all_requests }}" diff --git a/utils/helm/speckle-server/values.schema.json b/utils/helm/speckle-server/values.schema.json index 471bd6c93e..ecba2e8c94 100644 --- a/utils/helm/speckle-server/values.schema.json +++ b/utils/helm/speckle-server/values.schema.json @@ -1211,6 +1211,11 @@ "ratelimiting": { "type": "object", "properties": { + "enabled": { + "type": "boolean", + "description": "If enabled, rate limiting will be applied to the Speckle server.", + "default": true + }, "all_requests": { "type": "number", "description": "The maximum number of requests that can be made to the Speckle server in a moving one second window.", diff --git a/utils/helm/speckle-server/values.yaml b/utils/helm/speckle-server/values.yaml index 278a9115d0..44a79e99aa 100644 --- a/utils/helm/speckle-server/values.yaml +++ b/utils/helm/speckle-server/values.yaml @@ -746,6 +746,8 @@ server: ## memory: 3Gi ratelimiting: + ## @param server.ratelimiting.enabled If enabled, rate limiting will be applied to the Speckle server. + enabled: true ## @param server.ratelimiting.all_requests The maximum number of requests that can be made to the Speckle server in a moving one second window. all_requests: 500 ## @param server.ratelimiting.burst_all_requests If the regular limit is exceeded, the limit is increased to the burst limit. This is the maximum number of requests that can be made to the Speckle server in a moving one minute window. From d2d62103703c8ed91e3a725331443d022d1a9628 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:23:54 +0000 Subject: [PATCH 53/69] Disable rate limiter in CI --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index ded5637270..47030bceeb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -496,6 +496,7 @@ jobs: S3_REGION: '' # optional, defaults to 'us-east-1' ENCRYPTION_KEYS_PATH: 'test/assets/automate/encryptionKeys.json' FF_BILLING_INTEGRATION_ENABLED: 'true' + RATELIMITER_ENABLED: 'false' steps: - checkout - restore_cache: @@ -578,6 +579,7 @@ jobs: S3_REGION: '' # optional, defaults to 'us-east-1' ENCRYPTION_KEYS_PATH: 'test/assets/automate/encryptionKeys.json' DISABLE_ALL_FFS: 'true' + RATELIMITER_ENABLED: 'false' test-server-multiregion: <<: *test-server-job @@ -624,6 +626,7 @@ jobs: FF_WORKSPACES_MODULE_ENABLED: 'true' FF_WORKSPACES_MULTI_REGION_ENABLED: 'true' RUN_TESTS_IN_MULTIREGION_MODE: true + RATELIMITER_ENABLED: 'false' test-frontend-2: docker: &docker-node-browsers-image From c188fa98320a95526d510f983d908e33a932e97d Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:30:54 +0000 Subject: [PATCH 54/69] Explicitly disable ratelimiter --- setup/fuzzer/docker-compose-speckle.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/fuzzer/docker-compose-speckle.yml b/setup/fuzzer/docker-compose-speckle.yml index e1649f2bba..d62f6324c5 100644 --- a/setup/fuzzer/docker-compose-speckle.yml +++ b/setup/fuzzer/docker-compose-speckle.yml @@ -44,6 +44,7 @@ services: DISABLE_NOTIFICATIONS_CONSUMPTION: true STRATEGY_LOCAL: true + RATELIMITER_ENABLED: false networks: - speckle-server_default From fef31989c4bbb1a933ff5590fb7a1893a21ef438 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 15:01:04 +0000 Subject: [PATCH 55/69] More fixes to openapi specification --- setup/fuzzer/dictionary.restler.json | 1 - setup/fuzzer/settings.restler.json | 6 +++- setup/fuzzer/speckle-server.openapi.json | 45 +++++++++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/setup/fuzzer/dictionary.restler.json b/setup/fuzzer/dictionary.restler.json index 5ecb49fabe..a4ab5d3f74 100644 --- a/setup/fuzzer/dictionary.restler.json +++ b/setup/fuzzer/dictionary.restler.json @@ -12,7 +12,6 @@ "restler_fuzzable_bool": ["true"], "restler_fuzzable_object": ["{ \"fuzz\": false }"], "restler_custom_payload": { - "/graphql/post/content-type": ["application/json"], "streamId": ["815704124b"] }, "restler_custom_payload_unquoted": {}, diff --git a/setup/fuzzer/settings.restler.json b/setup/fuzzer/settings.restler.json index e15b14a987..04e5334eda 100644 --- a/setup/fuzzer/settings.restler.json +++ b/setup/fuzzer/settings.restler.json @@ -1,5 +1,4 @@ { - "per_resource_settings": {}, "max_combinations": 20, "target_ip": "127.0.0.1", "target_port": 3000, @@ -15,5 +14,10 @@ "location": "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/token.txt", "token_refresh_interval": 300 } + }, + "per_resource_settings": { + "/auth/local/register": { + "create_once": 1 + } } } diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index 23782ad433..2c057df12d 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -191,6 +191,20 @@ "summary": "Logs a user out by invalidating token and refresh token", "security": [], "operationId": "postAuthLogout", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "token": { "type": "string" }, + "refreshToken": { "type": "string" } + }, + "required": ["token", "refreshToken"] + } + } + } + }, "responses": { "200": { "description": "Successfully logged out" }, "400": { @@ -450,6 +464,26 @@ "summary": "Upload objects to the project (stream)", "security": [{ "BearerAuth": [] }], "operationId": "postObjects", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "property_name_irrelevant": { + "type": "string", + "format": "binary" + } + } + }, + "encoding": { + "property_name_irrelevant": { + "contentType": "application/gzip, text/plain, application/json, application/octet-stream" + } + } + } + } + }, "responses": { "200": { "description": "Objects were successfully uploaded." }, "401": { "description": "Unauthorized" } @@ -963,7 +997,15 @@ "operationId": "postGraphql", "requestBody": { "content": { - "application/json": {} + "application/json": { + "schema": { + "type": "object", + "properties": { + "query": { "type": "string" } + }, + "required": ["query"] + } + } } }, "responses": { @@ -974,6 +1016,7 @@ "schema": { "type": "object", "properties": { + "data": { "type": "object" }, "errors": { "type": "array", "items": { From ed09a8cf9a7f6d17fb37b62fca3424b7483f9512 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 15:09:42 +0000 Subject: [PATCH 56/69] Remove caching --- .github/workflows/rest-api-fuzzer.yml | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml index 406c48e7e2..ef95104dd9 100644 --- a/.github/workflows/rest-api-fuzzer.yml +++ b/.github/workflows/rest-api-fuzzer.yml @@ -57,16 +57,17 @@ jobs: run: | pip install -r ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt - - name: Restore cached Restler binaries - id: cache-restler-bin-restore - uses: actions/cache/restore@v4 - with: - path: | - ${{ github.workspace }}/bin/restler - key: restler-binaries-${{ env.RESTLER_VERSION }}-${{ hashFiles('speckle-server/.github/workflows/rest-api-fuzzer.yml') }} + # This doesn't currently work as it cannot find path to compiler + # - name: Restore cached Restler binaries + # id: cache-restler-bin-restore + # uses: actions/cache/restore@v4 + # with: + # path: | + # ${{ github.workspace }}/bin/restler + # key: restler-binaries-${{ env.RESTLER_VERSION }}-${{ hashFiles('speckle-server/.github/workflows/rest-api-fuzzer.yml') }} - name: Build RESTler - if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' + # if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' run: | python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin python -m compileall -b ${{ github.workspace }}/bin/restler @@ -76,14 +77,14 @@ jobs: ls -la ${{ github.workspace }}/bin/restler ls -la ${{ github.workspace }}/bin/restler/Restler - - name: Save Restler binaries to cache - if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' - id: cache-restler-bin-save - uses: actions/cache/save@v4 - with: - path: | - ${{ github.workspace }}/bin/restler - key: ${{ steps.cache-restler-bin-restore.outputs.cache-primary-key }} + # - name: Save Restler binaries to cache + # if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' + # id: cache-restler-bin-save + # uses: actions/cache/save@v4 + # with: + # path: | + # ${{ github.workspace }}/bin/restler + # key: ${{ steps.cache-restler-bin-restore.outputs.cache-primary-key }} - name: Restore cached Restler configuration id: cache-config-restore From 49884b529fa6a8cb142dfc9fc2ff5ccce49c12d1 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:01:07 +0000 Subject: [PATCH 57/69] fix(server/blobstorage): handles errors with missing content-type header --- packages/server/modules/blobstorage/index.ts | 17 ++++++++--- .../tests/blobstorage.integration.spec.js | 11 +++++++ .../tests/fileuploads.integration.spec.ts | 29 +++++++++++++++++++ 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/packages/server/modules/blobstorage/index.ts b/packages/server/modules/blobstorage/index.ts index e7e5c059d5..112fe1edc2 100644 --- a/packages/server/modules/blobstorage/index.ts +++ b/packages/server/modules/blobstorage/index.ts @@ -129,10 +129,19 @@ export const init: SpeckleModule['init'] = async (app) => { uploadError?: Error | null | string formKey: string }>[] = [] - const busboy = Busboy({ - headers: req.headers, - limits: { fileSize: getFileSizeLimit() } - }) + let busboy: Busboy.Busboy + try { + // Busboy does some validation of user input (headers) on creation + busboy = Busboy({ + headers: req.headers, + limits: { fileSize: getFileSizeLimit() } + }) + } catch (err) { + throw new BadRequestError( + err instanceof Error ? err.message : 'Error while uploading blob', + ensureError(err, 'Unknown error while uploading blob') + ) + } const [projectDb, projectStorage] = await Promise.all([ getProjectDbClient({ projectId: streamId }), diff --git a/packages/server/modules/blobstorage/tests/blobstorage.integration.spec.js b/packages/server/modules/blobstorage/tests/blobstorage.integration.spec.js index e81dba53f5..4637cfec2e 100644 --- a/packages/server/modules/blobstorage/tests/blobstorage.integration.spec.js +++ b/packages/server/modules/blobstorage/tests/blobstorage.integration.spec.js @@ -227,4 +227,15 @@ describe('Blobs integration @blobstorage', () => { expect(response.status).to.equal(400) }) + + it('Returns 400 for missing content-type', async () => { + const streamId = await createStreamForTest() + const response = await request(app) + .post(`/api/stream/${streamId}/blob`) + .set('Authorization', `Bearer ${token}`) + // .set('Content-type', 'multipart/form-data; boundary=XXX') // purposefully missing content-type header + + console.log(response.text) + expect(response.status).to.equal(400) + }) }) diff --git a/packages/server/modules/fileuploads/tests/fileuploads.integration.spec.ts b/packages/server/modules/fileuploads/tests/fileuploads.integration.spec.ts index e9277d2a7e..c15ca76b73 100644 --- a/packages/server/modules/fileuploads/tests/fileuploads.integration.spec.ts +++ b/packages/server/modules/fileuploads/tests/fileuploads.integration.spec.ts @@ -287,6 +287,35 @@ describe('FileUploads @fileuploads', () => { ).to.have.lengthOf(0) }) + it('Returns 400 for missing headers', async () => { + const response = await request(app) + .post(`/api/file/autodetect/${createdStreamId}/main`) + .set('Authorization', `Bearer ${userOneToken}`) + // .set('Content-type', 'multipart/form-data; boundary=XXX') // purposely missing content type + + expect(response.status).to.equal(400) + expect(response.headers['content-type']).to.contain('application/json;') + expect(response.body.error.message).to.contain('Missing Content-Type') + const gqlResponse = await sendRequest(userOneToken, { + query: `query ($streamId: String!) { + stream(id: $streamId) { + id + fileUploads { + id + fileName + convertedStatus + } + } + }`, + variables: { streamId: createdStreamId } + }) + expect(noErrors(gqlResponse)) + expect( + gqlResponse.body.data.stream.fileUploads, + JSON.stringify(gqlResponse.body.data) + ).to.have.lengthOf(0) + }) + it('Returns OK but describes errors for too big files', async () => { const response = await request(app) .post(`/api/file/autodetect/${createdStreamId}/main`) From b56ba47a955b9e96a06d648aa9a9b79b24d4654e Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:02:53 +0000 Subject: [PATCH 58/69] More openapi specification improvements --- setup/fuzzer/speckle-server.openapi.json | 53 ++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index 2c057df12d..1e8f21f17b 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -41,6 +41,20 @@ "schema": { "type": "string" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { "type": "string", "format": "email" }, + "password": { "type": "string" } + }, + "required": ["email", "password"] + } + } + } + }, "responses": { "200": { "description": "User logged in successfully" }, "400": { "description": "Invalid input" }, @@ -231,6 +245,21 @@ "schema": { "type": "string" } } ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary" + } + } + } + } + } + }, "responses": { "200": { "description": "Successfully uploaded a blob to the project" @@ -470,14 +499,14 @@ "schema": { "type": "object", "properties": { - "property_name_irrelevant": { + "file": { "type": "string", "format": "binary" } } }, "encoding": { - "property_name_irrelevant": { + "file": { "contentType": "application/gzip, text/plain, application/json, application/octet-stream" } } @@ -588,7 +617,10 @@ "schema": { "type": "object", "properties": { - "objects": { "type": "array", "items": { "type": "string" } } + "objects": { + "type": "string", + "description": "A JSON-stringified array of object Ids. NOTE this is a string!" + } }, "required": ["objects"] } @@ -700,6 +732,21 @@ "summary": "Uploads a file to a project (stream)", "security": [{ "BearerAuth": [] }], "operationId": "postFileBranch", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary" + } + } + } + } + } + }, "responses": { "200": { "description": "file successfully uploaded to the project (stream)" From 29ee4f41254cfac270787bf926cbe6b2c8d180c5 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Thu, 2 Jan 2025 17:34:45 +0000 Subject: [PATCH 59/69] Provide default app Ids --- setup/fuzzer/dictionary.restler.json | 11 +- setup/fuzzer/speckle-server.openapi.json | 129 +++++++++++++++++++++-- 2 files changed, 131 insertions(+), 9 deletions(-) diff --git a/setup/fuzzer/dictionary.restler.json b/setup/fuzzer/dictionary.restler.json index a4ab5d3f74..9c538e9cab 100644 --- a/setup/fuzzer/dictionary.restler.json +++ b/setup/fuzzer/dictionary.restler.json @@ -12,7 +12,16 @@ "restler_fuzzable_bool": ["true"], "restler_fuzzable_object": ["{ \"fuzz\": false }"], "restler_custom_payload": { - "streamId": ["815704124b"] + "streamId": ["815704124b"], + "appId": [ + "spklwebapp", + "spklpwerbi", + "spklexcel", + "sca", + "sdm", + "spklautoma", + "explorer" + ] }, "restler_custom_payload_unquoted": {}, "restler_custom_payload_uuid4_suffix": {}, diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index 1e8f21f17b..1323eef902 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -104,7 +104,14 @@ } }, "responses": { - "200": { "description": "User registered successfully" }, + "302": { + "description": "User registered successfully", + "headers": { + "Location": { + "schema": { "type": "string", "format": "uri" } + } + } + }, "400": { "description": "Invalid input", "content": { @@ -135,8 +142,14 @@ "security": [], "operationId": "getAuthAccesscode", "responses": { - "200": { "description": "Returns an access code in the body" }, - "302": { "description": "Redirects with access code in url query" }, + "302": { + "description": "Redirects with access code in url query", + "headers": { + "Location": { + "schema": { "type": "string", "format": "uri" } + } + } + }, "400": { "description": "Invalid access code, or the app does not exist", "content": { @@ -146,8 +159,7 @@ } } } - }, - "500": { "description": "Internal error" } + } } }, "options": { @@ -264,6 +276,25 @@ "200": { "description": "Successfully uploaded a blob to the project" }, + "400": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "message": { "type": "string" }, + "code": { "type": "string" } + } + } + } + } + } + } + }, "404": { "description": "Stream could not be found", "content": { @@ -351,7 +382,17 @@ "description": "Successfully retrieved a blob from the project" }, "401": { "description": "Unauthorized" }, - "404": { "description": "Stream or blob could not be found." } + "404": { + "description": "Stream or blob could not be found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { "error": { "type": "string" } } + } + } + } + } } }, "delete": { @@ -515,6 +556,10 @@ }, "responses": { "200": { "description": "Objects were successfully uploaded." }, + "400": { + "description": "Invalid input", + "content": { "text/html": { "schema": { "type": "string" } } } + }, "401": { "description": "Unauthorized" } } } @@ -540,7 +585,9 @@ "operationId": "optionsObject", "responses": { "200": { "description": "Options were retrieved." }, - "404": { "description": "Not found" } + "404": { + "description": "Not found" + } } }, "get": { @@ -550,7 +597,10 @@ "responses": { "200": { "description": "Objects were downloaded." }, "401": { "description": "Unauthorized" }, - "404": { "description": "Stream or Object was not found." } + "404": { + "description": "Stream or Object was not found.", + "content": { "text/html": { "schema": { "type": "string" } } } + } } } }, @@ -629,6 +679,25 @@ }, "responses": { "200": { "description": "A diff was successfully computed." }, + "400": { + "description": "Invalid input", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "message": { "type": "string" }, + "code": { "type": "string" } + } + } + } + } + } + } + }, "401": { "description": "Unauthorized", "headers": { @@ -664,6 +733,25 @@ "operationId": "postGetobjects", "responses": { "200": { "description": "All objects were successfully retrieved." }, + "400": { + "description": "Invalid input", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "message": { "type": "string" }, + "code": { "type": "string" } + } + } + } + } + } + } + }, "401": { "description": "Unauthorized" }, "404": { "description": "Stream was not found.", @@ -751,6 +839,25 @@ "200": { "description": "file successfully uploaded to the project (stream)" }, + "400": { + "description": "Invalid input", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "message": { "type": "string" }, + "code": { "type": "string" } + } + } + } + } + } + } + }, "404": { "description": "Stream or branch could not be found.", "content": { @@ -1070,6 +1177,12 @@ "type": "object", "properties": { "message": { "type": "string" }, + "locations": { + "type": "array", + "items": { + "type": "object" + } + }, "extensions": { "type": "object", "properties": { From 39efe0943c7d60ce1c20868453a8ca7603696562 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 08:01:09 +0000 Subject: [PATCH 60/69] Enhance OpenAPI specification --- setup/fuzzer/speckle-server.openapi.json | 66 +++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json index 1323eef902..2c2abca3be 100644 --- a/setup/fuzzer/speckle-server.openapi.json +++ b/setup/fuzzer/speckle-server.openapi.json @@ -136,12 +136,43 @@ "name": "appId", "required": true, "schema": { "type": "string" } + }, + { + "in": "query", + "name": "challenge", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "query", + "name": "token", + "required": true, + "schema": { "type": "string" } + }, + { + "in": "query", + "name": "preventRedirect", + "required": false, + "schema": { "type": "boolean" } } ], "summary": "Generates an access code for an app.", "security": [], "operationId": "getAuthAccesscode", "responses": { + "200": { + "description": "Access code generated successfully.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "redirectUrl": { "type": "string", "format": "uri" } + } + } + } + } + }, "302": { "description": "Redirects with access code in url query", "headers": { @@ -268,6 +299,11 @@ "format": "binary" } } + }, + "encoding": { + "file": { + "contentType": "text/plain, application/json, application/octet-stream" + } } } } @@ -731,8 +767,36 @@ "summary": "Get all objects for a project (stream)", "security": [{ "BearerAuth": [] }], "operationId": "postGetobjects", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "objects": { + "type": "string", + "description": "A JSON-stringified array of object Ids. NOTE this is a string!" + } + } + } + } + } + }, "responses": { - "200": { "description": "All objects were successfully retrieved." }, + "200": { + "description": "All objects were successfully retrieved.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { "type": "string" } + } + }, + "text/plain": { + "schema": { "type": "string" } + } + } + }, "400": { "description": "Invalid input", "content": { From f30b04e272abd7194af686398525b48108de81d2 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:26:07 +0000 Subject: [PATCH 61/69] ci(fuzz tests): graphql fuzz testing --- .github/workflows/graphql-api-fuzzer.yml | 147 +++ .github/workflows/rest-api-fuzzer.yml | 265 ----- setup/fuzzer/annotations.restler.json | 3 - setup/fuzzer/config.restler.json | 25 - setup/fuzzer/dictionary.restler.json | 30 - setup/fuzzer/settings.restler.json | 23 - setup/fuzzer/speckle-server.openapi.json | 1276 ---------------------- setup/fuzzer/token.txt | 2 - 8 files changed, 147 insertions(+), 1624 deletions(-) create mode 100644 .github/workflows/graphql-api-fuzzer.yml delete mode 100644 .github/workflows/rest-api-fuzzer.yml delete mode 100644 setup/fuzzer/annotations.restler.json delete mode 100644 setup/fuzzer/config.restler.json delete mode 100644 setup/fuzzer/dictionary.restler.json delete mode 100644 setup/fuzzer/settings.restler.json delete mode 100644 setup/fuzzer/speckle-server.openapi.json delete mode 100644 setup/fuzzer/token.txt diff --git a/.github/workflows/graphql-api-fuzzer.yml b/.github/workflows/graphql-api-fuzzer.yml new file mode 100644 index 0000000000..9c6f924987 --- /dev/null +++ b/.github/workflows/graphql-api-fuzzer.yml @@ -0,0 +1,147 @@ +name: GraphQL API Fuzz Test + +on: + workflow_dispatch: + # schedule: + # - cron: "15 4 3 * *" # Run at 4:15am on the 3rd of every month + pull_request: + paths: + - '.github/workflows/graphql-api-fuzzer.yml' + - 'setup/fuzzer-graphql/**/*' + - 'setup/fuzzer/docker-compose-speckle.yml' + - 'setup/fuzzer/speckle.backup.sql' + +env: + BUILD_CONFIGURATION: Release + BUILD_PLATFORM: 'Any CPU' + PYTHON_VERSION: '3.8' + DOTNET_VERSION: '6.0.x' + GRAPHQLER_VERSION: '2.3.6' + +jobs: + graphql-fuzzer: + name: Fuzz test speckle-server Graphql API + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - uses: actions/checkout@v4 + name: Checkout speckle-server + with: + path: 'speckle-server' + + - uses: actions/checkout@v4 + name: Checkout Graphqler Fuzzer + with: + repository: omar2535/GraphQLer + ref: v${{ env.GRAPHQLER_VERSION }} + path: 'graphqler-fuzzer' # The path to clone the repository within the {{ github.workspace }} directory + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + cache: 'poetry' + cache-dependency-path: ${{ github.workspace }}/graphqler-fuzzer/poetry.lock + + - name: Install dependencies with Poetry + working-directory: ${{ github.workspace }}/graphqler-fuzzer + run: | + poetry shell + poetry install + + - name: Deploy dependencies (docker compose) + run: | + docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml up --detach + + - name: Seed the database + run: | + sudo apt-get update + sudo apt-get install --yes --no-install-recommends postgresql-client + PGPASSWORD=speckle psql -h 127.0.0.1 -U speckle -d speckle -p 5432 -w < ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle.backup.sql + + - name: Deploy speckle-server (docker compose) + working-directory: ${{ github.workspace }} + timeout-minutes: 1 + run: | + docker compose --file ${{ github.workspace }}/speckle-server/setup/fuzzer/docker-compose-speckle.yml up --detach + + - name: Restore cached Graphqler configuration + id: cache-config-restore + uses: actions/cache/restore@v4 + with: + path: | + ${{ github.workspace }}/graphqlerConfig + key: graphqler-config-${{ github.sha }} + + - name: Generate Graphqler config from Graphql server + if: steps.cache-config-restore.outputs.cache-hit != 'true' + run: | + python -m graphqler --mode compile --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput + + - name: Print the Graphqler configuration + run: | + ls -la ${{ github.workspace }} || true + ls -la ${{ github.workspace }}/graphqlerOutput || true + ls -la ${{ github.workspace }}/graphqlerOutput/compiled || true + # echo "" + # echo "############################################" + # echo "# Engine settings #" + # echo "# To customize, copy and save this file to #" + # echo "# setup/fuzzer/settings.graphqler.json #" + # echo "############################################" + # echo "" + # cat ${{ github.workspace }}/graphqlerOutput/compiled/engine_settings.json + + - name: Save Graphqler Config + if: steps.cache-config-restore.outputs.cache-hit != 'true' + id: cache-config-save + uses: actions/cache/save@v4 + with: + path: | + ${{ github.workspace }}/graphqlerOutput + key: ${{ steps.cache-config-restore.outputs.cache-primary-key }} + + - name: Run Graphqler coverage test + run: | + until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do + echo "Waiting a further 3 seconds for speckle-server to start..." + sleep 3 + done + + python -m graphqler --mode fuzz --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput --auth 'Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12' + + - name: Print the results + if: always() + run: | + ls -la ${{ github.workspace }}/graphqlerOutput + ls -la ${{ github.workspace }}/graphqlerOutput/logs || true + echo "" + echo "############################################" + echo "# Status.txt #" + echo "############################################" + echo "" + cat ${{ github.workspace }}/graphqlerOutput/stats.txt || true + echo "" + echo "############################################" + echo "# ./logs/fuzzer.log #" + echo "############################################" + echo "" + cat ${{ github.workspace }}/logs/fuzzer.log || true + + - uses: actions/upload-artifact@v4 + name: Store the Test output + if: always() + with: + name: fuzz-test-graphql-api-output + path: ${{ github.workspace }}/graphqlerOutput + if-no-files-found: error + retention-days: 5 + overwrite: true + + - name: Print Docker Compose logs + if: always() + run: | + docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml logs + docker compose --file ${{ github.workspace }}/speckle-server/setup/fuzzer/docker-compose-speckle.yml logs diff --git a/.github/workflows/rest-api-fuzzer.yml b/.github/workflows/rest-api-fuzzer.yml deleted file mode 100644 index ef95104dd9..0000000000 --- a/.github/workflows/rest-api-fuzzer.yml +++ /dev/null @@ -1,265 +0,0 @@ -name: REST API Fuzz Test - -on: - workflow_dispatch: - # schedule: - # - cron: "15 4 3 * *" # Run at 4:15am on the 3rd of every month - pull_request: - paths: - - '.github/workflows/rest-api-fuzzer.yml' - - 'setup/fuzzer/**/*' - -env: - BUILD_CONFIGURATION: Release - BUILD_PLATFORM: 'Any CPU' - RESTLER_VERSION: '9.2.4' - PYTHON_VERSION: '3.8' - DOTNET_VERSION: '6.0.x' - -jobs: - build-restler-fuzzer: - name: Fuzz test speckle-server REST API - runs-on: ubuntu-latest - permissions: - contents: read - - steps: - - uses: actions/checkout@v4 - name: Checkout speckle-server - with: - path: 'speckle-server' - - - uses: actions/checkout@v4 - name: Checkout RESTler Fuzzer - with: - repository: microsoft/restler-fuzzer - ref: v${{ env.RESTLER_VERSION }} - path: 'restler-fuzzer' # The path to clone the repository within the {{ github.workspace }} directory - - - name: Setup .NET ${{ env.DOTNET_VERSION }} - uses: actions/setup-dotnet@v4 - with: - dotnet-version: ${{ env.DOTNET_VERSION }} - cache: true - cache-dependency-path: ${{ github.workspace }}/restler-fuzzer/src/Restler.sln - - - name: Restore NuGet packages - run: dotnet restore ${{ github.workspace }}/restler-fuzzer/src/Restler.sln - - - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@v4 - with: - python-version: ${{ env.PYTHON_VERSION }} - cache: 'pip' - cache-dependency-path: ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt - - - name: Install engine (Python) dependencies - run: | - pip install -r ${{ github.workspace }}/restler-fuzzer/restler/requirements.txt - - # This doesn't currently work as it cannot find path to compiler - # - name: Restore cached Restler binaries - # id: cache-restler-bin-restore - # uses: actions/cache/restore@v4 - # with: - # path: | - # ${{ github.workspace }}/bin/restler - # key: restler-binaries-${{ env.RESTLER_VERSION }}-${{ hashFiles('speckle-server/.github/workflows/rest-api-fuzzer.yml') }} - - - name: Build RESTler - # if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' - run: | - python ${{ github.workspace }}/restler-fuzzer/build-restler.py --dest_dir ${{ github.workspace }}/bin - python -m compileall -b ${{ github.workspace }}/bin/restler - - - name: Debug the built output - run: | - ls -la ${{ github.workspace }}/bin/restler - ls -la ${{ github.workspace }}/bin/restler/Restler - - # - name: Save Restler binaries to cache - # if: steps.cache-restler-bin-restore.outputs.cache-hit != 'true' - # id: cache-restler-bin-save - # uses: actions/cache/save@v4 - # with: - # path: | - # ${{ github.workspace }}/bin/restler - # key: ${{ steps.cache-restler-bin-restore.outputs.cache-primary-key }} - - - name: Restore cached Restler configuration - id: cache-config-restore - uses: actions/cache/restore@v4 - with: - path: | - ${{ github.workspace }}/restlerConfig - key: restler-config-${{ hashFiles('speckle-server/setup/fuzzer/speckle-server.openapi.json') }} - - - name: Generate RESTler config from OpenAPI specification - if: steps.cache-config-restore.outputs.cache-hit != 'true' - run: | - ${{ github.workspace }}/bin/restler/Restler generate_config --specs ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle-server.openapi.json - - - name: Print the Restler configuration - run: | - ls -la ${{ github.workspace }} - ls -la ${{ github.workspace }}/restlerConfig - echo "" - echo "############################################" - echo "# Engine settings #" - echo "# To customize, copy and save this file to #" - echo "# setup/fuzzer/settings.restler.json #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/restlerConfig/engine_settings.json - echo "" - echo "############################################" - echo "# Config #" - echo "# To customize, copy and save this file to #" - echo "# setup/fuzzer/config.restler.json #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/restlerConfig/config.json - echo "" - echo "############################################" - echo "# Dictionary #" - echo "# To customize, copy and save this file to #" - echo "# setup/fuzzer/dictionary.restler.json #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/restlerConfig/dict.json - echo "" - echo "############################################" - echo "# Annotations #" - echo "# To customize, copy and save this file to #" - echo "# setup/fuzzer/annotations.restler.json #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/restlerConfig/annotations.json - - - name: Save Restler Config - if: steps.cache-config-restore.outputs.cache-hit != 'true' - id: cache-config-save - uses: actions/cache/save@v4 - with: - path: | - ${{ github.workspace }}/restlerConfig - key: ${{ steps.cache-config-restore.outputs.cache-primary-key }} - - - name: Restore cached Restler grammar - id: cache-grammar-restore - uses: actions/cache/restore@v4 - with: - path: | - ${{ github.workspace }}/Compile - key: restler-grammar-${{ hashFiles('speckle-server/setup/fuzzer/*.json') }} - - - name: Generate RESTler grammar from Restler config - if: steps.cache-grammar-restore.outputs.cache-hit != 'true' - run: | - ${{ github.workspace }}/bin/restler/Restler compile ${{ github.workspace }}/speckle-server/setup/fuzzer/config.restler.json - - - name: Print the contents of the Restler compile directory - if: always() - run: | - ls -la ${{ github.workspace }} || true - ls -la ${{ github.workspace }}/Compile || true - cat $(find ${{ github.workspace }}/Compile -type f -name "*.log") || true - - - name: Save Grammar - if: steps.cache-grammar-restore.outputs.cache-hit != 'true' - id: cache-grammar-save - uses: actions/cache/save@v4 - with: - path: | - ${{ github.workspace }}/Compile - key: ${{ steps.cache-grammar-restore.outputs.cache-primary-key }} - - - name: Deploy dependencies (docker compose) - run: | - docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml up --detach - - - name: Seed the database - run: | - sudo apt-get update - sudo apt-get install --yes --no-install-recommends postgresql-client - PGPASSWORD=speckle psql -h 127.0.0.1 -U speckle -d speckle -p 5432 -w < ${{ github.workspace }}/speckle-server/setup/fuzzer/speckle.backup.sql - - - name: Deploy speckle-server (docker compose) - working-directory: ${{ github.workspace }} - timeout-minutes: 1 - run: | - docker compose --file ${{ github.workspace }}/speckle-server/setup/fuzzer/docker-compose-speckle.yml up --detach - - - name: Run RESTler coverage test - run: | - until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do - echo "Waiting a further 3 seconds for speckle-server to start..." - sleep 3 - done - - ${{ github.workspace }}/bin/restler/Restler test \ - --grammar_file "${{ github.workspace }}/Compile/grammar.py" \ - --dictionary_file "${{ github.workspace }}/speckle-server/setup/fuzzer/dictionary.restler.json" \ - --settings "${{ github.workspace }}/speckle-server/setup/fuzzer/settings.restler.json" \ - --no_ssl \ - --target_ip "127.0.0.1" \ - --target_port "3000" - - - name: Print the results - if: always() - run: | - ls -la ${{ github.workspace }}/Test - ls -la ${{ github.workspace }}/Test/RestlerResults || true - ls -la ${{ github.workspace }}/Test/ResponseBuckets || true - echo "" - echo "############################################" - echo "# Engine stderr #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/Test/EngineStdErr.txt || true - echo "" - echo "############################################" - echo "# Engine stdout #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/Test/EngineStdOut.txt || true - echo "" - echo "############################################" - echo "# Results analyzer stderr #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/Test/ResultsAnalyzerStdErr.txt || true - echo "" - echo "############################################" - echo "# Results analyzer stdout #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/Test/ResultsAnalyzerStdOut.txt || true - echo "" - echo "############################################" - echo "# Coverage failures to investigate #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/Test/coverage_failures_to_investigate.txt || true - echo "" - echo "############################################" - echo "# Restler logs #" - echo "############################################" - echo "" - cat ${{ github.workspace }}/Test/restler-*.log || true - - - uses: actions/upload-artifact@v4 - name: Store the Test output - if: always() - with: - name: fuzz-test-rest-api-output - path: ${{ github.workspace }}/Test - if-no-files-found: error - retention-days: 5 - overwrite: true - - - name: Print Docker Compose logs - if: always() - run: | - docker compose --file ${{ github.workspace }}/speckle-server/docker-compose-deps.yml logs - docker compose --file ${{ github.workspace }}/speckle-server/setup/fuzzer/docker-compose-speckle.yml logs diff --git a/setup/fuzzer/annotations.restler.json b/setup/fuzzer/annotations.restler.json deleted file mode 100644 index 2ce82289a3..0000000000 --- a/setup/fuzzer/annotations.restler.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "x-restler-global-annotations": [] -} diff --git a/setup/fuzzer/config.restler.json b/setup/fuzzer/config.restler.json deleted file mode 100644 index c7cce303b0..0000000000 --- a/setup/fuzzer/config.restler.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "SwaggerSpecFilePath": [ - "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/speckle-server.openapi.json" - ], - "GrammarOutputDirectoryPath": "/home/runner/work/speckle-server/speckle-server/Compile", - "CustomDictionaryFilePath": "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/dictionary.restler.json", - "EngineSettingsFilePath": "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/settings.restler.json", - "AnnotationFilePath": "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/annotations.restler.json", - "IncludeOptionalParameters": true, - "UseHeaderExamples": true, - "UsePathExamples": false, - "UseQueryExamples": true, - "UseBodyExamples": true, - "UseAllExamplePayloads": false, - "DiscoverExamples": false, - "ExamplesDirectory": "", - "DataFuzzing": true, - "ReadOnlyFuzz": false, - "ResolveQueryDependencies": true, - "ResolveBodyDependencies": true, - "ResolveHeaderDependencies": false, - "UseRefreshableToken": true, - "AllowGetProducers": false, - "TrackFuzzedParameterNames": false -} diff --git a/setup/fuzzer/dictionary.restler.json b/setup/fuzzer/dictionary.restler.json deleted file mode 100644 index 9c538e9cab..0000000000 --- a/setup/fuzzer/dictionary.restler.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "restler_fuzzable_string": ["fuzzstring"], - "restler_fuzzable_string_unquoted": [], - "restler_fuzzable_datetime": ["2019-06-26T20:20:39+00:00"], - "restler_fuzzable_datetime_unquoted": [], - "restler_fuzzable_date": ["2019-06-26"], - "restler_fuzzable_date_unquoted": [], - "restler_fuzzable_uuid4": ["566048da-ed19-4cd3-8e0a-b7e0e1ec4d72"], - "restler_fuzzable_uuid4_unquoted": [], - "restler_fuzzable_int": ["1"], - "restler_fuzzable_number": ["1.23"], - "restler_fuzzable_bool": ["true"], - "restler_fuzzable_object": ["{ \"fuzz\": false }"], - "restler_custom_payload": { - "streamId": ["815704124b"], - "appId": [ - "spklwebapp", - "spklpwerbi", - "spklexcel", - "sca", - "sdm", - "spklautoma", - "explorer" - ] - }, - "restler_custom_payload_unquoted": {}, - "restler_custom_payload_uuid4_suffix": {}, - "restler_custom_payload_header": {}, - "restler_custom_payload_query": {} -} diff --git a/setup/fuzzer/settings.restler.json b/setup/fuzzer/settings.restler.json deleted file mode 100644 index 04e5334eda..0000000000 --- a/setup/fuzzer/settings.restler.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "max_combinations": 20, - "target_ip": "127.0.0.1", - "target_port": 3000, - "ignore_decoding_failures": true, - "exclude_requests": [ - { - "endpoint": "/api/stream/{streamId}/blobs", - "methods": ["DELETE"] - } - ], - "authentication": { - "token": { - "location": "/home/runner/work/speckle-server/speckle-server/speckle-server/setup/fuzzer/token.txt", - "token_refresh_interval": 300 - } - }, - "per_resource_settings": { - "/auth/local/register": { - "create_once": 1 - } - } -} diff --git a/setup/fuzzer/speckle-server.openapi.json b/setup/fuzzer/speckle-server.openapi.json deleted file mode 100644 index 2c2abca3be..0000000000 --- a/setup/fuzzer/speckle-server.openapi.json +++ /dev/null @@ -1,1276 +0,0 @@ -{ - "openapi": "3.1.1", - "info": { - "title": "Speckle.", - "version": "dev", - "license": { - "name": "Apache 2.0", - "url": "https://github.com/specklesystems/speckle-server?tab=License-1-ov-file#readme" - } - }, - "servers": [ - { - "url": "https://app.speckle.systems" - } - ], - "paths": { - "/explorer": { - "get": { - "operationId": "getExplorer", - "security": [], - "summary": "GraphQL API Explorer", - "description": "GraphQL API Explorer", - "responses": { - "200": { - "description": "Returns the GraphQL API Explorer", - "content": { "text/html": { "schema": { "type": "string" } } } - } - } - } - }, - "/auth/local/login": { - "post": { - "summary": "Login with email and password", - "operationId": "postAuthLocalLogin", - "security": [], - "parameters": [ - { - "in": "query", - "name": "challenge", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { "type": "string", "format": "email" }, - "password": { "type": "string" } - }, - "required": ["email", "password"] - } - } - } - }, - "responses": { - "200": { "description": "User logged in successfully" }, - "400": { "description": "Invalid input" }, - "401": { - "description": "Invalid credentials", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "err": { "type": "boolean" }, - "message": { "type": "string" } - } - } - } - } - } - } - } - }, - "/auth/local/register": { - "post": { - "summary": "Register with email and password", - "security": [], - "operationId": "postAuthLocalRegister", - "parameters": [ - { - "in": "query", - "name": "challenge", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { "type": "string", "format": "email" }, - "password": { "type": "string" }, - "name": { "type": "string" } - }, - "required": ["email", "password", "name"] - } - } - } - }, - "responses": { - "302": { - "description": "User registered successfully", - "headers": { - "Location": { - "schema": { "type": "string", "format": "uri" } - } - } - }, - "400": { - "description": "Invalid input", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "err": { "type": "string" } - } - } - } - } - } - } - } - }, - "/auth/accesscode": { - "get": { - "parameters": [ - { - "in": "query", - "name": "appId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "query", - "name": "challenge", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "query", - "name": "token", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "query", - "name": "preventRedirect", - "required": false, - "schema": { "type": "boolean" } - } - ], - "summary": "Generates an access code for an app.", - "security": [], - "operationId": "getAuthAccesscode", - "responses": { - "200": { - "description": "Access code generated successfully.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "redirectUrl": { "type": "string", "format": "uri" } - } - } - } - } - }, - "302": { - "description": "Redirects with access code in url query", - "headers": { - "Location": { - "schema": { "type": "string", "format": "uri" } - } - } - }, - "400": { - "description": "Invalid access code, or the app does not exist", - "content": { - "text/html": { - "schema": { - "type": "string" - } - } - } - } - } - }, - "options": { - "summary": "Generates a new API token", - "security": [], - "operationId": "optionsAuthAccesscode", - "responses": { - "200": { "description": "Options for generating a new API token" }, - "404": { "description": "Not found" } - } - } - }, - "/auth/token": { - "post": { - "summary": "Generates a new API token", - "security": [], - "operationId": "postAuthToken", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "appId": { "type": "string" }, - "appSecret": { "type": "string" }, - "accessCode": { "type": "string" }, - "challenge": { "type": "string" }, - "refreshToken": { "type": "string" } - }, - "required": ["appId", "appSecret"] - } - } - } - }, - "responses": { - "200": { "description": "Generates a new API token" }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "err": { "type": "string" } - } - } - } - } - } - } - } - }, - "/auth/logout": { - "post": { - "summary": "Logs a user out by invalidating token and refresh token", - "security": [], - "operationId": "postAuthLogout", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "token": { "type": "string" }, - "refreshToken": { "type": "string" } - }, - "required": ["token", "refreshToken"] - } - } - } - }, - "responses": { - "200": { "description": "Successfully logged out" }, - "400": { - "description": "Error while logging out", - "content": { - "text/html": { - "schema": { "type": "string" } - } - } - } - } - } - }, - "/api/stream/{streamId}/blob": { - "post": { - "summary": "Upload a new blob to a project (stream)", - "security": [{ "BearerAuth": [] }], - "operationId": "postStreamBlobNew", - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "format": "binary" - } - } - }, - "encoding": { - "file": { - "contentType": "text/plain, application/json, application/octet-stream" - } - } - } - } - }, - "responses": { - "200": { - "description": "Successfully uploaded a blob to the project" - }, - "400": { - "description": "Internal server error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "object", - "properties": { - "message": { "type": "string" }, - "code": { "type": "string" } - } - } - } - } - } - } - }, - "404": { - "description": "Stream could not be found", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "string" - } - } - } - } - } - } - } - } - }, - "/api/stream/{streamId}/blob/diff": { - "post": { - "summary": "Determine the difference (diff) between the provided array of blob Ids and those stored on the server", - "security": [{ "BearerAuth": [] }], - "operationId": "postStreamBlobDiff", - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "type": "string" } - } - } - } - }, - "responses": { - "200": { - "description": "The difference between the list of blob Ids provided in the body of the request and those stored on the server" - }, - "404": { - "description": "Stream could not be found", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "string" - } - } - } - } - } - } - } - } - }, - "/api/stream/{streamId}/blob/{blobId}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "blobId", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "summary": "Gets a blob from a project (stream)", - "security": [{ "BearerAuth": [] }], - "operationId": "getStreamBlob", - "responses": { - "200": { - "description": "Successfully retrieved a blob from the project" - }, - "401": { "description": "Unauthorized" }, - "404": { - "description": "Stream or blob could not be found.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "error": { "type": "string" } } - } - } - } - } - } - }, - "delete": { - "summary": "Deletes a blob from a project (stream)", - "operationId": "deleteStreamBlob", - "security": [{ "BearerAuth": [] }], - "responses": { - "204": { - "description": "Successfully deleted a blob from the project" - }, - "404": { - "description": "Stream or blob could not be found.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "string" - } - } - } - } - } - } - } - } - }, - "/api/stream/{streamId}/blobs": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - } - ], - "get": { - "summary": "Gets all the blobs of a project (stream)", - "operationId": "getStreamBlobs", - "security": [{ "BearerAuth": [] }], - "responses": { - "200": { - "description": "Successfully retrieved all the blobs from the project" - }, - "401": { "description": "Unauthorized" }, - "404": { - "description": "Stream could not be found.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "error": { "type": "string" } } - } - } - } - } - } - }, - "delete": { - "summary": "Deletes all the blobs from a project (stream)", - "operationId": "deleteStreamBlobs", - "security": [{ "BearerAuth": [] }], - "responses": { "501": { "description": "Not implemented." } } - } - }, - "/static": { - "get": { - "summary": "Static assets", - "security": [], - "operationId": "getStatic", - "responses": { - "200": { "description": "An asset was retrieved." }, - "301": { - "description": "Redirects to the home page.", - "headers": { - "Location": { - "schema": { "type": "string", "format": "uri" } - } - }, - "content": { - "text/html": { - "schema": { "type": "string" } - } - } - } - } - } - }, - "/liveness": { - "options": { - "summary": "Liveness options", - "security": [], - "operationId": "optionsLiveness", - "responses": { - "200": { "description": "Options for liveness endpoint." } - } - }, - "get": { - "summary": "Indicates whether the application is alive.", - "security": [], - "operationId": "getLiveness", - "responses": { "200": { "description": "The application is alive." } } - } - }, - "/readiness": { - "options": { - "summary": "Readiness endpoint options", - "security": [], - "operationId": "optionsReadiness", - "responses": { "200": { "description": "Options were retrieved." } } - }, - "get": { - "summary": "Indicates whether the application is ready to accept traffic", - "security": [], - "operationId": "getReadiness", - "responses": { "200": { "description": "The application is ready." } } - } - }, - "/objects/{streamId}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - } - ], - "options": { - "summary": "The options for this endpoint", - "security": [], - "operationId": "optionsObjects", - "responses": { - "200": { "description": "Options were retrieved." }, - "404": { "description": "Not found" } - } - }, - "post": { - "summary": "Upload objects to the project (stream)", - "security": [{ "BearerAuth": [] }], - "operationId": "postObjects", - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "format": "binary" - } - } - }, - "encoding": { - "file": { - "contentType": "application/gzip, text/plain, application/json, application/octet-stream" - } - } - } - } - }, - "responses": { - "200": { "description": "Objects were successfully uploaded." }, - "400": { - "description": "Invalid input", - "content": { "text/html": { "schema": { "type": "string" } } } - }, - "401": { "description": "Unauthorized" } - } - } - }, - "/objects/{streamId}/{objectId}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "objectId", - "required": true, - "schema": { "type": "string" } - } - ], - "options": { - "summary": "Options for downloading an object from a project (stream)", - "security": [], - "operationId": "optionsObject", - "responses": { - "200": { "description": "Options were retrieved." }, - "404": { - "description": "Not found" - } - } - }, - "get": { - "summary": "Download objects from a project (stream)", - "security": [{ "BearerAuth": [] }], - "operationId": "getObject", - "responses": { - "200": { "description": "Objects were downloaded." }, - "401": { "description": "Unauthorized" }, - "404": { - "description": "Stream or Object was not found.", - "content": { "text/html": { "schema": { "type": "string" } } } - } - } - } - }, - "/objects/{streamId}/{objectId}/single": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "objectId", - "required": true, - "schema": { "type": "string" } - } - ], - "options": { - "summary": "Options for downloading a single object from a project (stream)", - "security": [], - "operationId": "optionsObjectSingle", - "responses": { - "200": { "description": "Options were retrieved." }, - "404": { "description": "Not found" } - } - }, - "get": { - "summary": "Options for downloading a single object from a project (stream)", - "security": [{ "BearerAuth": [] }], - "operationId": "getObjectSingle", - "responses": { - "200": { "description": "An object was retrieved." }, - "401": { "description": "Unauthorized" }, - "404": { "description": "Stream or Object was not found" } - } - } - }, - "/api/diff/{streamId}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - } - ], - "options": { - "summary": "Options for the endpoint", - "security": [], - "operationId": "optionsDiff", - "responses": { - "200": { "description": "Options were retrieved." }, - "404": { "description": "Not found" } - } - }, - "post": { - "summary": "Options for getting the diff of objects for a project (stream)", - "security": [{ "BearerAuth": [] }], - "operationId": "postDiff", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "objects": { - "type": "string", - "description": "A JSON-stringified array of object Ids. NOTE this is a string!" - } - }, - "required": ["objects"] - } - } - } - }, - "responses": { - "200": { "description": "A diff was successfully computed." }, - "400": { - "description": "Invalid input", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "object", - "properties": { - "message": { "type": "string" }, - "code": { "type": "string" } - } - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "headers": { - "X-RateLimit-Remaining": { - "schema": { "type": "integer" } - } - } - } - } - } - }, - "/api/getobjects/{streamId}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - } - ], - "options": { - "summary": "Options for the endpoint", - "security": [], - "operationId": "optionsGetobjects", - "responses": { - "200": { "description": "Options were retrieved." }, - "404": { "description": "Not found" } - } - }, - "post": { - "summary": "Get all objects for a project (stream)", - "security": [{ "BearerAuth": [] }], - "operationId": "postGetobjects", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "objects": { - "type": "string", - "description": "A JSON-stringified array of object Ids. NOTE this is a string!" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "All objects were successfully retrieved.", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "type": "string" } - } - }, - "text/plain": { - "schema": { "type": "string" } - } - } - }, - "400": { - "description": "Invalid input", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "object", - "properties": { - "message": { "type": "string" }, - "code": { "type": "string" } - } - } - } - } - } - } - }, - "401": { "description": "Unauthorized" }, - "404": { - "description": "Stream was not found.", - "headers": { - "X-RateLimit-Remaining": { - "schema": { "type": "integer" } - } - } - } - } - } - }, - "/auth/verifyemail": { - "get": { - "summary": "Verify email", - "security": [], - "operationId": "getAuthVerifyemail", - "description": "Verifies an email address", - "parameters": [ - { - "in": "query", - "name": "t", - "required": true, - "schema": { "type": "string" } - } - ], - "responses": { - "302": { - "description": "Redirects to the home page.", - "headers": { - "Location": { - "schema": { "type": "string", "format": "uri" } - } - } - } - } - } - }, - "/api/file/{fileType}/{streamId}/{branchName}": { - "parameters": [ - { - "in": "path", - "name": "fileType", - "required": true, - "schema": { - "oneOf": [ - { "type": "string" }, - { "type": "string", "enum": ["autodetect"] } - ] - } - }, - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "branchName", - "required": true, - "schema": { "type": "string" } - } - ], - "post": { - "summary": "Uploads a file to a project (stream)", - "security": [{ "BearerAuth": [] }], - "operationId": "postFileBranch", - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "file": { - "type": "string", - "format": "binary" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "file successfully uploaded to the project (stream)" - }, - "400": { - "description": "Invalid input", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "object", - "properties": { - "message": { "type": "string" }, - "code": { "type": "string" } - } - } - } - } - } - } - }, - "404": { - "description": "Stream or branch could not be found.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "string" - } - } - } - } - } - } - } - } - }, - "/metrics": { - "get": { - "summary": "Metrics", - "security": [], - "operationId": "getMetrics", - "description": "Returns Prometheus metrics", - "responses": { "200": { "description": "Returns Prometheus metrics" } } - } - }, - "/preview/{streamId}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "angle", - "required": true, - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0 }, - { "type": "string", "enum": ["all"] } - ] - } - } - ], - "options": { - "summary": "Options for the endpoint", - "security": [], - "operationId": "optionsPreviewAngle", - "responses": { - "200": { "description": "Options successfully retrieved." } - } - }, - "get": { - "summary": "Retrieve a preview for the project (stream), at an optional angle", - "security": [{ "BearerAuth": [] }], - "operationId": "getPreviewAngle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } - } - } - } - } - } - }, - "/preview/{streamId}/branches/{branchName}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "branchName", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "angle", - "required": true, - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0 }, - { "type": "string", "enum": ["all"] } - ] - } - } - ], - "options": { - "summary": "Options for the endpoint", - "security": [], - "operationId": "optionsPreviewBranchAngle", - "responses": { - "200": { "description": "Options successfully retrieved." } - } - }, - "get": { - "summary": "Retrieve a preview for the project (stream) and model (branch), at an optional angle", - "security": [{ "BearerAuth": [] }], - "operationId": "getPreviewBranchAngle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } - } - } - } - } - } - }, - "/preview/{streamId}/commits/{commitId}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "commitId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "angle", - "required": true, - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0 }, - { "type": "string", "enum": ["all"] } - ] - } - } - ], - "options": { - "summary": "Options for the endpoint", - "security": [], - "operationId": "optionsPreviewCommitAngle", - "responses": { - "200": { "description": "Options successfully retrieved." } - } - }, - "get": { - "summary": "Retrieve a preview for the project (stream) and version (commit), at an optional angle", - "security": [{ "BearerAuth": [] }], - "operationId": "getPreviewCommitAngle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } - } - } - } - } - } - }, - "/preview/{streamId}/objects/{objectId}/{angle}": { - "parameters": [ - { - "in": "path", - "name": "streamId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "objectId", - "required": true, - "schema": { "type": "string" } - }, - { - "in": "path", - "name": "angle", - "schema": { - "oneOf": [ - { "type": "integer", "minimum": 0, "maximum": 360 }, - { "type": "string", "enum": ["all"] } - ] - } - } - ], - "options": { - "summary": "Options for the endpoint", - "security": [], - "operationId": "optionsPreviewObjectAngle", - "responses": { - "200": { "description": "Options successfully retrieved." } - } - }, - "get": { - "summary": "Retrieve a preview for the project (stream) and object, at an optional angle", - "security": [{ "BearerAuth": [] }], - "operationId": "getPreviewObjectAngle", - "responses": { - "200": { - "description": "A preview was successfully retrieved.", - "content": { - "image/png": { - "schema": { "type": "string", "format": "binary" } - } - } - }, - "403": { "description": "Forbidden" } - } - } - }, - "/auth/pwdreset/request": { - "post": { - "summary": "Reset a password", - "security": [], - "operationId": "postAuthPasswordresetRequest", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { "type": "string", "format": "email" } - }, - "required": ["email"] - } - } - } - }, - "responses": { - "200": { - "description": "The password reset workflow was successfully started." - }, - "400": { - "description": "Invalid input", - "content": { - "text/html": { - "schema": { "type": "string" } - } - } - } - } - } - }, - "/auth/pwdreset/finalize": { - "post": { - "summary": "Finish resetting a password", - "security": [], - "operationId": "postAuthPasswordresetFinalize", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "tokenId": { "type": "string" }, - "password": { "type": "string" } - }, - "required": ["tokenId", "password"] - } - } - } - }, - "responses": { - "200": { "description": "The password was successfully reset." }, - "400": { - "description": "Invalid input", - "content": { - "text/html": { - "schema": { "type": "string" } - } - } - } - } - } - }, - "/graphql": { - "post": { - "summary": "GraphQL", - "security": [{ "BearerAuth": [] }], - "operationId": "postGraphql", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "query": { "type": "string" } - }, - "required": ["query"] - } - } - } - }, - "responses": { - "400": { - "description": "Invalid input", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "data": { "type": "object" }, - "errors": { - "type": "array", - "items": { - "type": "object", - "properties": { - "message": { "type": "string" }, - "locations": { - "type": "array", - "items": { - "type": "object" - } - }, - "extensions": { - "type": "object", - "properties": { - "code": { "type": "string" } - } - } - } - } - } - } - } - } - } - } - } - } - } - }, - "components": { - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer" - } - } - } -} diff --git a/setup/fuzzer/token.txt b/setup/fuzzer/token.txt deleted file mode 100644 index c80a63dc84..0000000000 --- a/setup/fuzzer/token.txt +++ /dev/null @@ -1,2 +0,0 @@ -{u'app1': {}} -Authorization: Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12 From b9352c976f716ac9c093746a2ed8236a81c8903d Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:32:54 +0000 Subject: [PATCH 62/69] Tag is capitalized, just to be different from convention :fml: --- .github/workflows/graphql-api-fuzzer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/graphql-api-fuzzer.yml b/.github/workflows/graphql-api-fuzzer.yml index 9c6f924987..16788ac205 100644 --- a/.github/workflows/graphql-api-fuzzer.yml +++ b/.github/workflows/graphql-api-fuzzer.yml @@ -35,7 +35,7 @@ jobs: name: Checkout Graphqler Fuzzer with: repository: omar2535/GraphQLer - ref: v${{ env.GRAPHQLER_VERSION }} + ref: V${{ env.GRAPHQLER_VERSION }} path: 'graphqler-fuzzer' # The path to clone the repository within the {{ github.workspace }} directory - name: Set up Python ${{ env.PYTHON_VERSION }} From 39b35b64d9d3eb6e03ff86898b2fd127ca42de18 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:35:22 +0000 Subject: [PATCH 63/69] Poetry needs to be explicitly installed --- .github/workflows/graphql-api-fuzzer.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/graphql-api-fuzzer.yml b/.github/workflows/graphql-api-fuzzer.yml index 16788ac205..c6300bb26f 100644 --- a/.github/workflows/graphql-api-fuzzer.yml +++ b/.github/workflows/graphql-api-fuzzer.yml @@ -38,6 +38,9 @@ jobs: ref: V${{ env.GRAPHQLER_VERSION }} path: 'graphqler-fuzzer' # The path to clone the repository within the {{ github.workspace }} directory + - name: Install poetry + run: pipx install poetry + - name: Set up Python ${{ env.PYTHON_VERSION }} uses: actions/setup-python@v4 with: From 5c88e11ae8f8805fc03b4392f5fcde089df4e3b6 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:40:14 +0000 Subject: [PATCH 64/69] Use supported python version --- .github/workflows/graphql-api-fuzzer.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/graphql-api-fuzzer.yml b/.github/workflows/graphql-api-fuzzer.yml index c6300bb26f..48bc13134b 100644 --- a/.github/workflows/graphql-api-fuzzer.yml +++ b/.github/workflows/graphql-api-fuzzer.yml @@ -12,10 +12,7 @@ on: - 'setup/fuzzer/speckle.backup.sql' env: - BUILD_CONFIGURATION: Release - BUILD_PLATFORM: 'Any CPU' - PYTHON_VERSION: '3.8' - DOTNET_VERSION: '6.0.x' + PYTHON_VERSION: '3.12' GRAPHQLER_VERSION: '2.3.6' jobs: From e814908021a847bf22c39cdd3af4ec060519fc32 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:42:39 +0000 Subject: [PATCH 65/69] copy pasta error; poetry shell makes no sense in CI --- .github/workflows/graphql-api-fuzzer.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/graphql-api-fuzzer.yml b/.github/workflows/graphql-api-fuzzer.yml index 48bc13134b..b335411708 100644 --- a/.github/workflows/graphql-api-fuzzer.yml +++ b/.github/workflows/graphql-api-fuzzer.yml @@ -48,7 +48,6 @@ jobs: - name: Install dependencies with Poetry working-directory: ${{ github.workspace }}/graphqler-fuzzer run: | - poetry shell poetry install - name: Deploy dependencies (docker compose) From abb2a6955863b18c46a34c642785acb87fcdb76d Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:47:45 +0000 Subject: [PATCH 66/69] run graphqler using local path not global module --- .github/workflows/graphql-api-fuzzer.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/graphql-api-fuzzer.yml b/.github/workflows/graphql-api-fuzzer.yml index b335411708..0f9b4b80ca 100644 --- a/.github/workflows/graphql-api-fuzzer.yml +++ b/.github/workflows/graphql-api-fuzzer.yml @@ -76,8 +76,9 @@ jobs: - name: Generate Graphqler config from Graphql server if: steps.cache-config-restore.outputs.cache-hit != 'true' + working-directory: ${{ github.workspace }}/graphqler-fuzzer run: | - python -m graphqler --mode compile --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput + python ./graphqler --mode compile --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput - name: Print the Graphqler configuration run: | @@ -103,13 +104,14 @@ jobs: key: ${{ steps.cache-config-restore.outputs.cache-primary-key }} - name: Run Graphqler coverage test + working-directory: ${{ github.workspace }}/graphqler-fuzzer run: | until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do echo "Waiting a further 3 seconds for speckle-server to start..." sleep 3 done - python -m graphqler --mode fuzz --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput --auth 'Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12' + python ./graphqler --mode fuzz --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput --auth 'Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12' - name: Print the results if: always() From 77476b7980e285c5c5d243c8915e5518e6eacd4e Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 10:02:40 +0000 Subject: [PATCH 67/69] need to run python inside the poetry environment, such n00b --- .github/workflows/graphql-api-fuzzer.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/graphql-api-fuzzer.yml b/.github/workflows/graphql-api-fuzzer.yml index 0f9b4b80ca..74a7e666d4 100644 --- a/.github/workflows/graphql-api-fuzzer.yml +++ b/.github/workflows/graphql-api-fuzzer.yml @@ -78,7 +78,7 @@ jobs: if: steps.cache-config-restore.outputs.cache-hit != 'true' working-directory: ${{ github.workspace }}/graphqler-fuzzer run: | - python ./graphqler --mode compile --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput + poetry run python ./graphqler --mode compile --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput - name: Print the Graphqler configuration run: | @@ -111,7 +111,7 @@ jobs: sleep 3 done - python ./graphqler --mode fuzz --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput --auth 'Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12' + poetry run python ./graphqler --mode fuzz --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput --auth 'Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12' - name: Print the results if: always() From d169bc356884faffbe4f90af02c4235944344de7 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 12:07:56 +0000 Subject: [PATCH 68/69] Add graphqler configuration file --- .github/workflows/graphql-api-fuzzer.yml | 4 +-- setup/fuzzer/config.graphqler.toml | 44 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 setup/fuzzer/config.graphqler.toml diff --git a/.github/workflows/graphql-api-fuzzer.yml b/.github/workflows/graphql-api-fuzzer.yml index 74a7e666d4..0ea019bf0e 100644 --- a/.github/workflows/graphql-api-fuzzer.yml +++ b/.github/workflows/graphql-api-fuzzer.yml @@ -103,7 +103,7 @@ jobs: ${{ github.workspace }}/graphqlerOutput key: ${{ steps.cache-config-restore.outputs.cache-primary-key }} - - name: Run Graphqler coverage test + - name: Run Graphqler fuzz test working-directory: ${{ github.workspace }}/graphqler-fuzzer run: | until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do @@ -111,7 +111,7 @@ jobs: sleep 3 done - poetry run python ./graphqler --mode fuzz --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput --auth 'Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12' + poetry run python ./graphqler --mode fuzz --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput --auth 'Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12' --config ${{ github.workspace }}/speckle-server/setup/fuzzer/config.graphqler.toml - name: Print the results if: always() diff --git a/setup/fuzzer/config.graphqler.toml b/setup/fuzzer/config.graphqler.toml new file mode 100644 index 0000000000..e0efe108ae --- /dev/null +++ b/setup/fuzzer/config.graphqler.toml @@ -0,0 +1,44 @@ +# Configuration + +# For debugging purposes +DEBUG = false + +# For clairvoyance +WORDLIST_PATH = "static/wordlist.txt" + +# For the resolver +MAX_LEVENSHTEIN_THRESHOLD = 20 # A very high threshold, we could probably lower this, but this almost guarantees us to find a matching object name - ID + +# For the linker +GRAPH_VISUALIZATION_OUTPUT = "dependency_graph.png" + +# For materializers +MAX_OBJECT_CYCLES = 3 +MAX_OUTPUT_SELECTOR_DEPTH = 3 +HARD_CUTOFF_DEPTH = 20 +MAX_INPUT_DEPTH = 20 + +# For using GraphQLer in different modes +USE_OBJECTS_BUCKET = true # This mode is for when we want to use the objects bucket +USE_DEPENDENCY_GRAPH = true # This mode is for when we want to use DFS through the dependency graph +NO_DATA_COUNT_AS_SUCCESS = false # This mode is for when we want to count no data in the data object as a success or failure + +# For fuzzing +ALLOW_DELETION_OF_OBJECTS = false # This mode is for when we want to allow the deletion of objects from the objects bucket when coming across a DELETE mutation success +MAX_FUZZING_ITERATIONS = 5 +MAX_TIME = 180 # in seconds +SKIP_MAXIMAL_PAYLOADS = false # This mode is for when we want to skip the maximal payloads +SKIP_DOS_ATTACKS = true # This mode is for when we want to skip the DoS check +SKIP_INJECTION_ATTACKS = false # This mode is for when we want to skip the injection check +SKIP_MISC_ATTACKS = false # This mode is for when we want to skip the miscellaneous attacks + +# For each request +REQUEST_TIMEOUT = 30 # in seconds +TIME_BETWEEN_REQUESTS = 0.001 # in seconds + +# For custom skipping specific nodes""" +SKIP_NODES = [] + +# Put custom headers here +[CUSTOM_HEADERS] +Accept = "application/json" From c9eb9cf35853e6ea16c39f1b66dbddd601241a09 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Jan 2025 12:20:18 +0000 Subject: [PATCH 69/69] Compile and fuzz in a single step --- .github/workflows/graphql-api-fuzzer.yml | 66 ++++++++++++------------ 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/.github/workflows/graphql-api-fuzzer.yml b/.github/workflows/graphql-api-fuzzer.yml index 0ea019bf0e..cf6d0a837c 100644 --- a/.github/workflows/graphql-api-fuzzer.yml +++ b/.github/workflows/graphql-api-fuzzer.yml @@ -65,26 +65,30 @@ jobs: timeout-minutes: 1 run: | docker compose --file ${{ github.workspace }}/speckle-server/setup/fuzzer/docker-compose-speckle.yml up --detach + until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do + echo "Waiting a further 3 seconds for speckle-server to start..." + sleep 3 + done - - name: Restore cached Graphqler configuration - id: cache-config-restore - uses: actions/cache/restore@v4 - with: - path: | - ${{ github.workspace }}/graphqlerConfig - key: graphqler-config-${{ github.sha }} - - - name: Generate Graphqler config from Graphql server - if: steps.cache-config-restore.outputs.cache-hit != 'true' - working-directory: ${{ github.workspace }}/graphqler-fuzzer - run: | - poetry run python ./graphqler --mode compile --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput - - - name: Print the Graphqler configuration - run: | - ls -la ${{ github.workspace }} || true - ls -la ${{ github.workspace }}/graphqlerOutput || true - ls -la ${{ github.workspace }}/graphqlerOutput/compiled || true + # - name: Restore cached Graphqler configuration + # id: cache-config-restore + # uses: actions/cache/restore@v4 + # with: + # path: | + # ${{ github.workspace }}/graphqlerConfig + # key: graphqler-config-${{ github.sha }} + + # - name: Generate Graphqler config from Graphql server + # if: steps.cache-config-restore.outputs.cache-hit != 'true' + # working-directory: ${{ github.workspace }}/graphqler-fuzzer + # run: | + # poetry run python ./graphqler --mode compile --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput + + # - name: Print the Graphqler configuration + # run: | + # ls -la ${{ github.workspace }} || true + # ls -la ${{ github.workspace }}/graphqlerOutput || true + # ls -la ${{ github.workspace }}/graphqlerOutput/compiled || true # echo "" # echo "############################################" # echo "# Engine settings #" @@ -93,25 +97,19 @@ jobs: # echo "############################################" # echo "" # cat ${{ github.workspace }}/graphqlerOutput/compiled/engine_settings.json - - - name: Save Graphqler Config - if: steps.cache-config-restore.outputs.cache-hit != 'true' - id: cache-config-save - uses: actions/cache/save@v4 - with: - path: | - ${{ github.workspace }}/graphqlerOutput - key: ${{ steps.cache-config-restore.outputs.cache-primary-key }} + # - name: Save Graphqler Config + # if: steps.cache-config-restore.outputs.cache-hit != 'true' + # id: cache-config-save + # uses: actions/cache/save@v4 + # with: + # path: | + # ${{ github.workspace }}/graphqlerOutput + # key: ${{ steps.cache-config-restore.outputs.cache-primary-key }} - name: Run Graphqler fuzz test working-directory: ${{ github.workspace }}/graphqler-fuzzer run: | - until curl --output /dev/null --silent --head --fail http://127.0.0.1:3000/readiness; do - echo "Waiting a further 3 seconds for speckle-server to start..." - sleep 3 - done - - poetry run python ./graphqler --mode fuzz --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput --auth 'Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12' --config ${{ github.workspace }}/speckle-server/setup/fuzzer/config.graphqler.toml + poetry run python ./graphqler --mode run --url http://127.0.0.1:3000/graphql --path ${{ github.workspace }}/graphqlerOutput --auth 'Bearer 103b2cf86168ec87fc6ec88978455667feb0f08d12' --config ${{ github.workspace }}/speckle-server/setup/fuzzer/config.graphqler.toml - name: Print the results if: always()