From 419bee75c7ee6195d9c31c9ddb6342ebbb1f9358 Mon Sep 17 00:00:00 2001 From: rartych Date: Thu, 7 Mar 2024 13:23:03 +0100 Subject: [PATCH 1/9] linting ruleset add --- .github/workflows/megalinter.yml | 78 ++++++ .github/workflows/spectral_oas_lint.yml | 36 +++ .spectral.yml | 258 ++++++++++++++++++ .yamllint.yaml | 35 +++ lint_function/camara-language-avoid-telco.js | 40 +++ lint_function/camara-reserved-words.js | 98 +++++++ ...-no-secrets-in-path-or-query-parameters.js | 26 ++ 7 files changed, 571 insertions(+) create mode 100644 .github/workflows/megalinter.yml create mode 100644 .github/workflows/spectral_oas_lint.yml create mode 100644 .spectral.yml create mode 100644 .yamllint.yaml create mode 100644 lint_function/camara-language-avoid-telco.js create mode 100644 lint_function/camara-reserved-words.js create mode 100644 lint_function/camara-security-no-secrets-in-path-or-query-parameters.js diff --git a/.github/workflows/megalinter.yml b/.github/workflows/megalinter.yml new file mode 100644 index 00000000..6bda7009 --- /dev/null +++ b/.github/workflows/megalinter.yml @@ -0,0 +1,78 @@ +--- +# MegaLinter GitHub Action configuration file +# More info at https://megalinter.io +# CAMARA Project - Github Action for Pull Reqests +# 31.01.2024 - initial version + +name: MegaLinter + +on: # yamllint disable-line rule:truthy + # Pull Requests to main + pull_request: + branches: [master, main] + +env: # Comment env block if you do not want to apply fixes + # Apply linter fixes configuration + APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool) + APPLY_FIXES_EVENT: pull_request # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all) + APPLY_FIXES_MODE: commit # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request) + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + build: + name: MegaLinter + runs-on: ubuntu-latest + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR + # Remove the ones you do not need + contents: write + issues: write + pull-requests: write + steps: + # Git Checkout + - name: Checkout Code + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances + - name: Install Spectral + run: npm install -g @stoplight/spectral + - name: Install Spectral functions + run: npm install -g @stoplight/spectral-functions + # - name: Run spectral:oas Spectral Linting + # run: spectral lint code/API_definitions/*.yaml --verbose --ruleset .spectral.yml + # Replace openapi.yaml file with your API specification file + + # MegaLinter + - name: MegaLinter + id: ml + # You can override MegaLinter flavor used to have faster performances + # More info at https://megalinter.io/flavors/ + uses: oxsecurity/megalinter/flavors/java@v7.3.0 + env: + # All available variables are described in documentation + # https://megalinter.io/configuration/ + PRINT_ALPACA: false + # VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources + VALIDATE_ALL_CODEBASE: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY + DISABLE: COPYPASTE,MARKDOWN + DISABLE_LINTERS: SPELL_CSPELL,SPELL_LYCHEE,YAML_PRETTIER,REPOSITORY_GRYPE, REPOSITORY_SEMGREP,REPOSITORY_DEVSKIM,REPOSITORY_KICS,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,REPOSITORY_CHECKOV,REPOSITORY_GITLEAKS,YAML_V8R,JAVA_PMD,JAVA_CHECKSTYLE + YAML_YAMLLINT_CONFIG_FILE: ".yamllint.yaml" + OPENAPI_SPECTRAL_CONFIG_FILE: ".spectral.yml" + YAML_YAMLLINT_FILTER_REGEX_INCLUDE: "(code/)" + OPENAPI_SPECTRAL_FILTER_REGEX_INCLUDE: "(code/)" + + # Upload MegaLinter artifacts + - name: Archive production artifacts + if: ${{ success() }} || ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: MegaLinter reports + path: | + megalinter-reports + mega-linter.log diff --git a/.github/workflows/spectral_oas_lint.yml b/.github/workflows/spectral_oas_lint.yml new file mode 100644 index 00000000..a828fd58 --- /dev/null +++ b/.github/workflows/spectral_oas_lint.yml @@ -0,0 +1,36 @@ +--- +# CAMARA Project - workflow configuration to manually run CAMARA OAS rules +# see https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow +# 31.01.2024 - initial version + +name: Spectral manual run + +on: workflow_dispatch + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + build: + name: Spectral linting + runs-on: ubuntu-latest + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR + # Remove the ones you do not need + contents: write + issues: write + pull-requests: write + steps: + # Git Checkout + - name: Checkout Code + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances + - name: Install Spectral + run: npm install -g @stoplight/spectral + - name: Install Spectral functions + run: npm install -g @stoplight/spectral-functions + - name: Run Spectral linting + run: spectral lint code/API_definitions/*.yaml --verbose --ruleset .spectral.yml diff --git a/.spectral.yml b/.spectral.yml new file mode 100644 index 00000000..0b16508e --- /dev/null +++ b/.spectral.yml @@ -0,0 +1,258 @@ +# CAMARA Project - linting ruleset - documentation avaialable here: +# https://github.com/camaraproject/Commonalities/blob/main/documentation/Linting-rules.md +# 31.01.2024 - initial version + +extends: "spectral:oas" +functions: + - camara-reserved-words + - camara-language-avoid-telco + - camara-security-no-secrets-in-path-or-query-parameters +functionsDir: "./lint_function" +rules: + # Built-in OpenAPI Specification ruleset. Each rule then can be enabled individually. + # The severity keyword is optional in rule definition and can be error, warn, info, hint, or off. The default value is warn. + contact-properties: false + duplicated-entry-in-enum: true + info-contact: true + info-description: true + info-license: true + license-url: true + no-$ref-siblings: error + no-eval-in-markdown: true + no-script-tags-in-markdown: true + openapi-tags: false + openapi-tags-alphabetical: false + openapi-tags-uniqueness: error + operation-description: true + operation-operationId: true + operation-operationId-unique: error + operation-operationId-valid-in-url: true + operation-parameters: true + operation-singular-tag: true + operation-success-response: true + operation-tags: true + operation-tag-defined: true + path-declarations-must-exist: true + path-keys-no-trailing-slash: true + path-not-include-query: true + path-params: error + tag-description: false + typed-enum: true + oas3-api-servers: true + oas3-examples-value-or-externalValue: true + oas3-operation-security-defined: false + oas3-parameter-description: false + oas3-schema: true + oas3-server-not-example.com: false + oas3-server-trailing-slash: true + oas3-unused-component: true + oas3-valid-media-example: true + oas3-valid-schema-example: true + # oas3-server-variables: true + + # Custom Rules Utilizing Spectral's Built-in Functions and JavaScript Implementations + + camara-language-avoid-telco: + message: "{{error}}" + severity: hint + description: | + This rule checks for telco-specific terminology in your API definitions and suggests more inclusive terms. + given: "$..*.*" + then: + function: camara-language-avoid-telco + recommended: false # Set to true/false to enable/disable this rule + + camara-oas-version: + message: "OpenAPI Version Error: The OpenAPI specification must adhere to version 3.0.3." + severity: error + description: | + This rule validates the OpenAPI version in your specification and requires compliance with version 3.0.3. + given: "$" + then: + field: openapi + function: pattern + functionOptions: + match: 3.0.3 + recommended: true # Set to true/false to enable/disable this rule + + camara-path-param-id: + message: "Path Parameter Naming Warning: Use 'resource_id' instead of just 'id' in path parameters." + severity: warn + description: | + This rule ensures consistent and descriptive naming for path parameters in your OpenAPI specification. + Please use 'resource_id' instead of just 'id' for your path parameters. + given: "$..parameters[?(@.in == 'path')]" + then: + field: name + function: pattern + functionOptions: + notMatch: \b(id|Id|ID|iD)\b + recommended: true # Set to true/false to enable/disable this rule + + camara-security-no-secrets-in-path-or-query-parameters: + message: "Sensitive data found in path: {{error}} Consider avoiding the use of Sesentive data " + severity: warn + description: | + This rule checks for sensitive data ('MSISDN' and 'IMSI') in API paths and suggests avoiding their use. + given: + - "$.paths" + then: + function: camara-security-no-secrets-in-path-or-query-parameters + recommended: true # Set to true/false to enable/disable this rule + + camara-http-methods: + description: "Ensure that all path URLs have valid HTTP methods (GET, PUT, POST, DELETE, PATCH, OPTIONS)." + message: "Invalid HTTP method for '{{path}}'. Must be one of get, put, post, delete, patch, options." + severity: error + given: $.paths[*][*]~ + then: + function: pattern + functionOptions: + match: "^(get|put|post|delete|patch|options)$" + recommended: true # Set to true/false to enable/disable this rule + + camara-get-no-request-body: + message: There must be no request body for Get and DELETE + severity: error + given: + - "$.paths.*.get" + - "$.paths.*.delete" + then: + field: requestBody + function: falsy + recommended: true # Set to true/false to enable/disable this rule + + camara-reserved-words: + message: "Reserved words found {{error}} Consider avoiding the use of reserved word " + severity: warn + description: | + This rule checks Reserved words must not be used in the following parts of an API specification [Paths, Request Body properties, Component, Operation Id, Security Schema] + given: + - "$.paths" # Paths + - "$..parameters[*]" # Path or Query Parameter Names: + - "$..components.schemas.*.properties.*" # Request and Response body parameter + - "$.paths.*." # Path and Operation Names: + - "$.components.securitySchemes" # Security Schemes: + - "$.components.*.*" # Component Names: + - "$.paths.*.*.operationId" # OperationIds: + then: + function: camara-reserved-words + recommended: true # Set to true/false to enable/disable this rule + + camara-routes-description: + message: "Functionality method description Warning: Each method should have description." + severity: warn + description: | + This rule checks if each operation (POST, GET, DELETE, PUT, PATCH, OPTIONS) in your API specification has a description. + Ensure that you have added a 'summary' field for each operation in your OpenAPI specification. + given: + - "$.paths.*.post" + - "$.paths.*.get" + - "$.paths.*.delete" + - "$.paths.*.put" + - "$.paths.*.patch" + - "$.paths.*.options" + then: + field: description + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-parameters-descriptions: + message: "Parameter description is missing or empty: {{error}}" + severity: warn + description: | + This Spectral rule ensures that each path parameter in the API specification has a descriptive and meaningful description. + given: + - "$.paths..parameters.*" + then: + field: description + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-response-descriptions: + message: "Parameter description is missing or empty: {{error}}" + severity: warn + description: | + This Spectral rule ensures that each responese object in the API specification has a descriptive and meaningful description. + given: + - "$.paths..responses.*" + then: + field: description + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-properties-descriptions: + message: "Property description is missing or empty: {{error}}" + severity: warn + description: | + This Spectral rule ensures that each propoerty within objects in the API specification has a descriptive and meaningful description. + given: + - "$.components.*.*" + - "$.components.*.*.properties.*" + then: + field: description + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-operation-summary: + message: "Operation Summary Warning: Each operation should include a short summary for better understanding." + severity: warn + description: | + This rule checks if each operation (POST, GET, DELETE, PUT, PATCH, OPTIONS) in your API specification has a meaningful summary. + Ensure that you have added a 'summary' field for each operation in your OpenAPI specification. + given: + - "$.paths.*.post" + - "$.paths.*.get" + - "$.paths.*.delete" + - "$.paths.*.put" + - "$.paths.*.patch" + - "$.paths.*.options" + then: + field: summary + function: truthy + recommended: true # Set to true/false to enable/disable this rule + + camara-discriminator-use: + description: | + Ensure that API definition YAML files with oneOf or anyOf sections include a discriminator object for serialization, deserialization, and validation. + severity: hint + given: "$..[?(@.oneOf || @.anyOf)]" + then: + field: discriminator + function: truthy + description: "Discriminator object is required when using oneOf or anyOf." + recommended: true # Set to true/false to enable/disable this rule + + camara-operationid-casing-convention: + message: Operation Id must be in Camel case "{{error}}" + severity: hint + description: | + This rule checks Operation ids should follow a specific case convention: camel case. + given: "$.paths.*.*.operationId" + then: + function: casing + functionOptions: + type: camel + recommended: true # Set to true/false to enable/disable this rule + + camara-schema-casing-convention: + description: This rule checks schema should follow a specific case convention pascal case. + message: "{{property}} should be pascal case (UppperCamelCase)" + severity: warn + given: $.components.schemas[*]~ + then: + function: casing + functionOptions: + type: pascal + recommended: true # Set to true/false to enable/disable this rule + + camara-parameter-casing-convention: + description: Paths should be kebab-case. + severity: error + message: "{{property}} is not kebab-case: {{error}}" + given: $.paths[*]~ + then: + function: pattern + functionOptions: + match: "^\/([a-z0-9]+(-[a-z0-9]+)*)?(\/[a-z0-9]+(-[a-z0-9]+)*|\/{.+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces + recommended: true # Set to true/false to enable/disable this rule diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 00000000..081ef093 --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,35 @@ +--- +# CAMARA Project - YAML linting configuration for yamllint https://yamllint.readthedocs.io/en/latest/rules.html +# 31.01.2024 - initial version + +yaml-files: + - '*.yaml' + - '*.yml' + - '.yamllint' + +rules: + braces: enable + brackets: enable + colons: enable + commas: enable + comments: + min-spaces-from-content: 1 + level: error + comments-indentation: + level: error + document-end: disable + document-start: disable + empty-lines: enable + empty-values: disable + hyphens: enable + indentation: enable + key-duplicates: enable + key-ordering: disable + line-length: disable + new-line-at-end-of-file: enable + new-lines: disable + octal-values: disable + quoted-strings: disable + trailing-spaces: enable + truthy: + level: error diff --git a/lint_function/camara-language-avoid-telco.js b/lint_function/camara-language-avoid-telco.js new file mode 100644 index 00000000..061b5431 --- /dev/null +++ b/lint_function/camara-language-avoid-telco.js @@ -0,0 +1,40 @@ +// CAMARA Project - support function for Spectral linter +// 31.01.2024 - initial version + +const replacements = [ + { original: 'UE', recommended: 'device' }, + { original: 'MSISDN', recommended: 'phone number' }, + { original: 'mobile network', recommended: 'network' } +]; + +export default async function (input) { + const errors = []; + const suggestions = []; + + // Iterate over properties of the input object + for (const path in input) { + const value = input[path]; + + // Check if the value is a string + if (typeof value === 'string') { + for (const replacement of replacements) { + const original = replacement.original; + const recommended = replacement.recommended; + + // Use a regular expression to match 'original' as a standalone word + const regex = new RegExp(`\\b${original}\\b`, 'g'); + + // Check if 'original' exists in the value + if (regex.test(value)) { + errors.push(replacement); + suggestions.push(` Telco-specific terminology found in input: Consider replacing '${original}' with '${recommended}'.`); + } + } + } + } + + // Check if any word from 'replacements' is in the suggestions + if (errors.length > 0) { + console.log(`Hint camara-language-avoid-telco ` + suggestions.join(', ')); + } +}; diff --git a/lint_function/camara-reserved-words.js b/lint_function/camara-reserved-words.js new file mode 100644 index 00000000..c28e63ab --- /dev/null +++ b/lint_function/camara-reserved-words.js @@ -0,0 +1,98 @@ +// CAMARA Project - support function for Spectral linter +// 31.01.2024 - initial version + +const reservedWords = [ + 'abstract', + 'apiclient', + 'apiexception', + 'apiresponse', + 'assert', + 'boolean', + 'break', + 'byte', + 'case', + 'catch', + 'char', + 'class', + 'configuration', + 'const', + 'continue', + 'do', + 'double', + 'else', + 'extends', + 'file', + 'final', + 'finally', + 'float', + 'for', + 'goto', + 'if', + 'implements', + 'import', + 'instanceof', + 'int', + 'interface', + 'list', + 'localdate', + 'localreturntype', + 'localtime', + 'localvaraccept', + 'localvaraccepts', + 'localvarauthnames', + 'localvarcollectionqueryparams', + 'localvarcontenttype', + 'localvarcontenttypes', + 'localvarcookieparams', + 'localvarformparams', + 'localvarheaderparams', + 'localvarpath', + 'localvarpostbody', + 'localvarqueryparams', + 'long', + 'native', + 'new', + 'null', + 'object', + 'offsetdatetime', + 'package', + 'private', + 'protected', + 'public', + 'return', + 'short', + 'static', + 'strictfp', + 'stringutil', + 'super', + 'switch', + 'synchronized', + 'this', + 'throw', + 'throws', + 'transient', + 'try', + 'void', + 'volatile', + 'while' +]; +// Reserved word 'enum' and 'default' are removed from above reserved word array as they are common in openAPI keyword +export default async function lintReservedWords(input) { + // Iterate over properties of the input object + for (const path in input) { + if (typeof path === 'string') { + + for (const word of reservedWords) { + const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word + + if (regex.test(path)) { + const warningRuleName = 'camara-reserved-words'; + const description = `Reserved words found in input: Consider avoiding the use of reserved word '${word}'`; + // const location = `${path}`; + + console.log(`warning ${warningRuleName} ${description} ${path}`); + } + } + } + } +} diff --git a/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js b/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js new file mode 100644 index 00000000..ebbff2a4 --- /dev/null +++ b/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js @@ -0,0 +1,26 @@ +// CAMARA Project - support function for Spectral linter +// 31.01.2024 - initial version + +const sensitiveData = ['MSISDN','IMSI','phoneNumber']; + +export default async function (input) { + + // Iterate over properties of the input object + for (const path in input) { + + if (typeof path === 'string') { + for (const word of sensitiveData ) { + const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word + + if (regex.test(path)) { + + const warningRuleName = 'camara-security-no-secrets-in-path-or-query-parameters'; + const description = `sensitiveData Data found in path: Consider avoiding the use of sensitiveData data '${word}'`; + const location = `paths.${path}`; + console.log(`warning ${warningRuleName} ${description} ${location}`); + + } + } + } + } +} From cec1b88eb70f17c3f4a22562cfb3c1bcc7eb2e2a Mon Sep 17 00:00:00 2001 From: rartych Date: Thu, 7 Mar 2024 13:54:58 +0100 Subject: [PATCH 2/9] geofencing.yaml cleaned --- code/API_definitions/geofencing.yaml | 98 ++++++++++++++-------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/code/API_definitions/geofencing.yaml b/code/API_definitions/geofencing.yaml index 02930c45..7c367c6d 100644 --- a/code/API_definitions/geofencing.yaml +++ b/code/API_definitions/geofencing.yaml @@ -3,47 +3,47 @@ info: title: Device geofencing API description: | API to create, retrieve and delete event subscriptions to realize geofencing for a user device. - + # Introduction - + With this API, customers can create subscriptions for their devices to receive notifications when a device enters or exits a specified area. - - The area provided in the request is described by a circle determined by coordinates (latitude and longitude) and an accuracy defined by the radius. - + + The area provided in the request is described by a circle determined by coordinates (latitude and longitude) and an accuracy defined by the radius. + Upon successfully creating a subscription, the API will provide an Event Subscription ID, and it will indicate the subscription's expiration date. - + If the geofencing-state of a device changes, the event subscriber will be notified back to the provided Notification-Url given by the subscription-request. - + Device geofencing API could be useful in scenarios such as: - - - Tracking devices for Presetting of Home-Settings + + - Tracking devices for Presetting of Home-Settings - Tracking of logistics - + # Relevant terms and definitions - + * **Device**: A device refers to any physical entity that can connect to a network and participate in network communication. - + * **Area**: It specifies the geographical surface which a device is planned to enter or exit. - + # API Functionality - + The API exposes following capabilities: - + ## Device Geofencing subscription - These endpoints allow to manage event subscription on geofencing device location event. - + These endpoints allow to manage event subscription on geofencing device location event. + The CAMARA subscription model is detailed in the CAMARA API design guideline document and follows CloudEvents specification. - It is mandatory in the subscription to provide the event `type` for which the client would like to subscribe. - + It is mandatory in the subscription to provide the event `type` for which the client would like to subscribe. + Following event ``type`` are managed for this API: - ``org.camaraproject.geofencing.v0.area-entered`` - Event triggered when the device enters the given area - + - ``org.camaraproject.geofencing.v0.area-left`` - Event triggered when the device leaves the given area - - Note: Additionally to these list, ``org.camaraproject.geofencing.v0.subscription-ends`` notification `type` is sent when the subscription ends. - This notification did not requires dedicated subscription. - It is used when the subscription expire time (required by the requester) has been reached or if the API server has to stop sending notification prematurely. + + Note: Additionally to these list, ``org.camaraproject.geofencing.v0.subscription-ends`` notification `type` is sent when the subscription ends. + This notification did not requires dedicated subscription. + It is used when the subscription expire time (required by the requester) has been reached or if the API server has to stop sending notification prematurely. ### Notification callback @@ -51,11 +51,11 @@ info: _**WARNING**: This callback endpoint must be exposed on the consumer side as `POST /{$request.body#/webhook/notificationUrl}`. Developers may provide a callback URL on which notifications regarding geofencing can be received from the service provider. - If an event occurs the application will send events to the provided webhook - 'notificationUrl'._ - + If an event occurs the application will send events to the provided webhook - 'notificationUrl'._ + # Further info and support - - (FAQs will be added in a later version of the documentation) + + (FAQs will be added in a later version of the documentation) termsOfService: http://swagger.io/terms/ contact: @@ -461,7 +461,7 @@ components: type: string description: | area-entered - Event triggered when the device enters the given area - + area-left - Event triggered when the device leaves the given area enum: - org.camaraproject.geofencing.v0.area-entered @@ -471,9 +471,9 @@ components: type: string description: | area-entered - Event triggered when the device enters the given area - + area-left - Event triggered when the device leaves the given area - + subscription-ends - Event triggered when the subscription ends enum: - org.camaraproject.geofencing.v0.area-entered @@ -500,9 +500,9 @@ components: $ref: "#/components/schemas/SubscriptionDetail" subscriptionExpireTime: type: string - format: date-time - description: The date time when the location-tracking has to be terminated. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + format: date-time + description: The date time when the location-tracking has to be terminated. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. Recommended format is yyyy-MM-dd'T'HH:mm:ss.SSSZ (i.e. which allows 2023-07-03T14:27:08.312+02:00 or 2023-07-03T12:27:08.312Z) required: - webhook @@ -521,26 +521,26 @@ components: type: string format: date-time description: The date time when the subscription started. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. Recommended format is yyyy-MM-dd'T'HH:mm:ss.SSSZ (i.e. which allows 2023-07-03T14:27:08.312+02:00 or 2023-07-03T12:27:08.312Z) expiresAt: type: string format: date-time - description: The date time when the subscription will expire or expired. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + description: The date time when the subscription will expire or expired. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. Recommended format is yyyy-MM-dd'T'HH:mm:ss.SSSZ (i.e. which allows 2023-07-03T14:27:08.312+02:00 or 2023-07-03T12:27:08.312Z) required: - - subscriptionId + - subscriptionId EventTime: format: date-time type: string description: | - Timestamp of when the occurrence happened. - If the time of the occurrence cannot be determined then this attribute MAY be set to some other time (such as the current time) by the CloudEvents producer, - however all producers for the same source MUST be consistent in this respect. In other words, - either they all use the actual time of the occurrence or they all use the same algorithm to determine the value used. - It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. + Timestamp of when the occurrence happened. + If the time of the occurrence cannot be determined then this attribute MAY be set to some other time (such as the current time) by the CloudEvents producer, + however all producers for the same source MUST be consistent in this respect. In other words, + either they all use the actual time of the occurrence or they all use the same algorithm to determine the value used. + It must follow [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) and must have time zone. Recommended format is yyyy-MM-dd'T'HH:mm:ss.SSSZ (i.e. which allows 2023-07-03T14:27:08.312+02:00 or 2023-07-03T12:27:08.312Z) CloudEvent: @@ -696,7 +696,7 @@ components: status: 400 code: INVALID_ARGUMENT message: "Invalid argument" - + Generic401: description: Unauthenticated content: @@ -707,7 +707,7 @@ components: status: 401 code: UNAUTHENTICATED message: "Authorization failed: ..." - + Generic403: description: Permission denied content: @@ -718,7 +718,7 @@ components: status: 403 code: PERMISSION_DENIED message: "Operation not allowed: ..." - + Generic404: description: Not found content: @@ -729,7 +729,7 @@ components: status: 404 code: NOT_FOUND message: "The specified resource is not found" - + Generic409: description: Conflict content: @@ -740,7 +740,7 @@ components: status: 409 code: Conflict message: "There is conflict in the request" - + Generic500: description: Internal server error content: @@ -751,7 +751,7 @@ components: status: 500 code: INTERNAL message: "Internal server error" - + Generic503: description: Service unavailable content: From d6a7e64ab5e15ac54401c35af03e6ad8eb198a5a Mon Sep 17 00:00:00 2001 From: rartych Date: Thu, 7 Mar 2024 14:29:24 +0100 Subject: [PATCH 3/9] location-retrieval.yaml --- code/API_definitions/location-retrieval.yaml | 38 ++++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/code/API_definitions/location-retrieval.yaml b/code/API_definitions/location-retrieval.yaml index d6200b7d..db097fb4 100644 --- a/code/API_definitions/location-retrieval.yaml +++ b/code/API_definitions/location-retrieval.yaml @@ -2,22 +2,22 @@ openapi: 3.0.3 info: title: Location retrieval API description: | - This API provides the ability to retrieve a device location. + This API provides the ability to retrieve a device location. # Introduction - With this API, customers can retrieve the area where a certain user device is localized. + With this API, customers can retrieve the area where a certain user device is localized. The area provided in the response could be described: - - by a circle determined by coordinates (latitude and longitude) and a radius. + - by a circle determined by coordinates (latitude and longitude) and a radius. - by a simple polygon delimited by segments connecting consecutively an array of coordinates (points). The last point connects to the first point to delimit a closed shape bounded with straight sides. The retrieved shape depends on the network conditions at the subscriber's location and any of the supported shapes could be received. - + The requester could optionally ask for a freshness of the localization information by providing a maxAge ("I want a location not older than 600 seconds") - The result accuracy depends on the network's ability and accuracy to locate the device. - - Additionally to location information, the answer will also provide indication about the location time. + The result accuracy depends on the network's ability and accuracy to locate the device. + + Additionally to location information, the answer will also provide indication about the location time. Location retrieval API could be useful in scenarios such as: @@ -51,7 +51,7 @@ info: # Further info and support - (FAQs will be added in a later version of the documentation) + (FAQs will be added in a later version of the documentation) termsOfService: http://swagger.io/terms/ contact: email: project-email@sample.com @@ -114,7 +114,7 @@ paths: $ref: '#/components/responses/Generic503' security: - openId: - - location-retrieval:read + - location-retrieval:read components: securitySchemes: @@ -212,8 +212,6 @@ components: format: ipv6 example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 - - Location: type: object description: Device location @@ -221,13 +219,13 @@ components: - lastLocationTime - area properties: - lastLocationTime: + lastLocationTime: description: Last date and time when the device was localized. It must follow RFC 3339 and must have time zone. Recommended format is yyyy-MM-dd'T'HH:mm:ss.SSSZ (i.e. which allows 2023-07-03T14:27:08.312+02:00 or 2023-07-03T12:27:08.312Z) type: string format: date-time area: $ref: '#/components/schemas/Area' - + Area: type: object properties: @@ -253,14 +251,14 @@ components: Circle: description: Circular area - allOf: + allOf: - $ref: "#/components/schemas/Area" - type: object required: - center - radius properties: - center: + center: $ref: "#/components/schemas/Point" radius: type: number @@ -287,15 +285,15 @@ components: Point: type: object description: Coordinates (latitude, longitude) defining a location in a map - required: + required: - latitude - longitude - properties: + properties: latitude: $ref: "#/components/schemas/Latitude" longitude: $ref: "#/components/schemas/Longitude" - example: + example: latitude: 50.735851 longitude: 7.10066 @@ -305,7 +303,7 @@ components: format: double minimum: -90 maximum: 90 - + Longitude: description: Longitude component of location type: number @@ -405,7 +403,7 @@ components: lastLocationTime: 2023-10-17T13:18:23.682Z area: areaType: CIRCLE - center: + center: latitude: 45.754114 longitude: 4.860374 radius: 800 From 8518bcf7ba5fece51b588bf88b66c8e6762fd56b Mon Sep 17 00:00:00 2001 From: rartych Date: Thu, 7 Mar 2024 14:51:23 +0100 Subject: [PATCH 4/9] location-verification.yaml --- .../location-verification.yaml | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/code/API_definitions/location-verification.yaml b/code/API_definitions/location-verification.yaml index cb0d4f28..5e5888e5 100644 --- a/code/API_definitions/location-verification.yaml +++ b/code/API_definitions/location-verification.yaml @@ -2,20 +2,20 @@ openapi: 3.0.3 info: title: Device location verification API description: | - This API provides the customer with the ability to verify the location of a device. + This API provides the customer with the ability to verify the location of a device. # Introduction Customers are able to verify whether the location of certain user device is within the area specified. Currently the only area supported as input is a circle determined by the a set of coordinates (latitude and longitude) and some expected accuracy (radius). - The verification result depends on the network's ability and accuracy to locate the device at the requested area. - + The verification result depends on the network's ability and accuracy to locate the device at the requested area. + * If the network's estimation of the device's location is fully contained within the requested area, the verification result is `TRUE`. - * If the network's estimation of the device's location does not overlap with the requested area at all, the verification result is `FALSE` . + * If the network's estimation of the device's location does not overlap with the requested area at all, the verification result is `FALSE`. * If the network's estimation of the device's location partially overlaps with the requested area, or it fully contains the requested area (because it is larger), the result is 'PARTIAL'. In this case, a `match_rate` may be included in the response, indicating an estimation of the likelihood of the match in percent. * Lastly, the network may not be able to locate the device. In this case, the verification result is `UNKNOWN`. - The client may optionally include a `maxAge` indication. If the location information known to the server is older than the specified `maxAge`, the verification result will be `UNKNOWN` and the `lastLocationTime` attribute may indicate the last available time for the device location. + The client may optionally include a `maxAge` indication. If the location information known to the server is older than the specified `maxAge`, the verification result will be `UNKNOWN` and the `lastLocationTime` attribute may indicate the last available time for the device location. `lastLocationTime` will be always included in the response unless there is no historical location information available for the device. In this case, `UNKNOWN` will be returned without `lastLocationTime`. @@ -42,7 +42,7 @@ info: # Further info and support - (FAQs will be added in a later version of the documentation) + (FAQs will be added in a later version of the documentation) termsOfService: http://swagger.io/terms/ contact: email: project-email@sample.com @@ -112,7 +112,7 @@ paths: application/json: schema: $ref: "#/components/schemas/VerifyLocationResponse" - examples: + examples: VERIFICATION_TRUE: summary: Match description: The network locates the device within the requested area @@ -124,7 +124,7 @@ paths: description: The requested area does not match the area where the network locates the device value: verificationResult: "FALSE" - lastLocationTime: 2023-09-07T10:40:52Z + lastLocationTime: 2023-09-07T10:40:52Z VERIFICATION_UNKNOWN_WITH_LAST_LOCATION_TIME: summary: Unknown with last location time description: The network cannot locate the device after the requested maxAge @@ -133,14 +133,14 @@ paths: lastLocationTime: 2023-09-07T10:40:52Z VERIFICATION_UNKNOWN_WITHOUT_LAST_LOCATION_TIME: summary: Unknown without last location time - description: The network cannot locate the device and there is no history available + description: The network cannot locate the device and there is no history available value: verificationResult: "UNKNOWN" VERIFICATION_PARTIAL: summary: Partial match description: The requested area partially matches the area where the network locates the device value: - verificationResult: "PARTIAL" + verificationResult: "PARTIAL" matchRate: 74 lastLocationTime: 2023-09-07T10:40:52Z "400": @@ -157,7 +157,7 @@ paths: $ref: "#/components/responses/Generic503" security: - openId: - - location-verification:verify + - location-verification:verify components: securitySchemes: openId: @@ -209,15 +209,15 @@ components: Point: type: object description: Coordinates (latitude, longitude) defining a location in a map - required: + required: - latitude - longitude - properties: + properties: latitude: $ref: "#/components/schemas/Latitude" longitude: $ref: "#/components/schemas/Longitude" - example: + example: latitude: 50.735851 longitude: 7.10066 Latitude: @@ -226,14 +226,14 @@ components: format: double minimum: -90 maximum: 90 - example: 50.735851 + example: 50.735851 Longitude: description: Longitude component of location type: number format: double minimum: -180 maximum: 180 - example: 7.10066 + example: 7.10066 VerifyLocationRequest: type: object properties: @@ -336,7 +336,7 @@ components: type: string format: ipv6 example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 - + MaxAge: description: The maximum age (in seconds) of the available location, which is accepted for the verification. type: integer @@ -345,7 +345,7 @@ components: VerificationResult: description: | Result of a verification request: - - `TRUE`: when the network locates the device within the requested area, + - `TRUE`: when the network locates the device within the requested area, - `FALSE`: when the requested area does not match the area where the network locates the device, - `UNKNOWN`: when the network cannot locate the device, - `PARTIAL`: when the requested area partially match the area where the network locates the device. A `match_rate` could be included in the response. From bf2759d27e992fe37aa42556bbd7296b2d1241e2 Mon Sep 17 00:00:00 2001 From: rartych Date: Thu, 7 Mar 2024 14:55:02 +0100 Subject: [PATCH 5/9] location-verification.yaml 2 --- code/API_definitions/location-verification.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/API_definitions/location-verification.yaml b/code/API_definitions/location-verification.yaml index 5e5888e5..16cd572b 100644 --- a/code/API_definitions/location-verification.yaml +++ b/code/API_definitions/location-verification.yaml @@ -42,7 +42,7 @@ info: # Further info and support - (FAQs will be added in a later version of the documentation) + (FAQs will be added in a later version of the documentation) termsOfService: http://swagger.io/terms/ contact: email: project-email@sample.com @@ -233,7 +233,7 @@ components: format: double minimum: -180 maximum: 180 - example: 7.10066 + example: 7.10066 VerifyLocationRequest: type: object properties: From b8175f5ce4d79a44025f5e516c5944d22ed62ac1 Mon Sep 17 00:00:00 2001 From: rartych Date: Thu, 7 Mar 2024 15:03:39 +0100 Subject: [PATCH 6/9] location-verification.yaml 3 --- code/API_definitions/location-verification.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/API_definitions/location-verification.yaml b/code/API_definitions/location-verification.yaml index 16cd572b..39ae7bdf 100644 --- a/code/API_definitions/location-verification.yaml +++ b/code/API_definitions/location-verification.yaml @@ -233,7 +233,7 @@ components: format: double minimum: -180 maximum: 180 - example: 7.10066 + example: 7.10066 VerifyLocationRequest: type: object properties: From 1baf3df0242e3233098e9a5672d1fc058b8b803e Mon Sep 17 00:00:00 2001 From: rartych Date: Thu, 7 Mar 2024 15:53:59 +0100 Subject: [PATCH 7/9] Revert "linting ruleset add" This reverts commit 419bee75c7ee6195d9c31c9ddb6342ebbb1f9358. --- .github/workflows/megalinter.yml | 78 ------ .github/workflows/spectral_oas_lint.yml | 36 --- .spectral.yml | 258 ------------------ .yamllint.yaml | 35 --- lint_function/camara-language-avoid-telco.js | 40 --- lint_function/camara-reserved-words.js | 98 ------- ...-no-secrets-in-path-or-query-parameters.js | 26 -- 7 files changed, 571 deletions(-) delete mode 100644 .github/workflows/megalinter.yml delete mode 100644 .github/workflows/spectral_oas_lint.yml delete mode 100644 .spectral.yml delete mode 100644 .yamllint.yaml delete mode 100644 lint_function/camara-language-avoid-telco.js delete mode 100644 lint_function/camara-reserved-words.js delete mode 100644 lint_function/camara-security-no-secrets-in-path-or-query-parameters.js diff --git a/.github/workflows/megalinter.yml b/.github/workflows/megalinter.yml deleted file mode 100644 index 6bda7009..00000000 --- a/.github/workflows/megalinter.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- -# MegaLinter GitHub Action configuration file -# More info at https://megalinter.io -# CAMARA Project - Github Action for Pull Reqests -# 31.01.2024 - initial version - -name: MegaLinter - -on: # yamllint disable-line rule:truthy - # Pull Requests to main - pull_request: - branches: [master, main] - -env: # Comment env block if you do not want to apply fixes - # Apply linter fixes configuration - APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool) - APPLY_FIXES_EVENT: pull_request # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all) - APPLY_FIXES_MODE: commit # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request) - -concurrency: - group: ${{ github.ref }}-${{ github.workflow }} - cancel-in-progress: true - -jobs: - build: - name: MegaLinter - runs-on: ubuntu-latest - permissions: - # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR - # Remove the ones you do not need - contents: write - issues: write - pull-requests: write - steps: - # Git Checkout - - name: Checkout Code - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances - - name: Install Spectral - run: npm install -g @stoplight/spectral - - name: Install Spectral functions - run: npm install -g @stoplight/spectral-functions - # - name: Run spectral:oas Spectral Linting - # run: spectral lint code/API_definitions/*.yaml --verbose --ruleset .spectral.yml - # Replace openapi.yaml file with your API specification file - - # MegaLinter - - name: MegaLinter - id: ml - # You can override MegaLinter flavor used to have faster performances - # More info at https://megalinter.io/flavors/ - uses: oxsecurity/megalinter/flavors/java@v7.3.0 - env: - # All available variables are described in documentation - # https://megalinter.io/configuration/ - PRINT_ALPACA: false - # VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources - VALIDATE_ALL_CODEBASE: true - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY - DISABLE: COPYPASTE,MARKDOWN - DISABLE_LINTERS: SPELL_CSPELL,SPELL_LYCHEE,YAML_PRETTIER,REPOSITORY_GRYPE, REPOSITORY_SEMGREP,REPOSITORY_DEVSKIM,REPOSITORY_KICS,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,REPOSITORY_CHECKOV,REPOSITORY_GITLEAKS,YAML_V8R,JAVA_PMD,JAVA_CHECKSTYLE - YAML_YAMLLINT_CONFIG_FILE: ".yamllint.yaml" - OPENAPI_SPECTRAL_CONFIG_FILE: ".spectral.yml" - YAML_YAMLLINT_FILTER_REGEX_INCLUDE: "(code/)" - OPENAPI_SPECTRAL_FILTER_REGEX_INCLUDE: "(code/)" - - # Upload MegaLinter artifacts - - name: Archive production artifacts - if: ${{ success() }} || ${{ failure() }} - uses: actions/upload-artifact@v4 - with: - name: MegaLinter reports - path: | - megalinter-reports - mega-linter.log diff --git a/.github/workflows/spectral_oas_lint.yml b/.github/workflows/spectral_oas_lint.yml deleted file mode 100644 index a828fd58..00000000 --- a/.github/workflows/spectral_oas_lint.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- -# CAMARA Project - workflow configuration to manually run CAMARA OAS rules -# see https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow -# 31.01.2024 - initial version - -name: Spectral manual run - -on: workflow_dispatch - -concurrency: - group: ${{ github.ref }}-${{ github.workflow }} - cancel-in-progress: true - -jobs: - build: - name: Spectral linting - runs-on: ubuntu-latest - permissions: - # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR - # Remove the ones you do not need - contents: write - issues: write - pull-requests: write - steps: - # Git Checkout - - name: Checkout Code - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances - - name: Install Spectral - run: npm install -g @stoplight/spectral - - name: Install Spectral functions - run: npm install -g @stoplight/spectral-functions - - name: Run Spectral linting - run: spectral lint code/API_definitions/*.yaml --verbose --ruleset .spectral.yml diff --git a/.spectral.yml b/.spectral.yml deleted file mode 100644 index 0b16508e..00000000 --- a/.spectral.yml +++ /dev/null @@ -1,258 +0,0 @@ -# CAMARA Project - linting ruleset - documentation avaialable here: -# https://github.com/camaraproject/Commonalities/blob/main/documentation/Linting-rules.md -# 31.01.2024 - initial version - -extends: "spectral:oas" -functions: - - camara-reserved-words - - camara-language-avoid-telco - - camara-security-no-secrets-in-path-or-query-parameters -functionsDir: "./lint_function" -rules: - # Built-in OpenAPI Specification ruleset. Each rule then can be enabled individually. - # The severity keyword is optional in rule definition and can be error, warn, info, hint, or off. The default value is warn. - contact-properties: false - duplicated-entry-in-enum: true - info-contact: true - info-description: true - info-license: true - license-url: true - no-$ref-siblings: error - no-eval-in-markdown: true - no-script-tags-in-markdown: true - openapi-tags: false - openapi-tags-alphabetical: false - openapi-tags-uniqueness: error - operation-description: true - operation-operationId: true - operation-operationId-unique: error - operation-operationId-valid-in-url: true - operation-parameters: true - operation-singular-tag: true - operation-success-response: true - operation-tags: true - operation-tag-defined: true - path-declarations-must-exist: true - path-keys-no-trailing-slash: true - path-not-include-query: true - path-params: error - tag-description: false - typed-enum: true - oas3-api-servers: true - oas3-examples-value-or-externalValue: true - oas3-operation-security-defined: false - oas3-parameter-description: false - oas3-schema: true - oas3-server-not-example.com: false - oas3-server-trailing-slash: true - oas3-unused-component: true - oas3-valid-media-example: true - oas3-valid-schema-example: true - # oas3-server-variables: true - - # Custom Rules Utilizing Spectral's Built-in Functions and JavaScript Implementations - - camara-language-avoid-telco: - message: "{{error}}" - severity: hint - description: | - This rule checks for telco-specific terminology in your API definitions and suggests more inclusive terms. - given: "$..*.*" - then: - function: camara-language-avoid-telco - recommended: false # Set to true/false to enable/disable this rule - - camara-oas-version: - message: "OpenAPI Version Error: The OpenAPI specification must adhere to version 3.0.3." - severity: error - description: | - This rule validates the OpenAPI version in your specification and requires compliance with version 3.0.3. - given: "$" - then: - field: openapi - function: pattern - functionOptions: - match: 3.0.3 - recommended: true # Set to true/false to enable/disable this rule - - camara-path-param-id: - message: "Path Parameter Naming Warning: Use 'resource_id' instead of just 'id' in path parameters." - severity: warn - description: | - This rule ensures consistent and descriptive naming for path parameters in your OpenAPI specification. - Please use 'resource_id' instead of just 'id' for your path parameters. - given: "$..parameters[?(@.in == 'path')]" - then: - field: name - function: pattern - functionOptions: - notMatch: \b(id|Id|ID|iD)\b - recommended: true # Set to true/false to enable/disable this rule - - camara-security-no-secrets-in-path-or-query-parameters: - message: "Sensitive data found in path: {{error}} Consider avoiding the use of Sesentive data " - severity: warn - description: | - This rule checks for sensitive data ('MSISDN' and 'IMSI') in API paths and suggests avoiding their use. - given: - - "$.paths" - then: - function: camara-security-no-secrets-in-path-or-query-parameters - recommended: true # Set to true/false to enable/disable this rule - - camara-http-methods: - description: "Ensure that all path URLs have valid HTTP methods (GET, PUT, POST, DELETE, PATCH, OPTIONS)." - message: "Invalid HTTP method for '{{path}}'. Must be one of get, put, post, delete, patch, options." - severity: error - given: $.paths[*][*]~ - then: - function: pattern - functionOptions: - match: "^(get|put|post|delete|patch|options)$" - recommended: true # Set to true/false to enable/disable this rule - - camara-get-no-request-body: - message: There must be no request body for Get and DELETE - severity: error - given: - - "$.paths.*.get" - - "$.paths.*.delete" - then: - field: requestBody - function: falsy - recommended: true # Set to true/false to enable/disable this rule - - camara-reserved-words: - message: "Reserved words found {{error}} Consider avoiding the use of reserved word " - severity: warn - description: | - This rule checks Reserved words must not be used in the following parts of an API specification [Paths, Request Body properties, Component, Operation Id, Security Schema] - given: - - "$.paths" # Paths - - "$..parameters[*]" # Path or Query Parameter Names: - - "$..components.schemas.*.properties.*" # Request and Response body parameter - - "$.paths.*." # Path and Operation Names: - - "$.components.securitySchemes" # Security Schemes: - - "$.components.*.*" # Component Names: - - "$.paths.*.*.operationId" # OperationIds: - then: - function: camara-reserved-words - recommended: true # Set to true/false to enable/disable this rule - - camara-routes-description: - message: "Functionality method description Warning: Each method should have description." - severity: warn - description: | - This rule checks if each operation (POST, GET, DELETE, PUT, PATCH, OPTIONS) in your API specification has a description. - Ensure that you have added a 'summary' field for each operation in your OpenAPI specification. - given: - - "$.paths.*.post" - - "$.paths.*.get" - - "$.paths.*.delete" - - "$.paths.*.put" - - "$.paths.*.patch" - - "$.paths.*.options" - then: - field: description - function: truthy - recommended: true # Set to true/false to enable/disable this rule - - camara-parameters-descriptions: - message: "Parameter description is missing or empty: {{error}}" - severity: warn - description: | - This Spectral rule ensures that each path parameter in the API specification has a descriptive and meaningful description. - given: - - "$.paths..parameters.*" - then: - field: description - function: truthy - recommended: true # Set to true/false to enable/disable this rule - - camara-response-descriptions: - message: "Parameter description is missing or empty: {{error}}" - severity: warn - description: | - This Spectral rule ensures that each responese object in the API specification has a descriptive and meaningful description. - given: - - "$.paths..responses.*" - then: - field: description - function: truthy - recommended: true # Set to true/false to enable/disable this rule - - camara-properties-descriptions: - message: "Property description is missing or empty: {{error}}" - severity: warn - description: | - This Spectral rule ensures that each propoerty within objects in the API specification has a descriptive and meaningful description. - given: - - "$.components.*.*" - - "$.components.*.*.properties.*" - then: - field: description - function: truthy - recommended: true # Set to true/false to enable/disable this rule - - camara-operation-summary: - message: "Operation Summary Warning: Each operation should include a short summary for better understanding." - severity: warn - description: | - This rule checks if each operation (POST, GET, DELETE, PUT, PATCH, OPTIONS) in your API specification has a meaningful summary. - Ensure that you have added a 'summary' field for each operation in your OpenAPI specification. - given: - - "$.paths.*.post" - - "$.paths.*.get" - - "$.paths.*.delete" - - "$.paths.*.put" - - "$.paths.*.patch" - - "$.paths.*.options" - then: - field: summary - function: truthy - recommended: true # Set to true/false to enable/disable this rule - - camara-discriminator-use: - description: | - Ensure that API definition YAML files with oneOf or anyOf sections include a discriminator object for serialization, deserialization, and validation. - severity: hint - given: "$..[?(@.oneOf || @.anyOf)]" - then: - field: discriminator - function: truthy - description: "Discriminator object is required when using oneOf or anyOf." - recommended: true # Set to true/false to enable/disable this rule - - camara-operationid-casing-convention: - message: Operation Id must be in Camel case "{{error}}" - severity: hint - description: | - This rule checks Operation ids should follow a specific case convention: camel case. - given: "$.paths.*.*.operationId" - then: - function: casing - functionOptions: - type: camel - recommended: true # Set to true/false to enable/disable this rule - - camara-schema-casing-convention: - description: This rule checks schema should follow a specific case convention pascal case. - message: "{{property}} should be pascal case (UppperCamelCase)" - severity: warn - given: $.components.schemas[*]~ - then: - function: casing - functionOptions: - type: pascal - recommended: true # Set to true/false to enable/disable this rule - - camara-parameter-casing-convention: - description: Paths should be kebab-case. - severity: error - message: "{{property}} is not kebab-case: {{error}}" - given: $.paths[*]~ - then: - function: pattern - functionOptions: - match: "^\/([a-z0-9]+(-[a-z0-9]+)*)?(\/[a-z0-9]+(-[a-z0-9]+)*|\/{.+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces - recommended: true # Set to true/false to enable/disable this rule diff --git a/.yamllint.yaml b/.yamllint.yaml deleted file mode 100644 index 081ef093..00000000 --- a/.yamllint.yaml +++ /dev/null @@ -1,35 +0,0 @@ ---- -# CAMARA Project - YAML linting configuration for yamllint https://yamllint.readthedocs.io/en/latest/rules.html -# 31.01.2024 - initial version - -yaml-files: - - '*.yaml' - - '*.yml' - - '.yamllint' - -rules: - braces: enable - brackets: enable - colons: enable - commas: enable - comments: - min-spaces-from-content: 1 - level: error - comments-indentation: - level: error - document-end: disable - document-start: disable - empty-lines: enable - empty-values: disable - hyphens: enable - indentation: enable - key-duplicates: enable - key-ordering: disable - line-length: disable - new-line-at-end-of-file: enable - new-lines: disable - octal-values: disable - quoted-strings: disable - trailing-spaces: enable - truthy: - level: error diff --git a/lint_function/camara-language-avoid-telco.js b/lint_function/camara-language-avoid-telco.js deleted file mode 100644 index 061b5431..00000000 --- a/lint_function/camara-language-avoid-telco.js +++ /dev/null @@ -1,40 +0,0 @@ -// CAMARA Project - support function for Spectral linter -// 31.01.2024 - initial version - -const replacements = [ - { original: 'UE', recommended: 'device' }, - { original: 'MSISDN', recommended: 'phone number' }, - { original: 'mobile network', recommended: 'network' } -]; - -export default async function (input) { - const errors = []; - const suggestions = []; - - // Iterate over properties of the input object - for (const path in input) { - const value = input[path]; - - // Check if the value is a string - if (typeof value === 'string') { - for (const replacement of replacements) { - const original = replacement.original; - const recommended = replacement.recommended; - - // Use a regular expression to match 'original' as a standalone word - const regex = new RegExp(`\\b${original}\\b`, 'g'); - - // Check if 'original' exists in the value - if (regex.test(value)) { - errors.push(replacement); - suggestions.push(` Telco-specific terminology found in input: Consider replacing '${original}' with '${recommended}'.`); - } - } - } - } - - // Check if any word from 'replacements' is in the suggestions - if (errors.length > 0) { - console.log(`Hint camara-language-avoid-telco ` + suggestions.join(', ')); - } -}; diff --git a/lint_function/camara-reserved-words.js b/lint_function/camara-reserved-words.js deleted file mode 100644 index c28e63ab..00000000 --- a/lint_function/camara-reserved-words.js +++ /dev/null @@ -1,98 +0,0 @@ -// CAMARA Project - support function for Spectral linter -// 31.01.2024 - initial version - -const reservedWords = [ - 'abstract', - 'apiclient', - 'apiexception', - 'apiresponse', - 'assert', - 'boolean', - 'break', - 'byte', - 'case', - 'catch', - 'char', - 'class', - 'configuration', - 'const', - 'continue', - 'do', - 'double', - 'else', - 'extends', - 'file', - 'final', - 'finally', - 'float', - 'for', - 'goto', - 'if', - 'implements', - 'import', - 'instanceof', - 'int', - 'interface', - 'list', - 'localdate', - 'localreturntype', - 'localtime', - 'localvaraccept', - 'localvaraccepts', - 'localvarauthnames', - 'localvarcollectionqueryparams', - 'localvarcontenttype', - 'localvarcontenttypes', - 'localvarcookieparams', - 'localvarformparams', - 'localvarheaderparams', - 'localvarpath', - 'localvarpostbody', - 'localvarqueryparams', - 'long', - 'native', - 'new', - 'null', - 'object', - 'offsetdatetime', - 'package', - 'private', - 'protected', - 'public', - 'return', - 'short', - 'static', - 'strictfp', - 'stringutil', - 'super', - 'switch', - 'synchronized', - 'this', - 'throw', - 'throws', - 'transient', - 'try', - 'void', - 'volatile', - 'while' -]; -// Reserved word 'enum' and 'default' are removed from above reserved word array as they are common in openAPI keyword -export default async function lintReservedWords(input) { - // Iterate over properties of the input object - for (const path in input) { - if (typeof path === 'string') { - - for (const word of reservedWords) { - const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word - - if (regex.test(path)) { - const warningRuleName = 'camara-reserved-words'; - const description = `Reserved words found in input: Consider avoiding the use of reserved word '${word}'`; - // const location = `${path}`; - - console.log(`warning ${warningRuleName} ${description} ${path}`); - } - } - } - } -} diff --git a/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js b/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js deleted file mode 100644 index ebbff2a4..00000000 --- a/lint_function/camara-security-no-secrets-in-path-or-query-parameters.js +++ /dev/null @@ -1,26 +0,0 @@ -// CAMARA Project - support function for Spectral linter -// 31.01.2024 - initial version - -const sensitiveData = ['MSISDN','IMSI','phoneNumber']; - -export default async function (input) { - - // Iterate over properties of the input object - for (const path in input) { - - if (typeof path === 'string') { - for (const word of sensitiveData ) { - const regex = new RegExp(`\\b${word}\\b`, 'g'); // Use a regular expression to match 'word' as a standalone word - - if (regex.test(path)) { - - const warningRuleName = 'camara-security-no-secrets-in-path-or-query-parameters'; - const description = `sensitiveData Data found in path: Consider avoiding the use of sensitiveData data '${word}'`; - const location = `paths.${path}`; - console.log(`warning ${warningRuleName} ${description} ${location}`); - - } - } - } - } -} From 4d081a10ecfe46a7a5c4fefb2c0e579af0d6dc83 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:35:46 +0200 Subject: [PATCH 8/9] Update location-verification.yaml --- code/API_definitions/location-verification.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/API_definitions/location-verification.yaml b/code/API_definitions/location-verification.yaml index 98add7ed..8ddb6da2 100644 --- a/code/API_definitions/location-verification.yaml +++ b/code/API_definitions/location-verification.yaml @@ -11,7 +11,7 @@ info: The verification result depends on the network's ability and accuracy to locate the device at the requested area. * If the network's estimation of the device's location is fully contained within the requested area, the verification result is `TRUE`. - * If the network's estimation of the device's location does not overlap with the requested area at all, the verification result is `FALSE` . + * If the network's estimation of the device's location does not overlap with the requested area at all, the verification result is `FALSE`. * If the network's estimation of the device's location partially overlaps with the requested area, or it fully contains the requested area (because it is larger), the result is 'PARTIAL'. In this case, a `match_rate` is included in the response, indicating an estimation of the likelihood of the match in percent. * Lastly, the network may not be able to locate the device. In this case, the verification result is `UNKNOWN`. From 393b63d2664ce651b9bb2a723f3d049ab3008f52 Mon Sep 17 00:00:00 2001 From: Rafal Artych <121048129+rartych@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:37:15 +0200 Subject: [PATCH 9/9] Update geofencing.yaml Update of trailing spaces removal --- code/API_definitions/geofencing.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/API_definitions/geofencing.yaml b/code/API_definitions/geofencing.yaml index 7c00de80..8b162784 100644 --- a/code/API_definitions/geofencing.yaml +++ b/code/API_definitions/geofencing.yaml @@ -40,12 +40,12 @@ info: - ``org.camaraproject.geofencing.v0.area-entered`` - Event triggered when the device enters the given area - ``org.camaraproject.geofencing.v0.area-left`` - Event triggered when the device leaves the given area - - Note: Additionally to these list, ``org.camaraproject.geofencing.v0.subscription-ends`` notification `type` is sent when the subscription ends. - This notification does not require dedicated subscription. + + Note: Additionally to these list, ``org.camaraproject.geofencing.v0.subscription-ends`` notification `type` is sent when the subscription ends. + This notification does not require dedicated subscription. It is used when: - - the subscription expire time (optionally set by the requester) has been reached + - the subscription expire time (optionally set by the requester) has been reached - the maximum number of subscription events (optionally set by the requester) has been reached - the API server has to stop sending notification prematurely @@ -111,7 +111,7 @@ paths: The Device Location server will call this endpoint whenever a device geofencing related event occurs. operationId: postNotification parameters: - - $ref: '#/components/parameters/x-correlator' + - $ref: '#/components/parameters/x-correlator' requestBody: required: true content: @@ -130,7 +130,7 @@ paths: description: Successful notification headers: x-correlator: - $ref: '#/components/headers/x-correlator' + $ref: '#/components/headers/x-correlator' "400": $ref: "#/components/responses/Generic400" "401":