-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* serverless initial commit * update secret name to normal follow convention * missed removing caller when removed target
- Loading branch information
1 parent
eee0fa1
commit 3697c39
Showing
22 changed files
with
2,464 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
node_modules | ||
node_modules | ||
kubernetes | ||
auth | ||
events | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
name: Pipeline | ||
|
||
on: | ||
push: | ||
branches: | ||
- 'main' | ||
- 'master' | ||
- 'feature**' | ||
|
||
env: | ||
REGION: <% index .Params `region` %> | ||
CI_USER_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
CI_USER_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
SAM_TEMPLATE: template.yaml | ||
STAGE_STACK_NAME: <% .Name %>-stage | ||
PROD_STACK_NAME: <% .Name %>-prod | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- run: | | ||
# trigger the tests here | ||
build-and-deploy-feature-stage: | ||
# this stage is triggered only for feature branches (feature*), | ||
# which will build the stack and deploy to a stack named with branch name. | ||
# if: startsWith(github.ref, 'refs/heads/feature') | ||
needs: [test] | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-python@v2 | ||
- uses: actions/setup-node@v2 | ||
# Modules get packaged into lambda functions with the node_modules folder | ||
# so we must obtain the modules inside CI | ||
- name: Install Lambda Authorizer modules | ||
run: | | ||
cd ./auth && | ||
npm install --production | ||
- uses: aws-actions/setup-sam@v1 | ||
- run: | | ||
sam build \ | ||
--template ${SAM_TEMPLATE} \ | ||
--use-container | ||
- name: Assume the testing pipeline user role | ||
uses: aws-actions/configure-aws-credentials@v1 | ||
with: | ||
aws-access-key-id: ${{ env.CI_USER_ACCESS_KEY_ID }} | ||
aws-secret-access-key: ${{ env.CI_USER_SECRET_ACCESS_KEY }} | ||
aws-region: ${{ env.REGION }} | ||
- name: Deploy to feature stack in the testing account | ||
shell: bash | ||
run: | | ||
sam deploy \ | ||
--template ${SAM_TEMPLATE} \ | ||
--config-file ./config.toml \ | ||
--config-env stage \ | ||
--region ${REGION} \ | ||
--no-fail-on-empty-changeset | ||
integration-test: | ||
needs: [build-and-deploy-feature-stage] | ||
runs-on: ubuntu-latest | ||
steps: | ||
## Example of smoke test against staging env before deploying to production | ||
## To be enhanced to more sophisicated checks | ||
- run: echo "TEST_RESPONSE_COD=$(curl -o /dev/null -s -w \"%{http_code}\" https://<% index .Params `stagingBackendSubdomain` %><% index .Params `stagingHostRoot` %>/status/ready)" >> $GITHUB_ENV | ||
- if: env.TEST_RESPONSE_COD >= 400 | ||
run: exit 1 | ||
|
||
build-and-deploy-feature-prod: | ||
# this stage is triggered only for feature branches (feature*), | ||
# which will build the stack and deploy to a stack named with branch name. | ||
# if: startsWith(github.ref, 'refs/heads/feature') | ||
needs: [integration-test] | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-python@v2 | ||
- uses: actions/setup-node@v2 | ||
# Modules get packaged into lambda functions with the node_modules folder | ||
# so we must obtain the modules inside CI | ||
- name: Install Lambda Authorizer modules | ||
run: | | ||
cd ./auth && | ||
npm install --production | ||
- uses: aws-actions/setup-sam@v1 | ||
- run: | | ||
sam build \ | ||
--template ${SAM_TEMPLATE} \ | ||
--use-container | ||
- name: Assume the testing pipeline user role | ||
uses: aws-actions/configure-aws-credentials@v1 | ||
with: | ||
aws-access-key-id: ${{ env.CI_USER_ACCESS_KEY_ID }} | ||
aws-secret-access-key: ${{ env.CI_USER_SECRET_ACCESS_KEY }} | ||
aws-region: ${{ env.REGION }} | ||
- name: Deploy to feature stack in Production | ||
shell: bash | ||
run: | | ||
sam deploy \ | ||
--template ${SAM_TEMPLATE} \ | ||
--config-file ./config.toml \ | ||
--config-env prod \ | ||
--region ${REGION} \ | ||
--no-fail-on-empty-changeset |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
FROM public.ecr.aws/lambda/nodejs:14 | ||
|
||
COPY . . | ||
|
||
RUN touch .env | ||
RUN npm i --production | ||
|
||
CMD ["src/app.lambdaHandler"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
NODE_ENV=development | ||
ISSUER_BASE_URL= | ||
CLIENT_ID= | ||
CLIENT_SECRET= | ||
COOKIE_SIGNING_SECRET= | ||
COOKIE_DOMAIN="127.0.0.1" | ||
AUTH_ENDPOINT="http://127.0.0.1:9000" | ||
FRONTEND_URL="http://127.0.0.1:3000" | ||
SERVER_PORT=9000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
var serverless = require("serverless-http"); | ||
var express = require('express'); | ||
const { auth } = require('express-openid-connect'); | ||
|
||
|
||
// OIDC settings | ||
const issuerBaseURL = process.env.ISSUER_BASE_URL; | ||
const clientID = process.env.CLIENT_ID; | ||
const clientSecret = process.env.CLIENT_SECRET; | ||
// Redirect URL settings | ||
const authorizerEndpoint = process.env.AUTH_ENDPOINT; | ||
const frontendURL = process.env.FRONTEND_URL; | ||
const authScope = process.env.AUTH_SCOPE || 'openid profile email'; | ||
// Cookie settings | ||
const cookieDomain = process.env.COOKIE_DOMAIN; | ||
const cookieAllowInsecure = process.env.ALLOW_INSECURE_COOKIES === "true"; | ||
const cookieSigningSecret = process.env.COOKIE_SIGNING_SECRET; | ||
const jwtCookieKey = process.env.JWT_COOKIE_KEY; | ||
|
||
const app = express(); | ||
|
||
// For development you may need to run this function locally | ||
const lambdaRuntime = process.env.NODE_ENV === 'development' ? false : true; | ||
// If request is from Authorize request must use context.succeed instead of res.json() | ||
// this is for API gateway to parse versus it going to the end user | ||
const isAuthorizerRequest = (req) => lambdaRuntime && (req.apiGateway.event.type === 'REQUEST'); | ||
|
||
const cookieParamsOverride = cookieAllowInsecure ? { secure: false, sameSite: 'Lax' } : {}; | ||
|
||
// By Default, this OIDC Authorizer sets an encrypted JWE, you can use this when migration to EKS | ||
// to also set a JWT token on client cookie for JWT authorizer middleware, defaults to undefined | ||
const afterCallback = jwtCookieKey ? (req, res, session) => { | ||
res.cookie(jwtCookieKey, session.id_token, { | ||
domain: cookieDomain, | ||
path: "/", | ||
...cookieParamsOverride, | ||
}); | ||
return session | ||
} : undefined; | ||
|
||
if (!lambdaRuntime) { | ||
const cors = require("cors"); | ||
app.use(cors({ | ||
origin: frontendURL, | ||
credentials: true, | ||
})); | ||
} | ||
|
||
app.use((req, res, next) => { | ||
auth({ | ||
issuerBaseURL: issuerBaseURL, | ||
baseURL: authorizerEndpoint, | ||
routes: { | ||
postLogoutRedirect: frontendURL, | ||
}, | ||
afterCallback, | ||
session: { | ||
cookie: { | ||
domain: cookieDomain, | ||
path: "/", | ||
...cookieParamsOverride, | ||
}, | ||
}, | ||
getLoginState(req, options) { | ||
if (req.originalUrl === "/login") { | ||
return { | ||
returnTo: frontendURL || options.returnTo || req.originalUrl, | ||
}; | ||
} else if (!req.oidc.isAuthenticated()) { | ||
const response = { | ||
isAuthorized: false, | ||
context: { | ||
loginUrl: `${authorizerEndpoint}/login`, | ||
}, | ||
}; | ||
|
||
if (isAuthorizerRequest(req)) { | ||
res.simpleResponse = response; | ||
} | ||
res.status(401).json(response); | ||
return {}; | ||
} | ||
}, | ||
clientID, | ||
clientSecret, | ||
secret: cookieSigningSecret, | ||
idpLogout: true, | ||
authorizationParams: { | ||
response_type: 'code', | ||
scope: authScope, | ||
} | ||
})(req, res, next); | ||
}); | ||
|
||
app.use('/*', (req, res) => { | ||
const response = { | ||
isAuthorized: true, | ||
context: { ...req.oidc.user } | ||
}; | ||
if (isAuthorizerRequest(req)) { | ||
res.simpleResponse = response; | ||
} | ||
res.json(response); | ||
}); | ||
|
||
app.use((err, req, res) => { | ||
console.error(req.originalUrl, err); | ||
}); | ||
|
||
// In lambda runtime it exports the lambdaHandler instead of http server listening | ||
if (!lambdaRuntime) { | ||
const port = process.env.SERVER_PORT || 80; | ||
app.listen(port, () => { | ||
console.log(`Authorizer listening at http://localhost:${port}`); | ||
}); | ||
} | ||
|
||
module.exports.lambdaHandler = serverless(app, { | ||
response(response, event, context) { | ||
if (response.simpleResponse) { | ||
return context.succeed({ ...response.simpleResponse }) | ||
} | ||
} | ||
}); |
Oops, something went wrong.