1 34 package net.myvietnam.mvncore.security; 35 36 import java.util.*; 37 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 import net.myvietnam.mvncore.exception.FloodException; 41 import net.myvietnam.mvncore.util.DateUtil; 42 43 51 public class FloodControl { 52 53 private static Log log = LogFactory.getLog(FloodControl.class); 54 55 56 public static int MAX_MVNCORE_ACTION_ID = 999; 57 58 private static Map actionControlMap = new TreeMap(); 59 60 static final long REMOVE_INTERVAL = DateUtil.MINUTE * 2; 62 private FloodControl() { 63 } 64 65 71 public static void setOption(Integer action, int actionsPerHour) { 72 getControlledAction(action).setActionsPerHour(actionsPerHour); 73 } 74 75 public static int getActionsPerHour(Integer action) { 76 return getControlledAction(action).getActionsPerHour(); 77 } 78 79 85 public static boolean reachMaximum(Integer action, String strIP) { 86 return getControlledAction(action).reachMaximum(strIP); 87 } 88 89 99 public static void ensureNotReachMaximum(Integer action, String strIP) throws FloodException { 100 if (reachMaximum(action, strIP)) { 101 log.info("Attempt to exceed the maximum number of actions: ActionID = " + action + " and IP = " + strIP); 102 throw new FloodException("You have reached the maximum number of actions for this page (actionID = " + action + "). Please try this page later. This is to prevent forum from being flooded."); 104 } 105 } 106 107 113 public static void increaseCount(Integer action, String strIP) { 114 getControlledAction(action).increaseCount(strIP); 115 } 116 117 124 public static void resetActionHistory(Integer action, String strIP) { 125 getControlledAction(action).resetActionHistory(strIP); 126 } 127 128 134 private static synchronized ControlledAction getControlledAction(Integer action) { 135 ControlledAction controlledAction = (ControlledAction)actionControlMap.get(action); 136 if (controlledAction == null) { 137 controlledAction = new ControlledAction(); 138 actionControlMap.put(action, controlledAction); 139 } 140 return controlledAction; 141 } 142 } 143 144 147 class ControlledAction { 148 private int actionsPerHour = 0; 149 private Map ipMap = new TreeMap(); 150 private long lastRemoveTime = 0; 151 152 void setActionsPerHour(int actionsPerHour) { 153 if (actionsPerHour >= 0) { 154 this.actionsPerHour = actionsPerHour; 155 } 156 } 157 158 int getActionsPerHour() { 159 return actionsPerHour; 160 } 161 162 boolean reachMaximum(String strIP) { 163 removeTimeoutControlledIP(); 164 return getControlledIP(strIP).reachMaximum(); 165 } 166 167 void increaseCount(String strIP) { 168 removeTimeoutControlledIP(); 169 getControlledIP(strIP).increaseCount(); 170 } 171 172 void resetActionHistory(String strIP) { 173 removeTimeoutControlledIP(); 174 getControlledIP(strIP).resetActionHistory(); 175 } 176 177 private synchronized ControlledIP getControlledIP(String strIP) { 178 ControlledIP controlledIP = (ControlledIP)ipMap.get(strIP); 179 if (controlledIP == null) { 180 controlledIP = new ControlledIP(actionsPerHour); 181 ipMap.put(strIP, controlledIP); 182 } else { 183 controlledIP.setActionsPerHour(actionsPerHour); 185 } 186 return controlledIP; 187 } 188 189 private synchronized void removeTimeoutControlledIP() { 190 long now = System.currentTimeMillis(); 191 if ((now - lastRemoveTime) > FloodControl.REMOVE_INTERVAL) { 192 lastRemoveTime = now; 193 Collection ipList = ipMap.values(); 194 for (Iterator iter = ipList.iterator(); iter.hasNext(); ) { 195 ControlledIP currentControlledIP = (ControlledIP)iter.next(); 196 if (now - currentControlledIP.getLastIncrementTime() > DateUtil.HOUR) { 197 iter.remove(); 198 } 199 } 200 } 201 } 202 } 203 204 207 class ControlledIP { 208 private int actionsPerHour = 0; 209 private long lastRemoveTime = 0; 210 private long lastIncrementTime = 0; 211 private ArrayList actionHistoryList = new ArrayList(); 212 213 ControlledIP(int actionsPerHour) { 214 if (actionsPerHour >= 0) { 215 this.actionsPerHour = actionsPerHour; 216 } 217 } 218 219 void setActionsPerHour(int actionsPerHour) { 220 if (actionsPerHour >= 0) { 221 this.actionsPerHour = actionsPerHour; 222 } 223 } 224 225 long getLastIncrementTime() { 226 return lastIncrementTime; 227 } 228 229 void increaseCount() { 230 long now = System.currentTimeMillis(); 231 lastIncrementTime = now; 232 actionHistoryList.add(new Long (now)); 233 } 234 235 void resetActionHistory() { 236 lastRemoveTime = 0; 237 lastIncrementTime = 0; 238 actionHistoryList.clear(); 239 } 240 241 boolean reachMaximum() { 242 if (actionsPerHour == 0) { return false; 244 } 245 246 if (actionHistoryList.size() < actionsPerHour) { 247 return false; 248 } 249 250 removeTimeoutActions(); 252 253 return (actionHistoryList.size() >= actionsPerHour); 254 } 255 256 private synchronized void removeTimeoutActions() { 257 long now = System.currentTimeMillis(); 258 if (now - lastRemoveTime > FloodControl.REMOVE_INTERVAL) { 259 lastRemoveTime = now; 260 for (Iterator iter = actionHistoryList.iterator(); iter.hasNext(); ) { 261 Long currentAction = (Long )iter.next(); 262 if ((now - currentAction.longValue()) > DateUtil.HOUR) { 263 iter.remove(); 264 } 265 } } 267 } 268 } 269 | Popular Tags |