Skip to content

Commit

Permalink
move ip address check to thirdPartyAuthn function
Browse files Browse the repository at this point in the history
  • Loading branch information
pearl-truss committed Feb 1, 2024
1 parent 5558d8d commit 062e170
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 42 deletions.
15 changes: 13 additions & 2 deletions services/app-api/src/authn/thirdPartyAuthn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { initTracer, recordException } from '../../../uploads/src/lib/otel'

export async function userFromThirdPartyAuthorizer(
store: Store,
userId: string
userId: string,
ipAddress: string
) {
// // setup otel tracing
const otelCollectorURL = process.env.REACT_APP_OTEL_COLLECTOR_URL
Expand All @@ -17,8 +18,18 @@ export async function userFromThirdPartyAuthorizer(

const serviceName = 'third-party-authorizer'
initTracer(serviceName, otelCollectorURL)

const allowedIpAddresses = process.env.ALLOWED_IP_ADDRESSES
if (allowedIpAddresses === undefined || allowedIpAddresses === '') {
throw new Error(
'Configuration Error: ALLOWD_IP_ADDRESSES is required to run app-api.'
)
}
try {
const ipAddressIsValid = allowedIpAddresses.includes(ipAddress)
if (!ipAddressIsValid) {
const errMsg = new Error('bad ip address')
return err(errMsg)
}
// Lookup user from postgres
const auroraUser = await lookupUserAurora(store, userId)
if (auroraUser instanceof Error) {
Expand Down
4 changes: 3 additions & 1 deletion services/app-api/src/handlers/apollo_gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ function contextForRequestForFetcher(userFetcher: userFromAuthProvider): ({
const requestSpan = anyContext[requestSpanKey]
const authProvider =
event.requestContext.identity.cognitoAuthenticationProvider
const ipAddress = context.requestContext.identity.sourceIp
// This handler is shared with the third_party_API_authorizer
// when called from the 3rd party authorizer the cognito auth provider
// is not valid for instead the authorizer returns a user ID
Expand Down Expand Up @@ -94,7 +95,8 @@ function contextForRequestForFetcher(userFetcher: userFromAuthProvider): ({
} else if (fromThirdPartyAuthorizer && userId) {
userResult = await userFromThirdPartyAuthorizer(
store,
userId
userId,
ipAddress
)
}

Expand Down
44 changes: 5 additions & 39 deletions services/app-api/src/handlers/third_party_API_authorizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { newJWTLib } from '../jwt'

const stageName = process.env.stage
const jwtSecret = process.env.JWT_SECRET
const allowedIpAddresses = process.env.ALLOWED_IP_ADDRESSES

if (stageName === undefined) {
throw new Error('Configuration Error: stage is required')
Expand All @@ -20,12 +19,6 @@ if (jwtSecret === undefined || jwtSecret === '') {
)
}

if (allowedIpAddresses === undefined || allowedIpAddresses === '') {
throw new Error(
'Configuration Error: ALLOWD_IP_ADDRESSES is required to run app-api.'
)
}

const jwtLib = newJWTLib({
issuer: `mcreview-${stageName}`,
signingKey: Buffer.from(jwtSecret, 'hex'),
Expand All @@ -37,38 +30,12 @@ export const main: APIGatewayTokenAuthorizerHandler = async (
): Promise<APIGatewayAuthorizerResult> => {
const authToken = event.authorizationToken.replace('Bearer ', '')
try {
const parsedEvent = JSON.parse(JSON.stringify(event))
console.info(
parsedEvent?.multiValueHeaders?.Host[0],
'Multivalue header host'
)
const host = parsedEvent?.multiValueHeaders?.Host[0]
console.info(parsedEvent, '============ PARSED EVENT =============')
console.info({
message: `${parsedEvent?.headers}`,
operation: 'parsed event',
status: 'LOGGED',
})
if (host === undefined) {
// TODO: remove this log
// eslint-disable-next-line
console.log(parsedEvent)
console.error('Invalid host on header')

return generatePolicy(undefined, event, false)
}
// host is formatted as ipAddress:port
// the following will remove the :port to leave just the ip address
const ipAddress = host.slice(0, host.indexOf(':'))
const ipAddressIsValid = allowedIpAddresses.includes(ipAddress)
console.info(ipAddress, 'IP Address')
console.info(allowedIpAddresses, 'Allowed IP Address')
// authentication step for validating JWT token
const userId = jwtLib.userIDFromToken(authToken)
if (userId instanceof Error) {
console.error('Invalid auth token')

return generatePolicy(undefined, event, ipAddressIsValid)
return generatePolicy(undefined, event)
}

console.info({
Expand All @@ -77,20 +44,19 @@ export const main: APIGatewayTokenAuthorizerHandler = async (
status: 'SUCCESS',
})

return generatePolicy(userId, event, ipAddressIsValid)
return generatePolicy(userId, event)
} catch (err) {
console.error(
'unexpected exception attempting to validate authorization',
err
)
return generatePolicy(undefined, event, false)
return generatePolicy(undefined, event)
}
}

const generatePolicy = function (
userId: string | undefined,
event: APIGatewayTokenAuthorizerEvent,
ipAddressIsValid: boolean
event: APIGatewayTokenAuthorizerEvent
): APIGatewayAuthorizerResult {
// If the JWT is verified as valid, and the request comes from an allowed IP address
// send an Allow policy
Expand All @@ -100,7 +66,7 @@ const generatePolicy = function (
Statement: [
{
Action: 'execute-api:Invoke',
Effect: userId && ipAddressIsValid ? 'Allow' : 'Deny',
Effect: userId ? 'Allow' : 'Deny',
Resource: event['methodArn'],
},
],
Expand Down

0 comments on commit 062e170

Please sign in to comment.