abuse_protection.js 2.33 KB
'use strict';

const Router = require('koa-router');
const ApiCache = require('../../ci/api_cache');
const _ = require('lodash');

const {
    MemcachedHost
} = require('../../models');

let r = new Router();

const defensive = {
    index: async(ctx, next) => {
        const regexp = /pc:limiter:faker:(.*)/;
        const threshold = ctx.request.query.threshold || 100;
        const limit = ctx.request.query.limit || 10;

        let hosts = await MemcachedHost.findAll();
        let results = await Promise.all(_.map(hosts, (h) => {
            return (new ApiCache(h.host)).find((key) => {
                return regexp.test(key);
            });
        }));

        let list = [];


        if (results && results[0]) {
            Object.keys(results[0]).forEach((key) => {
                const index = results[0][key];

                if (index > threshold) {
                    list.push({
                        ip: ((key) => {
                            const m = key.match(regexp);

                            return m && m.length > 0 ? m[1] : 'Unknown';
                        })(key),
                        index: index
                    })
                }
            });
        }

        list = _.orderBy(list, (item) => {
            return item.index;
        }, 'desc').slice(0, limit);

        await ctx.render('action/abuse_protection', {
            list: list,
            threshold: threshold,
            limit: limit
        });
    },
    lock: async(ctx, next) => {
        let hosts = await MemcachedHost.findAll();
        await Promise.all(_.map(hosts, (h) => {
            const key = `pc:limiter:${ctx.request.body.remoteIp}`,
                value = 9999,
                ttl = 60 * 60 * 8; // 封停8小时

            return (new ApiCache(h.host)).setKey(key, value, ttl);
        }));

        return ctx.body = {
            code: 200
        };
    },
    unlock: async(ctx, next) => {
        let hosts = await MemcachedHost.findAll();
        await Promise.all(_.map(hosts, (h) => {
            const key = `pc:limiter:${ctx.request.body.remoteIp}`;

            return (new ApiCache(h.host)).delKey(key);
        }));

        return ctx.body = {
            code: 200
        };
    }
};

r.get('/abuse_protection', defensive.index);
r.post('/lock', defensive.lock);
r.post('/unlock', defensive.unlock);

module.exports = r;