Authored by 郭成尧

done

... ... @@ -195,7 +195,7 @@ class ApiCache {
if (result.length === 0) {
this._log('empty items')
}
// for each server...
// for each server...
result.forEach(itemSet => {
var keys = Object.keys(itemSet);
... ... @@ -255,4 +255,3 @@ class ApiCache {
}
module.exports = ApiCache;
... ...
'use strict';
const ws = require('../../lib/ws');
const redis = require('../../lib/redis');
class ApiCache {
constructor() {
this.redis = redis.client;
}
async setKey(key, value, ttl, force) {
this._log(`setting ${key}`);
let setRes = '';
if (ttl && force) {
setRes = await this.redis.setAsync(key, value, 'EX', ttl);
}
if (ttl && !force) {
setRes = await this.redis.setAsync(key, value, 'NX', 'EX', ttl);
}
if (!ttl && force) {
setRes = await this.redis.setAsync(key, value);
}
if (!ttl && !force) {
setRes = await this.redis.setAsync(key, value, 'NX');
}
if (setRes === 'OK') {
this._log(`set ${key} success`);
} else {
this._log(`set ${key} fail`);
}
return setRes;
}
delKey(key) {
this._log(`deleting ${key}`);
let delRes = this.redis.delAsync(key);
if (delRes === 'OK') {
this._log(`deleted ${key} success`);
} else {
this._log(`deleted ${key} fail`);
}
}
_log(message) {
ws.broadcast(`/api_cache/log`, {
host: this.host,
msg: message
});
}
}
module.exports = ApiCache;
... ...
... ... @@ -16,7 +16,7 @@ const tester = require('../../zookeeper/tester');
const getter = require('../../zookeeper/getter');
const Model = require('../../models/model');
const _ = require('lodash');
const ApiCache = require('../../ci/api_cache');
const ApiCache = require('../../ci/api_cache_redis');
const envs = {
p1oduction: '线上环境',
... ... @@ -24,6 +24,10 @@ const envs = {
test: '测试环境'
};
const UA_LIST_PREFIX = 'pc:limiter:ua:'; // ua 列表
const WHITE_LIST_PREFIX = 'whitelist:ip:'; // 白名单前缀
const BLACK_LIST_PREFIX = 'pc:limiter:'; // 黑名单前缀
class Store extends Model {
constructor() {
super('abuse_protection');
... ... @@ -57,21 +61,28 @@ const makeServer = ((ipKey, uaKey, listName, black) => {
});
},
change_ua: async(ctx, next) => {
const doUpdate = async(ua) => {
const doUpdate = async (ua) => {
console.log('include ua:' + ua);
let hosts = await MemcachedHost.findAll();
await Promise.all(_.map(hosts, (h) => {
const key = `pc:limiter:ua:${black ? 'black' : 'white'}`,
value = JSON.parse(ua || '[]');
let uaObj = [];
try {
uaObj = JSON.parse(ua);
} catch (error) {
console.error(error);
}
uaObj = _.uniq(uaObj);
const keyPrefix = `${UA_LIST_PREFIX}${black ? 'black' : 'white'}`;
return (new ApiCache(h.host)).setKey(key, value, 0);
}));
await new ApiCache().setKey(keyPrefix, JSON.stringify(uaObj), 0, true);
};
let result = await servers.setLists(ctx);
await doUpdate(ctx.query.val);
let result = await servers.setLists(ctx);
if (result) {
ctx.body = {
listName: listName,
... ... @@ -88,46 +99,46 @@ const makeServer = ((ipKey, uaKey, listName, black) => {
},
change_ip: async(ctx, next) => {
let oldList = await servers.getLists(ipKey);
let newList = JSON.parse(ctx.query.val || '[]');
const newList = JSON.parse(ctx.query.val || '[]');
const exclude = async(ip) => {
console.log('exclude:' + ip);
// 黑名单封停 IP
const lock = async (ip) => {
console.log(`lock ip: ${ip}`);
let hosts = await MemcachedHost.findAll();
await Promise.all(_.map(hosts, (h) => {
const key = `pc:limiter:${ip}`,
value = -1,
ttl = 0;
const key = `${BLACK_LIST_PREFIX}${ip}`;
const value = 9999;
const ttl = 60 * 60 * 24 * 30; // 封停一月
return (new ApiCache(h.host)).setKey(key, value, ttl);
}));
await new ApiCache().setKey(key, value, ttl);
};
const lock = async(ip) => {
console.log('lock:' + ip);
// 从黑名单移除 IP,解锁
const unlock = async (ip) => {
console.log(`unlock ip: ${ip}`);
let hosts = await MemcachedHost.findAll();
await Promise.all(_.map(hosts, (h) => {
const key = `pc:limiter:${ip}`,
value = 9999,
ttl = 60 * 60 * 24 * 30; // 封停一月
const key = `${BLACK_LIST_PREFIX}${ip}`;
return (new ApiCache(h.host)).setKey(key, value, ttl);
}));
await new ApiCache().delKey(key);
};
const unlock = async(ip) => {
console.log('unlock:' + ip);
// ip 添加到白名单
const addToWhiteList = async ip => {
console.log(`addToWhiteList ip: ${ip}`);
let hosts = await MemcachedHost.findAll();
await Promise.all(_.map(hosts, (h) => {
const key = `pc:limiter:${ip}`;
const key = `${WHITE_LIST_PREFIX}${ip}`;
return (new ApiCache(h.host)).delKey(key);
}));
await new ApiCache().setKey(key, true);
};
// ip 从白名单移除
const removeFromWhiteList = async ip => {
console.log(`removeFromWhiteList ip: ${ip}`);
const key = `${WHITE_LIST_PREFIX}${ip}`;
await new ApiCache().delKey(key);
}
const unlockList = [];
_.each(oldList, (item) => {
... ... @@ -140,17 +151,20 @@ const makeServer = ((ipKey, uaKey, listName, black) => {
if (black) {
lock(ip);
} else {
exclude(ip);
addToWhiteList(ip);
}
});
_.each(unlockList, (ip) => {
unlock(ip);
if (black) {
unlock(ip);
} else {
removeFromWhiteList(ip);
}
});
let result = await servers.setLists(ctx);
if (result) {
ctx.body = {
listName: listName,
... ... @@ -174,7 +188,20 @@ const makeServer = ((ipKey, uaKey, listName, black) => {
},
async setLists(ctx, type) {
let {path, val} = ctx.query;
let { path, val } = ctx.query;
let valArr = [];
try {
valArr = JSON.parse(val);
} catch (error) {
console.error(error);
}
if (valArr.length) {
valArr = _.uniq(valArr);
val = JSON.stringify(valArr);
}
const rec = await store.findOne({
path: path
... ... @@ -204,4 +231,4 @@ const makeServer = ((ipKey, uaKey, listName, black) => {
return r;
});
module.exports = makeServer;
\ No newline at end of file
module.exports = makeServer;
... ...
... ... @@ -91,4 +91,4 @@
}
});
</script>
\ No newline at end of file
</script>
... ...