Skip to content

Commit

Permalink
feat(doctor): prevent installations with ghost user
Browse files Browse the repository at this point in the history
refs #47

- Adds a check to the `install` category
- Check is disabled for local installs
- Check will prevent user from installation, if the `ghost` user exists and user is logged in as such
- Adds tests. Still 💯
  • Loading branch information
aileen authored and acburdine committed Mar 26, 2018
1 parent cdc9c31 commit dde6bf0
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/commands/doctor/checks/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
const nodeVersion = require('./node-version');
const loggedInUser = require('./logged-in-user');
const loggedInGhostUser = require('./logged-in-ghost-user');
const loggedInUserOwner = require('./logged-in-user-owner');
const installFolderPermissions = require('./install-folder-permissions');
Expand All @@ -13,6 +14,7 @@ const checkMemory = require('./check-memory');

module.exports = [
nodeVersion,
loggedInUser,
loggedInGhostUser,
loggedInUserOwner,
installFolderPermissions,
Expand Down
28 changes: 28 additions & 0 deletions lib/commands/doctor/checks/logged-in-user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';
const errors = require('../../../errors');
const chalk = require('chalk');
const ghostUser = require('../../../utils/use-ghost-user');

const taskTitle = 'Checking logged in user';

function loggedInUser() {
const uid = process.getuid();
const ghostStats = ghostUser.getGhostUid();

if (ghostStats && ghostStats.uid === uid) {
throw new errors.SystemError({
message: 'You can\'t install Ghost with a user called `ghost`. Please use a different user(name).',
help: `${chalk.green('https://docs.ghost.org/docs/install#section-create-a-new-user')}`,
task: taskTitle
});
}

return;
}

module.exports = {
title: taskTitle,
task: loggedInUser,
enabled: (ctx) => !ctx.local && !(ctx.instance && ctx.instance.process.name === 'local') && ctx.system.platform.linux && !(ctx.argv && ctx.argv.process === 'local'),
category: ['install']
};
84 changes: 84 additions & 0 deletions test/unit/commands/doctor/checks/logged-in-user-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
'use strict';
const expect = require('chai').expect;
const sinon = require('sinon');
const errors = require('../../../../../lib/errors');
const ghostUser = require('../../../../../lib/utils/use-ghost-user');

const loggedInUser = require('../../../../../lib/commands/doctor/checks/logged-in-user');

describe('Unit: Doctor Checks > loggedInUser', function () {
const sandbox = sinon.sandbox.create();

afterEach(() => {
sandbox.restore();
});

it('enabled works', function () {
expect(loggedInUser.enabled({
local: true,
system: {platform: {linux: true}},
argv: {}
}), 'false if local is true').to.be.false;
expect(loggedInUser.enabled({
local: false,
instance: {process: {name: 'local'}},
system: {platform: {linux: false}}
}), 'false if local is false and process name is local').to.be.false;
expect(loggedInUser.enabled({
local: false,
instance: {process: {name: 'systemd'}},
system: {platform: {linux: false}}
}), 'false if local is false and process name is not local and platform is not linux').to.be.false;
expect(loggedInUser.enabled({
local: false,
instance: {process: {name: 'systemd'}},
system: {platform: {linux: true}}
}), 'true if local is false and process name is not local and platform is linux').to.be.true;
expect(loggedInUser.enabled({
local: false,
instance: {process: {name: 'systemd'}},
system: {platform: {linux: true}},
argv: {process: 'local'}
}), 'false if local is false and process name is not local and platform is linux, but argv local is given').to.be.false;
});

it('rejects if user name is ghost', function () {
const processStub = sandbox.stub(process, 'getuid').returns(501);
const ghostUserStub = sandbox.stub(ghostUser, 'getGhostUid').returns({uid: 501, guid: 501});

try {
loggedInUser.task();
} catch (error) {
expect(error).to.exist;
expect(error).to.be.an.instanceof(errors.SystemError);
expect(processStub.calledOnce).to.be.true;
expect(ghostUserStub.calledOnce).to.be.true;
}
});

it('passes if user name is not ghost', function () {
const processStub = sandbox.stub(process, 'getuid').returns(1000);
const ghostUserStub = sandbox.stub(ghostUser, 'getGhostUid').returns(false);

try {
loggedInUser.task();
expect(processStub.calledOnce).to.be.true;
expect(ghostUserStub.calledOnce).to.be.true;
} catch (error) {
expect(error).to.not.exist;
}
});

it('passes if ghost user exists but not currently used', function () {
const processStub = sandbox.stub(process, 'getuid').returns(1000);
const ghostUserStub = sandbox.stub(ghostUser, 'getGhostUid').returns({uid: 501, guid: 501});

try {
loggedInUser.task();
expect(processStub.calledOnce).to.be.true;
expect(ghostUserStub.calledOnce).to.be.true;
} catch (error) {
expect(error).to.not.exist;
}
});
});

0 comments on commit dde6bf0

Please sign in to comment.