Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 531473 - Properly support orion.auth.admin.default.password in th…
…e Node server
  • Loading branch information
mrennie committed Feb 21, 2018
1 parent 282e73c commit 30e895a
Show file tree
Hide file tree
Showing 6 changed files with 544 additions and 228 deletions.
92 changes: 37 additions & 55 deletions modules/orionode/lib/metastore/fs/store.js
Expand Up @@ -32,7 +32,7 @@ const FILENAME_METASTORE = "metastore.json",
DESCRIPTION_METASTORE = "This JSON file is at the root of the Orion metadata store responsible for persisting user, workspace and project files and metadata.";

// The current version of the Simple Meta Store.
var VERSION = 8;
const VERSION = 8;

function getUserRootLocation(options, userId) {
return options.configParams.get('orion.single.user') ? nodePath.join(options.configParams.get('orion.single.user.metaLocation') || os.homedir(), '.orion') : nodePath.join.apply(null, metaUtil.readMetaUserFolder(options.workspaceDir, userId));
Expand Down Expand Up @@ -107,7 +107,7 @@ function FsMetastore(options) {
this._options = options;
this._taskList = {};
this._lockMap = {};
this._isSingleUser = options.configParams.get('orion.single.user');
this._isSingleUser = !!options.configParams.get('orion.single.user');
}

FsMetastore.prototype.lock = function(userId, shared) {
Expand All @@ -133,15 +133,32 @@ FsMetastore.prototype.lock = function(userId, shared) {

FsMetastore.prototype.setup = function(options) {
if (!this._isSingleUser) {
/* verify that existing metadata in this workspace will be usable by this server */
var path = nodePath.join(this._options.workspaceDir, FILENAME_METASTORE);
fs.readFileAsync(path, 'utf8').then(
function(content) {
metaUtil.initializeAdminUser(options, this).then(function(user) {
/* verify that existing metadata in this workspace will be usable by this server */
var path = nodePath.join(this._options.workspaceDir, FILENAME_METASTORE);
fs.readFile(path, 'utf8', function(err, content) {
if(err) {
if (err.code === "ENOENT") {
/* brand new workspace */
var obj = {};
obj[KEY_ORION_VERSION] = VERSION;
obj[KEY_ORION_DESCRIPTION] = DESCRIPTION_METASTORE;
writeJSON(path, obj).then(
null,
function(error) {
throw new Error("Failed to write the metadata file for the new workspace at: " + path, error);
}
);
} else {
throw new Error("Failed to access the workspace metadata at: " + path, err);
}
return;
}
var json = JSON.parse(content);
var metaVersion = parseInt(json[KEY_ORION_VERSION], 10);
if (metaVersion < VERSION) {
/* this is fine, user metadata will be migrated when they next log in */
var obj = {};
obj = {};
obj[KEY_ORION_VERSION] = VERSION;
obj[KEY_ORION_DESCRIPTION] = DESCRIPTION_METASTORE;
writeJSON(path, obj).then(
Expand All @@ -155,58 +172,18 @@ FsMetastore.prototype.setup = function(options) {
} else if (isNaN(metaVersion)) {
throw new Error("Invalid metadata version ('" + metaVersion + "') read from " + path);
}
},
function(error) {
if (error.code === "ENOENT") {
/* brand new workspace */
var obj = {};
obj[KEY_ORION_VERSION] = VERSION;
obj[KEY_ORION_DESCRIPTION] = DESCRIPTION_METASTORE;
writeJSON(path, obj).then(
null,
function(error) {
throw new Error("Failed to write the metadata file for the new workspace at: " + path, error);
}
);
} else {
throw new Error("Failed to access the workspace metadata at: " + path, error);
}
}
);
});
}.bind(this), function rejectAdmin(err) {
throw err;
});
}

// Used only for single user case (Electron or local debug)
options.authenticate = [function(req, res, next) {
if (this._isSingleUser) {
this.getUser("anonymous", function(err, user) {
if (err) {
throw new Error("Failed to get 'anonymous' user's metadata");
}
if (!user) {
this.createUser({
username: "anonymous",
fullname: "anonymous",
email: "anonymous",
password: "default",
properties: {}
}, /** @callback */ function(err, user) {
// TODO can err possibly happen in this context?
req.user = user;
next();
});
} else {
req.user = user;
next();
}
}.bind(this));
} else {
next();
}
metaUtil.initializeAnonymousUser(req, next, this);
}.bind(this)];
};

Object.assign(FsMetastore.prototype, {

createWorkspace: function(userId, workspaceData, callback) {
if (!userId) {
return callback(new Error('createWorkspace.userId is null'));
Expand Down Expand Up @@ -610,9 +587,14 @@ Object.assign(FsMetastore.prototype, {

/** @callback */
getAllUsers: function(start, rows, callback) {
this.getUser("anonymous", function(err, user) {
callback(err, user ? [user] : user);
});
if(typeof this._options.workspaceDir === 'string') {
if(this._isSingleUser) {
return this.getUser("anonymous", function(err, user) {
callback(err, user ? [user] : user);
});
}
}
return [];
},

/** @callback */
Expand Down
3 changes: 2 additions & 1 deletion modules/orionode/lib/metastore/mongodb/store.js
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016 IBM Corporation and others.
* Copyright (c) 2016, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution
Expand Down Expand Up @@ -165,6 +165,7 @@ MongoDbMetastore.prototype.setup = function(options) {
passport.use(orionAccount.createStrategy());
passport.serializeUser(orionAccount.serializeUser());
passport.deserializeUser(orionAccount.deserializeUser());
metaUtil.initializeAdminUser(options, this);
};

Object.assign(MongoDbMetastore.prototype, {
Expand Down
80 changes: 74 additions & 6 deletions modules/orionode/lib/metastore/util/metaUtil.js
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017 IBM Corporation and others.
* Copyright (c) 2017, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution
Expand All @@ -8,10 +8,78 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
var args = require('../../args');
var async = require("async");
var api = require('../../api');
var SEPARATOR = "-";
const args = require('../../args'),
async = require("async"),
api = require('../../api'),
Promise = require('bluebird');

const SEPARATOR = "-";

/**
* If the `orion.auth.admin.default.password` property is set, automatically create an admin user
* @param {{?}} options The server options map
* @param {{?}} store The backing metastore to create the admin user in
* @returns {Promise} Returns a promise to create the default admin user
* @since 18.0
*/
module.exports.initializeAdminUser = function initializeAdminUser(options, store) {
return new Promise(function(resolve, reject) {
const pw = options.configParams.get("orion.auth.admin.default.password");
if(typeof pw === 'string' && pw.length > 0) {
const userData = {
username: "admin",
email: "admin",
fullname: "admin",
password: pw,
properties:{}
};
store.createUser(userData, function(err, user) {
if(err) {
return reject(err);
}
return resolve(user);
});
}
return resolve({});
});
};

/**
* Utility function to initialize the `anonymous` user. This function does not return a result, instead it calls the
* given `next()` function to proceed
* @param {XMLHttpRequest} req The original request
* @param {fn} next The routing function to proceed with once the user is initialized
* @param {{?}} store The backing file store
* @since 18.0
*/
module.exports.initializeAnonymousUser = function initializeAnonymousUser(req, next, store) {
if (store._isSingleUser) {
store.getUser("anonymous", function(err, user) {
if (err) {
throw new Error("Failed to get 'anonymous' user's metadata");
}
if (!user) {
store.createUser({
username: "anonymous",
fullname: "anonymous",
email: "anonymous",
password: "default",
properties: {}
}, /** @callback */ function(err, user) {
// TODO can err possibly happen in this context?
req.user = user;
next();
});
} else {
req.user = user;
next();
}
});
} else {
next();
}
};

module.exports.encodeWorkspaceId = function (userId, workspaceName) {
var workspaceId = workspaceName.replace(/ /g, "").replace(/\#/g, "").replace(/\-/g, "");
return userId + SEPARATOR + workspaceId;
Expand Down Expand Up @@ -96,5 +164,5 @@ module.exports.getWorkspaceMeta = function (workspaceIds, store, workspaceRoot){
});
}).then(function(){
return workspaceInfos;
})
});
};

0 comments on commit 30e895a

Please sign in to comment.