<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ page import="java.util.*,java.io.*,weaver.filter.XssUtil" %>
<%@ page import="weaver.security.classLoader.ReflectMethodCall,weaver.hrm.*,java.util.regex.*" %>
<jsp:useBean id="xssUtil" class="weaver.filter.XssUtil" scope="page"></jsp:useBean>
<%String secondPrefixPath = xssUtil.null2String(xssUtil.getRule().get("second-prefix-path"));%>
<%

	User userr = HrmUserVarify.getUser(request, response);
	if(userr == null){
		return;
	}
	 XssUtil sc = new XssUtil();
	String oldUrlWarnOpen = sc.null2String(sc.getRule().get("old-url-warn-open-level"));
	String currentFlag = "";
	if ("1".equals(oldUrlWarnOpen)) {
		currentFlag = "未登录接口访问防护模式，登录后接口警告模式";
	} else if ("2".equals(oldUrlWarnOpen)) {
		currentFlag = "警告模式";
	} else if ("3".equals(oldUrlWarnOpen)) {
		currentFlag = "拦截模式";
	} else if ("4".equals(oldUrlWarnOpen)) {
		currentFlag = "jsp接口防护模式";
	}
	int uid = sc.getIntValue(sc.null2String(sc.getRule().get("userID")),1);
	if(userr.getUID()!=uid){
		//response.sendRedirect("/notice/noright.jsp");
		out.println("please login with admin.");
		return;
	}

	if(userr!=null && !"".equals(request.getParameter("ip"))){
		if("allow".equals(request.getParameter("src"))){
			try{
				//xssUtil.getTmpForbiddenIpMap().remove(request.getParameter("ip"));
				Map forbiddenIp = (Map)xssUtil.getTmpForbiddenIpMap().get(request.getParameter("ip"));
				forbiddenIp.put("status","false");
				forbiddenIp.put("type","Manager manual allow");
			}catch(Exception e){}
		}else if("forbidden".equals(request.getParameter("src"))){
			try{
				Map forbiddenIp = (Map)xssUtil.getTmpForbiddenIpMap().get(request.getParameter("ip"));
				if(forbiddenIp == null) {
					xssUtil.putToTmpForbiddenIpMap(request.getParameter("ip"), request.getRequestURI(), "Manager manual join");
					forbiddenIp = (Map)xssUtil.getTmpForbiddenIpMap().get(request.getParameter("ip"));
				}
				forbiddenIp.put("status","true");
				forbiddenIp.put("type","Manager manual join");
			}catch(Exception e){}
		}
	}
	
%>


<%
	String doubleLoginCheckSuccessTime = (String) session.getAttribute("doubleLoginCheckSuccessTime");
	long currentData = new Date().getTime();
	if (doubleLoginCheckSuccessTime == null || currentData - Long.valueOf(doubleLoginCheckSuccessTime) > 10 * 60 * 1000) {
%>
<jsp:include page="/security/login/commonSecondLogin.jsp" />
<% return; }%>

<!DOCTYPE html>
<html lang="zh-CN">
<head lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>历史接口拦截信息</title>
	<link rel="stylesheet" href="<%=secondPrefixPath%>/js/jquery-clockpicker/assets/css/bootstrap.min_wev8.css">
	<script src="<%=secondPrefixPath%>/security/js/checkLogin.min.js"></script>
	<script src="<%=secondPrefixPath%>/js/jquery-clockpicker/assets/js/bootstrap.min_wev8.js"></script>
	<script  type="text/javascript" src="<%=secondPrefixPath%>/js/rsa/jsencrypt.js"></script>
	<script  type="text/javascript" src="<%=secondPrefixPath%>/js/rsa/rsa.js"></script>
    <link href="<%=secondPrefixPath%>/security/monitor/logparser/static/bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
    <link href="<%=secondPrefixPath%>/security/monitor/logparser/static/bootstrap-3.3.5/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css"/>
	<script type="text/javascript">


		function addWhite(data) {
			if(confirm("确定将此接口加入白名单吗？")){

				$.ajax({
					url: (window.ecologyContentPath||"") + "/security/updateTime.jsp",
					type:"post",
					data:{
						url:data
					},
					success:function(data){
						alert(data.trim());
						//alert('添加成功')
						location.reload();
					}
				});

			}
		}

		function forbiddenUrl(data, type) {

		    var msg = "";
		    if (type == '1') {
		    	msg = "确定将此接口加入禁止访问黑名单吗？";
			} else if (type == '2') {
				msg = "确定将此接口从黑名单中解封吗？";
			}
			if(confirm(msg)){
				$.ajax({
					url: (window.ecologyContentPath||"") + "/security/updateTime.jsp",
					type:"post",
					data:{
						forbiddenUrl:data,
						type:type
					},
					success:function(data){
						var resultData = data.trim();
						console.log(resultData);
						if (resultData === '200') {
							alert("成功");
							location.reload();
						} else {
							alert(resultData);
						}
					}
				});

			}
		}

		function closeloginpanel() {
			window.location.reload();
		}


		function allow(ip){

			if (ip == null || ip.trim() === '') {
				alert("源ip不允许为空");
				return;
			}

			if(confirm("该IP由于存在疑似可疑系统的行为而被禁止访问系统. 你确定要解封吗？")){
				document.getElementById("ip").value=ip;
				document.getElementById("src").value="allow";
				document.getElementById("updateRulesForm").submit();
			}
		}

		function openBlock() {
				$.ajax({
					url: (window.ecologyContentPath||"") + "/security/updateTime.jsp",
					type:"post",
					data:{
						isOpen:1
					},
					success:function(data){
						var resultData = data.trim();
						console.log(resultData);
						if (resultData === '200') {
							alert("开启拦截模式成功");
							var open_deatil = document.getElementById("open_deatil");
							open_deatil.innerText = "拦截模式已启动-点击查看防护描述";
							open_deatil.className = "btn btn-primary";

							var btn_open_block = document.getElementById("btn_open_block");
							btn_open_block.innerText = "已开启";
							btn_open_block.setAttribute("disabled", "true");

							$('#Modal').modal('hide');
						} else {
							alert(resultData);
						}
					}
				});
		}

		function forbidden(ip,path,desc){

			if (ip == null || ip.trim() === '') {
				alert("源ip不允许为空");
				return;
			}

			if(confirm("禁止后，该IP将无法访问系统。你确定要加入禁止该IP吗？")){
				document.getElementById("ip").value=ip;
				document.getElementById("src").value="forbidden";
				document.getElementById("url").value= path;
				document.getElementById("desc").value= desc;
				document.getElementById("updateRulesForm").submit();
			}
		}

	</script>

	<style>
		.dec_title{

			font-weight: bold;
			color: black;

		}
		.dec_title_content{
			text-indent:2em;

		}

		.modal-body{
			max-height: 500px;
			overflow-y: auto;
		}

		.dec_title_content_span {
			background-color: yellow;
		}
	</style>

</head>
<body>
<div class="container">
    <h2 class="text-center">历史接口拦截信息</h2>
	<%
		if ("3".equals(oldUrlWarnOpen)) {
	%>
		<h4 class="text-right"><button class="btn btn-primary" data-toggle="modal" data-target="#Modal">拦截模式已启动-点击查看防护描述</button></h4>
	<%
	} else {
	%>
		<h4 class="text-right"><button class="btn btn btn-danger" data-toggle="modal" data-target="#Modal" id="open_deatil">开启拦截-点击查看防护描述</button></h4>
	<%
		}
	%>

</div>

<div class="modal fade" id="Modal">
	<div class="modal-dialog modal-dialog-centered">
		<div class="modal-content">
			<div class="modal-header" style="height: 50px">
				<button type="button" class="close" data-dismiss="modal">
					<%--<span>&times;</span>--%>
				</button>
				<h5 class="modal-title" id="modalTitle" style="font-weight: bold; color: black">历史接口防护的简单介绍以及开启之后的使用影响</h5>
			</div>

			<div class="modal-body">
				<p class="dec_title">当前开启模式:</p>
				<p class="dec_title_content"><span class="dec_title_content_span"><%=currentFlag%></span></p>
				<p class="dec_title">防护介绍:</p>
				<p class="dec_title_content">此功能主要针对于长时间（默认是40天）未使用的功能（接口）进行防护。</p>
				<p class="dec_title_content"><span class="dec_title_content_span">功能超过默认时长未访问，当再次访问的时候进行拦截，在默认时长期间进行访问，会延长此功能允许访问时间，计算方式为：当前时间+默认时长（此防护与超时登录类似，比如设置超时时间30分钟，30分钟未登录再此访问时需要重新登录）。</span></p>

				<p class="dec_title"><span class="dec_title_content_span">开启优势:</span></p>
				<p class="dec_title_content">在<span class="dec_title_content_span">护网</span>或者<span class="dec_title_content_span">攻防演练</span>等特殊时期，开启此防护<span class="dec_title_content_span">拦截模式</span>之后，能有效防止已<span class="dec_title_content_span">废弃</span>也存在漏洞的接口被攻击者恶意利用、
					以及<span class="dec_title_content_span">后门文件</span>的利用（即使攻击者绕过安全设备上传了后门文件在服务器中，因为此防护<span class="dec_title_content_span">拦截模式</span>的开启，会进行拦截）以及一些未知接口的攻击。</p>

				<p class="dec_title">开启影响:</p>
				<p class="dec_title_content">标准功能和二开功能的影响：比如应用的某个功能长时间未使用，当超过默认时长再次进行访问的时候，会进行阻断。</p>
				<p class="dec_title_content">新增功能的影响：比如客户开启这个防护已经<span class="dec_title_content_span">超过了默认时长</span>，然后开发了新功能，假设开发的是一个jsp文件，需要放在对应目录下进行访问，第一次访问时会直接拦截。</p>

				<p class="dec_title">加白名单方式:</p>
				<p class="dec_title_content">下面列表中存在数据，红色背景属于拦截信息，非红色是警告信息（警告属于日志记录，非拦截），点击添加白名单按钮即可。</p>

				<p class="dec_title"><span class="dec_title_content_span">防护关闭操作方式:</span></p>
				<p class="dec_title_content">打开ecology/WEB-INF/prop/oldUrlBaseTime.properties文件，修改warn_level=后面的值：</p>
				<p class="dec_title_content">warn_level=1：登录前的功能防护模式，登录后的为警告模式;</p>
				<p class="dec_title_content">warn_level=2：警告模式，不进行防护;</p>
				<p class="dec_title_content">warn_level=3：防护模式，全部接口防护;<span class="dec_title_content_span">（点击确定开启按钮就是指开启全部拦截;如果想确认当前已开启哪种模式，看此弹框的第一行有说明）</span></p>
				<p class="dec_title_content">warn_level=4：针对jsp接口的请求开启防护模式，其他接口为告警模式;</p>
				<p class="dec_title_content">然后使用管理员登录访问/updateRules.jsp（集群环境需要使用单节点访问，如果不能，重启也生效）。</p>


			</div>


			<div class="modal-footer">
				<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
				<%
					if ("3".equals(oldUrlWarnOpen)) {
				%>
					<button type="button" class="btn btn-primary" disabled="true">已开启</button>
				<%
					} else {

				%>
					<button type="button" class="btn btn-primary" onclick="openBlock()" id="btn_open_block">确定开启</button>
				<%
					}
				%>

			</div>
		</div>
	</div>
</div>

<br>
<form action="<%=secondPrefixPath%>/security/monitor/logparser/oldUrl.jsp" id="updateRulesForm" name="updateRulesForm" style="display:none;" method="post">
	<input type="hidden" name = "ip" id="ip"/>
	<input type="hidden" name = "src" id="src" value="allow"/>
	<input type="hidden" name = "url" id="url" value=""/>
	<input type="hidden" name = "desc" id="desc" value=""/>
</form>

<div class="bs-example" data-example-id="hoverable-table">
    <table class="table table-hover table-responsive  table-condensed table-striped">
      <thead>
      <tr>
          <th style="width:15%">日期</th>
          <th style="width:25%">路径</th>
          <th style="width:20%">描述</th>
          <th style="width:15%">referer</th>
		  <th style="width:15%">第一次拦截时间</th>
		  <th style="width:15%">ip</th>
		  <th style="width:10%">操作</th>
      </tr>
      </thead>
      <tbody>
	  <%!
	           //返回正则的方法
				public String returnNeedStr(String reg,String str){
					try{
						Pattern pattern = Pattern.compile(reg);
						Matcher matcher = pattern.matcher(str);
						while(matcher.find()){
							return htmlEncode(matcher.group(1));
						}
					}catch(Exception e){
					   // e.printStackTrace();
					}
					return  null;
				}

				//返回正则的方法
				public String returnNeedStr2(String reg,String str){
					try{
						Pattern pattern = Pattern.compile(reg);
						Matcher matcher = pattern.matcher(str);
						while(matcher.find()){
							return htmlEncode(matcher.group(0));
						}
					}catch(Exception e){
						// e.printStackTrace();
					}
					return  null;
				}

				public  String htmlEncode(String source) {
						if(source == null) {
						   return "";
						}
					   String html = "";
					   StringBuffer buffer = new StringBuffer();
						for(int i = 0; i < source.length(); i++) {
						   char c = source.charAt(i);
						   switch (c) {
						   case '<':
							   buffer.append("&lt;");
							   break;
						   case '>':
							   buffer.append("&gt;");
							   break;
						   case '&':
							   buffer.append("&amp;");
							   break;
						   case '"':
							   buffer.append("&quot;");
							   break;
						   case 10:
						   case 13:
							   break;
						   default:
							   buffer.append(c);
						   }
						}
					   html = buffer.toString();
					   return html;
		 		}

		 		public void compareTime() {

				}

		  		private static Pattern compile = Pattern.compile(".+path=(.*?)\\sreferer=(.*?)\\sfirstBlockTime=(.*?)\\sblockTime=(.*?)\\sdefaultBaseTime=(.*?)\\soldUrlWarnOpen=(.*?)\\ssource ip:(.*?)\\s.*security validate failed!");

				public List<Map<String, String>> analysisLog(String filePath) {

					List<Map<String, String>> listMap = new ArrayList<Map<String, String>>();
					Map<String, Map<String, String>> logMap = new HashMap<String, Map<String, String>>();
					File file = new File(filePath);
					if (!file.exists()) {
						return listMap;
					}

					BufferedReader bufferedReader = null;
					try {
						bufferedReader = new BufferedReader(new FileReader(file));
						String content = bufferedReader.readLine();
						while (content != null) {
							if (content.contains("failed[old url warning")) {
								Matcher matcher = compile.matcher(content.trim());
								if (matcher.matches()) {
									Map<String, String> map = new HashMap<String, String>();
									map.put("path", matcher.group(1));
									map.put("referer", matcher.group(2));
									map.put("firstBlockTime", matcher.group(3));
									map.put("blockTime", matcher.group(4));
									map.put("defaultBaseTime", matcher.group(5));
									map.put("oldUrlWarnOpen", matcher.group(6));
									map.put("ip", matcher.group(7));
									map.put("warn", "1");
									logMap.put(matcher.group(1), map);
								}

							}
							content = bufferedReader.readLine();
						}

						Set<Map.Entry<String, Map<String, String>>> entries = logMap.entrySet();
						for (Map.Entry<String, Map<String, String>> entry : entries) {
							listMap.add(entry.getValue());
						}

					} catch (Exception e) {
						e.printStackTrace();
					} finally {
						if (bufferedReader != null) {
							try {
								bufferedReader.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}

					return listMap;
				}

	     %>
		  <%


			  Map map = xssUtil.getTmpForbiddenIpMap();

			  Map<String, Map<String, String>> blockDelayUrlMap = (Map<String, Map<String, String>>) xssUtil.getRule().get("blockDelayUrlMap");
			  if (blockDelayUrlMap == null) {
				  blockDelayUrlMap = new HashMap<String, Map<String, String>>();
			  }

			  // YYYY-MM-DD
			  String currentDateString = XssUtil.getCurrentDateString();
			  List<Map<String, String>> pathCacheList = new ArrayList<Map<String, String>>();
			  Set<Map.Entry<String, Map<String, String>>> entries = blockDelayUrlMap.entrySet();
			  for (Map.Entry<String, Map<String, String>> entry : entries) {
				  Map<String, String> pathInfo = entry.getValue();
				  // YYYY-MM-DD
				  String time = xssUtil.null2String(pathInfo.get("time"));
				  // 时间戳
				  String blockTime = xssUtil.null2String(pathInfo.get("blockTime"));
				  if ("".equals(blockTime)) continue;
				  if (time.equals(currentDateString)) {
					  pathCacheList.add(pathInfo);
				  }
			  }

			  Comparator<Map<String, String>> comparator = new Comparator<Map<String, String>>() {
				  @Override
				  public int compare(Map<String, String> map1, Map<String, String> map2) {
					  Long blockTime1 = Long.valueOf(map1.get("blockTime"));
					  Long blockTime2 = Long.valueOf(map2.get("blockTime"));
					  return blockTime2.compareTo(blockTime1);
				  }
			  };

			  pathCacheList.sort(comparator);

			  // 读取当前日志的告警信息
			  String securityLogFile = sc.getXssLogFilePath() + "/systemSecurity" + XssUtil.getCurrentDateString() + ".log";
			  List<Map<String, String>> maps = analysisLog(securityLogFile);
			  maps.sort(comparator);
			  pathCacheList.addAll(maps);

			  if (pathCacheList == null || pathCacheList.isEmpty()) {
				  out.println("<tr><td>暂无拦截记录<td></tr>");
				  return;
			  }

			  int num = 0;
			  Map<String,List<String>> oldUrlWarnAndBlockLog = new HashMap<String,List<String>>();
			  for (Map<String, String> pathInfo : pathCacheList) {
				  if (num > 100) {
				  	num = 0;
				  	break;
				  } else {
				  	num++;
				  }
				  String blockTime = xssUtil.null2String(pathInfo.get("blockTime"));
				  String blockTimeStr = xssUtil.getTimeString(new Date(Long.valueOf(blockTime)));
				  String uri = htmlEncode(xssUtil.null2String(pathInfo.get("path")));
				  String referer = xssUtil.null2String(pathInfo.get("referer"));
				  String firstBlockTime = xssUtil.null2String(pathInfo.get("firstBlockTime"));
				  String firstBlockTimeStr = xssUtil.getTimeString(new Date(Long.valueOf(firstBlockTime)));
				  String ip = xssUtil.null2String(pathInfo.get("ip"));
				  String warn = xssUtil.null2String(pathInfo.get("warn"));

				  if (!"".equals(warn)) {
					  out.println("<tr>");
				  } else {
					  //out.println("<tr style='background-color: #dc2a2a; '>");
					  out.println("<tr style='background-color: #e02222;'>");
				  }

				  out.println(" <td data-toggle=\"modal\" style='vertical-align: middle;'>"+ blockTimeStr +"</td>");

				  out.println(" <td data-toggle=\"modal\" style='vertical-align: middle;'>" + uri +"</td>");
				  List<String> oldUrlWarnAndBlockList = oldUrlWarnAndBlockLog.get(currentDateString);
				  if (oldUrlWarnAndBlockList == null) {
					  oldUrlWarnAndBlockList = new ArrayList<String>();
					  oldUrlWarnAndBlockLog.put(currentDateString, oldUrlWarnAndBlockList);
				  }
				  oldUrlWarnAndBlockList.add(uri.toLowerCase());

				  if (!"".equals(warn)) {
					  out.println(" <td data-toggle=\"modal\" style='vertical-align: middle;'>warning</td>");
				  } else {
					  out.println(" <td data-toggle=\"modal\" style='vertical-align: middle;'>old url reject</td>");
				  }

				  out.println(" <td data-toggle=\"modal\" style='vertical-align: middle;'>"+ htmlEncode(referer) +"</td>");

				  out.println(" <td data-toggle=\"modal\" style='vertical-align: middle;'>"+ firstBlockTimeStr +"</td>");

				  out.println(" <td data-toggle=\"modal\" style='vertical-align: middle;'>"+ htmlEncode(ip) +"</td>");

				  StringBuilder opStr = new StringBuilder("");
				  opStr.append("<div style='display:flex'>");
				  if ("".equals(warn)) {
					  opStr.append("<div style='cursor:pointer;margin: 8px;padding: 4px;border: 1px solid #337ab7; width:90px;height:28px;text-align:center;color:#ffffff;border-radius:4px; background-color:#337AB7;' onclick=\"addWhite('" + uri + "');\">加入白名单</div>");
				  }

				  Map<String, String[]> forbiddenNeedCheckUrlList = (Map<String, String[]>) sc.getRule().get("forbidden-need-check-urls");
				  //Map<String, List<String>> oldUrlWarnAndBlockLogMap = sc.getRule().get("oldUrlWarnAndBlockLog") == null? new HashMap<String, List<String>>() : (Map<String, List<String>>) sc.getRule().get("oldUrlWarnAndBlockLog");
				  //List<String> oldUrlWarnAndBlockLogData = oldUrlWarnAndBlockLogMap.get(currentDateString);
				  if (forbiddenNeedCheckUrlList != null && (forbiddenNeedCheckUrlList.get(uri) != null || forbiddenNeedCheckUrlList.get(uri.toLowerCase()) != null)) {
					  opStr.append("<div style='cursor:pointer;margin: 8px;padding: 4px;border: 1px solid #f0ad4e; width:90px;height:28px;text-align:center;color:#ffffff;border-radius:4px; background-color:#f0ad4e;' onclick=\"forbiddenUrl('" + uri + "', '2');\">解封接口</div>");
				  } else {
					  opStr.append("<div style='cursor:pointer;margin: 8px;padding: 4px;border: 1px solid #337ab7; width:90px;height:28px;text-align:center;color:#ffffff;border-radius:4px; background-color:#337AB7;' onclick=\"forbiddenUrl('" + uri + "', '1');\">禁止接口</div>");
				  }


				  if(ip != null && map!=null) {
					  Map ipMap = (Map) map.get(ip);
					  if(ipMap!=null) {
						  if ("true".equals("" + ipMap.get("status"))) {
							  opStr.append("<div style='cursor:pointer;margin: 8px;padding: 4px;border: 1px solid #f0ad4e; width:90px;height:28px;text-align:center;color:#ffffff;border-radius:4px; background-color:#f0ad4e;' onclick=\"allow('"+htmlEncode(ip)+"','"+uri+"','');\">解封ip</div>");
						  }else{
							  opStr.append("<div style='cursor:pointer;margin: 8px;padding: 4px;border: 1px solid #337ab7; width:90px;height:28px;text-align:center;color:#ffffff;border-radius:4px; background-color:#337AB7;' onclick=\"forbidden('"+htmlEncode(ip)+"','"+uri+"','');\">禁止ip</div>");
						  }
					  } else {
						  opStr.append("<div style='cursor:pointer;margin: 8px;padding: 4px;border: 1px solid #337AB7; width:90px;height:28px;text-align:center;color:#ffffff;border-radius:4px; background-color:#337AB7;' onclick=\"forbidden('"+htmlEncode(ip)+"','"+uri+"','');\">禁止ip</div>");
					  }
				  }
				  opStr.append("</div>");
				  //String opStr = "<div style=\"margin-left:auto;margin-right:auto;text-align:center;cursor:pointer;color:#ffffff;width:90px;height:28px;padding: 3px;border:1px solid #337ab7; border-radius:4px; background-color:#337ab7;\" onclick=\"addWhite('" + uri + "');\">加入白名单</div>";
				  /*if (!"".equals(warn)) {
					  out.println(" <td data-toggle=\"modal\">警告</td>");
				  } else {
					  out.println(" <td data-toggle=\"modal\">"+opStr+"</td>");
				  }*/

				  out.println(" <td data-toggle=\"modal\" style='vertical-align: middle;'>"+opStr.toString()+"</td>");
				  out.println("</tr>");
			  }

			  // 可禁止的接口数据
			  xssUtil.getRule().put("oldUrlWarnAndBlockLog",oldUrlWarnAndBlockLog);
     %>
      </tbody>
    </table>



</div>
</body>
</html>