Added migrations for Self-Serve Migration Integration and API key

refs https://github.com/TryGhost/Team/issues/2790
refs 3747df1bc8 (diff-396038cecd7a381616d00954ae18a655ae2a8af71ea65866bf09d2c7cc1b5235)

- This integration will be used to perform self-serve migrations.
- The integration will be limited to these Admin API endpoints:
POST /ghost/api/admin/db
POST /ghost/api/admin/db/media/inline
POST /ghost/api/admin/members/upload
GET   /ghost/api/admin/tags/:id
GET   /ghost/api/admin/tags/slug/:slug
This commit is contained in:
Naz 2023-03-21 20:40:45 +01:00
parent 317b9aee20
commit 0b107f5af5
No known key found for this signature in database
9 changed files with 183 additions and 6 deletions

View File

@ -0,0 +1,31 @@
const logging = require('@tryghost/logging');
const {default: ObjectID} = require('bson-objectid');
const {createTransactionalMigration, meta} = require('../../utils');
module.exports = createTransactionalMigration(
async function up(knex) {
logging.info('Creating "Self-Serve Migration Integration" role');
const existingRole = await knex('roles').where({
name: 'Self-Serve Migration Integration'
}).first();
if (existingRole) {
logging.warn('"Self-Serve Migration Integration" role already exists, skipping');
return;
}
await knex('roles').insert({
id: (new ObjectID()).toHexString(),
name: 'Self-Serve Migration Integration',
description: 'Core Integration for the Ghost Explore directory',
created_by: meta.MIGRATION_USER,
created_at: knex.raw('current_timestamp')
});
},
async function down(knex) {
logging.info('Deleting role "Self-Serve Migration Integration"');
await knex('roles').where({
name: 'Self-Serve Migration Integration'
}).del();
}
);

View File

@ -0,0 +1,37 @@
const logging = require('@tryghost/logging');
const {default: ObjectID} = require('bson-objectid');
const {createTransactionalMigration, meta} = require('../../utils');
module.exports = createTransactionalMigration(
async function up(knex) {
logging.info('Creating "Self-Serve Migration Integration"');
const existingIntegration = await knex('integrations').where({
name: 'Self-Serve Migration Integration',
slug: 'self-serve-migration'
}).first();
if (existingIntegration) {
logging.warn('Integration already exists, skipping');
return;
}
await knex('integrations').insert({
id: (new ObjectID()).toHexString(),
type: 'core',
name: 'Self-Serve Migration Integration',
description: 'Core Integration for the Self-Serve migration tool',
slug: 'self-serve-migration',
created_at: knex.raw('current_timestamp'),
created_by: meta.MIGRATION_USER
});
},
async function down(knex) {
logging.info('Deleting "Self-Serve Migration Integration"');
await knex('integrations').where({
type: 'core',
name: 'Self-Serve Migration Integration',
slug: 'self-serve-migration'
}).del();
}
);

View File

@ -0,0 +1,72 @@
const {InternalServerError} = require('@tryghost/errors');
const logging = require('@tryghost/logging');
const security = require('@tryghost/security');
const {default: ObjectID} = require('bson-objectid');
const {createTransactionalMigration, meta} = require('../../utils');
module.exports = createTransactionalMigration(
async function up(knex) {
logging.info('Adding Admin API key for "Self-Serve Migration Integration"');
const integration = await knex('integrations').where({
slug: 'self-serve-migration',
name: 'Self-Serve Migration Integration'
}).first();
if (!integration) {
throw new InternalServerError('Could not find "Self-Serve Migration Integration"');
}
const role = await knex('roles').where({
name: 'Self-Serve Migration Integration'
}).first();
if (!role) {
throw new InternalServerError('Could not find "Self-Serve Migration Integration" Role');
}
const existingKey = await knex('api_keys').where({
integration_id: integration.id,
role_id: role.id
}).first();
if (existingKey) {
logging.warn('Admin API key for "Self-Serve Migration Integration" already exists');
return;
}
await knex('api_keys').insert({
id: (new ObjectID()).toHexString(),
type: 'core',
secret: security.secret.create('admin'),
role_id: role.id,
integration_id: integration.id,
created_at: knex.raw('current_timestamp'),
created_by: meta.MIGRATION_USER
});
},
async function down(knex) {
logging.info('Removing "Self-Serve Migration Integration" API key');
const integration = await knex('integrations').where({
slug: 'self-serve-migration',
type: 'core',
name: 'Self-Serve Migration Integration'
}).first();
const role = await knex('roles').where({
name: 'Self-Serve Migration Integration'
}).first();
if (!role || !integration) {
logging.warn('Could not delete "Self-Serve Migration Integration" API key');
return;
}
logging.info('Deleting "Self-Serve Migration Integration" API Key');
await knex('api_keys').where({
integration_id: integration.id,
role_id: role.id
}).del();
}
);

View File

@ -76,6 +76,10 @@
"name": "Ghost Explore Integration",
"description": "Internal Integration for the Ghost Explore directory"
},
{
"name": "Self-Serve Migration Integration",
"description": "Internal Integration for the Self-Serve migration tool"
},
{
"name": "DB Backup Integration",
"description": "Internal DB Backup Client"
@ -701,6 +705,18 @@
"type": "core",
"api_keys": [{"type": "admin", "role": "Ghost Explore Integration"}]
},
{
"slug": "self-serve-migration",
"name": "Self-Serve Migration Integration",
"description": "Core Self-Serve Migration integration",
"type": "core",
"api_keys": [
{
"type": "admin",
"role": "Self-Serve Migration Integration"
}
]
},
{
"slug": "ghost-backup",
"name": "Ghost Backup",

View File

@ -23,7 +23,7 @@ describe('Integrations API', function () {
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200);
should.equal(res.body.integrations.length, 5);
should.equal(res.body.integrations.length, 6);
// there is no enforced order for integrations which makes order different on SQLite and MySQL
const zapierIntegration = _.find(res.body.integrations, {name: 'Zapier'}); // from migrations
@ -34,6 +34,9 @@ describe('Integrations API', function () {
const exploreIntegration = _.find(res.body.integrations, {name: 'Test Core Integration'}); // from fixtures
should.exist(exploreIntegration);
const selfServeMigrationIntegration = _.find(res.body.integrations, {name: 'Self-Serve Migration Integration'}); // from fixtures
should.exist(selfServeMigrationIntegration);
});
it('Can not read internal integration', async function () {

View File

@ -25,7 +25,7 @@ describe('Roles API', function () {
should.exist(response);
should.exist(response.roles);
localUtils.API.checkResponse(response, 'roles');
response.roles.should.have.length(9);
response.roles.should.have.length(10);
localUtils.API.checkResponse(response.roles[0], 'role');
localUtils.API.checkResponse(response.roles[1], 'role');
localUtils.API.checkResponse(response.roles[2], 'role');
@ -35,6 +35,7 @@ describe('Roles API', function () {
localUtils.API.checkResponse(response.roles[6], 'role');
localUtils.API.checkResponse(response.roles[7], 'role');
localUtils.API.checkResponse(response.roles[8], 'role');
localUtils.API.checkResponse(response.roles[9], 'role');
});
it('Can request roles which i am able to assign to other users', async function () {

View File

@ -225,7 +225,7 @@ describe('Database Migration (special functions)', function () {
// Roles
should.exist(result.roles);
result.roles.length.should.eql(9);
result.roles.length.should.eql(10);
result.roles.at(0).get('name').should.eql('Administrator');
result.roles.at(1).get('name').should.eql('Editor');
result.roles.at(2).get('name').should.eql('Author');
@ -233,8 +233,9 @@ describe('Database Migration (special functions)', function () {
result.roles.at(4).get('name').should.eql('Owner');
result.roles.at(5).get('name').should.eql('Admin Integration');
result.roles.at(6).get('name').should.eql('Ghost Explore Integration');
result.roles.at(7).get('name').should.eql('DB Backup Integration');
result.roles.at(8).get('name').should.eql('Scheduler Integration');
result.roles.at(7).get('name').should.eql('Self-Serve Migration Integration');
result.roles.at(8).get('name').should.eql('DB Backup Integration');
result.roles.at(9).get('name').should.eql('Scheduler Integration');
// Permissions
result.permissions.toJSON().should.be.CompletePermissions();

View File

@ -36,7 +36,7 @@ const validateRouteSettings = require('../../../../../core/server/services/route
describe('DB version integrity', function () {
// Only these variables should need updating
const currentSchemaHash = '67a16bde6f7dd46c5e07d7fca1005a53';
const currentFixturesHash = 'd99d3c2891e79b8662ed6a312490d2fd';
const currentFixturesHash = 'dc2d5430edd212bf579e3533bdbfe806';
const currentSettingsHash = '7b567742b9667d38191d8455c422c5d5';
const currentRoutesHash = '3d180d52c663d173a6be791ef411ed01';

View File

@ -76,6 +76,10 @@
"name": "Ghost Explore Integration",
"description": "Internal Integration for the Ghost Explore directory"
},
{
"name": "Self-Serve Migration Integration",
"description": "Internal Integration for the Self-Serve migration tool"
},
{
"name": "DB Backup Integration",
"description": "Internal DB Backup Client"
@ -881,6 +885,18 @@
"type": "core",
"api_keys": [{"type": "admin", "role": "Ghost Explore Integration"}]
},
{
"slug": "self-serve-migration",
"name": "Self-Serve Migration Integration",
"description": "Core Self-Serve Migration integration",
"type": "core",
"api_keys": [
{
"type": "admin",
"role": "Self-Serve Migration Integration"
}
]
},
{
"slug": "ghost-backup",
"name": "Ghost Backup",