added check for blocked content and updated claimid flow to use rejected promises

This commit is contained in:
bill bittner 2018-04-29 12:17:23 -07:00
parent c89fdd390e
commit d57a6b3340
12 changed files with 211 additions and 173 deletions

View file

@ -1,4 +1,4 @@
const db = require('../../../../models');
const db = require('../../../../models/index');
const { publishing: { primaryClaimAddress, additionalClaimAddresses } } = require('../../../../../config/siteConfig.js');
const Sequelize = require('sequelize');
const Op = Sequelize.Op;

View file

@ -1,4 +1,4 @@
const checkClaimAvailability = require('../utils/checkClaimAvailability.js');
const checkClaimAvailability = require('./checkClaimAvailability.js');
const { sendGATimingEvent } = require('../../../../utils/googleAnalytics.js');
const { handleErrorResponse } = require('../../../utils/errorHandlers.js');

View file

@ -0,0 +1,31 @@
const logger = require('winston');
const db = require('../../../../models');
const getClaimIdByChannel = (channelName, channelClaimId, claimName) => {
return new Promise((resolve, reject) => {
db.Certificate
.getLongChannelId(channelName, channelClaimId)
.then(longChannelId => {
return db.Claim.getClaimIdByLongChannelId(longChannelId, claimName);
})
.then(longClaimId => {
resolve(longClaimId);
})
.catch(error => {
reject(error);
});
});
};
const getClaimId = (channelName, channelClaimId, name, claimId) => {
if (channelName) {
logger.debug(`getClaimIdByChannel(${channelName}, ${channelClaimId}, ${name})`);
return getClaimIdByChannel(channelName, channelClaimId, name);
} else {
logger.debug(`db.Claim.getLongClaimId(${name}, ${claimId})`);
return db.Claim.getLongClaimId(name, claimId);
}
};
module.exports = getClaimId;

View file

@ -1,4 +1,4 @@
const getClaimId = require('../../../utils/getClaimId.js');
const getClaimId = require('./getClaimId.js');
const { handleErrorResponse } = require('../../../utils/errorHandlers.js');
const NO_CHANNEL = 'NO_CHANNEL';
@ -16,16 +16,22 @@ const claimLongId = ({ ip, originalUrl, body, params }, res) => {
const claimName = body.claimName;
const claimId = body.claimId;
getClaimId(channelName, channelClaimId, claimName, claimId)
.then(result => {
if (result === NO_CHANNEL) {
return res.status(404).json({success: false, message: 'No matching channel could be found'});
}
if (result === NO_CLAIM) {
return res.status(404).json({success: false, message: 'No matching claim id could be found'});
}
res.status(200).json({success: true, data: result});
.then(fullClaimId => {
res.status(200).json({success: true, data: fullClaimId});
})
.catch(error => {
if (error === NO_CLAIM) {
return res.status(404).json({
success: false,
message: 'No claim id could be found',
});
}
if (error === NO_CHANNEL) {
return res.status(404).json({
success: false,
message: 'No channel id could be found',
});
}
handleErrorResponse(originalUrl, ip, error, res);
});
};

View file

@ -4,7 +4,7 @@ const { sendGATimingEvent } = require('../../../../utils/googleAnalytics.js');
const { handleErrorResponse } = require('../../../utils/errorHandlers.js');
const checkClaimAvailability = require('../utils/checkClaimAvailability.js');
const checkClaimAvailability = require('../availability/checkClaimAvailability.js');
const publish = require('./publish.js');
const createBasicPublishParams = require('./createBasicPublishParams.js');

View file

@ -1,50 +1,43 @@
const logger = require('winston');
const getClaimId = require('../../utils/getClaimId.js');
const getLocalFileRecord = require('../../utils/getLocalFileRecord.js');
const db = require('../../../models');
const getClaimId = require('../../api/claim/longId/getClaimId.js');
const { handleErrorResponse } = require('../../utils/errorHandlers.js');
const NO_FILE = 'NO_FILE';
const serveAssetToClient = require('./serveAssetToClient.js');
const NO_CHANNEL = 'NO_CHANNEL';
const NO_CLAIM = 'NO_CLAIM';
const serveAssetToClient = (claimId, name, res) => {
return getLocalFileRecord(claimId, name)
.then(fileRecord => {
// check that a local record was found
if (fileRecord === NO_FILE) {
return res.status(307).redirect(`/api/claim/get/${name}/${claimId}`);
}
// serve the file
const {filePath, fileType} = fileRecord;
logger.verbose(`serving file: ${filePath}`);
const sendFileOptions = {
headers: {
'X-Content-Type-Options': 'nosniff',
'Content-Type' : fileType || 'image/jpeg',
},
};
res.status(200).sendFile(filePath, sendFileOptions);
})
.catch(error => {
throw error;
});
};
const BLOCKED_CLAIM = 'BLOCKED_CLAIM';
const getClaimIdAndServeAsset = (channelName, channelClaimId, claimName, claimId, originalUrl, ip, res) => {
// get the claim Id and then serve the asset
getClaimId(channelName, channelClaimId, claimName, claimId)
.then(fullClaimId => {
if (fullClaimId === NO_CLAIM) {
return res.status(404).json({success: false, message: 'no claim id could be found'});
} else if (fullClaimId === NO_CHANNEL) {
return res.status(404).json({success: false, message: 'no channel id could be found'});
}
serveAssetToClient(fullClaimId, claimName, res);
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');
claimId = fullClaimId;
return db.Blocked.isNotBlocked(fullClaimId, claimName);
})
.then(() => {
serveAssetToClient(claimId, claimName, res);
})
.catch(error => {
if (error === NO_CLAIM) {
return res.status(404).json({
success: false,
message: 'No claim id could be found',
});
}
if (error === NO_CHANNEL) {
return res.status(404).json({
success: false,
message: 'No channel id could be found',
});
}
if (error === BLOCKED_CLAIM) {
return res.status(410).json({
success: false,
message: 'In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications. For more details, see https://lbry.io/faq/dmca',
});
}
handleErrorResponse(originalUrl, ip, error, res);
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail');
});
};

View file

@ -1,4 +1,4 @@
const db = require('../../models');
const db = require('../../../models');
const NO_FILE = 'NO_FILE';

View file

@ -0,0 +1,28 @@
const logger = require('winston');
const getLocalFileRecord = require('./getLocalFileRecord.js');
const NO_FILE = 'NO_FILE';
const serveAssetToClient = (claimId, name, res) => {
return getLocalFileRecord(claimId, name)
.then(fileRecord => {
// check that a local record was found
if (fileRecord === NO_FILE) {
return res.status(307).redirect(`/api/claim/get/${name}/${claimId}`);
}
// serve the file
const {filePath, fileType} = fileRecord;
logger.verbose(`serving file: ${filePath}`);
const sendFileOptions = {
headers: {
'X-Content-Type-Options': 'nosniff',
'Content-Type' : fileType || 'image/jpeg',
},
};
res.status(200).sendFile(filePath, sendFileOptions);
})
.catch(error => {
throw error;
});
};
module.exports = serveAssetToClient;

View file

@ -1,57 +0,0 @@
const logger = require('winston');
const db = require('../../models');
const NO_CHANNEL = 'NO_CHANNEL';
const NO_CLAIM = 'NO_CLAIM';
const getClaimIdByClaim = (claimName, claimId) => {
logger.debug(`getClaimIdByClaim(${claimName}, ${claimId})`);
return new Promise((resolve, reject) => {
db.Claim.getLongClaimId(claimName, claimId)
.then(longClaimId => {
if (!longClaimId) {
resolve(NO_CLAIM);
}
resolve(longClaimId);
})
.catch(error => {
reject(error);
});
});
};
const getClaimIdByChannel = (channelName, channelClaimId, claimName) => {
logger.debug(`getClaimIdByChannel(${channelName}, ${channelClaimId}, ${claimName})`);
return new Promise((resolve, reject) => {
db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id
.then(longChannelId => {
if (!longChannelId) {
return [null, null];
}
return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id
})
.then(([longChannelId, longClaimId]) => {
if (!longChannelId) {
return resolve(NO_CHANNEL);
}
if (!longClaimId) {
return resolve(NO_CLAIM);
}
resolve(longClaimId);
})
.catch(error => {
reject(error);
});
});
};
const getClaimId = (channelName, channelClaimId, name, claimId) => {
if (channelName) {
return getClaimIdByChannel(channelName, channelClaimId, name);
} else {
return getClaimIdByClaim(name, claimId);
}
};
module.exports = getClaimId;

View file

@ -1,9 +1,19 @@
const logger = require('winston');
const BLOCKED_CLAIM = 'BLOCKED_CLAIM';
module.exports = (sequelize, { STRING }) => {
const Blocked = sequelize.define(
'Blocked',
{
claimId: {
type : STRING,
allowNull: false,
},
name: {
type : STRING,
allowNull: false,
},
outpoint: {
type : STRING,
allowNull: false,
@ -14,22 +24,24 @@ module.exports = (sequelize, { STRING }) => {
}
);
Blocked.isBlocked = function (outpoint) {
logger.debug(`checking to see if ${outpoint} is blocked`);
Blocked.isNotBlocked = function (claimId, name) {
logger.debug(`checking to see if ${name}#${claimId} is not blocked`);
return new Promise((resolve, reject) => {
this.findOne({
where: {
outpoint,
claimId,
name,
},
})
.then(result => {
if (!result) {
return resolve(false);
if (result) {
return reject(BLOCKED_CLAIM);
}
resolve(true);
})
.catch(error => {
reject(error);
logger.error(error);
reject(BLOCKED_CLAIM);
});
});
};

View file

@ -1,6 +1,16 @@
const logger = require('winston');
const returnShortId = require('./utils/returnShortId.js');
const NO_CHANNEL = 'NO_CHANNEL';
function isLongChannelId (channelId) {
return (channelId && (channelId.length === 40));
}
function isShortChannelId (channelId) {
return (channelId && (channelId.length < 40));
}
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
const Certificate = sequelize.define(
'Certificate',
@ -121,6 +131,25 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
});
};
Certificate.validateLongChannelId = function (name, claimId) {
logger.debug(`validateLongChannelId(${name}, ${claimId})`);
return new Promise((resolve, reject) => {
this.findOne({
where: {name, claimId},
})
.then(result => {
if (!result) {
return reject(NO_CHANNEL);
}
resolve(claimId);
})
.catch(error => {
logger.error(error);
reject(NO_CHANNEL);
});
});
};
Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {
logger.debug(`getLongChannelIdFromShortChannelId(${channelName}, ${channelClaimId})`);
return new Promise((resolve, reject) => {
@ -137,13 +166,14 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
.then(result => {
switch (result.length) {
case 0:
return resolve(null);
default: // note results must be sorted
return reject(NO_CHANNEL);
default:
return resolve(result[0].claimId);
}
})
.catch(error => {
reject(error);
logger.error(error);
reject(NO_CHANNEL);
});
});
};
@ -159,43 +189,26 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
.then(result => {
switch (result.length) {
case 0:
return resolve(null);
return reject(NO_CHANNEL);
default:
return resolve(result[0].claimId);
}
})
.catch(error => {
reject(error);
});
});
};
Certificate.validateLongChannelId = function (name, claimId) {
logger.debug(`validateLongChannelId(${name}, ${claimId})`);
return new Promise((resolve, reject) => {
this.findOne({
where: {name, claimId},
})
.then(result => {
if (!result) {
return resolve(null);
};
resolve(claimId);
})
.catch(error => {
reject(error);
logger.error(error);
reject(NO_CHANNEL);
});
});
};
Certificate.getLongChannelId = function (channelName, channelClaimId) {
logger.debug(`getLongChannelId(${channelName}, ${channelClaimId})`);
if (channelClaimId && (channelClaimId.length === 40)) { // if a full channel id is provided
if (isLongChannelId(channelClaimId)) {
return this.validateLongChannelId(channelName, channelClaimId);
} else if (channelClaimId && channelClaimId.length < 40) { // if a short channel id is provided
} else if (isShortChannelId(channelClaimId)) {
return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId);
} else {
return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided
return this.getLongChannelIdFromChannelName(channelName);
}
};

View file

@ -2,6 +2,8 @@ const logger = require('winston');
const returnShortId = require('./utils/returnShortId.js');
const { assetDefaults: { thumbnail: defaultThumbnail }, details: { host } } = require('../../config/siteConfig.js');
const NO_CLAIM = 'NO_CLAIM';
function determineFileExtensionFromContentType (contentType) {
switch (contentType) {
case 'image/jpeg':
@ -17,14 +19,14 @@ function determineFileExtensionFromContentType (contentType) {
logger.debug('setting unknown file type as file extension jpeg');
return 'jpeg';
}
};
}
function determineThumbnail (storedThumbnail, defaultThumbnail) {
if (storedThumbnail === '') {
return defaultThumbnail;
}
return storedThumbnail;
};
}
function prepareClaimData (claim) {
// logger.debug('preparing claim data based on resolved data:', claim);
@ -32,7 +34,15 @@ function prepareClaimData (claim) {
claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);
claim['host'] = host;
return claim;
};
}
function isLongClaimId (claimId) {
return (claimId && (claimId.length === 40));
}
function isShortClaimId (claimId) {
return (claimId && (claimId.length < 40));
}
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
const Claim = sequelize.define(
@ -265,6 +275,27 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
});
};
Claim.validateLongClaimId = function (name, claimId) {
return new Promise((resolve, reject) => {
this.findOne({
where: {
name,
claimId,
},
})
.then(result => {
if (!result) {
return reject(NO_CLAIM);
}
resolve(claimId);
})
.catch(error => {
logger.error(error);
reject(NO_CLAIM);
});
});
};
Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {
return new Promise((resolve, reject) => {
this
@ -279,13 +310,14 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
.then(result => {
switch (result.length) {
case 0:
return resolve(null);
default: // note results must be sorted
return reject(NO_CLAIM);
default:
return resolve(result[0].claimId);
}
})
.catch(error => {
reject(error);
logger.error(error);
reject(NO_CLAIM);
});
});
};
@ -295,51 +327,31 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
this
.findAll({
where: { name },
order: [['effectiveAmount', 'DESC'], ['height', 'ASC']], // note: maybe height and effective amount need to switch?
order: [['effectiveAmount', 'DESC'], ['height', 'ASC']],
})
.then(result => {
logger.debug('length of result', result.length);
switch (result.length) {
case 0:
return resolve(null);
return reject(NO_CLAIM);
default:
return resolve(result[0].dataValues.claimId);
}
})
.catch(error => {
reject(error);
});
});
};
Claim.validateLongClaimId = function (name, claimId) {
return new Promise((resolve, reject) => {
this.findOne({
where: {
name,
claimId,
},
})
.then(result => {
if (!result) {
return resolve(null);
};
resolve(claimId);
})
.catch(error => {
reject(error);
logger.error(error);
reject(NO_CLAIM);
});
});
};
Claim.getLongClaimId = function (claimName, claimId) {
logger.debug(`getLongClaimId(${claimName}, ${claimId})`);
if (claimId && (claimId.length === 40)) { // if a full claim id is provided
// logger.debug(`getLongClaimId(${claimName}, ${claimId})`);
if (isLongClaimId(claimId)) {
return this.validateLongClaimId(claimName, claimId);
} else if (claimId && claimId.length < 40) {
return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided
} else if (isShortClaimId(claimId)) {
return this.getLongClaimIdFromShortClaimId(claimName, claimId);
} else {
return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided
return this.getTopFreeClaimIdByClaimName(claimName);
}
};