improve: OAuth2 UI and test suite (via #5066)
* create `features` folder * add base oauth2 server * continue implementing OAuth tests * WIP * add password flow tests * modify Password flow credential types * remove query string credential type * add test case for Authorization flow * add specific Authorization value for Password flow test * WIP * fix linter issues
This commit is contained in:
98
package-lock.json
generated
98
package-lock.json
generated
@@ -2341,28 +2341,49 @@
|
||||
"dev": true
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
|
||||
"integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
|
||||
"version": "1.18.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
|
||||
"integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bytes": "3.0.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.1",
|
||||
"http-errors": "~1.6.2",
|
||||
"iconv-lite": "0.4.19",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "~1.6.3",
|
||||
"iconv-lite": "0.4.23",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.5.1",
|
||||
"raw-body": "2.3.2",
|
||||
"type-is": "~1.6.15"
|
||||
"qs": "6.5.2",
|
||||
"raw-body": "2.3.3",
|
||||
"type-is": "~1.6.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"iconv-lite": {
|
||||
"version": "0.4.19",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
||||
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
|
||||
"version": "0.4.23",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
|
||||
"integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
|
||||
"integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bytes": "3.0.0",
|
||||
"http-errors": "1.6.3",
|
||||
"iconv-lite": "0.4.23",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -6421,14 +6442,14 @@
|
||||
}
|
||||
},
|
||||
"express": {
|
||||
"version": "4.16.3",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
|
||||
"integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
|
||||
"version": "4.16.4",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
|
||||
"integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"accepts": "~1.3.5",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.18.2",
|
||||
"body-parser": "1.18.3",
|
||||
"content-disposition": "0.5.2",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.3.1",
|
||||
@@ -6445,10 +6466,10 @@
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.3",
|
||||
"qs": "6.5.1",
|
||||
"proxy-addr": "~2.0.4",
|
||||
"qs": "6.5.2",
|
||||
"range-parser": "~1.2.0",
|
||||
"safe-buffer": "5.1.1",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.16.2",
|
||||
"serve-static": "1.13.2",
|
||||
"setprototypeof": "1.1.0",
|
||||
@@ -6464,10 +6485,10 @@
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
|
||||
"dev": true
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"statuses": {
|
||||
@@ -9397,9 +9418,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
|
||||
"integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=",
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
|
||||
"integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=",
|
||||
"dev": true
|
||||
},
|
||||
"is-absolute-url": {
|
||||
@@ -15478,6 +15499,23 @@
|
||||
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
|
||||
"dev": true
|
||||
},
|
||||
"oauth2-server": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "http://registry.npmjs.org/oauth2-server/-/oauth2-server-2.4.1.tgz",
|
||||
"integrity": "sha1-2m3QVMAh7JwpQ59dGijeY9ArcWw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"basic-auth": "~0.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"basic-auth": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "http://registry.npmjs.org/basic-auth/-/basic-auth-0.0.1.tgz",
|
||||
"integrity": "sha1-Md22WEP2w1xv6nvrRqmHy4zhiSQ=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@@ -18364,13 +18402,13 @@
|
||||
}
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
|
||||
"integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
|
||||
"integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.6.0"
|
||||
"ipaddr.js": "1.8.0"
|
||||
}
|
||||
},
|
||||
"proxy-agent": {
|
||||
|
||||
@@ -95,9 +95,11 @@
|
||||
"babel-preset-react": "^6.23.0",
|
||||
"babel-preset-stage-0": "^6.22.0",
|
||||
"babel-runtime": "^6.23.0",
|
||||
"body-parser": "^1.18.3",
|
||||
"bundlesize": "^0.17.0",
|
||||
"chromedriver": "^2.38.3",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"cors": "^2.8.4",
|
||||
"css-loader": "^0.28.11",
|
||||
"cypress": "^3.1.0",
|
||||
"dedent": "^0.7.0",
|
||||
@@ -108,6 +110,7 @@
|
||||
"eslint-plugin-mocha": "^4.11.0",
|
||||
"eslint-plugin-react": "^7.10.0",
|
||||
"expect": "^1.20.2",
|
||||
"express": "^4.16.4",
|
||||
"extract-text-webpack-plugin": "^3.0.2",
|
||||
"file-loader": "^1.1.11",
|
||||
"git-describe": "^4.0.1",
|
||||
@@ -124,6 +127,7 @@
|
||||
"npm-run-all": "^4.1.2",
|
||||
"null-loader": "0.1.1",
|
||||
"nyc": "^11.3.0",
|
||||
"oauth2-server": "^2.4.1",
|
||||
"open": "0.0.5",
|
||||
"postcss-loader": "^2.1.5",
|
||||
"raw-loader": "0.5.1",
|
||||
|
||||
@@ -24,7 +24,7 @@ export default class Oauth2 extends React.Component {
|
||||
let username = auth && auth.get("username") || ""
|
||||
let clientId = auth && auth.get("clientId") || authConfigs.clientId || ""
|
||||
let clientSecret = auth && auth.get("clientSecret") || authConfigs.clientSecret || ""
|
||||
let passwordType = auth && auth.get("passwordType") || "request-body"
|
||||
let passwordType = auth && auth.get("passwordType") || "basic"
|
||||
|
||||
this.state = {
|
||||
appName: authConfigs.appName,
|
||||
@@ -150,14 +150,13 @@ export default class Oauth2 extends React.Component {
|
||||
}
|
||||
</Row>
|
||||
<Row>
|
||||
<label htmlFor="password_type">type:</label>
|
||||
<label htmlFor="password_type">Client credentials location:</label>
|
||||
{
|
||||
isAuthorized ? <code> { this.state.passwordType } </code>
|
||||
: <Col tablet={10} desktop={10}>
|
||||
<select id="password_type" data-name="passwordType" onChange={ this.onInputChange }>
|
||||
<option value="basic">Authorization header</option>
|
||||
<option value="request-body">Request body</option>
|
||||
<option value="basic">Basic auth</option>
|
||||
<option value="query">Query parameters</option>
|
||||
</select>
|
||||
</Col>
|
||||
}
|
||||
@@ -165,7 +164,7 @@ export default class Oauth2 extends React.Component {
|
||||
</Row>
|
||||
}
|
||||
{
|
||||
( flow === APPLICATION || flow === IMPLICIT || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "basic") ) &&
|
||||
( flow === APPLICATION || flow === IMPLICIT || flow === ACCESS_CODE || flow === PASSWORD ) &&
|
||||
( !isAuthorized || isAuthorized && this.state.clientId) && <Row>
|
||||
<label htmlFor="client_id">client_id:</label>
|
||||
{
|
||||
@@ -183,7 +182,7 @@ export default class Oauth2 extends React.Component {
|
||||
}
|
||||
|
||||
{
|
||||
( flow === APPLICATION || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "basic") ) && <Row>
|
||||
( (flow === APPLICATION || flow === ACCESS_CODE || flow === PASSWORD) && <Row>
|
||||
<label htmlFor="client_secret">client_secret:</label>
|
||||
{
|
||||
isAuthorized ? <code> ****** </code>
|
||||
@@ -197,7 +196,7 @@ export default class Oauth2 extends React.Component {
|
||||
}
|
||||
|
||||
</Row>
|
||||
}
|
||||
)}
|
||||
|
||||
{
|
||||
!isAuthorized && scopes && scopes.size ? <div className="scopes">
|
||||
|
||||
@@ -80,7 +80,7 @@ export default class LiveResponse extends React.Component {
|
||||
</div>
|
||||
}
|
||||
<h4>Server response</h4>
|
||||
<table className="responses-table">
|
||||
<table className="responses-table live-responses-table">
|
||||
<thead>
|
||||
<tr className="responses-header">
|
||||
<td className="col col_header response-col_status">Code</td>
|
||||
|
||||
@@ -74,28 +74,23 @@ export const authorizePassword = ( auth ) => ( { authActions } ) => {
|
||||
let { schema, name, username, password, passwordType, clientId, clientSecret } = auth
|
||||
let form = {
|
||||
grant_type: "password",
|
||||
scope: auth.scopes.join(scopeSeparator)
|
||||
scope: auth.scopes.join(scopeSeparator),
|
||||
username,
|
||||
password
|
||||
}
|
||||
let query = {}
|
||||
let headers = {}
|
||||
|
||||
if ( passwordType === "basic") {
|
||||
headers.Authorization = "Basic " + btoa(username + ":" + password)
|
||||
} else {
|
||||
Object.assign(form, {username}, {password})
|
||||
switch (passwordType) {
|
||||
case "request-body":
|
||||
setClientIdAndSecret(form, clientId, clientSecret)
|
||||
break
|
||||
|
||||
switch ( passwordType ) {
|
||||
case "query":
|
||||
setClientIdAndSecret(query, clientId, clientSecret)
|
||||
break
|
||||
|
||||
case "request-body":
|
||||
setClientIdAndSecret(form, clientId, clientSecret)
|
||||
break
|
||||
|
||||
default:
|
||||
headers.Authorization = "Basic " + btoa(clientId + ":" + clientSecret)
|
||||
}
|
||||
case "basic":
|
||||
headers.Authorization = "Basic " + btoa(clientId + ":" + clientSecret)
|
||||
break
|
||||
default:
|
||||
console.warn(`Warning: invalid passwordType ${passwordType} was passed, not including client id and secret`)
|
||||
}
|
||||
|
||||
return authActions.authorizeRequest({ body: buildFormData(form), url: schema.get("tokenUrl"), name, headers, query, auth})
|
||||
|
||||
50
test/e2e-cypress/helpers/oauth2-server/index.js
Normal file
50
test/e2e-cypress/helpers/oauth2-server/index.js
Normal file
@@ -0,0 +1,50 @@
|
||||
// from https://github.com/pedroetb/node-oauth2-server-example
|
||||
|
||||
var Http = require("http")
|
||||
var path = require("path")
|
||||
var express = require("express")
|
||||
var bodyParser = require("body-parser")
|
||||
var oauthserver = require("oauth2-server")
|
||||
var cors = require("cors")
|
||||
|
||||
var app = express()
|
||||
|
||||
app.use(cors())
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: true }))
|
||||
|
||||
app.use(bodyParser.json())
|
||||
|
||||
app.oauth = oauthserver({
|
||||
model: require("./model.js"),
|
||||
grants: ["password", "client_credentials", "implicit"],
|
||||
debug: true
|
||||
})
|
||||
|
||||
app.all("/oauth/token", app.oauth.grant())
|
||||
|
||||
app.get("/swagger.yaml", function (req, res) {
|
||||
res.sendFile(path.join(__dirname, "swagger.yaml"))
|
||||
})
|
||||
|
||||
app.get("*", app.oauth.authorise(), function (req, res) {
|
||||
res.send("Secret secrets are no fun, secret secrets hurt someone.")
|
||||
})
|
||||
|
||||
app.use(app.oauth.errorHandler())
|
||||
|
||||
function startServer() {
|
||||
var httpServer = Http.createServer(app)
|
||||
httpServer.listen("3231")
|
||||
|
||||
return function stopServer() {
|
||||
httpServer.close()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = startServer
|
||||
|
||||
if (require.main === module) {
|
||||
// for debugging
|
||||
startServer()
|
||||
}
|
||||
141
test/e2e-cypress/helpers/oauth2-server/model.js
Normal file
141
test/e2e-cypress/helpers/oauth2-server/model.js
Normal file
@@ -0,0 +1,141 @@
|
||||
// from https://github.com/pedroetb/node-oauth2-server-example
|
||||
|
||||
var config = {
|
||||
clients: [{
|
||||
clientId: "application",
|
||||
clientSecret: "secret"
|
||||
}],
|
||||
confidentialClients: [{
|
||||
clientId: "confidentialApplication",
|
||||
clientSecret: "topSecret"
|
||||
}],
|
||||
tokens: [],
|
||||
users: [{
|
||||
id: "123",
|
||||
username: "swagger",
|
||||
password: "password"
|
||||
}]
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the memory storage content (for debug).
|
||||
*/
|
||||
|
||||
var dump = function () {
|
||||
|
||||
console.log("clients", config.clients)
|
||||
console.log("confidentialClients", config.confidentialClients)
|
||||
console.log("tokens", config.tokens)
|
||||
console.log("users", config.users)
|
||||
}
|
||||
|
||||
/*
|
||||
* Methods used by all grant types.
|
||||
*/
|
||||
|
||||
var getAccessToken = function (bearerToken, callback) {
|
||||
|
||||
var tokens = config.tokens.filter(function (token) {
|
||||
|
||||
return token.accessToken === bearerToken
|
||||
})
|
||||
|
||||
return callback(false, tokens[0])
|
||||
}
|
||||
|
||||
var getClient = function (clientId, clientSecret, callback) {
|
||||
|
||||
var clients = config.clients.filter(function (client) {
|
||||
|
||||
return client.clientId === clientId && client.clientSecret === clientSecret
|
||||
})
|
||||
|
||||
var confidentialClients = config.confidentialClients.filter(function (client) {
|
||||
|
||||
return client.clientId === clientId && client.clientSecret === clientSecret
|
||||
})
|
||||
|
||||
callback(false, clients[0] || confidentialClients[0])
|
||||
}
|
||||
|
||||
var grantTypeAllowed = function (clientId, grantType, callback) {
|
||||
|
||||
var clientsSource,
|
||||
clients = []
|
||||
|
||||
if (grantType === "password") {
|
||||
clientsSource = config.clients
|
||||
} else if (grantType === "client_credentials") {
|
||||
clientsSource = config.confidentialClients
|
||||
}
|
||||
|
||||
if (clientsSource) {
|
||||
clients = clientsSource.filter(function (client) {
|
||||
|
||||
return client.clientId === clientId
|
||||
})
|
||||
}
|
||||
|
||||
callback(false, clients.length)
|
||||
}
|
||||
|
||||
var saveAccessToken = function (accessToken, clientId, expires, user, callback) {
|
||||
|
||||
config.tokens.push({
|
||||
accessToken: accessToken,
|
||||
expires: expires,
|
||||
clientId: clientId,
|
||||
user: user
|
||||
})
|
||||
|
||||
callback(false)
|
||||
}
|
||||
|
||||
/*
|
||||
* Method used only by password grant type.
|
||||
*/
|
||||
|
||||
var getUser = function (username, password, callback) {
|
||||
|
||||
var users = config.users.filter(function (user) {
|
||||
|
||||
return user.username === username && user.password === password
|
||||
})
|
||||
|
||||
callback(false, users[0])
|
||||
}
|
||||
|
||||
/*
|
||||
* Method used only by client_credentials grant type.
|
||||
*/
|
||||
|
||||
var getUserFromClient = function (clientId, clientSecret, callback) {
|
||||
|
||||
var clients = config.confidentialClients.filter(function (client) {
|
||||
|
||||
return client.clientId === clientId && client.clientSecret === clientSecret
|
||||
})
|
||||
|
||||
var user
|
||||
|
||||
if (clients.length) {
|
||||
user = {
|
||||
username: clientId
|
||||
}
|
||||
}
|
||||
|
||||
callback(false, user)
|
||||
}
|
||||
|
||||
/**
|
||||
* Export model definition object.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
getAccessToken: getAccessToken,
|
||||
getClient: getClient,
|
||||
grantTypeAllowed: grantTypeAllowed,
|
||||
saveAccessToken: saveAccessToken,
|
||||
getUser: getUser,
|
||||
getUserFromClient: getUserFromClient
|
||||
}
|
||||
36
test/e2e-cypress/helpers/oauth2-server/swagger.yaml
Normal file
36
test/e2e-cypress/helpers/oauth2-server/swagger.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
swagger: "2.0"
|
||||
host: localhost:3231
|
||||
paths:
|
||||
/password:
|
||||
get:
|
||||
summary: OAuth2 Password
|
||||
security:
|
||||
- oauthPassword: []
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
/application:
|
||||
get:
|
||||
summary: OAuth2 Application
|
||||
security:
|
||||
- oauthApplication: []
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
securityDefinitions:
|
||||
oauthPassword:
|
||||
type: oauth2
|
||||
flow: password
|
||||
tokenUrl: /oauth/token
|
||||
oauthApplication:
|
||||
type: oauth2
|
||||
flow: application
|
||||
tokenUrl: /oauth/token
|
||||
oauthImplicit:
|
||||
type: oauth2
|
||||
flow: implicit
|
||||
authorizationUrl: /oauth/token
|
||||
@@ -1,3 +1,4 @@
|
||||
const startOAuthServer = require("../helpers/oauth2-server")
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
@@ -12,6 +13,7 @@
|
||||
// the project's config changing)
|
||||
|
||||
module.exports = (on, config) => {
|
||||
startOAuthServer()
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
}
|
||||
|
||||
@@ -18,3 +18,10 @@ import "./commands"
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
|
||||
|
||||
// Remove fetch, so Cypress can intercept XHRs
|
||||
// see https://github.com/cypress-io/cypress/issues/95
|
||||
Cypress.on("window:before:load", win => {
|
||||
win.fetch = null
|
||||
})
|
||||
55
test/e2e-cypress/tests/features/oauth2-flows/application.js
Normal file
55
test/e2e-cypress/tests/features/oauth2-flows/application.js
Normal file
@@ -0,0 +1,55 @@
|
||||
describe("OAuth2 Application flow", function() {
|
||||
beforeEach(() => {
|
||||
cy.server()
|
||||
cy.route({
|
||||
url: "**/oauth/*",
|
||||
method: "POST"
|
||||
}).as("tokenRequest")
|
||||
})
|
||||
|
||||
it("should make an application flow Authorization header request", () => {
|
||||
cy
|
||||
.visit("/?url=http://localhost:3231/swagger.yaml")
|
||||
.get(".btn.authorize")
|
||||
.click()
|
||||
|
||||
.get("div.modal-ux-content > div:nth-child(2)").within(() => {
|
||||
cy.get("#client_id")
|
||||
.clear()
|
||||
.type("confidentialApplication")
|
||||
|
||||
.get("#client_secret")
|
||||
.clear()
|
||||
.type("topSecret")
|
||||
|
||||
.get("button.btn.modal-btn.auth.authorize.button")
|
||||
.click()
|
||||
})
|
||||
|
||||
cy.get("button.close-modal")
|
||||
.click()
|
||||
|
||||
.get("#operations-default-get_application")
|
||||
.click()
|
||||
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("body")
|
||||
.should("equal", "grant_type=client_credentials")
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("headers")
|
||||
.its("authorization")
|
||||
.should("equal", "Basic Y29uZmlkZW50aWFsQXBwbGljYXRpb246dG9wU2VjcmV0")
|
||||
|
||||
.get(".live-responses-table .response-col_status")
|
||||
.contains("200")
|
||||
})
|
||||
})
|
||||
122
test/e2e-cypress/tests/features/oauth2-flows/password.js
Normal file
122
test/e2e-cypress/tests/features/oauth2-flows/password.js
Normal file
@@ -0,0 +1,122 @@
|
||||
describe("OAuth2 Password flow", function() {
|
||||
beforeEach(() => {
|
||||
cy.server()
|
||||
cy.route({
|
||||
url: "**/oauth/*",
|
||||
method: "POST"
|
||||
}).as("tokenRequest")
|
||||
})
|
||||
|
||||
it("should make a password flow Authorization header request", () => {
|
||||
cy
|
||||
.visit("/?url=http://localhost:3231/swagger.yaml")
|
||||
.get(".btn.authorize")
|
||||
.click()
|
||||
|
||||
.get("#oauth_username")
|
||||
.type("swagger")
|
||||
|
||||
.get("#oauth_password")
|
||||
.type("password")
|
||||
|
||||
.get("#password_type")
|
||||
.select("basic")
|
||||
|
||||
.get("#client_id")
|
||||
.clear()
|
||||
.type("application")
|
||||
|
||||
.get("#client_secret")
|
||||
.clear()
|
||||
.type("secret")
|
||||
|
||||
.get("div.modal-ux-content > div:nth-child(1) > div > div:nth-child(2) > div > div.auth-btn-wrapper > button.btn.modal-btn.auth.authorize.button")
|
||||
.click()
|
||||
|
||||
.get("button.close-modal")
|
||||
.click()
|
||||
|
||||
.get("#operations-default-get_password")
|
||||
.click()
|
||||
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("body")
|
||||
.should("include", "grant_type=password")
|
||||
.should("include", "username=swagger")
|
||||
.should("include", "password=password")
|
||||
.should("not.include", "client_id")
|
||||
.should("not.include", "client_secret")
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("headers")
|
||||
.its("authorization")
|
||||
.should("equal", "Basic YXBwbGljYXRpb246c2VjcmV0")
|
||||
|
||||
.get(".live-responses-table .response-col_status")
|
||||
.contains("200")
|
||||
})
|
||||
|
||||
it("should make a Password flow request-body request", () => {
|
||||
cy
|
||||
.visit("/?url=http://localhost:3231/swagger.yaml")
|
||||
.get(".btn.authorize")
|
||||
.click()
|
||||
|
||||
.get("#oauth_username")
|
||||
.type("swagger")
|
||||
|
||||
.get("#oauth_password")
|
||||
.type("password")
|
||||
|
||||
.get("#password_type")
|
||||
.select("request-body")
|
||||
|
||||
.get("#client_id")
|
||||
.clear()
|
||||
.type("application")
|
||||
|
||||
.get("#client_secret")
|
||||
.clear()
|
||||
.type("secret")
|
||||
|
||||
.get("div.modal-ux-content > div:nth-child(1) > div > div:nth-child(2) > div > div.auth-btn-wrapper > button.btn.modal-btn.auth.authorize.button")
|
||||
.click()
|
||||
|
||||
.get("button.close-modal")
|
||||
.click()
|
||||
|
||||
.get("#operations-default-get_password")
|
||||
.click()
|
||||
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("body")
|
||||
.should("include", "grant_type=password")
|
||||
.should("include", "username=swagger")
|
||||
.should("include", "password=password")
|
||||
.should("include", "client_id=application")
|
||||
.should("include", "client_secret=secret")
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("headers")
|
||||
.should("not.have.property", "authorization")
|
||||
|
||||
.get(".live-responses-table .response-col_status")
|
||||
.contains("200")
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user