Adding test cases for current app middleware as well as removing some old middlewares that were no longer used.

This commit is contained in:
mike12345567 2021-04-13 13:32:09 +01:00
parent a52f296d78
commit c51dacd0fe
6 changed files with 150 additions and 211 deletions

View File

@ -1,73 +0,0 @@
// const jwt = require("jsonwebtoken")
// const STATUS_CODES = require("../utilities/statusCodes")
// const { getRole, getBuiltinRoles } = require("../utilities/security/roles")
// const { AuthTypes } = require("../constants")
// const {
// getAppId,
// getCookieName,
// clearCookie,
// setCookie,
// isClient,
// } = require("../utilities")
// module.exports = async (ctx, next) => {
// if (ctx.path === "/builder") {
// await next()
// return
// }
// // do everything we can to make sure the appId is held correctly
// // we hold it in state as a
// let appId = getAppId(ctx)
// const cookieAppId = ctx.cookies.get(getCookieName("currentapp"))
// const builtinRoles = getBuiltinRoles()
// if (appId && cookieAppId !== appId) {
// setCookie(ctx, appId, "currentapp")
// } else if (cookieAppId) {
// appId = cookieAppId
// }
// let token, authType
// if (!isClient(ctx)) {
// token = ctx.cookies.get(getCookieName())
// authType = AuthTypes.BUILDER
// }
// if (!token && appId) {
// token = ctx.cookies.get(getCookieName(appId))
// authType = AuthTypes.APP
// }
// if (!token) {
// ctx.auth.authenticated = false
// ctx.appId = appId
// ctx.user = {
// role: builtinRoles.PUBLIC,
// }
// await next()
// return
// }
// try {
// ctx.auth.authenticated = authType
// const jwtPayload = jwt.verify(token, ctx.config.jwtSecret)
// ctx.appId = appId
// ctx.auth.apiKey = jwtPayload.apiKey
// ctx.user = {
// ...jwtPayload,
// role: await getRole(appId, jwtPayload.roleId),
// }
// // appId no longer carried in user, make sure
// delete ctx.user.appId
// } catch (err) {
// console.log(err)
// if (authType === AuthTypes.BUILDER) {
// clearCookie(ctx)
// ctx.status = 200
// return
// } else {
// ctx.throw(err.status || STATUS_CODES.FORBIDDEN, err.text)
// }
// }
// await next()
// }

View File

@ -39,13 +39,13 @@ module.exports = async (ctx, next) => {
roleId = BUILTIN_ROLE_IDS.PUBLIC roleId = BUILTIN_ROLE_IDS.PUBLIC
} else if ( } else if (
requestAppId != null && requestAppId != null &&
(appCookie == null || requestAppId === appCookie.appId) (appCookie == null || requestAppId !== appCookie.appId)
) { ) {
const globalUser = await getGlobalUsers(ctx, requestAppId, ctx.user.email) const globalUser = await getGlobalUsers(ctx, requestAppId, ctx.user.email)
updateCookie = true updateCookie = true
appId = requestAppId appId = requestAppId
roleId = globalUser.roles[requestAppId] || BUILTIN_ROLE_IDS.PUBLIC roleId = globalUser.roles[requestAppId] || BUILTIN_ROLE_IDS.PUBLIC
} else if (requestAppId == null && appCookie != null) { } else if (appCookie != null) {
appId = appCookie.appId appId = appCookie.appId
roleId = appCookie.roleId || BUILTIN_ROLE_IDS.PUBLIC roleId = appCookie.roleId || BUILTIN_ROLE_IDS.PUBLIC
} }

View File

@ -1,124 +0,0 @@
const { AuthTypes } = require("../../constants")
const authenticatedMiddleware = require("../authenticated")
const jwt = require("jsonwebtoken")
jest.mock("jsonwebtoken")
class TestConfiguration {
constructor(middleware) {
this.middleware = authenticatedMiddleware
this.ctx = {
config: {},
auth: {},
cookies: {
set: jest.fn(),
get: jest.fn(),
},
headers: {},
params: {},
path: "",
request: {
headers: {},
},
throw: jest.fn(),
}
this.next = jest.fn()
}
setHeaders(headers) {
this.ctx.headers = headers
}
executeMiddleware() {
return this.middleware(this.ctx, this.next)
}
afterEach() {
jest.resetAllMocks()
}
}
describe("Authenticated middleware", () => {
let config
beforeEach(() => {
config = new TestConfiguration()
})
afterEach(() => {
config.afterEach()
})
it("calls next() when on the builder path", async () => {
config.ctx.path = "/builder"
await config.executeMiddleware()
expect(config.next).toHaveBeenCalled()
})
it("sets a new cookie when the current cookie does not match the app id from context", async () => {
const appId = "app_123"
config.setHeaders({
"x-budibase-app-id": appId,
})
config.ctx.cookies.get.mockImplementation(() => "cookieAppId")
await config.executeMiddleware()
expect(config.ctx.cookies.set).toHaveBeenCalledWith(
"budibase:currentapp:local",
appId,
expect.any(Object)
)
})
it("sets the correct BUILDER auth type information when the x-budibase-type header is not 'client'", async () => {
config.ctx.cookies.get.mockImplementation(() => "budibase:builder:local")
jwt.verify.mockImplementationOnce(() => ({
apiKey: "1234",
roleId: "BUILDER",
}))
await config.executeMiddleware()
expect(config.ctx.auth.authenticated).toEqual(AuthTypes.BUILDER)
expect(config.ctx.user).toMatchSnapshot()
})
it("sets the correct APP auth type information when the user is not in the builder", async () => {
config.setHeaders({
"x-budibase-type": "client",
})
config.ctx.cookies.get.mockImplementation(() => `budibase:app:local`)
jwt.verify.mockImplementationOnce(() => ({
apiKey: "1234",
roleId: "ADMIN",
}))
await config.executeMiddleware()
expect(config.ctx.auth.authenticated).toEqual(AuthTypes.APP)
expect(config.ctx.user).toMatchSnapshot()
})
it("marks the user as unauthenticated when a token cannot be determined from the users cookie", async () => {
config.executeMiddleware()
expect(config.ctx.auth.authenticated).toBe(false)
expect(config.ctx.user.role).toEqual({
_id: "PUBLIC",
name: "Public",
permissionId: "public",
})
})
it("clears the cookie when there is an error authenticating in the builder", async () => {
config.ctx.cookies.get.mockImplementation(() => "budibase:builder:local")
jwt.verify.mockImplementationOnce(() => {
throw new Error()
})
await config.executeMiddleware()
expect(config.ctx.cookies.set).toBeCalledWith("budibase:builder:local")
})
})

View File

@ -1,6 +1,5 @@
const authorizedMiddleware = require("../authorized") const authorizedMiddleware = require("../authorized")
const env = require("../../environment") const env = require("../../environment")
const { AuthTypes } = require("../../constants")
const { PermissionTypes, PermissionLevels } = require("../../utilities/security/permissions") const { PermissionTypes, PermissionLevels } = require("../../utilities/security/permissions")
jest.mock("../../environment", () => ({ jest.mock("../../environment", () => ({
prod: false, prod: false,

View File

@ -0,0 +1,148 @@
mockAuthWithNoCookie()
mockWorker()
function mockWorker() {
jest.mock("../../utilities/workerRequests", () => ({
getGlobalUsers: () => {
return {
email: "test@test.com",
roles: {
"app_test": "BASIC",
}
}
}
}))
}
function mockReset() {
jest.resetModules()
mockWorker()
}
function mockAuthWithNoCookie() {
jest.resetModules()
mockWorker()
jest.mock("@budibase/auth", () => ({
getAppId: jest.fn(),
setCookie: jest.fn(),
getCookie: jest.fn(),
Cookies: {},
}))
}
function mockAuthWithCookie() {
jest.resetModules()
mockWorker()
jest.mock("@budibase/auth", () => ({
getAppId: () => {
return "app_test"
},
setCookie: jest.fn(),
getCookie: () => ({ appId: "app_different", roleId: "PUBLIC" }),
Cookies: {
Auth: "auth",
CurrentApp: "currentapp",
}
}))
}
class TestConfiguration {
constructor() {
this.next = jest.fn()
this.throw = jest.fn()
this.ctx = {
next: this.next,
throw: this.throw
}
}
setUser() {
this.ctx.user = {
email: "test@test.com",
}
}
executeMiddleware() {
// import as late as possible for mocks
const currentAppMiddleware = require("../currentapp")
return currentAppMiddleware(this.ctx, this.next)
}
}
describe("Current app middleware", () => {
let config
beforeEach(() => {
config = new TestConfiguration()
})
afterEach(() => {
jest.clearAllMocks()
})
describe("test having no cookies or app ID", () => {
it("should be able to proceed with nothing setup", async () => {
await config.executeMiddleware()
expect(config.next).toHaveBeenCalled()
})
})
describe("check get public for app when not logged in", () => {
it("should be able to proceed with no login, but cookies configured", async () => {
mockAuthWithCookie()
await config.executeMiddleware()
expect(config.ctx.roleId).toEqual("PUBLIC")
expect(config.ctx.appId).toEqual("app_test")
expect(config.next).toHaveBeenCalled()
})
})
describe("check functionality when logged in", () => {
async function checkExpected(setCookie) {
config.setUser()
await config.executeMiddleware()
const cookieFn = require("@budibase/auth").setCookie
if (setCookie) {
expect(cookieFn).toHaveBeenCalled()
} else {
expect(cookieFn).not.toHaveBeenCalled()
}
expect(config.ctx.roleId).toEqual("BASIC")
expect(config.ctx.appId).toEqual("app_test")
expect(config.next).toHaveBeenCalled()
}
it("should be able to setup an app token when cookie not setup", async () => {
mockAuthWithCookie()
await checkExpected(true)
})
it("should perform correct when no cookie exists", async () => {
mockReset()
jest.mock("@budibase/auth", () => ({
getAppId: () => {
return "app_test"
},
setCookie: jest.fn(),
getCookie: jest.fn(),
Cookies: {},
}))
await checkExpected(true)
})
it("lastly check what occurs when cookie doesn't need updated", async () => {
mockReset()
jest.mock("@budibase/auth", () => ({
getAppId: () => {
return "app_test"
},
setCookie: jest.fn(),
getCookie: () => ({ appId: "app_test", roleId: "BASIC" }),
Cookies: {},
}))
await checkExpected(false)
})
})
})

View File

@ -1,11 +0,0 @@
const env = require("../environment")
module.exports = async (ctx, next) => {
const selfHostKey =
ctx.request.headers["x-budibase-auth"] || ctx.request.body.selfHostKey
if (!selfHostKey || env.SELF_HOST_KEY !== selfHostKey) {
ctx.throw(401, "Request unauthorised")
} else {
await next()
}
}