mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into devel
This commit is contained in:
commit
b4efb78f7c
|
@ -320,7 +320,7 @@ SHELL_SERVER_ONLY = \
|
|||
@top_srcdir@/js/common/tests/shell-foxx-base-middleware.js \
|
||||
@top_srcdir@/js/common/tests/shell-foxx-template-middleware.js \
|
||||
@top_srcdir@/js/common/tests/shell-foxx-format-middleware.js \
|
||||
@top_srcdir@/js/common/tests/shell-foxx-transformer.js \
|
||||
@top_srcdir@/js/common/tests/shell-foxx-preprocessor.js \
|
||||
@top_srcdir@/js/common/tests/shell-graph-traversal.js \
|
||||
@top_srcdir@/js/common/tests/shell-graph-algorithms.js \
|
||||
@top_srcdir@/js/common/tests/shell-graph-measurement.js \
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*global module, require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Foxx application
|
||||
/// @brief Foxx Preprocessor
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
|
@ -28,8 +28,8 @@
|
|||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var Transformer,
|
||||
transform,
|
||||
var Preprocessor,
|
||||
preprocess,
|
||||
ArrayIterator,
|
||||
extend = require("underscore").extend;
|
||||
|
||||
|
@ -74,13 +74,13 @@ extend(ArrayIterator.prototype, {
|
|||
}
|
||||
});
|
||||
|
||||
Transformer = function (input) {
|
||||
Preprocessor = function (input) {
|
||||
'use strict';
|
||||
this.iterator = new ArrayIterator(input.split("\n"));
|
||||
this.inJSDoc = false;
|
||||
};
|
||||
|
||||
extend(Transformer.prototype, {
|
||||
extend(Preprocessor.prototype, {
|
||||
result: function () {
|
||||
'use strict';
|
||||
return this.iterator.entireString();
|
||||
|
@ -140,17 +140,17 @@ extend(Transformer.prototype, {
|
|||
}
|
||||
});
|
||||
|
||||
transform = function (input) {
|
||||
preprocess = function (input) {
|
||||
'use strict';
|
||||
var transformer = new Transformer(input);
|
||||
return transformer.convert().result();
|
||||
var processer = new Preprocessor(input);
|
||||
return processer.convert().result();
|
||||
};
|
||||
|
||||
// Only Exported for Tests, please use `transform`
|
||||
exports.Transformer = Transformer;
|
||||
// Only Exported for Tests, please use `process`
|
||||
exports.Preprocessor = Preprocessor;
|
||||
|
||||
// transform(str) returns the transformed String
|
||||
exports.transform = transform;
|
||||
// process(str) returns the processed String
|
||||
exports.preprocess = preprocess;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
|
@ -1,11 +1,11 @@
|
|||
require("internal").flushModuleCache();
|
||||
|
||||
var jsunity = require("jsunity"),
|
||||
transform = require("org/arangodb/foxx/transformer").transform,
|
||||
Transformer = require("org/arangodb/foxx/transformer").Transformer;
|
||||
preprocess = require("org/arangodb/foxx/preprocessor").preprocess,
|
||||
Preprocessor = require("org/arangodb/foxx/preprocessor").Preprocessor;
|
||||
|
||||
// High Level Spec Suite for the transform Function
|
||||
function TransformSpec () {
|
||||
// High Level Spec Suite for the preprocess Function
|
||||
function PreprocessSpec () {
|
||||
var testFileWithoutJSDoc, testFileWithJSDoc, testFileWithJSDocTransformed;
|
||||
|
||||
return {
|
||||
|
@ -40,18 +40,18 @@ function TransformSpec () {
|
|||
},
|
||||
|
||||
testDoesntChangeFileWithoutJSDocComments: function () {
|
||||
assertEqual(transform(testFileWithoutJSDoc), testFileWithoutJSDoc);
|
||||
assertEqual(preprocess(testFileWithoutJSDoc), testFileWithoutJSDoc);
|
||||
},
|
||||
|
||||
testTransformsFileWithJSDocComments: function () {
|
||||
assertEqual(transform(testFileWithJSDoc), testFileWithJSDocTransformed);
|
||||
assertEqual(preprocess(testFileWithJSDoc), testFileWithJSDocTransformed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Low level Spec Suite for the Transform prototype
|
||||
function TransformerSpec () {
|
||||
var i, result, testFileWithSingleJSDoc, testFileWithJSDocAndMultiline, transformedLineOne;
|
||||
function PreprocessorSpec () {
|
||||
var i, result, testFileWithSingleJSDoc, testFileWithJSDocAndMultiline, processedLineOne;
|
||||
|
||||
return {
|
||||
setUp: function () {
|
||||
|
@ -64,7 +64,7 @@ function TransformerSpec () {
|
|||
"}());"
|
||||
].join("\n");
|
||||
|
||||
transformedLineOne = [
|
||||
processedLineOne = [
|
||||
"(function() {",
|
||||
"applicationContext.comment(\"long description\");",
|
||||
" * test",
|
||||
|
@ -96,67 +96,67 @@ function TransformerSpec () {
|
|||
},
|
||||
|
||||
testSearchForFirstJSDocStart: function () {
|
||||
transformer = new Transformer(testFileWithSingleJSDoc);
|
||||
processer = new Preprocessor(testFileWithSingleJSDoc);
|
||||
|
||||
for (i = 0; i < 1; i++) {
|
||||
transformer.searchNext();
|
||||
processer.searchNext();
|
||||
}
|
||||
|
||||
assertEqual(transformer.getCurrentLineNumber(), 1);
|
||||
assertEqual(processer.getCurrentLineNumber(), 1);
|
||||
},
|
||||
|
||||
testContinueInJSDoc: function () {
|
||||
transformer = new Transformer(testFileWithSingleJSDoc);
|
||||
processer = new Preprocessor(testFileWithSingleJSDoc);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
transformer.searchNext();
|
||||
processer.searchNext();
|
||||
}
|
||||
|
||||
assertEqual(transformer.getCurrentLineNumber(), 2);
|
||||
assertEqual(processer.getCurrentLineNumber(), 2);
|
||||
},
|
||||
|
||||
testStopAtTheEndOfJSDoc: function () {
|
||||
transformer = new Transformer(testFileWithSingleJSDoc);
|
||||
processer = new Preprocessor(testFileWithSingleJSDoc);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
transformer.searchNext();
|
||||
processer.searchNext();
|
||||
}
|
||||
|
||||
assertUndefined(transformer.getCurrentLineNumber());
|
||||
assertUndefined(processer.getCurrentLineNumber());
|
||||
},
|
||||
|
||||
testDoNotIncludeNormalMultiline: function () {
|
||||
transformer = new Transformer(testFileWithMultiline);
|
||||
processer = new Preprocessor(testFileWithMultiline);
|
||||
|
||||
for (i = 0; i < 1; i++) {
|
||||
transformer.searchNext();
|
||||
processer.searchNext();
|
||||
}
|
||||
|
||||
assertUndefined(transformer.getCurrentLineNumber());
|
||||
assertUndefined(processer.getCurrentLineNumber());
|
||||
},
|
||||
|
||||
testDoNotIncludeNonJSDocComments: function () {
|
||||
transformer = new Transformer(testFileWithJSDocAndMultiline);
|
||||
processer = new Preprocessor(testFileWithJSDocAndMultiline);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
transformer.searchNext();
|
||||
processer.searchNext();
|
||||
}
|
||||
|
||||
assertUndefined(transformer.getCurrentLineNumber());
|
||||
assertUndefined(processer.getCurrentLineNumber());
|
||||
},
|
||||
|
||||
testConvertLine: function () {
|
||||
transformer = new Transformer(testFileWithSingleJSDoc);
|
||||
processer = new Preprocessor(testFileWithSingleJSDoc);
|
||||
|
||||
transformer.searchNext();
|
||||
transformer.convertLine();
|
||||
processer.searchNext();
|
||||
processer.convertLine();
|
||||
|
||||
assertEqual(transformer.result(), transformedLineOne);
|
||||
assertEqual(processer.result(), processedLineOne);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
jsunity.run(TransformSpec);
|
||||
jsunity.run(TransformerSpec);
|
||||
jsunity.run(PreprocessSpec);
|
||||
jsunity.run(PreprocessorSpec);
|
||||
|
||||
return jsunity.done();
|
|
@ -164,7 +164,63 @@ function SetRoutesFoxxControllerSpec () {
|
|||
}
|
||||
assertEqual(error, new Error("URL has to be a String"));
|
||||
assertEqual(routes.length, 0);
|
||||
}
|
||||
},
|
||||
|
||||
testAddALoginRoute: function () {
|
||||
var myFunc = function () {},
|
||||
routes = app.routingInfo.routes;
|
||||
|
||||
app.activateAuthentication({
|
||||
type: "cookie",
|
||||
cookieLifetime: 360000,
|
||||
cookieName: "my_cookie",
|
||||
sessionLifetime: 400
|
||||
});
|
||||
app.login('/simple/route', myFunc);
|
||||
assertEqual(routes[0].docs.httpMethod, 'POST');
|
||||
assertEqual(routes[0].url.methods, ["post"]);
|
||||
},
|
||||
|
||||
testRefuseLoginWhenAuthIsNotSetUp: function () {
|
||||
var myFunc = function () {},
|
||||
error;
|
||||
|
||||
try {
|
||||
app.login('/simple/route', myFunc);
|
||||
} catch(e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
assertEqual(error, new Error("Setup authentication first"));
|
||||
},
|
||||
|
||||
testAddALogoutRoute: function () {
|
||||
var myFunc = function () {},
|
||||
routes = app.routingInfo.routes;
|
||||
|
||||
app.activateAuthentication({
|
||||
type: "cookie",
|
||||
cookieLifetime: 360000,
|
||||
cookieName: "my_cookie",
|
||||
sessionLifetime: 400
|
||||
});
|
||||
app.logout('/simple/route', myFunc);
|
||||
assertEqual(routes[0].docs.httpMethod, 'POST');
|
||||
assertEqual(routes[0].url.methods, ["post"]);
|
||||
},
|
||||
|
||||
testRefuseLogoutWhenAuthIsNotSetUp: function () {
|
||||
var myFunc = function () {},
|
||||
error;
|
||||
|
||||
try {
|
||||
app.logout('/simple/route', myFunc);
|
||||
} catch(e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
assertEqual(error, new Error("Setup authentication first"));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ var _ = require("underscore");
|
|||
|
||||
var executeGlobalContextFunction = require("internal").executeGlobalContextFunction;
|
||||
var checkParameter = arangodb.checkParameter;
|
||||
var transformScript = require("org/arangodb/foxx/transformer").transform;
|
||||
var transformScript = require("org/arangodb/foxx/preprocessor").preprocess;
|
||||
|
||||
var developmentMode = require("internal").developmentMode;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, regexp: true, plusplus: true, continue: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 120, plusplus: true, continue: true */
|
||||
/*global require, exports */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -24,19 +24,176 @@
|
|||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Jan Steemann, Lucas Dohmen
|
||||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var arangodb = require("org/arangodb");
|
||||
var db = require("org/arangodb").db;
|
||||
var crypto = require("org/arangodb/crypto");
|
||||
var internal = require("internal");
|
||||
var arangodb = require("org/arangodb"),
|
||||
db = require("org/arangodb").db,
|
||||
crypto = require("org/arangodb/crypto"),
|
||||
internal = require("internal"),
|
||||
is = require("org/arangodb/is"),
|
||||
_ = require("underscore"),
|
||||
errors = require("internal").errors,
|
||||
defaultsFor = {},
|
||||
checkAuthenticationOptions,
|
||||
createStandardLoginHandler,
|
||||
createStandardLogoutHandler,
|
||||
createAuthenticationMiddleware,
|
||||
createSessionUpdateMiddleware,
|
||||
createAuthObject,
|
||||
generateToken,
|
||||
cloneDocument,
|
||||
checkPassword,
|
||||
encodePassword,
|
||||
Users,
|
||||
Sessions,
|
||||
CookieAuthentication,
|
||||
Authentication,
|
||||
UnauthorizedError;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- helper functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
createAuthenticationMiddleware = function (auth, applicationContext) {
|
||||
'use strict';
|
||||
return function (req, res) {
|
||||
var users = new Users(applicationContext),
|
||||
authResult = auth.authenticate(req);
|
||||
|
||||
if (authResult.errorNum === errors.ERROR_NO_ERROR) {
|
||||
req.currentSession = authResult.session;
|
||||
req.user = users.get(authResult.session.identifier);
|
||||
} else {
|
||||
req.currentSession = null;
|
||||
req.user = null;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
createSessionUpdateMiddleware = function () {
|
||||
'use strict';
|
||||
return function (req, res) {
|
||||
var session = req.currentSession;
|
||||
|
||||
if (is.existy(session)) {
|
||||
session.update();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
createAuthObject = function (applicationContext, opts) {
|
||||
'use strict';
|
||||
var sessions,
|
||||
cookieAuth,
|
||||
auth,
|
||||
options = opts || {};
|
||||
|
||||
checkAuthenticationOptions(options);
|
||||
|
||||
sessions = new Sessions(applicationContext, {
|
||||
lifetime: options.sessionLifetime
|
||||
});
|
||||
|
||||
cookieAuth = new CookieAuthentication(applicationContext, {
|
||||
lifetime: options.cookieLifetime,
|
||||
name: options.cookieName
|
||||
});
|
||||
|
||||
auth = new Authentication(applicationContext, sessions, cookieAuth);
|
||||
|
||||
return auth;
|
||||
};
|
||||
|
||||
checkAuthenticationOptions = function (options) {
|
||||
'use strict';
|
||||
if (options.type !== "cookie") {
|
||||
throw new Error("Currently only the following auth types are supported: cookie");
|
||||
}
|
||||
if (is.falsy(options.cookieLifetime)) {
|
||||
throw new Error("Please provide the cookieLifetime");
|
||||
}
|
||||
if (is.falsy(options.cookieName)) {
|
||||
throw new Error("Please provide the cookieName");
|
||||
}
|
||||
if (is.falsy(options.sessionLifetime)) {
|
||||
throw new Error("Please provide the sessionLifetime");
|
||||
}
|
||||
};
|
||||
|
||||
defaultsFor.login = {
|
||||
usernameField: "username",
|
||||
passwordField: "password",
|
||||
|
||||
onSuccess: function (req, res) {
|
||||
'use strict';
|
||||
res.json({
|
||||
user: req.user.identifier,
|
||||
key: req.currentSession._key
|
||||
});
|
||||
},
|
||||
|
||||
onError: function (req, res) {
|
||||
'use strict';
|
||||
res.status(401);
|
||||
res.json({
|
||||
error: "Username or Password was wrong"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
createStandardLoginHandler = function (auth, users, opts) {
|
||||
'use strict';
|
||||
var options = _.defaults(opts || {}, defaultsFor.login);
|
||||
|
||||
return function (req, res) {
|
||||
var username = req.body()[options.usernameField],
|
||||
password = req.body()[options.passwordField];
|
||||
|
||||
if (users.isValid(username, password)) {
|
||||
req.currentSession = auth.beginSession(req, res, username, {});
|
||||
req.user = users.get(req.currentSession.identifier);
|
||||
options.onSuccess(req, res);
|
||||
} else {
|
||||
options.onError(req, res);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
defaultsFor.logout = {
|
||||
onSuccess: function (req, res) {
|
||||
'use strict';
|
||||
res.json({
|
||||
notice: "Logged out!",
|
||||
});
|
||||
},
|
||||
|
||||
onError: function (req, res) {
|
||||
'use strict';
|
||||
res.status(401);
|
||||
res.json({
|
||||
error: "No session was found"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
createStandardLogoutHandler = function (auth, opts) {
|
||||
'use strict';
|
||||
var options = _.defaults(opts || {}, defaultsFor.logout);
|
||||
|
||||
return function (req, res) {
|
||||
if (is.existy(req.currentSession)) {
|
||||
auth.endSession(req, res, req.currentSession._key);
|
||||
req.user = null;
|
||||
req.currentSession = null;
|
||||
options.onSuccess(req, res);
|
||||
} else {
|
||||
options.onError(req, res);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Foxx
|
||||
/// @{
|
||||
|
@ -46,32 +203,31 @@ var internal = require("internal");
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function generateToken () {
|
||||
generateToken = function () {
|
||||
'use strict';
|
||||
|
||||
return internal.genRandomAlphaNumbers(32);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief deep-copies a document
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function cloneDocument (obj) {
|
||||
cloneDocument = function (obj) {
|
||||
"use strict";
|
||||
var copy, a;
|
||||
|
||||
if (obj === null || typeof(obj) !== "object") {
|
||||
if (obj === null || typeof obj !== "object") {
|
||||
return obj;
|
||||
}
|
||||
|
||||
var copy, a;
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
copy = [ ];
|
||||
copy = [];
|
||||
obj.forEach(function (i) {
|
||||
copy.push(cloneDocument(i));
|
||||
});
|
||||
}
|
||||
else if (obj instanceof Object) {
|
||||
copy = { };
|
||||
} else if (obj instanceof Object) {
|
||||
copy = {};
|
||||
for (a in obj) {
|
||||
if (obj.hasOwnProperty(a)) {
|
||||
copy[a] = cloneDocument(obj[a]);
|
||||
|
@ -80,46 +236,44 @@ function cloneDocument (obj) {
|
|||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks whether the plain text password matches the encoded one
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function checkPassword (plain, encoded) {
|
||||
checkPassword = function (plain, encoded) {
|
||||
'use strict';
|
||||
|
||||
var salted = encoded.substr(3, 8) + plain;
|
||||
var hex = crypto.sha256(salted);
|
||||
var salted = encoded.substr(3, 8) + plain,
|
||||
hex = crypto.sha256(salted);
|
||||
|
||||
return (encoded.substr(12) === hex);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief encodes a password
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function encodePassword (password) {
|
||||
encodePassword = function (password) {
|
||||
'use strict';
|
||||
var salt,
|
||||
encoded,
|
||||
random;
|
||||
|
||||
var salt;
|
||||
var encoded;
|
||||
|
||||
var random = crypto.rand();
|
||||
random = crypto.rand();
|
||||
if (random === undefined) {
|
||||
random = "time:" + internal.time();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
random = "random:" + random;
|
||||
}
|
||||
|
||||
salt = crypto.sha256(random);
|
||||
salt = salt.substr(0,8);
|
||||
salt = salt.substr(0, 8);
|
||||
|
||||
encoded = "$1$" + salt + "$" + crypto.sha256(salt + password);
|
||||
|
||||
|
||||
return encoded;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -142,19 +296,18 @@ function encodePassword (password) {
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function Users (applicationContext, options) {
|
||||
Users = function (applicationContext, options) {
|
||||
'use strict';
|
||||
|
||||
this._options = options || { };
|
||||
this._options = options || {};
|
||||
this._collection = null;
|
||||
|
||||
|
||||
if (this._options.hasOwnProperty("collectionName")) {
|
||||
this._collectionName = this._options.collectionName;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this._collectionName = applicationContext.collectionName("users");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -178,8 +331,8 @@ Users.prototype.storage = function () {
|
|||
|
||||
if (this._collection === null) {
|
||||
this._collection = db._collection(this._collectionName);
|
||||
|
||||
if (! this._collection) {
|
||||
|
||||
if (!this._collection) {
|
||||
throw new Error("users collection not found");
|
||||
}
|
||||
}
|
||||
|
@ -230,21 +383,21 @@ Users.prototype._validateIdentifier = function (identifier, allowObject) {
|
|||
|
||||
Users.prototype.setup = function (options) {
|
||||
'use strict';
|
||||
|
||||
var journalSize;
|
||||
var journalSize,
|
||||
createOptions;
|
||||
|
||||
if (typeof options === 'object' && options.hasOwnProperty('journalSize')) {
|
||||
journalSize = options.journalSize;
|
||||
}
|
||||
|
||||
var createOptions = {
|
||||
createOptions = {
|
||||
journalSize : journalSize || 2 * 1024 * 1024
|
||||
};
|
||||
|
||||
if (! db._collection(this._collectionName)) {
|
||||
if (!db._collection(this._collectionName)) {
|
||||
db._create(this._collectionName, createOptions);
|
||||
}
|
||||
|
||||
|
||||
this.storage().ensureUniqueConstraint("identifier");
|
||||
};
|
||||
|
||||
|
@ -254,7 +407,6 @@ Users.prototype.setup = function (options) {
|
|||
|
||||
Users.prototype.teardown = function () {
|
||||
'use strict';
|
||||
|
||||
var c = db._collection(this._collectionName);
|
||||
|
||||
if (c) {
|
||||
|
@ -268,7 +420,7 @@ Users.prototype.teardown = function () {
|
|||
|
||||
Users.prototype.flush = function () {
|
||||
'use strict';
|
||||
|
||||
|
||||
this.storage().truncate();
|
||||
};
|
||||
|
||||
|
@ -278,10 +430,11 @@ Users.prototype.flush = function () {
|
|||
|
||||
Users.prototype.add = function (identifier, password, active, data) {
|
||||
'use strict';
|
||||
|
||||
var c = this.storage();
|
||||
var c = this.storage(),
|
||||
user;
|
||||
|
||||
identifier = this._validateIdentifier(identifier, false);
|
||||
|
||||
|
||||
if (typeof password !== 'string') {
|
||||
throw new TypeError("invalid type for 'password'");
|
||||
}
|
||||
|
@ -293,11 +446,11 @@ Users.prototype.add = function (identifier, password, active, data) {
|
|||
active = true;
|
||||
}
|
||||
|
||||
var user = {
|
||||
user = {
|
||||
identifier: identifier,
|
||||
password: encodePassword(password),
|
||||
active: active,
|
||||
data: data || { }
|
||||
data: data || {}
|
||||
};
|
||||
|
||||
db._executeTransaction({
|
||||
|
@ -305,13 +458,12 @@ Users.prototype.add = function (identifier, password, active, data) {
|
|||
write: c.name()
|
||||
},
|
||||
action: function (params) {
|
||||
var c = db._collection(params.cn);
|
||||
var u = c.firstExample({ identifier: params.user.identifier });
|
||||
var c = db._collection(params.cn),
|
||||
u = c.firstExample({ identifier: params.user.identifier });
|
||||
|
||||
if (u === null) {
|
||||
c.save(params.user);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
c.replace(u._key, params.user);
|
||||
}
|
||||
},
|
||||
|
@ -332,8 +484,8 @@ Users.prototype.add = function (identifier, password, active, data) {
|
|||
|
||||
Users.prototype.updateData = function (identifier, data) {
|
||||
'use strict';
|
||||
|
||||
var c = this.storage();
|
||||
|
||||
identifier = this._validateIdentifier(identifier, true);
|
||||
|
||||
db._executeTransaction({
|
||||
|
@ -341,8 +493,8 @@ Users.prototype.updateData = function (identifier, data) {
|
|||
write: c.name()
|
||||
},
|
||||
action: function (params) {
|
||||
var c = db._collection(params.cn);
|
||||
var u = c.firstExample({ identifier: params.identifier });
|
||||
var c = db._collection(params.cn),
|
||||
u = c.firstExample({ identifier: params.identifier });
|
||||
|
||||
if (u === null) {
|
||||
throw new Error("user not found");
|
||||
|
@ -352,7 +504,7 @@ Users.prototype.updateData = function (identifier, data) {
|
|||
params: {
|
||||
cn: c.name(),
|
||||
identifier: identifier,
|
||||
data: data || { }
|
||||
data: data || {}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -365,18 +517,20 @@ Users.prototype.updateData = function (identifier, data) {
|
|||
|
||||
Users.prototype.setActive = function (identifier, active) {
|
||||
'use strict';
|
||||
|
||||
var c = this.storage();
|
||||
var c = this.storage(),
|
||||
user,
|
||||
doc;
|
||||
|
||||
identifier = this._validateIdentifier(identifier, true);
|
||||
|
||||
var user = c.firstExample({ identifier: identifier });
|
||||
user = c.firstExample({ identifier: identifier });
|
||||
|
||||
if (user === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// must clone because shaped json cannot be modified
|
||||
var doc = cloneDocument(user);
|
||||
doc = cloneDocument(user);
|
||||
doc.active = active;
|
||||
c.update(doc._key, doc, true, false);
|
||||
|
||||
|
@ -389,21 +543,23 @@ Users.prototype.setActive = function (identifier, active) {
|
|||
|
||||
Users.prototype.setPassword = function (identifier, password) {
|
||||
'use strict';
|
||||
|
||||
var c = this.storage();
|
||||
var c = this.storage(),
|
||||
user,
|
||||
doc;
|
||||
|
||||
identifier = this._validateIdentifier(identifier, true);
|
||||
|
||||
|
||||
if (typeof password !== 'string') {
|
||||
throw new TypeError("invalid type for 'password'");
|
||||
}
|
||||
|
||||
var user = c.firstExample({ identifier: identifier });
|
||||
user = c.firstExample({ identifier: identifier });
|
||||
|
||||
if (user === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var doc = cloneDocument(user);
|
||||
doc = cloneDocument(user);
|
||||
doc.password = encodePassword(password);
|
||||
c.update(doc._key, doc, true, false);
|
||||
|
||||
|
@ -416,11 +572,12 @@ Users.prototype.setPassword = function (identifier, password) {
|
|||
|
||||
Users.prototype.remove = function (identifier) {
|
||||
'use strict';
|
||||
|
||||
var c = this.storage();
|
||||
var c = this.storage(),
|
||||
user;
|
||||
|
||||
identifier = this._validateIdentifier(identifier, true);
|
||||
|
||||
var user = c.firstExample({ identifier: identifier });
|
||||
user = c.firstExample({ identifier: identifier });
|
||||
|
||||
if (user === null) {
|
||||
return false;
|
||||
|
@ -428,8 +585,7 @@ Users.prototype.remove = function (identifier) {
|
|||
|
||||
try {
|
||||
c.remove(user._key);
|
||||
}
|
||||
catch (err) {
|
||||
} catch (err) {
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -441,18 +597,19 @@ Users.prototype.remove = function (identifier) {
|
|||
|
||||
Users.prototype.get = function (identifier) {
|
||||
'use strict';
|
||||
|
||||
var c = this.storage();
|
||||
var c = this.storage(),
|
||||
user;
|
||||
|
||||
identifier = this._validateIdentifier(identifier, true);
|
||||
|
||||
var user = c.firstExample({ identifier: identifier });
|
||||
user = c.firstExample({ identifier: identifier });
|
||||
|
||||
if (user === null) {
|
||||
throw new Error("user not found");
|
||||
}
|
||||
|
||||
delete user.password;
|
||||
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
|
@ -462,26 +619,27 @@ Users.prototype.get = function (identifier) {
|
|||
|
||||
Users.prototype.isValid = function (identifier, password) {
|
||||
'use strict';
|
||||
|
||||
var c = this.storage();
|
||||
var c = this.storage(),
|
||||
user;
|
||||
|
||||
identifier = this._validateIdentifier(identifier, false);
|
||||
|
||||
var user = c.firstExample({ identifier: identifier });
|
||||
user = c.firstExample({ identifier: identifier });
|
||||
|
||||
if (user === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! user.active) {
|
||||
if (!user.active) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! checkPassword(password, user.password)) {
|
||||
if (!checkPassword(password, user.password)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
delete user.password;
|
||||
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
|
@ -505,25 +663,24 @@ Users.prototype.isValid = function (identifier, password) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function Sessions (applicationContext, options) {
|
||||
|
||||
Sessions = function (applicationContext, options) {
|
||||
'use strict';
|
||||
|
||||
this._applicationContext = applicationContext;
|
||||
this._options = options || { };
|
||||
this._options = options || {};
|
||||
this._collection = null;
|
||||
|
||||
if (! this._options.hasOwnProperty("minUpdateResoultion")) {
|
||||
if (!this._options.hasOwnProperty("minUpdateResoultion")) {
|
||||
this._options.minUpdateResolution = 10;
|
||||
}
|
||||
|
||||
|
||||
if (this._options.hasOwnProperty("collectionName")) {
|
||||
this._collectionName = this._options.collectionName;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this._collectionName = applicationContext.collectionName("sessions");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -543,6 +700,7 @@ function Sessions (applicationContext, options) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Sessions.prototype._toObject = function (session) {
|
||||
'use strict';
|
||||
var that = this;
|
||||
|
||||
return {
|
||||
|
@ -562,9 +720,11 @@ Sessions.prototype._toObject = function (session) {
|
|||
},
|
||||
|
||||
update: function () {
|
||||
if (! this._changed) {
|
||||
var oldExpires = this.expires;
|
||||
var newExpires = internal.time() + that._options.lifetime;
|
||||
var oldExpires, newExpires;
|
||||
|
||||
if (!this._changed) {
|
||||
oldExpires = this.expires;
|
||||
newExpires = internal.time() + that._options.lifetime;
|
||||
|
||||
if (newExpires - oldExpires > that._options.minUpdateResolution) {
|
||||
this.expires = newExpires;
|
||||
|
@ -599,18 +759,18 @@ Sessions.prototype._toObject = function (session) {
|
|||
|
||||
Sessions.prototype.setup = function (options) {
|
||||
'use strict';
|
||||
|
||||
var journalSize;
|
||||
var journalSize,
|
||||
createOptions;
|
||||
|
||||
if (typeof options === 'object' && options.hasOwnProperty('journalSize')) {
|
||||
journalSize = options.journalSize;
|
||||
}
|
||||
|
||||
var createOptions = {
|
||||
createOptions = {
|
||||
journalSize : journalSize || 4 * 1024 * 1024
|
||||
};
|
||||
|
||||
if (! db._collection(this._collectionName)) {
|
||||
if (!db._collection(this._collectionName)) {
|
||||
db._create(this._collectionName, createOptions);
|
||||
}
|
||||
|
||||
|
@ -623,7 +783,6 @@ Sessions.prototype.setup = function (options) {
|
|||
|
||||
Sessions.prototype.teardown = function () {
|
||||
'use strict';
|
||||
|
||||
var c = db._collection(this._collectionName);
|
||||
|
||||
if (c) {
|
||||
|
@ -640,8 +799,8 @@ Sessions.prototype.storage = function () {
|
|||
|
||||
if (this._collection === null) {
|
||||
this._collection = db._collection(this._collectionName);
|
||||
|
||||
if (! this._collection) {
|
||||
|
||||
if (!this._collection) {
|
||||
throw new Error("sessions collection not found");
|
||||
}
|
||||
}
|
||||
|
@ -655,38 +814,38 @@ Sessions.prototype.storage = function () {
|
|||
|
||||
Sessions.prototype.generate = function (identifier, data) {
|
||||
'use strict';
|
||||
var storage, token, session;
|
||||
|
||||
if (typeof identifier !== "string" || identifier.length === 0) {
|
||||
throw new TypeError("invalid type for 'identifier'");
|
||||
}
|
||||
|
||||
if (! this._options.hasOwnProperty("lifetime")) {
|
||||
|
||||
if (!this._options.hasOwnProperty("lifetime")) {
|
||||
throw new Error("no value specified for 'lifetime'");
|
||||
}
|
||||
|
||||
var storage = this.storage();
|
||||
storage = this.storage();
|
||||
|
||||
if (! this._options.allowMultiple) {
|
||||
if (!this._options.allowMultiple) {
|
||||
// remove previous existing sessions
|
||||
storage.byExample({ identifier: identifier }).toArray().forEach(function (s) {
|
||||
storage.remove(s);
|
||||
});
|
||||
}
|
||||
|
||||
while (true) {
|
||||
var token = generateToken();
|
||||
var session = {
|
||||
_key: token,
|
||||
while (true) {
|
||||
token = generateToken();
|
||||
session = {
|
||||
_key: token,
|
||||
expires: internal.time() + this._options.lifetime,
|
||||
identifier: identifier,
|
||||
data: data || { }
|
||||
data: data || {}
|
||||
};
|
||||
|
||||
try {
|
||||
storage.save(session);
|
||||
return this._toObject(session);
|
||||
}
|
||||
catch (err) {
|
||||
} catch (err) {
|
||||
// we might have generated the same key again
|
||||
if (err.hasOwnProperty("errorNum") &&
|
||||
err.errorNum === internal.errors.ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED) {
|
||||
|
@ -705,10 +864,10 @@ Sessions.prototype.generate = function (identifier, data) {
|
|||
|
||||
Sessions.prototype.update = function (token, data) {
|
||||
'use strict';
|
||||
|
||||
this.storage().update(token, {
|
||||
|
||||
this.storage().update(token, {
|
||||
expires: internal.time() + this._options.lifetime,
|
||||
data: data
|
||||
data: data
|
||||
}, true, false);
|
||||
};
|
||||
|
||||
|
@ -721,8 +880,7 @@ Sessions.prototype.terminate = function (token) {
|
|||
|
||||
try {
|
||||
this.storage().remove(token);
|
||||
}
|
||||
catch (err) {
|
||||
} catch (err) {
|
||||
// some error, e.g. document not found. we don't care
|
||||
}
|
||||
};
|
||||
|
@ -733,16 +891,17 @@ Sessions.prototype.terminate = function (token) {
|
|||
|
||||
Sessions.prototype.get = function (token) {
|
||||
'use strict';
|
||||
|
||||
var storage = this.storage();
|
||||
var storage = this.storage(),
|
||||
session,
|
||||
lifetime;
|
||||
|
||||
try {
|
||||
var session = storage.document(token);
|
||||
session = storage.document(token);
|
||||
|
||||
if (session.expires >= internal.time()) {
|
||||
// session still valid
|
||||
|
||||
var lifetime = this._options.lifetime;
|
||||
lifetime = this._options.lifetime;
|
||||
|
||||
return {
|
||||
errorNum: internal.errors.ERROR_NO_ERROR,
|
||||
|
@ -751,11 +910,10 @@ Sessions.prototype.get = function (token) {
|
|||
}
|
||||
|
||||
// expired
|
||||
return {
|
||||
return {
|
||||
errorNum: internal.errors.ERROR_SESSION_EXPIRED.code
|
||||
};
|
||||
}
|
||||
catch (err) {
|
||||
} catch (err) {
|
||||
// document not found etc.
|
||||
}
|
||||
|
||||
|
@ -785,11 +943,11 @@ Sessions.prototype.get = function (token) {
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function CookieAuthentication (applicationContext, options) {
|
||||
CookieAuthentication = function (applicationContext, options) {
|
||||
'use strict';
|
||||
|
||||
options = options || { };
|
||||
|
||||
options = options || {};
|
||||
|
||||
this._applicationContext = applicationContext;
|
||||
|
||||
this._options = {
|
||||
|
@ -800,10 +958,10 @@ function CookieAuthentication (applicationContext, options) {
|
|||
secure: options.secure || false,
|
||||
httpOnly: options.httpOnly || false
|
||||
};
|
||||
|
||||
|
||||
this._collectionName = applicationContext.collectionName("sessions");
|
||||
this._collection = null;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -825,11 +983,11 @@ function CookieAuthentication (applicationContext, options) {
|
|||
CookieAuthentication.prototype.getTokenFromRequest = function (req) {
|
||||
'use strict';
|
||||
|
||||
if (! req.hasOwnProperty("cookies")) {
|
||||
if (!req.hasOwnProperty("cookies")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! req.cookies.hasOwnProperty(this._options.name)) {
|
||||
if (!req.cookies.hasOwnProperty(this._options.name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -842,9 +1000,12 @@ CookieAuthentication.prototype.getTokenFromRequest = function (req) {
|
|||
|
||||
CookieAuthentication.prototype.setCookie = function (res, value) {
|
||||
'use strict';
|
||||
|
||||
var name = this._options.name;
|
||||
var cookie = {
|
||||
var name = this._options.name,
|
||||
cookie,
|
||||
i,
|
||||
n;
|
||||
|
||||
cookie = {
|
||||
name: name,
|
||||
value: value,
|
||||
lifeTime: (value === null || value === "") ? 0 : this._options.lifetime,
|
||||
|
@ -854,15 +1015,15 @@ CookieAuthentication.prototype.setCookie = function (res, value) {
|
|||
httpOnly: this._options.httpOnly
|
||||
};
|
||||
|
||||
if (! res.hasOwnProperty("cookies")) {
|
||||
if (!res.hasOwnProperty("cookies")) {
|
||||
res.cookies = [ ];
|
||||
}
|
||||
|
||||
if (! Array.isArray(res.cookies)) {
|
||||
if (!Array.isArray(res.cookies)) {
|
||||
res.cookies = [ res.cookies ];
|
||||
}
|
||||
|
||||
var i, n = res.cookies.length;
|
||||
n = res.cookies.length;
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (res.cookies[i].name === name) {
|
||||
// found existing cookie. overwrite it
|
||||
|
@ -898,7 +1059,7 @@ CookieAuthentication.prototype.getAuthenticationData = function (req) {
|
|||
|
||||
CookieAuthentication.prototype.beginSession = function (req, res, token, identifier, data) {
|
||||
'use strict';
|
||||
|
||||
|
||||
this.setCookie(res, token);
|
||||
};
|
||||
|
||||
|
@ -954,18 +1115,18 @@ CookieAuthentication.prototype.isResponsible = function (req) {
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function Authentication (applicationContext, sessions, authenticators) {
|
||||
Authentication = function (applicationContext, sessions, authenticators) {
|
||||
'use strict';
|
||||
|
||||
this._applicationContext = applicationContext;
|
||||
this._sessions = sessions;
|
||||
|
||||
if (! Array.isArray(authenticators)) {
|
||||
if (!Array.isArray(authenticators)) {
|
||||
authenticators = [ authenticators ];
|
||||
}
|
||||
|
||||
this._authenticators = authenticators;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -986,16 +1147,19 @@ function Authentication (applicationContext, sessions, authenticators) {
|
|||
|
||||
Authentication.prototype.authenticate = function (req) {
|
||||
'use strict';
|
||||
|
||||
var i, n = this._authenticators.length;
|
||||
var i,
|
||||
n = this._authenticators.length,
|
||||
authenticator,
|
||||
data,
|
||||
session;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
var authenticator = this._authenticators[i];
|
||||
authenticator = this._authenticators[i];
|
||||
|
||||
var data = authenticator.getAuthenticationData(req);
|
||||
data = authenticator.getAuthenticationData(req);
|
||||
|
||||
if (data !== null) {
|
||||
var session = this._sessions.get(data.token);
|
||||
session = this._sessions.get(data.token);
|
||||
|
||||
if (session) {
|
||||
return session;
|
||||
|
@ -1014,12 +1178,13 @@ Authentication.prototype.authenticate = function (req) {
|
|||
|
||||
Authentication.prototype.beginSession = function (req, res, identifier, data) {
|
||||
'use strict';
|
||||
|
||||
var session = this._sessions.generate(identifier, data);
|
||||
var i, n = this._authenticators.length;
|
||||
var session = this._sessions.generate(identifier, data),
|
||||
i,
|
||||
n = this._authenticators.length,
|
||||
authenticator;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
var authenticator = this._authenticators[i];
|
||||
authenticator = this._authenticators[i];
|
||||
|
||||
if (authenticator.isResponsible(req) &&
|
||||
authenticator.beginSession) {
|
||||
|
@ -1036,11 +1201,12 @@ Authentication.prototype.beginSession = function (req, res, identifier, data) {
|
|||
|
||||
Authentication.prototype.endSession = function (req, res, token) {
|
||||
'use strict';
|
||||
|
||||
var i, n = this._authenticators.length;
|
||||
var i,
|
||||
n = this._authenticators.length,
|
||||
authenticator;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
var authenticator = this._authenticators[i];
|
||||
authenticator = this._authenticators[i];
|
||||
|
||||
if (authenticator.isResponsible(req) &&
|
||||
authenticator.endSession) {
|
||||
|
@ -1057,11 +1223,12 @@ Authentication.prototype.endSession = function (req, res, token) {
|
|||
|
||||
Authentication.prototype.updateSession = function (req, res, session) {
|
||||
'use strict';
|
||||
|
||||
var i, n = this._authenticators.length;
|
||||
var i,
|
||||
n = this._authenticators.length,
|
||||
authenticator;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
var authenticator = this._authenticators[i];
|
||||
authenticator = this._authenticators[i];
|
||||
|
||||
if (authenticator.isResponsible(req) &&
|
||||
authenticator.updateSession) {
|
||||
|
@ -1089,11 +1256,11 @@ Authentication.prototype.updateSession = function (req, res, session) {
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function UnauthorizedError (message) {
|
||||
UnauthorizedError = function (message) {
|
||||
'use strict';
|
||||
this.message = message || "Unauthorized";
|
||||
this.statusCode = 401;
|
||||
}
|
||||
};
|
||||
|
||||
// http://stackoverflow.com/questions/783818/how-do-i-create-a-custom-error-in-javascript
|
||||
UnauthorizedError.prototype = new Error();
|
||||
|
@ -1111,11 +1278,16 @@ UnauthorizedError.prototype = new Error();
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.Users = Users;
|
||||
exports.Sessions = Sessions;
|
||||
exports.CookieAuthentication = CookieAuthentication;
|
||||
exports.Authentication = Authentication;
|
||||
exports.UnauthorizedError = UnauthorizedError;
|
||||
exports.Users = Users;
|
||||
exports.Sessions = Sessions;
|
||||
exports.CookieAuthentication = CookieAuthentication;
|
||||
exports.Authentication = Authentication;
|
||||
exports.UnauthorizedError = UnauthorizedError;
|
||||
exports.createStandardLoginHandler = createStandardLoginHandler;
|
||||
exports.createStandardLogoutHandler = createStandardLogoutHandler;
|
||||
exports.createAuthenticationMiddleware = createAuthenticationMiddleware;
|
||||
exports.createSessionUpdateMiddleware = createSessionUpdateMiddleware;
|
||||
exports.createAuthObject = createAuthObject;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -35,42 +35,7 @@ var Controller,
|
|||
_ = require("underscore"),
|
||||
extend = _.extend,
|
||||
is = require("org/arangodb/is"),
|
||||
internal = require("org/arangodb/foxx/internals"),
|
||||
defaultsFor = {};
|
||||
|
||||
defaultsFor.login = {
|
||||
usernameField: "username",
|
||||
passwordField: "password",
|
||||
|
||||
onSuccess: function (req, res) {
|
||||
res.json({
|
||||
user: req.user.identifier,
|
||||
key: req.currentSession._key
|
||||
});
|
||||
},
|
||||
|
||||
onError: function (req, res) {
|
||||
res.status(401);
|
||||
res.json({
|
||||
error: "Username or Password was wrong"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
defaultsFor.logout = {
|
||||
onSuccess: function (req, res) {
|
||||
res.json({
|
||||
notice: "Logged out!",
|
||||
});
|
||||
},
|
||||
|
||||
onError: function (req, res) {
|
||||
res.status(401);
|
||||
res.json({
|
||||
error: "No session was found"
|
||||
});
|
||||
}
|
||||
};
|
||||
internal = require("org/arangodb/foxx/internals");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- Controller
|
||||
|
@ -426,6 +391,31 @@ extend(Controller.prototype, {
|
|||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_controller_getUsers
|
||||
/// @brief Get the users of this controller
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
getUsers: function () {
|
||||
'use strict';
|
||||
var foxxAuthentication = require("org/arangodb/foxx/authentication"),
|
||||
users = new foxxAuthentication.Users(this.applicationContext);
|
||||
|
||||
return users;
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_controller_getAuth
|
||||
/// @brief Get the auth object of this controller
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
getAuth: function () {
|
||||
'use strict';
|
||||
if (is.notExisty(this.auth)) {
|
||||
throw new Error("Setup authentication first");
|
||||
}
|
||||
|
||||
return this.auth;
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @fn JSF_foxx_controller_activateAuthentication
|
||||
/// @brief Activate authentication for this app
|
||||
|
@ -453,57 +443,12 @@ extend(Controller.prototype, {
|
|||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
activateAuthentication: function (opts) {
|
||||
var foxxAuthentication = require("org/arangodb/foxx/authentication"),
|
||||
sessions,
|
||||
cookieAuth,
|
||||
app = this,
|
||||
applicationContext = this.applicationContext,
|
||||
options = opts || {};
|
||||
'use strict';
|
||||
var authentication = require("org/arangodb/foxx/authentication");
|
||||
|
||||
if (options.type !== "cookie") {
|
||||
throw new Error("Currently only the following auth types are supported: cookie");
|
||||
}
|
||||
if (is.falsy(options.cookieLifetime)) {
|
||||
throw new Error("Please provide the cookieLifetime");
|
||||
}
|
||||
if (is.falsy(options.cookieName)) {
|
||||
throw new Error("Please provide the cookieName");
|
||||
}
|
||||
if (is.falsy(options.sessionLifetime)) {
|
||||
throw new Error("Please provide the sessionLifetime");
|
||||
}
|
||||
|
||||
sessions = new foxxAuthentication.Sessions(this.applicationContext, {
|
||||
lifetime: options.sessionLifetime
|
||||
});
|
||||
|
||||
cookieAuth = new foxxAuthentication.CookieAuthentication(this.applicationContext, {
|
||||
lifetime: options.cookieLifetime,
|
||||
name: options.cookieName
|
||||
});
|
||||
|
||||
this.auth = new foxxAuthentication.Authentication(this.applicationContext, sessions, cookieAuth);
|
||||
|
||||
this.before("/*", function (req, res) {
|
||||
var users = new foxxAuthentication.Users(applicationContext),
|
||||
authResult = app.auth.authenticate(req);
|
||||
|
||||
if (authResult.errorNum === require("internal").errors.ERROR_NO_ERROR) {
|
||||
req.currentSession = authResult.session;
|
||||
req.user = users.get(authResult.session.identifier);
|
||||
} else {
|
||||
req.currentSession = null;
|
||||
req.user = null;
|
||||
}
|
||||
});
|
||||
|
||||
this.after("/*", function (req, res) {
|
||||
var session = req.currentSession;
|
||||
|
||||
if (is.existy(session)) {
|
||||
session.update();
|
||||
}
|
||||
});
|
||||
this.auth = authentication.createAuthObject(this.applicationContext, opts);
|
||||
this.before("/*", authentication.createAuthenticationMiddleware(this.auth, this.applicationContext));
|
||||
this.after("/*", authentication.createSessionUpdateMiddleware());
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -538,23 +483,9 @@ extend(Controller.prototype, {
|
|||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
login: function (route, opts) {
|
||||
var foxxAuthentication = require("org/arangodb/foxx/authentication"),
|
||||
auth = this.auth,
|
||||
users = new foxxAuthentication.Users(this.applicationContext),
|
||||
options = _.defaults(opts || {}, defaultsFor.login);
|
||||
|
||||
this.post(route, function (req, res) {
|
||||
var username = req.body()[options.usernameField],
|
||||
password = req.body()[options.passwordField];
|
||||
|
||||
if (users.isValid(username, password)) {
|
||||
req.currentSession = auth.beginSession(req, res, username, {});
|
||||
req.user = users.get(req.currentSession.identifier);
|
||||
options.onSuccess(req, res);
|
||||
} else {
|
||||
options.onError(req, res);
|
||||
}
|
||||
});
|
||||
'use strict';
|
||||
var authentication = require("org/arangodb/foxx/authentication");
|
||||
this.post(route, authentication.createStandardLoginHandler(this.getAuth(), this.getUsers(), opts));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -587,19 +518,9 @@ extend(Controller.prototype, {
|
|||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
logout: function (route, opts) {
|
||||
var auth = this.auth,
|
||||
options = _.defaults(opts || {}, defaultsFor.logout);
|
||||
|
||||
this.post(route, function (req, res) {
|
||||
if (is.existy(req.currentSession)) {
|
||||
auth.endSession(req, res, req.currentSession._key);
|
||||
req.user = null;
|
||||
req.currentSession = null;
|
||||
options.onSuccess(req, res);
|
||||
} else {
|
||||
options.onError(req, res);
|
||||
}
|
||||
});
|
||||
'use strict';
|
||||
var authentication = require("org/arangodb/foxx/authentication");
|
||||
this.post(route, authentication.createStandardLogoutHandler(this.getAuth(), opts));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue