1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-28 00:06:53 +01:00

When the user enters his username in to the field

a username cookie is updated and will be available
in all subsequent requests.

THIS IS NOT AUTHENTICATION! it is not safe and is
only implemented as a first edition. It does how ever
solve the issue where we are not able to see who
canged what.
This commit is contained in:
Ivar Conradi Østhus 2015-02-05 13:39:00 +01:00
parent 13ab89a91e
commit 2a4a76aaf5
9 changed files with 172 additions and 100 deletions

27
app.js
View File

@ -1,16 +1,17 @@
var express = require('express'), var express = require('express'),
bodyParser = require('body-parser'), bodyParser = require('body-parser'),
log4js = require('log4js'), cookieParser = require('cookie-parser'),
logger = require('./lib/logger'), log4js = require('log4js'),
routes = require('./lib/routes'), logger = require('./lib/logger'),
eventApi = require('./lib/eventApi'), routes = require('./lib/routes'),
featureApi = require('./lib/featureApi'), eventApi = require('./lib/eventApi'),
featureApi = require('./lib/featureApi'),
featureArchiveApi = require('./lib/featureArchiveApi'), featureArchiveApi = require('./lib/featureArchiveApi'),
strategyApi = require('./lib/strategyApi'), strategyApi = require('./lib/strategyApi'),
validator = require('express-validator'), validator = require('express-validator'),
app = express(), app = express(),
router = express.Router(), router = express.Router(),
baseUriPath = process.env.BASE_URI_PATH || ''; baseUriPath = process.env.BASE_URI_PATH || '';
if(app.get('env') === 'development') { if(app.get('env') === 'development') {
app.use(require('errorhandler')()); app.use(require('errorhandler')());
@ -38,6 +39,8 @@ app.set('port', process.env.HTTP_PORT || process.env.PORT || 4242);
app.use(baseUriPath, express.static(__dirname + '/public')); app.use(baseUriPath, express.static(__dirname + '/public'));
app.use(bodyParser.json({strict: false})); app.use(bodyParser.json({strict: false}));
app.use(cookieParser());
eventApi(router); eventApi(router);
featureApi(router); featureApi(router);
featureArchiveApi(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 NotFoundError = require('./error/NotFoundError');
var ValidationError = require('./error/ValidationError'); var ValidationError = require('./error/ValidationError');
var validateRequest = require('./error/validateRequest'); var validateRequest = require('./error/validateRequest');
var extractUser = require('./extractUser');
module.exports = function (app) { module.exports = function (app) {
@ -33,7 +34,7 @@ module.exports = function (app) {
.then(function() { .then(function() {
return eventStore.create({ return eventStore.create({
type: eventType.featureCreated, type: eventType.featureCreated,
createdBy: req.connection.remoteAddress, createdBy: extractUser(req),
data: req.body data: req.body
}); });
}) })
@ -56,7 +57,7 @@ module.exports = function (app) {
app.put('/features/:featureName', function (req, res) { app.put('/features/:featureName', function (req, res) {
var featureName = req.params.featureName; var featureName = req.params.featureName;
var userName = req.connection.remoteAddress; var userName = extractUser(req);
var updatedFeature = req.body; var updatedFeature = req.body;
updatedFeature.name = featureName; updatedFeature.name = featureName;
@ -83,7 +84,7 @@ module.exports = function (app) {
app.delete('/features/:featureName', function (req, res) { app.delete('/features/:featureName', function (req, res) {
var featureName = req.params.featureName; var featureName = req.params.featureName;
var userName = req.connection.remoteAddress; var userName = extractUser(req);
featureDb.getFeature(featureName) featureDb.getFeature(featureName)
.then(function () { .then(function () {
@ -118,4 +119,3 @@ module.exports = function (app) {
}); });
} }
}; };

View File

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

View File

@ -1,80 +1,81 @@
{ {
"name": "unleash-server", "name": "unleash-server",
"description": "unleash your features", "description": "unleash your features",
"version": "0.0.1", "version": "0.0.1",
"keywords": [ "keywords": [
"unleash", "unleash",
"feature toggle", "feature toggle",
"feature", "feature",
"toggle" "toggle"
],
"repository": {
"type": "git",
"url": "ssh://git@github.com:finn-no/unleash.git"
},
"bugs": {
"url": "https://github.com/finn-no/unleash/issues"
},
"private": true,
"scripts": {
"start": "NODE_ENV=production node server.js",
"build": "./node_modules/.bin/webpack",
"dev": "NODE_ENV=development supervisor --ignore ./node_modules/,./public/js server.js",
"test": "export PORT=4243 ; jest && jshint server.js lib test && jsxhint public/js/**/*.jsx && mocha test test/*.js && npm run coverage",
"docker-test": "export PORT=4243 ; ./scripts/docker-postgres.sh",
"pg-virtualenv-test": "pg_virtualenv npm run pg-virtualenv-chain",
"pg-virtualenv-chain": "export TEST_DATABASE_URL=postgres://$PGUSER:$PGPASSWORD@localhost:$PGPORT/postgres ; npm run db-migrate-testdb && npm test",
"db-migrate-testdb": "DATABASE_URL=$TEST_DATABASE_URL ./node_modules/.bin/db-migrate up",
"tdd": "mocha --watch test test/*",
"test-bamboo-ci": "mocha test test/*",
"coverage": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec",
"coverage-report": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage",
"postinstall": "npm run build",
"jest": "jest"
},
"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",
"express": "4.9.8",
"express-validator": "2.8.0",
"ini": "1.3.2",
"jsx-loader": "0.12.2",
"jsxhint": "0.4.15",
"knex": "^0.7.3",
"log4js": "0.6.21",
"moment": "^2.9.0",
"nconf": "0.6.9",
"pg": "3.6.1",
"react": "^0.12.0",
"reqwest": "^1.1.4",
"webpack": "1.4.15",
"webpack-dev-middleware": "^1.0.11"
},
"devDependencies": {
"chai": "1.9.1",
"coveralls": "^2.11.2",
"istanbul": "0.3.2",
"jest-cli": "^0.1.18",
"jshint": "2.5.2",
"mocha": "1.20.1",
"mocha-lcov-reporter": "0.0.1",
"pre-commit": "0.0.9",
"react-tools": "^0.12.0",
"supertest": "0.13.0",
"supervisor": "0.6.0",
"xmlbuilder": "2.4.4"
},
"jest": {
"scriptPreprocessor": "<rootDir>/jest-preprocessor.js",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react"
], ],
"repository": { "moduleFileExtensions": [
"type": "git", "jsx",
"url": "ssh://git@github.com:finn-no/unleash.git" "js"
}, ]
"bugs": { }
"url": "https://github.com/finn-no/unleash/issues"
},
"private": true,
"scripts": {
"start": "NODE_ENV=production node server.js",
"build": "./node_modules/.bin/webpack",
"dev": "NODE_ENV=development supervisor --ignore ./node_modules/,./public/js server.js",
"test": "export PORT=4243 ; jest && jshint server.js lib test && jsxhint public/js/**/*.jsx && mocha test test/*.js && npm run coverage",
"docker-test": "export PORT=4243 ; ./scripts/docker-postgres.sh",
"pg-virtualenv-test": "pg_virtualenv npm run pg-virtualenv-chain",
"pg-virtualenv-chain": "export TEST_DATABASE_URL=postgres://$PGUSER:$PGPASSWORD@localhost:$PGPORT/postgres ; npm run db-migrate-testdb && npm test",
"db-migrate-testdb": "DATABASE_URL=$TEST_DATABASE_URL ./node_modules/.bin/db-migrate up",
"tdd": "mocha --watch test test/*",
"test-bamboo-ci": "mocha test test/*",
"coverage": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec",
"coverage-report": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage",
"postinstall": "npm run build",
"jest": "jest"
},
"dependencies": {
"bluebird": "2.6.2",
"body-parser": "1.10.1",
"db-migrate": "0.7.1",
"deep-diff": "^0.3.0",
"errorhandler": "1.3.2",
"express": "4.9.8",
"express-validator": "2.8.0",
"ini": "1.3.2",
"jsx-loader": "0.12.2",
"jsxhint": "0.4.15",
"knex": "^0.7.3",
"log4js": "0.6.21",
"moment": "^2.9.0",
"nconf": "0.6.9",
"pg": "3.6.1",
"react": "^0.12.0",
"reqwest": "^1.1.4",
"webpack": "1.4.15",
"webpack-dev-middleware": "^1.0.11"
},
"devDependencies": {
"chai": "1.9.1",
"coveralls": "^2.11.2",
"istanbul": "0.3.2",
"jest-cli": "^0.1.18",
"jshint": "2.5.2",
"mocha": "1.20.1",
"mocha-lcov-reporter": "0.0.1",
"pre-commit": "0.0.9",
"react-tools": "^0.12.0",
"supertest": "0.13.0",
"supervisor": "0.6.0",
"xmlbuilder": "2.4.4"
},
"jest": {
"scriptPreprocessor": "<rootDir>/jest-preprocessor.js",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react"
],
"moduleFileExtensions": [
"jsx",
"js"
]
}
} }

View File

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

View File

@ -1,4 +1,5 @@
var React = require('react'); var React = require('react');
var User = require('./User');
var Menu = React.createClass({ var Menu = React.createClass({
render: function() { return ( render: function() { return (
@ -46,6 +47,9 @@ var Menu = React.createClass({
unleash admin unleash admin
</span> </span>
</a> </a>
<div style={{position: "absolute", right: "0"}}>
<User />
</div>
</div> </div>
</div> </div>
</div> </div>

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-pam">
<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;