1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01:00

Merge pull request #79 from finn-no/simple_authentication

Username in a cookie. Closes #33
This commit is contained in:
Ivar Conradi Østhus 2015-02-05 17:35:51 +01:00
commit e8818dda8e
10 changed files with 112 additions and 24 deletions

3
app.js
View File

@ -1,5 +1,6 @@
var express = require('express'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
log4js = require('log4js'),
logger = require('./lib/logger'),
routes = require('./lib/routes'),
@ -38,6 +39,8 @@ app.set('port', process.env.HTTP_PORT || process.env.PORT || 4242);
app.use(baseUriPath, express.static(__dirname + '/public'));
app.use(bodyParser.json({strict: false}));
app.use(cookieParser());
eventApi(router);
featureApi(router);
featureArchiveApi(router);

4
lib/extractUser.js Normal file
View File

@ -0,0 +1,4 @@
function extractUsername(req) {
return req.cookies.username || "unknown";
}
module.exports = extractUsername;

View File

@ -7,6 +7,7 @@ var NameExistsError = require('./error/NameExistsError');
var NotFoundError = require('./error/NotFoundError');
var ValidationError = require('./error/ValidationError');
var validateRequest = require('./error/validateRequest');
var extractUser = require('./extractUser');
module.exports = function (app) {
@ -33,7 +34,7 @@ module.exports = function (app) {
.then(function() {
return eventStore.create({
type: eventType.featureCreated,
createdBy: req.connection.remoteAddress,
createdBy: extractUser(req),
data: req.body
});
})
@ -56,7 +57,7 @@ module.exports = function (app) {
app.put('/features/:featureName', function (req, res) {
var featureName = req.params.featureName;
var userName = req.connection.remoteAddress;
var userName = extractUser(req);
var updatedFeature = req.body;
updatedFeature.name = featureName;
@ -83,7 +84,7 @@ module.exports = function (app) {
app.delete('/features/:featureName', function (req, res) {
var featureName = req.params.featureName;
var userName = req.connection.remoteAddress;
var userName = extractUser(req);
featureDb.getFeature(featureName)
.then(function () {
@ -118,4 +119,3 @@ module.exports = function (app) {
});
}
};

View File

@ -6,6 +6,7 @@ var logger = require('./logger');
var NameExistsError = require('./error/NameExistsError');
var ValidationError = require('./error/ValidationError');
var validateRequest = require('./error/validateRequest');
var extractUser = require('./extractUser');
module.exports = function (app) {
@ -24,7 +25,7 @@ module.exports = function (app) {
app.delete('/strategies/:name', function (req, res) {
eventStore.create({
type: eventType.strategyDeleted,
createdBy: req.connection.remoteAddress,
createdBy: extractUser(req),
data: {
name: req.params.name
}
@ -44,7 +45,7 @@ module.exports = function (app) {
.then(function() {
return eventStore.create({
type: eventType.strategyCreated,
createdBy: req.connection.remoteAddress,
createdBy: extractUser(req),
data: newStrategy
});
})
@ -75,4 +76,3 @@ module.exports = function (app) {
}
};

View File

@ -35,6 +35,7 @@
"dependencies": {
"bluebird": "2.6.2",
"body-parser": "1.10.1",
"cookie-parser": "^1.3.3",
"db-migrate": "0.7.1",
"deep-diff": "^0.3.0",
"errorhandler": "1.3.2",

View File

@ -1,11 +1,14 @@
var React = require('react');
var TabView = require('./components/TabView');
var Menu = require('./components/Menu');
var UserStore = require('./stores/UserStore');
var LogEntriesComponent = React.createFactory(require('./components/log/LogEntriesComponent'));
var FeatureTogglesComponent = React.createFactory(require('./components/feature/FeatureTogglesComponent'));
var StrategiesComponent = React.createFactory(require('./components/strategy/StrategiesComponent'));
var ArchiveFeatureComponent = React.createFactory(require('./components/feature/ArchiveFeatureComponent'));
UserStore.init();
var tabPanes = [
{
name: 'Feature Toggles',

View File

@ -1,10 +1,14 @@
var React = require('react');
var User = require('./User');
var Menu = React.createClass({
render: function() { return (
<div className="topbar mbl">
<div className="container">
<div className="page">
<div className="fright-ht768">
<User />
</div>
<div className="nav-level1 h4">
<a href="" className="homelink pln">
<span className="topbar-nav-svg-home">

View File

@ -0,0 +1,23 @@
var React = require('react');
var UserStore = require('../stores/UserStore');
var User = React.createClass({
onSave: function() {
var value = this.refs.username.getDOMNode().value.trim();
UserStore.set(value);
},
render: function() {
return (
<div className="r-pvm">
<input type="text" placeholder="username"
ref="username"
defaultValue={UserStore.get()}
onBlur={this.onSave} />
</div>
);
}
});
module.exports = User;

View File

@ -0,0 +1,34 @@
var _username;
//Ref: http://stackoverflow.com/questions/10730362/get-cookie-by-name
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') {
c = c.substring(1,c.length);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length,c.length);
}
}
return null;
}
var UserStore = {
init: function init() {
_username = readCookie("username");
},
set: function set(username) {
_username=username;
document.cookie="username="+_username+"; expires=Thu, 18 Dec 2099 12:00:00 UTC";
},
get: function get() {
return _username;
}
};
module.exports = UserStore;

View File

@ -36,6 +36,22 @@ describe('The features api', function () {
.expect(201, done);
});
it('creates new feature toggle with createdBy', function (done) {
request
.post('/features')
.send({name: 'com.test.Username', enabled: false})
.set('Cookie', ['username=ivaosthu'])
.set('Content-Type', 'application/json')
.end(function(){
request
.get('/events')
.end(function (err, res) {
assert.equal(res.body.events[0].createdBy, 'ivaosthu');
done();
});
});
});
it('require new feature toggle to have a name', function (done) {
request
.post('/features')