Skip to content

Commit

Permalink
Assignment9
Browse files Browse the repository at this point in the history
good hapi process monitoring & extending hapi request lifecycle

* important: use below to install good or get funky errors.
  `npm i good@8.0.0-rc1`
* configure good console to write log reports to a logfile.
  Configure confidence file for good to log: test, production, and default.
* Catch invalid attempts to access the ./private route.
  Extend the `onPreResponse` step of the lifecycle for the ./private route.
  So when invalid tokens are used to access ./private, the event is
  logged to the logfile.
* Add `{ debug: false }` config to Confidence file for tests.
  Otherwise, the tests print out hapi-auth-bearer-token error reports.
  • Loading branch information
zoe-1 committed Jan 19, 2018
1 parent c61e2f8 commit bf05c4b
Show file tree
Hide file tree
Showing 8 changed files with 361 additions and 51 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ config.json
coverage.*
.settings
test/fixtures/awesomeLog.json
test/fixtures/awesome_log
log
package-lock.json
97 changes: 92 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,94 @@
# university rewrite

* lesson1
* lesson2
* lesson3
* lesson4
* lesson5

### lesson1

basic hapi server


### lesson2

basic plugin ./version.js


### lesson3

100% test coverage and .travis.yml


### lesson4

hapi-auth-bearer-token

* add hapi-auth-bearer-token to the application.
* register the auth strategy in it's own plugin './authtoken.js'
* all routes must have valid token to be accessed
- currently only one route exists.
* adjusted project values to reflect assignment4
* 100% test coverage routes now need a valid token.


### lesson5

Configuring tls

* add tls set up to server configuration.


### lesson6

Using authStragies & prerequisites

* build ./authenticate and ./private points.
* use prerequisite extensions to execute authentication logic.
* Make simple database.js data store to authenticate user records with.
* Apply default authStrategy to ./private point.
* No authStrategy for ./authenticate point.


### lesson7

catabox-redis

* generate bearer-token upon successful authentication (cryptiles).
* Set bearer-token in catbox-cache along with user record.
* Expire the token after xxxxx time. Set expiresIn: value with
server.options.
* scopes for user record ['admin', 'member']
* create ./private point which requires admin scope for access.
* pre-empt one user from generating multiple tokens.


### lesson8

confidence

* Build confidence object in ./lib/configs.js
* Configure the object to be filtered by the `env` criteria
* (environment).
The environments will be production, test, default.
- production: configurations for deployment.
- test: configs for testing.
- default: configs for running on local enviroment.
* docs: https://github.com/hapijs/confidence
* TLS and confidence:
- confidence manipulates the tls certs if they are
loaded in the Confidence object. To solve the issue
load tls certs into configs object after confidence
generates it.


### lesson9

good hapi process monitoring & extending hapi request lifecycle

* important: use below to install good or get funky errors.<br/>
`npm i good@8.0.0-rc1`
* configure good console to write log reports to a logfile.
Configure confidence file for good to log: test, production, and default.
* Catch invalid attempts to access the ./private route.
Extend the `onPreResponse` step of the lifecycle for the ./private route.
So when invalid tokens are used to access ./private, the event is
logged to the logfile.
* Add `{ debug: false }` config to Confidence file for tests.
Otherwise, the tests print out hapi-auth-bearer-token error reports.
47 changes: 46 additions & 1 deletion lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ exports.Config = {
port: 443
},
test: {
debug: false,
port: 8000
},
$default: {
Expand All @@ -21,16 +22,60 @@ exports.Config = {
production: {
authToken: {
expiresIn: 6000
},
good: {
ops: {
interval: 1000
},
reporters: {
file: [{
module: 'good-squeeze',
name: 'Squeeze',
args: [{ ops: '*', log: '*', response: '*', error: '*' }]
}, {
module: 'good-squeeze',
name: 'SafeJson',
args: [
null,
{ seperator: ',' }
]
}, {
module: 'good-file',
args: ['./log/good_log']
}]
}
}
},
test: {
authToken: {
expiresIn: 50
expiresIn: 22
}
},
$default: {
authToken: {
expiresIn: ((1000 * 60) * 2)
},
good: {
ops: {
interval: 1000
},
reporters: {
myFileReporter: [{
module: 'good-squeeze',
name: 'Squeeze',
args: [{ ops: '*', log: '*', response: '*', error: '*' }]
}, {
module: 'good-squeeze',
name: 'SafeJson',
args: [
null,
{ seperator: ',' }
]
}, {
module: 'good-file',
args: ['./test/fixtures/awesome_log']
}]
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
'use strict';


// Load modules

const Hapi = require('hapi');
const Hoek = require('hoek');
const HapiAuthBearerToken = require('hapi-auth-bearer-token');
const AuthTokenStrategy = require('./authtoken');
const Cache = require('./cache');
const Good = require('good');

// Load custom plugins

const Version = require('./version');

const internals = {};


internals.init = async (serverOptions, pluginOptions) => {

Hoek.assert(typeof serverOptions === 'object', new Error('server options be supplied.')); // @todo add strict validation
Expand All @@ -24,7 +23,8 @@ internals.init = async (serverOptions, pluginOptions) => {
{ plugin: HapiAuthBearerToken, options: {} },
{ plugin: AuthTokenStrategy, options: {} },
{ plugin: Version, options: { message: 'lesson7' } },
{ plugin: Cache, options: { expiresIn: pluginOptions.authToken.expiresIn } }
{ plugin: Cache, options: { expiresIn: pluginOptions.authToken.expiresIn } },
{ plugin: Good, options: pluginOptions.good }
];

try {
Expand Down
47 changes: 42 additions & 5 deletions lib/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ exports.plugin = {

// * set cache records here (catbox-redis) lesson7.
// * prempt multiple authtokens
// if user already authenticated. If yes, return current authtoken.
// if user already authenticated then return current authtoken.
// * generate token with cryptiles.

const activeuser = await request.server.app.active.get(request.payload.username);
Expand All @@ -72,10 +72,25 @@ exports.plugin = {

const randomAuthToken = Cryptiles.randomString(36);

await request.server.app.authtokens.set(randomAuthToken, { username: result.userRecord.username, email: result.userRecord.email, scope: result.userRecord.scope });
await request.server.app.active.set(result.userRecord.username, { authtoken: randomAuthToken,username: result.userRecord.username, email: result.userRecord.email, scope: result.userRecord.scope });
const authTokenCacheRecord = {
username: result.userRecord.username,
email: result.userRecord.email,
scope: result.userRecord.scope
};

await request.server.app.authtokens.set(randomAuthToken, authTokenCacheRecord);

const activeCacheRecord = {
authtoken: randomAuthToken,
username: result.userRecord.username,
email: result.userRecord.email,
scope: result.userRecord.scope
};

await request.server.app.active.set(result.userRecord.username, activeCacheRecord);

const welcome = { result: 'welcome', message: 'successful authentication', token: randomAuthToken };

return welcome;
}

Expand All @@ -92,7 +107,6 @@ exports.plugin = {
pre: [{ method: authenticatePreperation, assign: 'welcome' }]
}
});
// curl -H "Content-Type: application/json" -X POST -d '{"username":"foofoo","password":"12345678"}' https://localhost:8000/authenticate

//
// ./private
Expand All @@ -103,14 +117,37 @@ exports.plugin = {
return 'privateData';
};

const onPreResponseStep = function (request, h) {

const response = request.response;

if (
(response.isBoom) &&
(response.message === 'Authentication data missing credentials information')
) {

// Attempt was made to access private data with bad credentials

request.server.log(['authentication', 'error', 'abuse'], 'Authentication data missing credentials information');
}

return h.continue;

};

server.route({
method: 'GET',
path: '/private',
config: {
description: 'private data for authenticated `admin` users.',
auth: { strategy: 'default', scope: ['admin'] },
handler: privateHandle
handler: privateHandle,
ext: {
onPreResponse: { method: onPreResponseStep }
}
}
});
}
};

// curl -H "Content-Type: application/json" -X POST -d '{"username":"foofoo","password":"12345678"}' https://localhost:8000/authenticate
Loading

0 comments on commit bf05c4b

Please sign in to comment.