@toa.io/extensions.exposition 1.0.0-alpha.20 → 1.0.0-alpha.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/components/context.toa.yaml +2 -2
  2. package/components/identity.basic/manifest.toa.yaml +18 -9
  3. package/components/identity.basic/operations/authenticate.d.ts +5 -1
  4. package/components/identity.basic/operations/authenticate.js +2 -2
  5. package/components/identity.basic/operations/authenticate.js.map +1 -1
  6. package/components/identity.basic/operations/incept.d.ts +11 -0
  7. package/components/identity.basic/operations/incept.js +13 -0
  8. package/components/identity.basic/operations/incept.js.map +1 -0
  9. package/components/identity.basic/operations/transit.d.ts +3 -3
  10. package/components/identity.basic/operations/transit.js +5 -3
  11. package/components/identity.basic/operations/transit.js.map +1 -1
  12. package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
  13. package/components/identity.basic/operations/types.d.ts +2 -0
  14. package/components/identity.basic/source/authenticate.ts +12 -5
  15. package/components/identity.basic/source/incept.ts +22 -0
  16. package/components/identity.basic/source/transit.ts +7 -5
  17. package/components/identity.basic/source/types.ts +2 -0
  18. package/components/identity.federation/manifest.toa.yaml +28 -11
  19. package/components/identity.federation/operations/authenticate.d.ts +2 -2
  20. package/components/identity.federation/operations/authenticate.js +6 -5
  21. package/components/identity.federation/operations/authenticate.js.map +1 -1
  22. package/components/identity.federation/operations/incept.d.ts +11 -0
  23. package/components/identity.federation/operations/{create.js → incept.js} +6 -7
  24. package/components/identity.federation/operations/incept.js.map +1 -0
  25. package/components/identity.federation/operations/lib/jwt.js +3 -3
  26. package/components/identity.federation/operations/lib/jwt.js.map +1 -1
  27. package/components/identity.federation/operations/schemas.d.ts +7 -3
  28. package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
  29. package/components/identity.federation/operations/types.d.ts +5 -0
  30. package/components/identity.federation/source/authenticate.ts +9 -6
  31. package/components/identity.federation/source/{create.ts → incept.ts} +10 -9
  32. package/components/identity.federation/source/lib/jwt.test.ts +2 -2
  33. package/components/identity.federation/source/lib/jwt.ts +3 -3
  34. package/components/identity.federation/source/schemas.ts +7 -3
  35. package/components/identity.federation/source/types.ts +6 -0
  36. package/components/identity.tokens/manifest.toa.yaml +7 -1
  37. package/components/identity.tokens/operations/authenticate.d.ts +2 -2
  38. package/components/identity.tokens/operations/authenticate.js +5 -2
  39. package/components/identity.tokens/operations/authenticate.js.map +1 -1
  40. package/components/identity.tokens/operations/decrypt.js +1 -0
  41. package/components/identity.tokens/operations/decrypt.js.map +1 -1
  42. package/components/identity.tokens/operations/encrypt.js +1 -0
  43. package/components/identity.tokens/operations/encrypt.js.map +1 -1
  44. package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -1
  45. package/components/identity.tokens/operations/types.d.ts +7 -0
  46. package/components/identity.tokens/source/authenticate.test.ts +11 -4
  47. package/components/identity.tokens/source/authenticate.ts +7 -3
  48. package/components/identity.tokens/source/decrypt.test.ts +5 -3
  49. package/components/identity.tokens/source/decrypt.ts +9 -8
  50. package/components/identity.tokens/source/encrypt.test.ts +4 -1
  51. package/components/identity.tokens/source/encrypt.ts +1 -0
  52. package/components/identity.tokens/source/types.ts +8 -0
  53. package/documentation/authorities.md +53 -0
  54. package/documentation/components.md +3 -3
  55. package/documentation/identity.md +17 -22
  56. package/documentation/require.md +1 -1
  57. package/documentation/vary.md +5 -11
  58. package/features/access.feature +55 -7
  59. package/features/annotation.feature +1 -0
  60. package/features/authorities.basic.feature +140 -0
  61. package/features/authorities.feature +32 -0
  62. package/features/authorities.federation.feature +99 -0
  63. package/features/authorities.tokens.feature +118 -0
  64. package/features/body.feature +2 -0
  65. package/features/cache.feature +39 -5
  66. package/features/cors.feature +4 -0
  67. package/features/directives.feature +3 -0
  68. package/features/dynamic.feature +4 -0
  69. package/features/errors.feature +12 -1
  70. package/features/etag.feature +6 -0
  71. package/features/identity.bans.feature +12 -3
  72. package/features/identity.basic.feature +34 -15
  73. package/features/identity.feature +7 -2
  74. package/features/identity.federation.feature +14 -4
  75. package/features/identity.roles.feature +29 -17
  76. package/features/identity.tokens.feature +18 -6
  77. package/features/io.feature +9 -0
  78. package/features/octets.entries.feature +8 -0
  79. package/features/octets.feature +22 -0
  80. package/features/octets.meta.feature +3 -0
  81. package/features/octets.workflows.feature +13 -0
  82. package/features/queries.feature +8 -0
  83. package/features/require.feature +3 -0
  84. package/features/response.feature +5 -2
  85. package/features/routes.feature +7 -0
  86. package/features/steps/Gateway.ts +23 -6
  87. package/features/streams.feature +1 -0
  88. package/features/timing.feature +3 -0
  89. package/features/vary.feature +49 -0
  90. package/package.json +7 -7
  91. package/readme.md +19 -14
  92. package/schemas/annotation.cos.yaml +1 -1
  93. package/source/Annotation.ts +3 -3
  94. package/source/Endpoint.ts +1 -1
  95. package/source/Factory.ts +8 -10
  96. package/source/Gateway.ts +2 -6
  97. package/source/HTTP/Context.ts +3 -1
  98. package/source/HTTP/Server.ts +23 -26
  99. package/source/HTTP/exceptions.ts +6 -0
  100. package/source/Query.ts +9 -5
  101. package/source/deployment.ts +25 -21
  102. package/source/directives/auth/Authorization.ts +18 -8
  103. package/source/directives/auth/Incept.ts +2 -1
  104. package/source/directives/vary/embeddings/Authority.ts +8 -0
  105. package/source/directives/vary/embeddings/index.ts +3 -1
  106. package/source/schemas.ts +1 -1
  107. package/transpiled/Annotation.d.ts +3 -3
  108. package/transpiled/Endpoint.js +1 -1
  109. package/transpiled/Endpoint.js.map +1 -1
  110. package/transpiled/Factory.js +9 -8
  111. package/transpiled/Factory.js.map +1 -1
  112. package/transpiled/Gateway.js.map +1 -1
  113. package/transpiled/HTTP/Context.d.ts +2 -1
  114. package/transpiled/HTTP/Context.js +3 -1
  115. package/transpiled/HTTP/Context.js.map +1 -1
  116. package/transpiled/HTTP/Server.d.ts +8 -1
  117. package/transpiled/HTTP/Server.js +14 -20
  118. package/transpiled/HTTP/Server.js.map +1 -1
  119. package/transpiled/HTTP/exceptions.d.ts +3 -0
  120. package/transpiled/HTTP/exceptions.js +7 -1
  121. package/transpiled/HTTP/exceptions.js.map +1 -1
  122. package/transpiled/Query.js +2 -2
  123. package/transpiled/Query.js.map +1 -1
  124. package/transpiled/deployment.d.ts +1 -1
  125. package/transpiled/deployment.js +21 -19
  126. package/transpiled/deployment.js.map +1 -1
  127. package/transpiled/directives/auth/Authorization.js +9 -4
  128. package/transpiled/directives/auth/Authorization.js.map +1 -1
  129. package/transpiled/directives/auth/Incept.js +2 -1
  130. package/transpiled/directives/auth/Incept.js.map +1 -1
  131. package/transpiled/directives/vary/embeddings/Authority.d.ts +5 -0
  132. package/transpiled/directives/vary/embeddings/Authority.js +10 -0
  133. package/transpiled/directives/vary/embeddings/Authority.js.map +1 -0
  134. package/transpiled/directives/vary/embeddings/index.js +3 -1
  135. package/transpiled/directives/vary/embeddings/index.js.map +1 -1
  136. package/transpiled/schemas.d.ts +1 -1
  137. package/transpiled/schemas.js +2 -2
  138. package/transpiled/schemas.js.map +1 -1
  139. package/transpiled/tsconfig.tsbuildinfo +1 -1
  140. package/components/identity.basic/operations/create.d.ts +0 -10
  141. package/components/identity.basic/operations/create.js +0 -10
  142. package/components/identity.basic/operations/create.js.map +0 -1
  143. package/components/identity.basic/source/create.ts +0 -18
  144. package/components/identity.federation/operations/create.d.ts +0 -10
  145. package/components/identity.federation/operations/create.js.map +0 -1
  146. package/source/HTTP/Server.test.ts +0 -126
@@ -8,6 +8,7 @@ let output: DecryptOutput
8
8
  let authenticate: Authenticate
9
9
 
10
10
  const identity: Identity = { id: generate() }
11
+ const authority = generate()
11
12
 
12
13
  beforeEach(() => {
13
14
  configuration = {
@@ -36,9 +37,12 @@ it.each([
36
37
  const iat = new Date(now - configuration.refresh * 1000 + shift).toISOString()
37
38
  const exp = new Date(now + 1000).toISOString()
38
39
 
39
- output = { identity, exp, iat, refresh: false }
40
+ output = { authority, identity, exp, iat, refresh: false }
40
41
 
41
- const result = await authenticate.execute('')
42
+ const result = await authenticate.execute({
43
+ authority,
44
+ credentials: ''
45
+ })
42
46
 
43
47
  expect(result).toEqual({ identity, refresh: expected })
44
48
  })
@@ -48,9 +52,12 @@ it.each([true, false])('should return stale: %s',
48
52
  const iat = new Date().toISOString()
49
53
  const exp = new Date(Date.now() + 1000).toISOString()
50
54
 
51
- output = { identity, exp, iat, refresh }
55
+ output = { authority, identity, exp, iat, refresh }
52
56
 
53
- const result = await authenticate.execute('')
57
+ const result = await authenticate.execute({
58
+ authority,
59
+ credentials: ''
60
+ })
54
61
 
55
62
  expect(result).toEqual({ identity, refresh })
56
63
  })
@@ -1,5 +1,5 @@
1
1
  import { type Maybe, type Operation } from '@toa.io/types'
2
- import { type AuthenticateOutput, type Context } from './types'
2
+ import type { AuthenticateInput, AuthenticateOutput, Context } from './types'
3
3
 
4
4
  export class Computation implements Operation {
5
5
  private refresh: number = 0
@@ -12,12 +12,15 @@ export class Computation implements Operation {
12
12
  this.observe = context.local.observe
13
13
  }
14
14
 
15
- public async execute (token: string): Promise<Maybe<AuthenticateOutput>> {
16
- const claim = await this.decrypt({ input: token })
15
+ public async execute (input: AuthenticateInput): Promise<Maybe<AuthenticateOutput>> {
16
+ const claim = await this.decrypt({ input: input.credentials })
17
17
 
18
18
  if (claim instanceof Error)
19
19
  return claim
20
20
 
21
+ if (claim.authority !== input.authority)
22
+ return ERR_AUTHORITY
23
+
21
24
  const identity = claim.identity
22
25
  const iat = new Date(claim.iat).getTime()
23
26
  const transient = claim.exp !== undefined
@@ -39,4 +42,5 @@ export class Computation implements Operation {
39
42
  }
40
43
  }
41
44
 
45
+ const ERR_AUTHORITY = new Error('AUTHORITY_MISMATCH')
42
46
  const ERR_TOKEN_REVOKED = new Error('TOKEN_REVOKED')
@@ -7,6 +7,8 @@ let configuration: Configuration
7
7
  let context: Context
8
8
  let encrypt: Encrypt
9
9
 
10
+ const authority = generate()
11
+
10
12
  beforeEach(() => {
11
13
  configuration = {
12
14
  key0: 'k3.local.m28p8SrbS467t-2IUjQuSOqmjvi24TbXhyjAW_dOrog',
@@ -25,14 +27,14 @@ it('should decrypt', async () => {
25
27
  const identity: Identity = { id: generate() }
26
28
  const lifetime = 100
27
29
 
28
- const reply = await encrypt.execute({ identity, lifetime })
30
+ const reply = await encrypt.execute({ authority, identity, lifetime })
29
31
 
30
32
  if (reply === undefined)
31
33
  throw new Error('?')
32
34
 
33
35
  const decrypted = await decrypt(reply, context)
34
36
 
35
- expect(decrypted).toMatchObject({ identity, refresh: false })
37
+ expect(decrypted).toMatchObject({ authority, identity, refresh: false })
36
38
  })
37
39
 
38
40
  it('should decrypt with key1', async () => {
@@ -48,7 +50,7 @@ it('should decrypt with key1', async () => {
48
50
  const identity: Identity = { id: generate() }
49
51
  const lifetime = 100
50
52
 
51
- const encrypted = await encrypt.execute({ identity, lifetime })
53
+ const encrypted = await encrypt.execute({ authority, identity, lifetime })
52
54
 
53
55
  if (encrypted === undefined)
54
56
  throw new Error('?')
@@ -2,8 +2,7 @@ import { V3 } from 'paseto'
2
2
  import { type Maybe } from '@toa.io/types'
3
3
  import { type Context, type Claim, type DecryptOutput } from './types'
4
4
 
5
- export async function computation (token: string, context: Context):
6
- Promise<Maybe<DecryptOutput>> {
5
+ export async function computation (token: string, context: Context): Promise<Maybe<DecryptOutput>> {
7
6
  let refresh = false
8
7
  let claim = await decrypt(token, context.configuration.key0)
9
8
 
@@ -14,12 +13,14 @@ Promise<Maybe<DecryptOutput>> {
14
13
 
15
14
  if (claim === null)
16
15
  return ERR_INVALID_TOKEN
17
- else return {
18
- identity: claim.identity,
19
- iat: claim.iat,
20
- exp: claim.exp,
21
- refresh
22
- }
16
+ else
17
+ return {
18
+ authority: claim.aud,
19
+ identity: claim.identity,
20
+ iat: claim.iat,
21
+ exp: claim.exp,
22
+ refresh
23
+ }
23
24
  }
24
25
 
25
26
  async function decrypt (token: string, key: string): Promise<Claim | null> {
@@ -8,6 +8,7 @@ import { type Context, type Identity } from './types'
8
8
  let encrypt: Encrypt
9
9
 
10
10
  const context: Context = {} as unknown as Context
11
+ const authority = generate()
11
12
 
12
13
  beforeEach(() => {
13
14
  context.configuration = {
@@ -25,6 +26,7 @@ it('should encrypt with given lifetime', async () => {
25
26
  const lifetime = 0.1
26
27
 
27
28
  const encrypted = await encrypt.execute({
29
+ authority,
28
30
  identity,
29
31
  lifetime
30
32
  })
@@ -32,7 +34,7 @@ it('should encrypt with given lifetime', async () => {
32
34
  if (encrypted === undefined)
33
35
  throw new Error('?')
34
36
 
35
- await expect(decrypt(encrypted, context)).resolves.toMatchObject({ identity })
37
+ await expect(decrypt(encrypted, context)).resolves.toMatchObject({ authority, identity })
36
38
 
37
39
  await timeout(lifetime * 1000)
38
40
 
@@ -44,6 +46,7 @@ it('should encrypt without lifetime INSECURE', async () => {
44
46
  const lifetime = 0
45
47
 
46
48
  const encrypted = await encrypt.execute({
49
+ authority,
47
50
  identity,
48
51
  lifetime
49
52
  })
@@ -20,6 +20,7 @@ export class Effect implements Operation {
20
20
 
21
21
  const payload: Partial<Claim> = {
22
22
  identity: input.identity,
23
+ aud: input.authority,
23
24
  exp
24
25
  }
25
26
 
@@ -23,17 +23,24 @@ export interface Identity extends Record<string, any> {
23
23
  id: string
24
24
  }
25
25
 
26
+ export interface AuthenticateInput {
27
+ authority: string
28
+ credentials: string
29
+ }
30
+
26
31
  export interface AuthenticateOutput {
27
32
  identity: Identity
28
33
  refresh: boolean
29
34
  }
30
35
 
31
36
  export interface EncryptInput {
37
+ authority: string
32
38
  identity: Identity
33
39
  lifetime?: number
34
40
  }
35
41
 
36
42
  export interface DecryptOutput {
43
+ authority: string
37
44
  identity: Identity
38
45
  iat: string
39
46
  exp?: string
@@ -42,6 +49,7 @@ export interface DecryptOutput {
42
49
 
43
50
  export interface Claim {
44
51
  identity: Identity
52
+ aud: string
45
53
  iat: string
46
54
  exp?: string
47
55
  }
@@ -0,0 +1,53 @@
1
+ # Authorities
2
+
3
+ Authorities are a mechanism that allows serving multiple domains from a single instance of the
4
+ application.
5
+
6
+ ## Definition
7
+
8
+ The `authorities` definition is a map of authority identifiers to the `:authority` pseudo-header
9
+ values.
10
+
11
+ ```yaml
12
+ # context.toa.yaml
13
+
14
+ exposition:
15
+ authorities:
16
+ one: the.one.com
17
+ two: the.two.com
18
+ ```
19
+
20
+ ## Ingress
21
+
22
+ Each host in the authority definition is used to create a Kubernetes Ingress resource.
23
+
24
+ > If the application is accessed with the `:authority` that does not match the authority definition,
25
+ > the response with `404` status code is returned.
26
+
27
+ ## Embedding
28
+
29
+ To pass the requested authority to the operation call, [`vary:embed` directive](vary.md#embeddings)
30
+ can be used.
31
+
32
+ ```yaml
33
+ # manifest.toa.yaml
34
+
35
+ exposition:
36
+ /:
37
+ GET:
38
+ vary:embed:
39
+ app: authority
40
+ endpoint: observe
41
+ ```
42
+
43
+ ## Identity
44
+
45
+ Credentials stored or issued by the [authentication system](identity.md) are associated with an
46
+ authority.
47
+ Credentials in one authority are not valid in another,
48
+ or may be associated with a different Identity; in other words, Identity exists in the context of an
49
+ authority.
50
+
51
+ > :warning:<br/>
52
+ > Changing the authority identifier will break compatibility with existing stored or issued
53
+ > credentials.
@@ -20,7 +20,7 @@ and pepper.
20
20
  configuration:
21
21
  identity.basic:
22
22
  rounds: 10 # salt rounds
23
- peper: '' # hashing pepper
23
+ pepper: '' # hashing pepper
24
24
  ```
25
25
 
26
26
  ### Credentials constraints
@@ -111,8 +111,8 @@ secrets.
111
111
  configuration:
112
112
  identity.federation:
113
113
  trust:
114
- - issuer: https://token.actions.githubusercontent.com
115
- audience:
114
+ - iss: https://token.actions.githubusercontent.com
115
+ aud:
116
116
  - https://github.com/tinovyatkin
117
117
  - https://github.com/temich
118
118
 
@@ -1,36 +1,30 @@
1
1
  # Identity
2
2
 
3
3
  Identity is the fundamental entity within an authentication system that represents the **unique
4
- identifier** of an
5
- individual, organization, application or device.
4
+ identifier** of an individual, organization, application or device.
6
5
 
7
- In order to prove its Identity, the request originator must provide a valid _credentials_ that are
8
- associated with that
9
- Identity.
6
+ To prove its Identity, the request originator must provide a valid _credentials_ that are associated
7
+ with that Identity.
10
8
 
11
9
  Identity is intrinsically linked to credentials, as an Identity is established only when the first
12
- set of credentials
13
- for that Identity is created.
10
+ set of credentials for that Identity is created.
14
11
  In other words, the creation of credentials marks the inception of an Identity.
15
12
  Once the last credentials are removed from the Identity, it ceases to exist.
16
13
  Without credentials, there is no basis for defining or asserting an Identity.
17
14
 
18
15
  ## Authentication
19
16
 
20
- The Authenticaiton system resolves provided credentials to an Identity using one of the supported
21
- authentication
22
- schemes.
17
+ The Authentication system resolves provided credentials to an Identity using one of the supported
18
+ authentication schemes.
23
19
 
24
20
  The Authentication is request-agnostic, meaning it does not depend on the specific URL being
25
- requested or the content of
26
- the request body.
21
+ requested or the content of the request body.
27
22
  The only information it handles is the value of the `Authorization` header.
28
23
 
29
- > Except for its own [management resources](#persistent-credentials).
24
+ > Except for its own [management resources](components.md).
30
25
 
31
26
  If the provided credentials are not valid or not associated with an Identity, then Authentication
32
- interrupts request
33
- processing and responds with an authentication error.
27
+ interrupts request processing and responds with an authentication error.
34
28
 
35
29
  ### Basic scheme
36
30
 
@@ -52,8 +46,8 @@ Authrization: Token v4.local.eyJzdWIiOiJqb2hu...
52
46
 
53
47
  The `Token` is the **primary** authentication scheme.
54
48
  If request originators use an alternative authentication scheme, they will receive a response
55
- containing `Token`
56
- credentials and will be required to switch to the `Token` scheme for any subsequent requests.
49
+ containing `Token`credentials and will be required to switch to the `Token` scheme for any
50
+ subsequent requests.
57
51
  Continued use of other authentication schemes will result in temporary blocking of requests.
58
52
 
59
53
  See [`identity.tokens` component](components.md#stateless-tokens).
@@ -69,7 +63,8 @@ to [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.ht
69
63
  Authorization: Bearer eyJhbGciOiJIUzI1...
70
64
  ```
71
65
 
72
- Trusted providers are specified using the `identity.federation` property within the configuration annotation.
66
+ Trusted providers are specified using the `identity.federation` property within the configuration
67
+ annotation.
73
68
 
74
69
  ```yaml
75
70
  # context.toa.yaml
@@ -77,13 +72,13 @@ Trusted providers are specified using the `identity.federation` property within
77
72
  configuration:
78
73
  identity.federation:
79
74
  trust:
80
- - issuer: https://accounts.google.com
81
- audience:
75
+ - iss: https://accounts.google.com
76
+ aud:
82
77
  - <GOOGLE_CLIENT_ID>
83
78
 
84
- - issuer: https://appleid.apple.com
79
+ - iss: https://appleid.apple.com
85
80
 
86
- - issuer: private.entity
81
+ - iss: private.entity
87
82
  secrets:
88
83
  HS384:
89
84
  key0: <THE-SECRET-STRING-FOR-HS384>
@@ -10,6 +10,6 @@ requires a set of headers to be present.
10
10
  ```yaml
11
11
  exposition:
12
12
  /:id:
13
- requires:header: if-match # enforce concurrency control
13
+ require:header: if-match # enforce concurrency control
14
14
  PUT: transit
15
15
  ```
@@ -7,17 +7,15 @@ operation call.
7
7
 
8
8
  ```yaml
9
9
  exposition:
10
- realms:
11
- toa: the.toa.io
12
10
  /:group:
13
11
  vary:languages: [en, fr]
14
12
  GET:
15
13
  vary:embed:
16
- lang: language # predefined embeddings
17
- realm: realm
14
+ app: authority # predefined embeddings
15
+ lang: language
18
16
  token: :x-access-token # raw header value
19
17
  group: /:group # route parameter
20
- endpoint: dummies.get
18
+ endpoint: observe
21
19
  ```
22
20
 
23
21
  ## Embeddings
@@ -31,13 +29,9 @@ If the value is an array, the first non-empty embedding function's result is use
31
29
  > If a property is already present in the input, the embedded value will overwrite its current
32
30
  > value.
33
31
 
34
- ### Realm
32
+ ### Authority
35
33
 
36
- Realm is an identifier of a domain used to access the Exposition.
37
- The list of domains is defined by the `vary:realms` directive,
38
- which is a map of realm names to their domain names.
39
-
40
- The `realm` embedding substitutes the realm identified based on the `host` request header.
34
+ The `authority` embedding substitutes request [authority identifier](authorities.md).
41
35
 
42
36
  ### Language
43
37
 
@@ -5,9 +5,9 @@ Feature: Access authorization
5
5
  Given the `identity.basic` database contains:
6
6
  # developer:secret
7
7
  # user:12345
8
- | _id | username | password |
9
- | efe3a65ebbee47ed95a73edd911ea328 | developer | $2b$10$ZRSKkgZoGnrcTNA5w5eCcu3pxDzdTduhteVYXcp56AaNcilNkwJ.O |
10
- | e8e4f9c2a68d419b861403d71fabc915 | user | $2b$10$Frszmrmsz9iwSXzBbRRMKeDVKsNxozkrLNSsN.SnVC.KPxLtQr/bK |
8
+ | _id | authority | username | password |
9
+ | efe3a65ebbee47ed95a73edd911ea328 | nex | developer | $2b$10$ZRSKkgZoGnrcTNA5w5eCcu3pxDzdTduhteVYXcp56AaNcilNkwJ.O |
10
+ | e8e4f9c2a68d419b861403d71fabc915 | nex | user | $2b$10$Frszmrmsz9iwSXzBbRRMKeDVKsNxozkrLNSsN.SnVC.KPxLtQr/bK |
11
11
  And the `identity.bans` database is empty
12
12
 
13
13
  Scenario: Deny by default
@@ -21,6 +21,7 @@ Feature: Access authorization
21
21
  When the following request is received:
22
22
  """
23
23
  GET / HTTP/1.1
24
+ host: nex.toa.io
24
25
  """
25
26
  Then the following reply is sent:
26
27
  """
@@ -40,6 +41,7 @@ Feature: Access authorization
40
41
  When the following request is received:
41
42
  """
42
43
  GET / HTTP/1.1
44
+ host: nex.toa.io
43
45
  accept: application/yaml
44
46
  """
45
47
  Then the following reply is sent:
@@ -62,6 +64,7 @@ Feature: Access authorization
62
64
  When the following request is received:
63
65
  """
64
66
  GET / HTTP/1.1
67
+ host: nex.toa.io
65
68
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
66
69
  """
67
70
  Then the following reply is sent:
@@ -83,6 +86,7 @@ Feature: Access authorization
83
86
  When the following request is received:
84
87
  """
85
88
  GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
89
+ host: nex.toa.io
86
90
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
87
91
  accept: application/yaml
88
92
  """
@@ -96,6 +100,7 @@ Feature: Access authorization
96
100
  When the following request is received:
97
101
  """
98
102
  GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
103
+ host: nex.toa.io
99
104
  authorization: Basic dXNlcjoxMjM0NQ==
100
105
  accept: application/yaml
101
106
  """
@@ -122,6 +127,7 @@ Feature: Access authorization
122
127
  # identity with `developer` and `user` roles
123
128
  """
124
129
  GET / HTTP/1.1
130
+ host: nex.toa.io
125
131
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
126
132
  accept: application/yaml
127
133
  """
@@ -136,6 +142,7 @@ Feature: Access authorization
136
142
  # identity with no roles
137
143
  """
138
144
  GET / HTTP/1.1
145
+ host: nex.toa.io
139
146
  authorization: Basic dXNlcjoxMjM0NQ==
140
147
  """
141
148
  Then the following reply is sent:
@@ -164,6 +171,7 @@ Feature: Access authorization
164
171
  When the following request is received:
165
172
  """
166
173
  GET /nested/ HTTP/1.1
174
+ host: nex.toa.io
167
175
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
168
176
  accept: text/plain
169
177
  """
@@ -177,6 +185,7 @@ Feature: Access authorization
177
185
  When the following request is received:
178
186
  """
179
187
  GET /javascript/ HTTP/1.1
188
+ host: nex.toa.io
180
189
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
181
190
  """
182
191
  Then the following reply is sent:
@@ -203,6 +212,7 @@ Feature: Access authorization
203
212
  # identity with `developer` and `user` roles
204
213
  """
205
214
  GET / HTTP/1.1
215
+ host: nex.toa.io
206
216
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
207
217
  accept: application/yaml
208
218
  """
@@ -240,6 +250,7 @@ Feature: Access authorization
240
250
  When the following request is received:
241
251
  """
242
252
  GET /rust/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
253
+ host: nex.toa.io
243
254
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
244
255
  accept: application/yaml
245
256
  """
@@ -253,6 +264,7 @@ Feature: Access authorization
253
264
  When the following request is received:
254
265
  """
255
266
  GET /javascript/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
267
+ host: nex.toa.io
256
268
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
257
269
  """
258
270
  Then the following reply is sent:
@@ -273,8 +285,37 @@ Feature: Access authorization
273
285
  """
274
286
  When the following request is received:
275
287
  """
276
- GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
277
- authorization: Token v3.local.9oEtVJkfRw4cOJ8M4DxuVuAN29dGT26XMYyPAoXtwrkdkiJVSVj46sMNAOdlxwKGszJZV_ReOL26dxDVlsQ7QAIuRhRPlvsHYNOhcD-LApoAXV0S3IK16EMoEv7tE9z70FCLC3WoIW9RIQ8PR3uZhAdhSgBilsVOpWrk4XtnfCIlVwhYMKu79a66oZZhV2Q7Kl3nfYsf84-6rAL_1H0MsqCDUHVXuIg
288
+ GET /identity/ HTTP/1.1
289
+ host: nex.toa.io
290
+ authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
291
+ accept: application/yaml
292
+ """
293
+ Then the following reply is sent:
294
+ """
295
+ 200 OK
296
+ authorization: Token ${{ developer.token }}
297
+
298
+ id: ${{ developer.id }}
299
+ """
300
+ When the following request is received:
301
+ """
302
+ GET /identity/ HTTP/1.1
303
+ host: nex.toa.io
304
+ authorization: Basic dXNlcjoxMjM0NQ==
305
+ accept: application/yaml
306
+ """
307
+ Then the following reply is sent:
308
+ """
309
+ 200 OK
310
+ authorization: Token ${{ user.token }}
311
+
312
+ id: ${{ user.id }}
313
+ """
314
+ When the following request is received:
315
+ """
316
+ GET /${{ developer.id }}/ HTTP/1.1
317
+ host: nex.toa.io
318
+ authorization: Token ${{ developer.token }}
278
319
  accept: application/yaml
279
320
  """
280
321
  Then the following reply is sent:
@@ -290,8 +331,9 @@ Feature: Access authorization
290
331
  """
291
332
  When the following request is received:
292
333
  """
293
- GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
294
- authorization: Token v3.local.cjlxn4IJ9hI92KuksguzDx7_kYxgDFFGFnfNchf0cWnmos34dqX2XpTAUBd-LqgqfuH-lVGfNvjBUkw5JtHRBiIAVaPHF3Ncc0eafwgH2DPme9pndZL92fWryGnJ-sMHA28Q6UcXsIfhgd2JZ0n-585SBhwlosC3gKTcVHK7XNljeaTen4jZPw8uY-pdbsm6dDq3aKMzl8K78_BTTfiNPG2cI_aNuHw
334
+ GET /${{ user.id }}/ HTTP/1.1
335
+ host: nex.toa.io
336
+ authorization: Token ${{ developer.token }}
295
337
  accept: application/yaml
296
338
  """
297
339
  Then the following reply is sent:
@@ -315,6 +357,7 @@ Feature: Access authorization
315
357
  When the following request is received:
316
358
  """
317
359
  GET / HTTP/1.1
360
+ host: nex.toa.io
318
361
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
319
362
  accept: application/yaml
320
363
  """
@@ -329,6 +372,7 @@ Feature: Access authorization
329
372
  When the following request is received:
330
373
  """
331
374
  GET / HTTP/1.1
375
+ host: nex.toa.io
332
376
  authorization: Token ${{ token }}
333
377
  accept: application/yaml
334
378
  """
@@ -355,6 +399,7 @@ Feature: Access authorization
355
399
  When the following request is received:
356
400
  """
357
401
  GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
402
+ host: nex.toa.io
358
403
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
359
404
  accept: application/yaml
360
405
  """
@@ -368,6 +413,7 @@ Feature: Access authorization
368
413
  When the following request is received:
369
414
  """
370
415
  GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
416
+ host: nex.toa.io
371
417
  authorization: Token v3.local.9oEtVJkfRw4cOJ8M4DxuVuAN29dGT26XMYyPAoXtwrkdkiJVSVj46sMNAOdlxwKGszJZV_ReOL26dxDVlsQ7QAIuRhRPlvsHYNOhcD-LApoAXV0S3IK16EMoEv7tE9z70FCLC3WoIW9RIQ8PR3uZhAdhSgBilsVOpWrk4XtnfCIlVwhYMKu79a66oZZhV2Q7Kl3nfYsf84-6rAL_1H0MsqCDUHVXuIg
372
418
  accept: text/plain
373
419
  """
@@ -390,6 +436,7 @@ Feature: Access authorization
390
436
  When the following request is received:
391
437
  """
392
438
  POST /identity/roles/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
439
+ host: nex.toa.io
393
440
  content-type: application/yaml
394
441
 
395
442
  role: developer
@@ -414,6 +461,7 @@ Feature: Access authorization
414
461
  When the following request is received:
415
462
  """
416
463
  GET /echo/ HTTP/1.1
464
+ host: nex.toa.io
417
465
  authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
418
466
  accept: application/yaml
419
467
  """
@@ -18,6 +18,7 @@ Feature: Annotation
18
18
  When the following request is received:
19
19
  """
20
20
  GET /foo/ HTTP/1.1
21
+ host: nex.toa.io
21
22
  accept: application/yaml
22
23
  """
23
24
  Then the following reply is sent: