feat: add OAuth 1.0 authentication support (#7482)

* feat: add OAuth 1.0 authentication support

Add full OAuth 1.0 (RFC 5849) authentication with support for
HMAC-SHA1/256/512, RSA-SHA1/256/512, and PLAINTEXT signature methods.
Includes UI components, bru/yml serialization, Postman import, code
generation, CLI support, and comprehensive playwright and unit tests.

* test: replace real-looking PEM literals with fake markers in oauth1 tests

Avoid tripping secret scanners by using obviously fake BEGIN/END markers
and non-sensitive base64 content in serialization and round-trip tests.

* fix: remove invalid OAuth1 placeholder header from code generator

OAuth1 requires runtime-computed nonce, timestamp, and signature that
cannot be pre-computed for a static code snippet. Return an empty array
instead of emitting an Authorization header with literal <signature>,
<timestamp>, <nonce> placeholders.

* fix: remove unreachable oauth1 case from WSAuth component

The oauth1 switch branch was dead code since it was not in
supportedAuthModes and the useEffect would reset it to 'none'
before it could render.

* fix: remove unused collectionPath param and use path.basename for filename extraction

* refactor: rename OAuth1 fields for clarity

- tokenSecret → accessTokenSecret
- signatureMethod → signatureEncoding
- addParamsTo value 'queryparams' → 'query'

* refactor: rename addParamsTo to placement in OAuth1 auth

* fix: add missing oauth1: null in buildOAuth2Config and upgrade @opencollection/types to 0.9.0

* test: add oauth1 import tests and fix missing oauth1: null in auth assertions

* ci: add auth playwright tests workflow for Linux, macOS, and Windows

* refactor: rename signatureEncoding to signatureMethod and fix timeline race condition

- Rename OAuth1 signatureEncoding to signatureMethod across all packages
- Fix timeline showing "No Headers/Body found" when request-sent IPC event
  arrives after response by retroactively updating the timeline entry
- Store requestUid in timeline entries for precise matching
- Correct timeline entry timestamp on retroactive update for proper sort order

* ci: add OAuth1 CLI tests and reorganize auth actions under oauth1/

- Add CLI tests that run full BRU and YML collections via bru run
- Add start-test-server actions for Linux, macOS, and Windows
- Move auth e2e and setup actions under auth/oauth1/ directory
- Fix Windows Playwright failures caused by unescaped backslashes in collectionPath template variable

* ci: reorder auth tests to run E2E tests before CLI tests

* ci: start test server after E2E tests to fix port 8081 conflict
This commit is contained in:
lohit
2026-03-27 13:29:42 +00:00
committed by GitHub
parent 784e851d4c
commit 95de14adcb
115 changed files with 7238 additions and 56 deletions

View File

@@ -0,0 +1,34 @@
meta {
name: OAuth1 HMAC-SHA1 200
type: http
seq: 1
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA1
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
res.body.resource.email: eq oauth1@example.com
}

View File

@@ -0,0 +1,33 @@
meta {
name: OAuth1 HMAC-SHA1 401
type: http
seq: 2
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: wrong_secret
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA1
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 401
res.body.error: eq Invalid signature
}

View File

@@ -0,0 +1,43 @@
meta {
name: OAuth1 HMAC-SHA1 Body 200
type: http
seq: 17
}
post {
url: {{localhost}}/api/auth/oauth1/resource
body: json
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA1
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: body
include_body_hash: true
}
body:json {
{
"test": "test"
}
}
body:text {
test
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,39 @@
meta {
name: OAuth1 HMAC-SHA1 Body JSON 200
type: http
seq: 21
}
post {
url: {{localhost}}/api/auth/oauth1/resource
body: json
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA1
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: body
include_body_hash: false
}
body:json {
{
"test": "data"
}
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,33 @@
meta {
name: OAuth1 HMAC-SHA1 POST 200
type: http
seq: 3
}
post {
url: {{localhost}}/api/auth/oauth1/resource
body: formUrlEncoded
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA1
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,33 @@
meta {
name: OAuth1 HMAC-SHA1 Query Params 200
type: http
seq: 4
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA1
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: query
include_body_hash: true
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,34 @@
meta {
name: OAuth1 HMAC-SHA256 200
type: http
seq: 1
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA256
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
res.body.resource.email: eq oauth1@example.com
}

View File

@@ -0,0 +1,33 @@
meta {
name: OAuth1 HMAC-SHA256 401
type: http
seq: 2
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: wrong_secret
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA256
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 401
res.body.error: eq Invalid signature
}

View File

@@ -0,0 +1,33 @@
meta {
name: OAuth1 HMAC-SHA256 Body 200
type: http
seq: 19
}
post {
url: {{localhost}}/api/auth/oauth1/resource
body: formUrlEncoded
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA256
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: body
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,34 @@
meta {
name: OAuth1 HMAC-SHA512 200
type: http
seq: 1
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA512
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
res.body.resource.email: eq oauth1@example.com
}

View File

@@ -0,0 +1,33 @@
meta {
name: OAuth1 HMAC-SHA512 401
type: http
seq: 2
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: wrong_secret
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: HMAC-SHA512
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 401
res.body.error: eq Invalid signature
}

View File

@@ -0,0 +1,34 @@
meta {
name: OAuth1 PLAINTEXT 200
type: http
seq: 1
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: PLAINTEXT
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
res.body.resource.email: eq oauth1@example.com
}

View File

@@ -0,0 +1,33 @@
meta {
name: OAuth1 PLAINTEXT 401
type: http
seq: 2
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: wrong_secret
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: PLAINTEXT
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 401
res.body.error: eq Invalid signature
}

View File

@@ -0,0 +1,33 @@
meta {
name: OAuth1 PLAINTEXT Body 200
type: http
seq: 18
}
post {
url: {{localhost}}/api/auth/oauth1/resource
body: formUrlEncoded
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: PLAINTEXT
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: body
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,33 @@
meta {
name: OAuth1 PLAINTEXT Query Params 200
type: http
seq: 15
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret: consumer_secret_1
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: PLAINTEXT
private_key:
timestamp:
nonce:
version: 1.0
realm:
placement: query
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,63 @@
meta {
name: OAuth1 RSA-SHA1 200
type: http
seq: 1
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret:
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: RSA-SHA1
private_key: '''
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
'''
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
res.body.resource.email: eq oauth1@example.com
}

View File

@@ -0,0 +1,66 @@
meta {
name: OAuth1 RSA-SHA1 Body formurlencoded 200
type: http
seq: 20
}
post {
url: {{localhost}}/api/auth/oauth1/resource
body: formUrlEncoded
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret:
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: RSA-SHA1
private_key: '''
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
'''
timestamp:
nonce:
version: 1.0
realm:
placement: body
include_body_hash: false
}
body:form-urlencoded {
test: test
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,62 @@
meta {
name: OAuth1 RSA-SHA1 Body 200
type: http
seq: 20
}
post {
url: {{localhost}}/api/auth/oauth1/resource
body: formUrlEncoded
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret:
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: RSA-SHA1
private_key: '''
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
'''
timestamp:
nonce:
version: 1.0
realm:
placement: body
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,34 @@
meta {
name: OAuth1 RSA-SHA1 File Key 200
type: http
seq: 15
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret:
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: RSA-SHA1
private_key: @file(test-private-key.pem)
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
res.body.resource.email: eq oauth1@example.com
}

View File

@@ -0,0 +1,62 @@
meta {
name: OAuth1 RSA-SHA1 Query Params 200
type: http
seq: 16
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret:
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: RSA-SHA1
private_key: '''
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
'''
timestamp:
nonce:
version: 1.0
realm:
placement: query
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
}

View File

@@ -0,0 +1,65 @@
meta {
name: OAuth1 RSA-SHA1 Variable Key 200
type: http
seq: 14
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret:
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: RSA-SHA1
private_key: {{private-key}}
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
res.body.resource.email: eq oauth1@example.com
}
script:pre-request {
bru.setVar('private-key', `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----`);
}

View File

@@ -0,0 +1,63 @@
meta {
name: OAuth1 RSA-SHA256 200
type: http
seq: 1
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret:
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: RSA-SHA256
private_key: '''
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
'''
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
res.body.resource.email: eq oauth1@example.com
}

View File

@@ -0,0 +1,63 @@
meta {
name: OAuth1 RSA-SHA512 200
type: http
seq: 1
}
get {
url: {{localhost}}/api/auth/oauth1/resource
body: none
auth: oauth1
}
auth:oauth1 {
consumer_key: consumer_key_1
consumer_secret:
access_token: access_token_1
token_secret: token_secret_1
callback_url:
verifier:
signature_method: RSA-SHA512
private_key: '''
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
'''
timestamp:
nonce:
version: 1.0
realm:
placement: header
include_body_hash: false
}
assert {
res.status: eq 200
res.body.resource.name: eq oauth1-test-resource
res.body.resource.email: eq oauth1@example.com
}

View File

@@ -0,0 +1,5 @@
{
"version": "1",
"name": "oauth1-testbench-bru",
"type": "collection"
}

View File

@@ -0,0 +1,3 @@
vars {
localhost: http://localhost:8081
}

View File

@@ -0,0 +1,36 @@
info:
name: OAuth1 HMAC-SHA1 200
type: http
seq: 1
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA1
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
- expression: res.body.resource.email
operator: eq
value: oauth1@example.com
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 HMAC-SHA1 401
type: http
seq: 2
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: wrong_secret
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA1
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "401"
- expression: res.body.error
operator: eq
value: Invalid signature
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 HMAC-SHA1 Body 200
type: http
seq: 17
http:
method: POST
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA1
version: "1.0"
placement: body
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,36 @@
info:
name: OAuth1 HMAC-SHA1 Body JSON 200
type: http
seq: 21
http:
method: POST
url: "{{localhost}}/api/auth/oauth1/resource"
body:
type: json
data: ""
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA1
version: "1.0"
placement: body
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 HMAC-SHA1 POST 200
type: http
seq: 3
http:
method: POST
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA1
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 HMAC-SHA1 Query Params 200
type: http
seq: 4
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA1
version: "1.0"
placement: query
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,36 @@
info:
name: OAuth1 HMAC-SHA256 200
type: http
seq: 1
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA256
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
- expression: res.body.resource.email
operator: eq
value: oauth1@example.com
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 HMAC-SHA256 401
type: http
seq: 2
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: wrong_secret
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA256
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "401"
- expression: res.body.error
operator: eq
value: Invalid signature
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 HMAC-SHA256 Body 200
type: http
seq: 19
http:
method: POST
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA256
version: "1.0"
placement: body
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,36 @@
info:
name: OAuth1 HMAC-SHA512 200
type: http
seq: 1
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA512
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
- expression: res.body.resource.email
operator: eq
value: oauth1@example.com
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 HMAC-SHA512 401
type: http
seq: 2
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: wrong_secret
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: HMAC-SHA512
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "401"
- expression: res.body.error
operator: eq
value: Invalid signature
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,36 @@
info:
name: OAuth1 PLAINTEXT 200
type: http
seq: 1
http:
method: GET
url: '{{localhost}}/api/auth/oauth1/resource'
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: PLAINTEXT
version: '1.0'
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: '200'
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
- expression: res.body.resource.email
operator: eq
value: oauth1@example.com
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 PLAINTEXT 401
type: http
seq: 2
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: wrong_secret
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: PLAINTEXT
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "401"
- expression: res.body.error
operator: eq
value: Invalid signature
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 PLAINTEXT Body 200
type: http
seq: 18
http:
method: POST
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: PLAINTEXT
version: "1.0"
placement: body
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,33 @@
info:
name: OAuth1 PLAINTEXT Query Params 200
type: http
seq: 15
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
consumerSecret: consumer_secret_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: PLAINTEXT
version: "1.0"
placement: query
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,66 @@
info:
name: OAuth1 RSA-SHA1 200
type: http
seq: 1
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: RSA-SHA1
privateKey:
type: text
value: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
- expression: res.body.resource.email
operator: eq
value: oauth1@example.com
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,65 @@
info:
name: OAuth1 RSA-SHA1 Body 200
type: http
seq: 20
http:
method: POST
url: "{{localhost}}/api/auth/oauth1/resource"
body:
type: form-urlencoded
auth:
type: oauth1
consumerKey: consumer_key_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: RSA-SHA1
privateKey:
type: text
value: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
version: "1.0"
placement: body
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,68 @@
info:
name: OAuth1 RSA-SHA1 Body formurlencoded 200
type: http
seq: 20
http:
method: POST
url: "{{localhost}}/api/auth/oauth1/resource"
body:
type: form-urlencoded
data:
- name: test
value: test
auth:
type: oauth1
consumerKey: consumer_key_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: RSA-SHA1
privateKey:
type: text
value: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
version: "1.0"
placement: body
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,38 @@
info:
name: OAuth1 RSA-SHA1 File Key 200
type: http
seq: 15
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: RSA-SHA1
privateKey:
type: file
value: test-private-key.pem
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
- expression: res.body.resource.email
operator: eq
value: oauth1@example.com
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,63 @@
info:
name: OAuth1 RSA-SHA1 Query Params 200
type: http
seq: 16
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: RSA-SHA1
privateKey:
type: text
value: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
version: "1.0"
placement: query
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,69 @@
info:
name: OAuth1 RSA-SHA1 Variable Key 200
type: http
seq: 14
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: RSA-SHA1
privateKey:
type: text
value: "{{private-key}}"
version: "1.0"
placement: header
includeBodyHash: false
runtime:
scripts:
- type: before-request
code: |-
bru.setVar('private-key', `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----`);
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
- expression: res.body.resource.email
operator: eq
value: oauth1@example.com
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,66 @@
info:
name: OAuth1 RSA-SHA256 200
type: http
seq: 1
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: RSA-SHA256
privateKey:
type: text
value: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
- expression: res.body.resource.email
operator: eq
value: oauth1@example.com
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,66 @@
info:
name: OAuth1 RSA-SHA512 200
type: http
seq: 1
http:
method: GET
url: "{{localhost}}/api/auth/oauth1/resource"
auth:
type: oauth1
consumerKey: consumer_key_1
accessToken: access_token_1
accessTokenSecret: token_secret_1
signatureEncoding: RSA-SHA512
privateKey:
type: text
value: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf/ioOwb6uGm01
WjL89sBOKmvMuwyGW33w+ud3eV5dWbHZbJTgCHMtjUVqGE4sVPnX8wfKgb00hVGZ
ZhbRsqquUMJL+7RHZA1G3ZcC2WPmrUvIpi13W7F/+wizRjDrutgK0oc4L7zUPhgE
+d+Qe6JHvFL376hqkD9Z6vd9jVNRDv7D2uJcG+Uc7ePM6yLzQeJILnfvSwxna89G
6YxfbYNjf/VKAcRM6UAR8aRGm/A9Qmdwsy08iRzlM0K5lid7Ath7ADJ+D6ezUIhl
qiI6sVrZdpsFXzuvcxjgAts54XoQsLCDZudTmzMs4BftswULCQFdj6c2oye9QKsu
EoZ0CvwNAgMBAAECggEAA1kIJu2QQIhhB0rEjQfaF5309NW9JK/pag91+claW3hd
q6papc1yIN6MjfRwPlE7i8npZygL03uEAkJhRoYHOEU3AOwFZluw7hiuPkBaQiDC
Ld1RpOZlnRidoqgHV1y+LzZ0ieJwgGhu4ZEbnSRZIvMihqRHJo5aJQGGUuQ60r6w
Z5N6j7GGCV14oGck6+0k/NhYrkhpbyl+AHPZeQ20L9ZaSpl+GD3RUgvx4nOhN1Fx
agovDCKwmRPSpuuBw6Wun1hKC9MuuL89CCy2yZ+MrjQmQJ/onKZKR2fc1I5g2JRu
z7xObQq/tAXIHKM27YYY5J3NcGtsy9tLpdtFDle/wQKBgQDfBaBURNs/ccVMMXSZ
T5lOo337Rv3bGFnoLwURUZrjJNGrHqLzeZvTNt0sXQX6Jbdeb5qnC/icng+QDEod
9hRVDz1rN+2YqG6AMvrX5dQSK1PmkwVHLles4sX7DsZaiKNYFFbXc9rt7kXBwDoE
LXYidqUIqZiOjMqCyNlfyHHnRQKBgQC3ppq7TCEWIfqLzsfOoqaKD/fDOrQLLmor
7RvAdGa+EyVeB1G+NQO00KN6U9W+SNPz0cEUYUZQiAaAghUGkNurrS1shr5k7aTX
pXpXtaA+xSEAd6w8lTl9mAfwZMBCcsfjyjPf1RPjZ6Tj2fdHqnsllSU5843LOqZK
CBXiitdKKQKBgQCVNEloN0zLLE1HxUpxiwxQzRZqtrr9ClST/mkQhhzuW+Kd7fgs
la5HZ0we8vkdun/sARRhL6Qa+7ADugUX+Frv8SsxARDG8eBDilfBevQfV7dg6fk8
/ucPNgQoC2Fujj1hnvHeYJcWWTN4BSeLRfLj6aZNnlD/BXgyeTbcWtjBVQKBgBhG
npd5hboePbczWzgWSftgBvk4jkoYFZK+4fc7q8UeVMcsIoMJEPdayPFHma5whAvr
wyEFhrzobiuYhlz60v7LgoChAxPmUe7rgdOMP6Vse2NLbmoHs7TFXu9I8h0WfRPA
S8EfsmRR8/rmeghwIZ0jLOuPJUQi+Y45qWLrxW+ZAoGAMXYhio9y93M0nRqjiiCR
YibnhpZxvrNiLPxNiUi/WxcWEvulpmbKxLUhiWJB1ZmRTiGYlnclQXUuRyaOQNTo
5TVAaNzDXayWVbxhx3Lb8NUV+QNUJEJOgjq4+NYw8fUZCr7T64pGGM4DJHPuHCBo
dJv7UByPuMKBIOYpy3Z+iWs=
-----END PRIVATE KEY-----
version: "1.0"
placement: header
includeBodyHash: false
runtime:
assertions:
- expression: res.status
operator: eq
value: "200"
- expression: res.body.resource.name
operator: eq
value: oauth1-test-resource
- expression: res.body.resource.email
operator: eq
value: oauth1@example.com
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,5 @@
name: Local
variables:
- name: localhost
value: http://localhost:8081

View File

@@ -0,0 +1,6 @@
opencollection: '1.0.0'
info:
name: oauth1-testbench-yml
bundled: false

View File

@@ -0,0 +1,10 @@
{
"maximized": false,
"lastOpenedCollections": ["{{collectionPath}}/bru", "{{collectionPath}}/yml"],
"preferences": {
"onboarding": {
"hasLaunchedBefore": true,
"hasSeenWelcomeModal": true
}
}
}

View File

@@ -0,0 +1,221 @@
import fs from 'fs';
import path from 'path';
import { test, expect } from '../../../playwright';
import {
sendRequestAndWaitForResponse, closeAllCollections, selectEnvironment,
openCollection, openRequest, selectResponsePaneTab
} from '../../utils/page';
import { runCollection, validateRunnerResults } from '../../utils/page/runner';
// The test PEM file is gitignored (*.pem). Write it to both fixture directories
// at module load time so collectionFixturePath includes it when copying.
const { TEST_RSA_PRIVATE_KEY } = require('../../../packages/bruno-tests/src/auth/oauth1');
const fixtureBase = path.join(__dirname, 'fixtures', 'collections');
for (const subdir of ['bru', 'yml']) {
const pemPath = path.join(fixtureBase, subdir, 'test-private-key.pem');
if (!fs.existsSync(pemPath)) {
fs.writeFileSync(pemPath, TEST_RSA_PRIVATE_KEY);
}
}
const BRU_COLLECTION = 'oauth1-testbench-bru';
const YML_COLLECTION = 'oauth1-testbench-yml';
const requests = [
{ name: 'OAuth1 HMAC-SHA1 200', status: 200 },
{ name: 'OAuth1 HMAC-SHA1 401', status: 401 },
{ name: 'OAuth1 HMAC-SHA1 POST 200', status: 200 },
{ name: 'OAuth1 HMAC-SHA1 Query Params 200', status: 200 },
{ name: 'OAuth1 HMAC-SHA256 200', status: 200 },
{ name: 'OAuth1 HMAC-SHA256 401', status: 401 },
{ name: 'OAuth1 HMAC-SHA512 200', status: 200 },
{ name: 'OAuth1 HMAC-SHA512 401', status: 401 },
{ name: 'OAuth1 PLAINTEXT 200', status: 200 },
{ name: 'OAuth1 PLAINTEXT 401', status: 401 },
{ name: 'OAuth1 PLAINTEXT Query Params 200', status: 200 },
{ name: 'OAuth1 RSA-SHA1 200', status: 200 },
{ name: 'OAuth1 RSA-SHA1 Query Params 200', status: 200 },
{ name: 'OAuth1 RSA-SHA256 200', status: 200 },
{ name: 'OAuth1 RSA-SHA512 200', status: 200 },
{ name: 'OAuth1 RSA-SHA1 Variable Key 200', status: 200 },
{ name: 'OAuth1 RSA-SHA1 File Key 200', status: 200 },
{ name: 'OAuth1 HMAC-SHA1 Body 200', status: 200 },
{ name: 'OAuth1 PLAINTEXT Body 200', status: 200 },
{ name: 'OAuth1 HMAC-SHA256 Body 200', status: 200 },
{ name: 'OAuth1 RSA-SHA1 Body 200', status: 200 },
{ name: 'OAuth1 RSA-SHA1 Body formurlencoded 200', status: 200 },
{ name: 'OAuth1 HMAC-SHA1 Body JSON 200', status: 200 }
];
const sendAllRequests = async (page, collectionName: string) => {
await openCollection(page, collectionName);
await selectEnvironment(page, 'Local', 'collection');
for (const { name, status } of requests) {
await test.step(name, async () => {
await openRequest(page, collectionName, name);
await sendRequestAndWaitForResponse(page, status);
});
}
};
const runAndValidate = async (page, collectionName: string) => {
await runCollection(page, collectionName);
await validateRunnerResults(page, {
totalRequests: requests.length,
passed: requests.length,
failed: 0
});
};
/**
* After sending a request, switch to the Timeline tab, expand the latest timeline item,
* and return locators for the request URL and headers section.
*/
const openTimelineRequest = async (page) => {
await selectResponsePaneTab(page, 'Timeline');
// Click the first (latest) timeline item header to expand it
const timelineItem = page.locator('.timeline-item').first();
await timelineItem.locator('.oauth-request-item-header').click();
return timelineItem;
};
const verifyPlacement = async (page, collectionName: string, requestName: string, placement: 'header' | 'query' | 'body') => {
await openRequest(page, collectionName, requestName);
await sendRequestAndWaitForResponse(page, 200);
const timelineItem = await openTimelineRequest(page);
const content = timelineItem.locator('.timeline-item-content');
if (placement === 'header') {
await expect(content).toContainText('Authorization');
await expect(content).toContainText('OAuth');
} else if (placement === 'query') {
const urlPre = content.locator('pre').first();
await expect(urlPre).toContainText('oauth_consumer_key');
} else {
// Body: oauth params should be in the request body, not in URL or Authorization header
const urlPre = content.locator('pre').first();
await expect(urlPre).not.toContainText('oauth_consumer_key');
// Body section is expanded by default — verify oauth params are in the body
await expect(content.locator('.collapsible-section').filter({ hasText: 'Body' })).toContainText('oauth_consumer_key');
}
};
test.describe('OAuth 1.0 Runner', () => {
test.afterAll(async ({ pageWithUserData: page }) => {
await closeAllCollections(page);
});
test.describe('[bru]', () => {
test('Send individual requests', async ({ pageWithUserData: page }) => {
test.setTimeout(3 * 60 * 1000);
await sendAllRequests(page, BRU_COLLECTION);
});
test('Run collection and verify all assertions pass', async ({ pageWithUserData: page }) => {
test.setTimeout(3 * 60 * 1000);
await runAndValidate(page, BRU_COLLECTION);
});
test('Verify Add Params To placement via timeline', async ({ pageWithUserData: page }) => {
test.setTimeout(3 * 60 * 1000);
await openCollection(page, BRU_COLLECTION);
await selectEnvironment(page, 'Local', 'collection');
await test.step('Header: HMAC-SHA1', async () => {
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA1 200', 'header');
});
await test.step('Query Params: HMAC-SHA1', async () => {
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA1 Query Params 200', 'query');
});
await test.step('Query Params: PLAINTEXT', async () => {
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 PLAINTEXT Query Params 200', 'query');
});
await test.step('Query Params: RSA-SHA1', async () => {
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 RSA-SHA1 Query Params 200', 'query');
});
await test.step('Body: HMAC-SHA1', async () => {
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA1 Body 200', 'body');
});
await test.step('Body: PLAINTEXT', async () => {
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 PLAINTEXT Body 200', 'body');
});
await test.step('Body: HMAC-SHA256', async () => {
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA256 Body 200', 'body');
});
await test.step('Body: RSA-SHA1', async () => {
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 RSA-SHA1 Body 200', 'body');
});
await test.step('Body: HMAC-SHA1 JSON (non-form body)', async () => {
await verifyPlacement(page, BRU_COLLECTION, 'OAuth1 HMAC-SHA1 Body JSON 200', 'body');
});
});
});
test.describe('[yml]', () => {
test('Send individual requests', async ({ pageWithUserData: page }) => {
test.setTimeout(3 * 60 * 1000);
await sendAllRequests(page, YML_COLLECTION);
});
test('Run collection and verify all assertions pass', async ({ pageWithUserData: page }) => {
test.setTimeout(3 * 60 * 1000);
await runAndValidate(page, YML_COLLECTION);
});
test('Verify Add Params To placement via timeline', async ({ pageWithUserData: page }) => {
test.setTimeout(3 * 60 * 1000);
await openCollection(page, YML_COLLECTION);
await selectEnvironment(page, 'Local', 'collection');
await test.step('Header: HMAC-SHA1', async () => {
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA1 200', 'header');
});
await test.step('Query Params: HMAC-SHA1', async () => {
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA1 Query Params 200', 'query');
});
await test.step('Query Params: PLAINTEXT', async () => {
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 PLAINTEXT Query Params 200', 'query');
});
await test.step('Query Params: RSA-SHA1', async () => {
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 RSA-SHA1 Query Params 200', 'query');
});
await test.step('Body: HMAC-SHA1', async () => {
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA1 Body 200', 'body');
});
await test.step('Body: PLAINTEXT', async () => {
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 PLAINTEXT Body 200', 'body');
});
await test.step('Body: HMAC-SHA256', async () => {
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA256 Body 200', 'body');
});
await test.step('Body: RSA-SHA1', async () => {
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 RSA-SHA1 Body 200', 'body');
});
await test.step('Body: HMAC-SHA1 JSON (non-form body)', async () => {
await verifyPlacement(page, YML_COLLECTION, 'OAuth1 HMAC-SHA1 Body JSON 200', 'body');
});
});
});
});

View File

@@ -0,0 +1,158 @@
import { test, expect } from '../../../playwright';
import {
closeAllCollections, createCollection, createRequest, openRequest,
selectRequestPaneTab, saveRequest
} from '../../utils/page';
const label = (page, text: string) => page.locator('label').filter({ hasText: new RegExp(`^${text}$`) });
const sectionLabel = (page, text: string) => page.locator('.oauth1-section-label').filter({ hasText: text });
const dropdownItem = (page, text: string) => page.locator('.dropdown-item').filter({ hasText: text });
const fieldRow = (page, text: string) => label(page, text).locator('..');
const editorIn = (row) => row.locator('.single-line-editor-wrapper .CodeMirror');
const typeInField = async (page, fieldName: string, value: string) => {
await editorIn(fieldRow(page, fieldName)).click();
await page.keyboard.type(value);
};
const selectAuthMode = async (page) => {
await page.locator('.auth-mode-label').click();
await dropdownItem(page, 'OAuth 1.0').click();
};
test.describe('OAuth 1.0 Authentication', () => {
test.afterAll(async ({ page }) => {
await closeAllCollections(page);
});
test('Request auth UI', async ({ page, createTmpDir }) => {
// Setup
await createCollection(page, 'oauth1-test', await createTmpDir());
await createRequest(page, 'oauth1-request', 'oauth1-test', { url: 'https://example.com/api' });
await openRequest(page, 'oauth1-test', 'oauth1-request');
await selectRequestPaneTab(page, 'Auth');
await selectAuthMode(page);
// Sections
await test.step('Three sections are visible', async () => {
for (const name of ['Configuration', 'Signature', 'Advanced']) {
await expect(sectionLabel(page, name)).toBeVisible();
}
});
// HMAC fields (top-level, always visible)
await test.step('HMAC mode shows correct fields', async () => {
for (const name of ['Consumer Key', 'Consumer Secret', 'Token', 'Token Secret']) {
await expect(label(page, name)).toBeVisible();
}
await expect(label(page, 'Private Key')).not.toBeVisible();
});
// Advanced section is collapsed by default
await test.step('Advanced fields are hidden by default', async () => {
for (const name of ['Callback URL', 'Verifier', 'Timestamp', 'Nonce', 'Version', 'Realm']) {
await expect(label(page, name)).not.toBeVisible();
}
});
// Expand Advanced section
await test.step('Clicking Advanced expands the section', async () => {
await sectionLabel(page, 'Advanced').click();
for (const name of ['Callback URL', 'Verifier', 'Timestamp', 'Nonce', 'Version', 'Realm']) {
await expect(label(page, name)).toBeVisible();
}
});
// Signature method dropdown
await test.step('All 7 signature methods in dropdown', async () => {
const sigDropdown = fieldRow(page, 'Signature Method').locator('.oauth1-dropdown-selector');
await sigDropdown.click();
for (const method of ['HMAC-SHA1', 'HMAC-SHA256', 'HMAC-SHA512', 'RSA-SHA1', 'RSA-SHA256', 'RSA-SHA512', 'PLAINTEXT']) {
await expect(dropdownItem(page, method)).toBeVisible();
}
});
// RSA mode toggles fields
await test.step('RSA mode shows Private Key, hides Consumer Secret', async () => {
await dropdownItem(page, 'RSA-SHA256').click();
const sigDropdown = fieldRow(page, 'Signature Method').locator('.oauth1-dropdown-selector');
await expect(sigDropdown.locator('.oauth1-dropdown-label')).toContainText('RSA-SHA256');
await expect(label(page, 'Private Key')).toBeVisible();
await expect(label(page, 'Consumer Secret')).not.toBeVisible();
// Private Key editor accepts input
const pkEditor = page.locator('.private-key-editor-wrapper .CodeMirror');
await expect(pkEditor).toBeVisible();
await pkEditor.click();
await page.keyboard.type('test-private-key');
// Switch back to HMAC-SHA1
await sigDropdown.click();
await dropdownItem(page, 'HMAC-SHA1').click();
await expect(label(page, 'Consumer Secret')).toBeVisible();
await expect(label(page, 'Private Key')).not.toBeVisible();
});
// Collapse and re-expand Advanced
await test.step('Clicking Advanced again collapses the section', async () => {
await sectionLabel(page, 'Advanced').click();
await expect(label(page, 'Callback URL')).not.toBeVisible();
await expect(label(page, 'Timestamp')).not.toBeVisible();
// Re-expand for subsequent steps
await sectionLabel(page, 'Advanced').click();
await expect(label(page, 'Callback URL')).toBeVisible();
});
// Fill fields
await test.step('Fill form fields', async () => {
await typeInField(page, 'Consumer Key', 'my-consumer-key');
await typeInField(page, 'Token', 'my-token');
await typeInField(page, 'Timestamp', '1234567890');
});
// Add Params To dropdown
await test.step('Add Params To dropdown cycles options', async () => {
const apDropdown = fieldRow(page, 'Add Params To').locator('.oauth1-dropdown-selector');
await expect(apDropdown.locator('.oauth1-dropdown-label')).toContainText('Header');
await apDropdown.click();
await dropdownItem(page, 'Query Params').click();
await expect(apDropdown.locator('.oauth1-dropdown-label')).toContainText('Query Params');
await apDropdown.click();
await dropdownItem(page, 'Header').click();
});
// Include Body Hash checkbox
await test.step('Include Body Hash checkbox toggles', async () => {
const checkbox = page.locator('input[type="checkbox"]');
const bodyHashLabel = page.locator('label').filter({ hasText: 'Include Body Hash' });
await expect(checkbox).not.toBeChecked();
await bodyHashLabel.click();
await expect(checkbox).toBeChecked();
await bodyHashLabel.click();
await expect(checkbox).not.toBeChecked();
});
await saveRequest(page);
});
test('Collection settings auth', async ({ page }) => {
const collectionRow = page.getByTestId('collections').locator('#sidebar-collection-name').filter({ hasText: 'oauth1-test' });
await collectionRow.click();
await page.locator('.tab.auth').click();
await selectAuthMode(page);
await test.step('Sections are visible, Advanced collapsed by default', async () => {
for (const name of ['Configuration', 'Signature', 'Advanced']) {
await expect(sectionLabel(page, name)).toBeVisible();
}
// Advanced fields hidden by default
await expect(label(page, 'Callback URL')).not.toBeVisible();
});
await test.step('Fill and save', async () => {
await typeInField(page, 'Consumer Key', 'collection-consumer-key');
await page.getByRole('button', { name: 'Save' }).click();
});
});
});