Skip to content
This repository has been archived by the owner on Jun 24, 2019. It is now read-only.

Protecting endpoints with a middleware #45

Open
wants to merge 2 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ jspm_packages

# Serverless directories
.serverless
*-function.json
Copy link
Member Author

@crysfel crysfel Apr 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we should commit these files and if so.... is there a way to put them somewhere else other than the root folder?

These files are created automatically when deploying with the serverless framework.


.DS_Store
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
"name": "codingcoach-api",
"version": "1.0.0",
"description": "Azure Functions sample for the Serverless framework",
"main": "handler.js",
"keywords": [
"azure",
"serverless"
],
"dependencies": {
"express-jwt": "^5.3.1",
"node-fetch": "^2.3.0"
},
"devDependencies": {
"serverless-azure-functions": "*"
}
}
}
28 changes: 28 additions & 0 deletions serverless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

service: codingcoach-api

# You can pin your service to only deploy with a specific Serverless version
# Check out our docs for more details
# frameworkVersion: "=X.X.X"

provider:
name: azure
location: West US

plugins:
- serverless-azure-functions

# you can add packaging information here
#package:
# include:
# - include-me.js
# - include-me-dir/**
# exclude:
# - exclude-me.js
# - exclude-me-dir/**

functions:
users: ${file(src/handlers/users/config.yml):users}
users-add: ${file(src/handlers/users/config.yml):usersadd}
hello: ${file(src/handlers/hello/config.yml):hello}

18 changes: 0 additions & 18 deletions services/hello/hello-function.json

This file was deleted.

57 changes: 0 additions & 57 deletions services/hello/serverless.yml

This file was deleted.

67 changes: 0 additions & 67 deletions services/users/serverless.yml

This file was deleted.

18 changes: 0 additions & 18 deletions services/users/store.js

This file was deleted.

18 changes: 0 additions & 18 deletions services/users/users-function.json

This file was deleted.

9 changes: 9 additions & 0 deletions src/config/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

module.exports = {
auth0: {
DOMAIN: process.env.AUTH0_DOMAIN,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another question I have is that every time I deploy... these values disappear in azure :( and I need to add it again, if I deploy a single function everything works as expected.

Anyone knows how to prevent that? Or how can we dynamically create those settings?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @crysfel, am not sure if these can be handled in the local.settings.json

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could set these variables in the serverless.yml

CLIENT_ID: process.env.AUTH0_CLIENT_ID,
CLIENT_SECRET: process.env.AUTH0_CLIENT_SECRET,
CERTIFICATE: process.env.AUTH0_CERTIFICATE,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These data is defined in azure as Application Settings, everything works great except for AUTH0_CERTIFICATE. For now I hardcoded the value of this variable in the azure console, which is not ideal.

The value of this variable is something like:

AUTH0_CERTIFICATE = `
-----BEGIN CERTIFICATE-----
ABC123.....
ABC123.....
ABC123.....
-----END CERTIFICATE-----`

It looks like when saving this value in the applications settings azure removes the \n and when used in the code doesn't work :(

Anyone can help me with this?

},
};
10 changes: 10 additions & 0 deletions src/handlers/hello/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
hello:
handler: src/handlers/hello/handler.hello
events:
- http: true
x-azure-settings:
authLevel : anonymous
- http: true
x-azure-settings:
direction: out
name: res
File renamed without changes.
20 changes: 20 additions & 0 deletions src/handlers/users/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
users:
handler: src/handlers/users/list.list
events:
- http: true
x-azure-settings:
authLevel : anonymous
- http: true
x-azure-settings:
direction: out
name: res
usersadd:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to make this as post instead of get and I'd like to use the path /users. Anyone can help me with that?

Copy link
Collaborator

@swissarmykirpan swissarmykirpan Apr 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is done in the function.json, there should be a function.json per function handler - since you are using serverless, there should be some config in the handler in the serverless.yml that allows you to specify this

handler: src/handlers/users/store.add
events:
- http: true
x-azure-settings:
authLevel : anonymous
- http: true
x-azure-settings:
direction: out
name: res
12 changes: 8 additions & 4 deletions services/users/list.js → src/handlers/users/list.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict';

/* eslint-disable no-param-reassign */
const authMiddleware = require('../../middlewares/auth0.js');

module.exports.list = function (context) {
module.exports.list = authMiddleware((context) => {
// TODO: get this data from the database
const users = [{
id: 1,
name: 'Emma Wedekind'
Expand All @@ -16,11 +17,14 @@ module.exports.list = function (context) {

context.res = {
status: 200,
body: users,
body: {
success: true,
users,
},
headers: {
'Content-Type': 'application/json'
}
};

context.done();
};
});
69 changes: 69 additions & 0 deletions src/handlers/users/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict';

const fetch = require('node-fetch');
const config = require('../../config/constants.js');
const authMiddleware = require('../../middlewares/auth0.js');

// Get an access token for the Auth0 Admin API
function getAdminAccessToken() {
const options = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: config.auth0.CLIENT_ID,
client_secret: config.auth0.CLIENT_SECRET,
audience: `${config.auth0.DOMAIN}/api/v2/`,
grant_type: 'client_credentials',
}),
};

return fetch(`${config.auth0.DOMAIN}/oauth/token`, options)
.then((response) => response.json());
}


// Get the user's profile from auth0
function getUserProfile(accessToken, userID) {
const options = {
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
return fetch(`${config.auth0.DOMAIN}/api/v2/users/${userID}`, options)
.then(response => response.json());
}

module.exports.add = authMiddleware(async (context, request) => {
let res = {};
try {
const data = await getAdminAccessToken();
const user = await getUserProfile(data.access_token, request.user.sub);

// @TODO: check if the current user already exist in the database,
// if not, we need to add the new record.

res = {
body: {
success: true,
message: 'User successfully saved',
user,
},
};
} catch (error) {
res = {
status: 500,
body: {
success: false,
error,
},
};
}

context.res = {
...res,
headers: {
'Content-Type': 'application/json'
},
};
context.done()
});
Loading