Skip to content

Commit

Permalink
馃帹 Importer disallows LTS imports
Browse files Browse the repository at this point in the history
refs #9742

- Ghost 2.0 won't support LTS imports
- only Ghost 1.0 imports
  • Loading branch information
kirrg001 committed Jul 19, 2018
1 parent 6f7dfa7 commit 6aaea0d
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 79 deletions.
7 changes: 0 additions & 7 deletions core/server/data/importer/importers/data/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@ class Base {
showNotFoundWarning: true
};

this.legacyKeys = {};
this.legacyMapper = (item) => {
return _.mapKeys(item, (value, key) => {
return this.legacyKeys[key] || key;
});
};

this.dataKeyToImport = options.dataKeyToImport;
this.dataToImport = _.cloneDeep(allDataFromFile[this.dataKeyToImport] || []);

Expand Down
24 changes: 24 additions & 0 deletions core/server/data/importer/importers/data/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
var _ = require('lodash'),
Promise = require('bluebird'),
semver = require('semver'),
common = require('../../../../lib/common'),
sequence = require('../../../../lib/promise/sequence'),
models = require('../../../../models'),
SubscribersImporter = require('./subscribers'),
Expand Down Expand Up @@ -49,6 +51,28 @@ DataImporter = {
modelOptions.importPersistUser = importOptions.importPersistUser;
}

if (!importData.meta) {
throw new common.errors.IncorrectUsageError({
message: 'Wrong importer structure. `meta` is missing.',
help: 'https://docs.ghost.org/docs/the-importer'
});
}

if (!importData.meta.version) {
throw new common.errors.IncorrectUsageError({
message: 'Wrong importer structure. `meta.version` is missing.',
help: 'https://docs.ghost.org/docs/the-importer'
});
}

// CASE: We deny LTS imports (from 1.0 we use the Ghost version you are on)
// @TODO: add migration guide link
if (!semver.valid(importData.meta.version)) {
return Promise.reject(new common.errors.InternalServerError({
message: 'Importing a LTS export into Ghost 2.0 is not allowed.'
}));
}

this.init(importData);

return models.Base.transaction(function (transacting) {
Expand Down
38 changes: 1 addition & 37 deletions core/server/data/importer/importers/data/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ class PostsImporter extends BaseImporter {
requiredImportedData: ['tags'],
requiredExistingData: ['tags']
});

this.legacyKeys = {
image: 'feature_image'
};
}

sanitizeAttributes() {
Expand Down Expand Up @@ -146,44 +142,12 @@ class PostsImporter extends BaseImporter {

beforeImport() {
debug('beforeImport');
let mobileDocContent;

this.sanitizeAttributes();
this.addNestedRelations();

// Remove legacy field language
this.dataToImport = _.filter(this.dataToImport, (data) => {
return _.omit(data, 'language');
});

this.dataToImport = this.dataToImport.map(this.legacyMapper);

// For legacy imports/custom imports with only html we can parse the markdown or html into a mobile doc card
// For now we can hardcode the version
_.each(this.dataToImport, (model) => {
if (!model.mobiledoc) {
if (model.markdown && model.markdown.length > 0) {
mobileDocContent = model.markdown;
} else if (model.html && model.html.length > 0) {
mobileDocContent = model.html;
} else {
// Set mobileDocContent to null else it will affect empty posts
mobileDocContent = null;
}
if (mobileDocContent) {
model.mobiledoc = JSON.stringify({
version: '0.3.1',
markups: [],
atoms: [],
cards: [['card-markdown', {cardName: 'card-markdown', markdown: mobileDocContent}]],
sections: [[10, 0]]
});
}
}

// NOTE: we remember the old post id for disqus
// We also check if amp already exists to prevent
// overwriting any comment ids from a 1.0 export
// NOTE: we remember the original post id for disqus
// (see https://github.com/TryGhost/Ghost/issues/8963)

// CASE 1: you import a 1.0 export (amp field contains the correct disqus id)
Expand Down
18 changes: 4 additions & 14 deletions core/server/data/importer/importers/data/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,23 @@ class SettingsImporter extends BaseImporter {
returnDuplicates: true,
showNotFoundWarning: false
};

// Map legacy keys
this.legacySettingsKeyValues = {
isPrivate: 'is_private',
activeTimezone: 'active_timezone',
cover: 'cover_image'
};
}

/**
* - 'core' and 'theme' are blacklisted
* - clean up legacy plugin setting references
* - handle labs setting
*/
beforeImport() {
debug('beforeImport');

let ltsActiveTheme = _.find(this.dataToImport, {key: 'activeTheme'});
let activeTheme = _.find(this.dataToImport, {key: 'active_theme'});

// If there is an lts we want to warn user that theme is not imported
if (ltsActiveTheme) {
// We don't import themes. You have to upload the theme first.
if (activeTheme) {
this.problems.push({
message: 'Theme not imported, please upload in Settings - Design',
help: this.modelName,
context: JSON.stringify(ltsActiveTheme)
context: JSON.stringify(activeTheme)
});
}

Expand All @@ -52,8 +44,6 @@ class SettingsImporter extends BaseImporter {
});

_.each(this.dataToImport, (obj) => {
obj.key = this.legacySettingsKeyValues[obj.key] || obj.key;

if (obj.key === 'labs' && obj.value) {
// Overwrite the labs setting with our current defaults
// Ensures things that are enabled in new versions, are turned on
Expand Down
7 changes: 0 additions & 7 deletions core/server/data/importer/importers/data/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ class TagsImporter extends BaseImporter {
modelName: 'Tag',
dataKeyToImport: 'tags'
});

// Map legacy keys
this.legacyKeys = {
image: 'feature_image'
};
}

fetchExisting(modelOptions) {
Expand Down Expand Up @@ -43,8 +38,6 @@ class TagsImporter extends BaseImporter {

let ops = [];

this.dataToImport = this.dataToImport.map(this.legacyMapper);

_.each(this.dataToImport, (obj) => {
ops.push(models[this.modelName].findOne({name: obj.name}, options)
.then((tag) => {
Expand Down
14 changes: 0 additions & 14 deletions core/server/data/importer/importers/data/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ class UsersImporter extends BaseImporter {
dataKeyToImport: 'users',
requiredFromFile: ['roles', 'roles_users']
});

// Map legacy keys
this.legacyKeys = {
image: 'profile_image',
cover: 'cover_image',
last_login: 'last_seen'
};
}

fetchExisting(modelOptions) {
Expand All @@ -39,13 +32,6 @@ class UsersImporter extends BaseImporter {

let role, lookup = {};

// Remove legacy field language
this.dataToImport = _.filter(this.dataToImport, (data) => {
return _.omit(data, 'language');
});

this.dataToImport = this.dataToImport.map(this.legacyMapper);

// NOTE: sort out duplicated roles based on incremental id
_.each(this.requiredFromFile.roles_users, (attachedRole) => {
if (lookup.hasOwnProperty(attachedRole.user_id)) {
Expand Down
46 changes: 46 additions & 0 deletions core/test/integration/data/importer/importers/data_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,35 @@ const exportedPreviousBody = () => {
});
};

const exportedLegacyBody = () => {
return _.clone({
db: [{
meta: {
exported_on: 1504269105806,
version: "300"
},
data: {
app_fields: [],
app_settings: [],
apps: [],
brute: [],
invites: [],
permissions: [],
permissions_roles: [],
permissions_users: [],
posts: [],
posts_tags: [],
roles: [],
roles_users: [],
settings: [],
subscribers: [],
tags: [],
users: []
}
}]
});
};

// Tests in here do an import for each test
describe('Integration: Importer', function () {
before(testUtils.teardown);
Expand Down Expand Up @@ -1075,3 +1104,20 @@ describe('1.0', function () {

it.skip('ensure we migrate the 1.0 html of a post');
});

describe('LTS', function () {
beforeEach(testUtils.teardown);
beforeEach(testUtils.setup('roles', 'owner', 'settings'));

it('disallows importing LTS imports', function () {
const exportData = exportedLegacyBody().db[0];

return dataImporter.doImport(exportData, importOptions)
.then(function () {
"0".should.eql(1, 'LTS import should fail');
})
.catch(function (err) {
err.message.should.eql('Importing a LTS export into Ghost 2.0 is not allowed.');
});
});
});

0 comments on commit 6aaea0d

Please sign in to comment.