Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rulesets): validate channel servers, server securities and operation securities #2122

Merged
merged 6 commits into from Jun 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
106 changes: 106 additions & 0 deletions docs/reference/asyncapi-rules.md
Expand Up @@ -30,6 +30,48 @@ All channel parameters should be defined in the `parameters` object of the chann

**Recommended:** Yes

### asyncapi-channel-servers

Channel servers must be defined in the `servers` object.

**Bad Example**

```yaml
asyncapi: "2.0.0"
info:
title: Awesome API
description: A very well defined API
version: "1.0"
servers:
production:
url: "stoplight.io"
protocol: "https"
channels:
hello:
servers:
- development
```

**Good Example**

```yaml
asyncapi: "2.0.0"
info:
title: Awesome API
description: A very well defined API
version: "1.0"
servers:
production:
url: "stoplight.io"
protocol: "https"
channels:
hello:
servers:
- production
```

**Recommended:** Yes

### asyncapi-headers-schema-type-object

The schema definition of the application headers must be of type “object”.
Expand Down Expand Up @@ -219,6 +261,38 @@ This operation ID is essentially a reference for the operation. Tools may use it

**Recommended:** Yes

### asyncapi-operation-security

Operation `security` values must match a scheme defined in the `components.securitySchemes` object. It also checks if there are `oauth2` scopes that have been defined for the given security.

**Recommended:** Yes

**Good Example**

```yaml
channels:
"user/signup":
publish:
security:
- petstore_auth: []
components:
securitySchemes:
petstore_auth: ...
```

**Bad Example**

```yaml
channels:
"user/signup":
publish:
security:
- not_defined: []
components:
securitySchemes:
petstore_auth: ...
```

### asyncapi-parameter-description

Parameter objects should have a `description`.
Expand Down Expand Up @@ -369,6 +443,38 @@ Server URL should not point at example.com.

**Recommended:** No

### asyncapi-server-security

Server `security` values must match a scheme defined in the `components.securitySchemes` object. It also checks if there are `oauth2` scopes that have been defined for the given security.

jonaslagoni marked this conversation as resolved.
Show resolved Hide resolved
**Recommended:** Yes

**Good Example**

```yaml
servers:
production:
url: test.mosquitto.org
security:
- petstore_auth: []
components:
securitySchemes:
petstore_auth: ...
```

**Bad Example**

```yaml
servers:
production:
url: test.mosquitto.org
security:
- not_defined: []
components:
securitySchemes:
petstore_auth: ...
```

### asyncapi-server-variables

All server URL variables should be defined in the `variables` object of the server. They should also not contain redundant variables that do not exist in the server address.
Expand Down
@@ -0,0 +1,141 @@
import { DiagnosticSeverity } from '@stoplight/types';
import testRule from './__helpers__/tester';

testRule('asyncapi-channel-servers', [
{
name: 'valid case',
document: {
asyncapi: '2.2.0',
servers: {
development: {},
production: {},
},
channels: {
channel: {
servers: ['development'],
},
},
},
errors: [],
},

{
name: 'valid case - without defined servers',
document: {
asyncapi: '2.2.0',
servers: {
development: {},
production: {},
},
channels: {
channel: {},
},
},
errors: [],
},

{
name: 'valid case - without defined servers in the root',
document: {
asyncapi: '2.2.0',
channels: {
channel: {},
},
},
errors: [],
},

{
name: 'valid case - without defined channels in the root',
document: {
asyncapi: '2.2.0',
servers: {
development: {},
production: {},
},
},
errors: [],
},

{
name: 'valid case - with empty array',
document: {
asyncapi: '2.2.0',
servers: {
development: {},
production: {},
},
channels: {
channel: {
servers: [],
},
},
},
errors: [],
},

{
name: 'invalid case',
document: {
asyncapi: '2.2.0',
servers: {
development: {},
production: {},
},
channels: {
channel: {
servers: ['another-server'],
},
},
},
errors: [
{
message: 'Channel contains server that are not defined on the "servers" object.',
path: ['channels', 'channel', 'servers', '0'],
severity: DiagnosticSeverity.Error,
},
],
},

{
name: 'invalid case - one server is defined, another one not',
document: {
asyncapi: '2.2.0',
servers: {
development: {},
production: {},
},
channels: {
channel: {
servers: ['production', 'another-server'],
},
},
},
errors: [
{
message: 'Channel contains server that are not defined on the "servers" object.',
path: ['channels', 'channel', 'servers', '1'],
severity: DiagnosticSeverity.Error,
},
],
},

{
name: 'invalid case - without defined servers',
document: {
asyncapi: '2.2.0',
channels: {
channel: {
servers: ['production'],
},
},
},
errors: [
{
message: 'Channel contains server that are not defined on the "servers" object.',
path: ['channels', 'channel', 'servers', '0'],
severity: DiagnosticSeverity.Error,
},
],
},
]);