/* * Copyright 2015 Evgeny Dolganov (evgenij.dolganov@gmail.com). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package och.util.servlet; import static och.util.ExceptionUtil.*; import static och.util.StringUtil.*; import static och.util.Util.*; import static och.util.codec.Base64.*; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.MessageDigest; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import och.util.crypto.AES128; public class WebUtil { public static final String CSRF_PROTECT_TOKEN = "CSRF_ProtectToken"; public static final String XML_HTTP_REQUEST_VAL = "XMLHttpRequest"; public static final String HEADER_X_REQUESTED_WITH = "X-Requested-With"; public static String getClientIp(HttpServletRequest req){ String ipAddress = req.getHeader("x-forwarded-for"); if (ipAddress == null) { ipAddress = req.getRemoteAddr(); } return ipAddress; } public static String getUserAgent(HttpServletRequest req){ return req.getHeader("User-Agent"); } public static String getReferer(HttpServletRequest req){ return req.getHeader("Referer"); } public static String encodeToken(String token, String key) { byte[] encoded = AES128.encode(token, key); String result = encodeBase64String(encoded); return result; } public static String decodeToken(String encoded, String key) { byte[] bytes = decodeBase64(encoded); return AES128.decode(bytes, key); } public static String createActivationCode(){ return randomSimpleId(); } public static String createSalt(){ return randomSimpleId(); } public static byte[] getHash(String input, String salt) { try { String salted = input + salt; MessageDigest md = MessageDigest.getInstance("SHA-512"); //512 - 64bytes md.update(getBytesUTF8(salted)); return md.digest(); }catch (Exception e) { throw getRuntimeExceptionOrThrowError(e); } } public static String generateRandomPsw(int length) { String out = encodeBase64String(randomUUID()).toLowerCase(); return out.length() > length? out.substring(0, length) : out; } public static boolean hasXReqHeader(HttpServletRequest req){ return XML_HTTP_REQUEST_VAL.equals(req.getHeader(HEADER_X_REQUESTED_WITH)); } public static void createAndSet_CSRF_ProtectToken(HttpSession session){ session.setAttribute(CSRF_PROTECT_TOKEN, create_CSRF_ProtectToken()); } public static String create_CSRF_ProtectToken(){ return encodeBase64String(randomUUID()); } public static String get_CSRF_ProtectTokenFromSession(HttpServletRequest req){ HttpSession session = req.getSession(false); return session == null? null : (String) session.getAttribute(CSRF_PROTECT_TOKEN); } public static void set_CSRF_ProtectTokenCookieFromSession(HttpServletRequest req, HttpServletResponse resp){ String token = get_CSRF_ProtectTokenFromSession(req); if(token == null){ return; } resp.addCookie(cookie(CSRF_PROTECT_TOKEN, token, true, -1)); } public static boolean isValid_CSRF_ProtectTokenInReq(HttpServletRequest req){ String token = get_CSRF_ProtectTokenFromSession(req); if(token == null){ return true; } String cookieToken = null; Cookie[] cookies = req.getCookies(); if(isEmpty(cookies)) return false; for (Cookie cookie : cookies) { if(CSRF_PROTECT_TOKEN.equals(cookie.getName())){ cookieToken = cookie.getValue(); break; } } String reqToken = req.getParameter("token"); return token.equals(cookieToken) && token.equals(reqToken); } public static Cookie getCookie(HttpServletRequest req, String name){ Cookie[] cookies = req.getCookies(); if(isEmpty(cookies)) return null; for (Cookie cookie : cookies) { if(name.equals(cookie.getName())){ return cookie; } } return null; } public static String getCookieVal(HttpServletRequest req, String name){ Cookie c = getCookie(req, name); return c != null? c.getValue() : null; } public static String filterQuery(String query, Set<String> onlyParams, Set<String> removeParams){ if( isEmpty(query) || (isEmpty(onlyParams) && isEmpty(removeParams))) return query; boolean isOnlyMode = ! isEmpty(onlyParams); List<String> validPairs = new LinkedList<>(); StringTokenizer st = new StringTokenizer(query, "&"); String pair; int eqIndex; String key; while(st.hasMoreTokens()){ pair = st.nextToken(); if(isEmpty(pair)) continue; eqIndex = pair.indexOf('='); if(eqIndex < 1) continue; key = pair.substring(0, eqIndex); if( isOnlyMode && ! onlyParams.contains(key)) continue; if( ! isOnlyMode && removeParams.contains(key)) continue; validPairs.add(pair); } StringBuilder sb = new StringBuilder(); boolean first = true; for(String pairVal : validPairs){ if(!first) sb.append('&'); else first = false; sb.append(pairVal); } return sb.toString(); } public static Cookie cookieForYear(String name, String val, boolean isHttpOnly){ return cookie(name, val, isHttpOnly, 60*60*24*365); } public static Cookie cookieForMonth(String name, String val, boolean isHttpOnly){ return cookie(name, val, isHttpOnly, 60*60*24*30); } public static Cookie cookie(String name, String val, boolean isHttpOnly, int maxAgeSec){ return cookie(name, val, isHttpOnly, "/", maxAgeSec); } public static Cookie cookie(String name, String val, boolean isHttpOnly, String path, int maxAgeSec){ Cookie cookie = new Cookie(name, val); cookie.setHttpOnly(isHttpOnly); cookie.setPath(path); cookie.setMaxAge(maxAgeSec); return cookie; } public static Cookie cookie(String name, String val, boolean isHttpOnly, String path, int maxAgeSec, String domain){ Cookie cookie = new Cookie(name, val); cookie.setHttpOnly(isHttpOnly); cookie.setPath(path); cookie.setMaxAge(maxAgeSec); cookie.setDomain(domain); return cookie; } public static Cookie deletedCookie(String name){ return deletedCookie(name, "/"); } public static Cookie deletedCookie(String name, String path){ Cookie cookie = new Cookie(name, ""); cookie.setPath(path); cookie.setMaxAge(0); return cookie; } public static String toHttps(String httpUrl){ if(httpUrl.startsWith("http://")){ return "https://"+httpUrl.substring("http://".length()); } return httpUrl; } public static void forward(HttpServletRequest req, HttpServletResponse resp, String path) throws ServletException, IOException{ req.getRequestDispatcher(path).forward(req, resp); } public static boolean isIp6_SimpleCheck(String ip){ return ip.contains(":"); } public static byte[] md5Hash(String s) { if(s == null) return null; try { byte[] bytes = s.getBytes("UTF-8"); MessageDigest md = MessageDigest.getInstance("MD5"); byte[] thedigest = md.digest(bytes); return thedigest; }catch(Exception e){ throw new IllegalStateException("can't md5Encode: "+s, e); } } public static String md5HashStr(String s){ return md5HashToStr(md5Hash(s)); } public static String md5HashToStr(byte[] messageDigest){ // Convert to hex string StringBuffer sb = new StringBuffer(); for (int i = 0; i < messageDigest.length; i++) { if ((0xff & messageDigest[i]) < 0x10) { sb.append('0'); } sb.append(Integer.toHexString(0xff & messageDigest[i])); } return sb.toString(); } public static void writeResp(HttpServletResponse resp, String text) throws IOException{ PrintWriter writer = resp.getWriter(); writer.println(text); writer.flush(); } public static String urlEncode(String param){ try { return URLEncoder.encode(param, UTF8); } catch (UnsupportedEncodingException e) { throw new IllegalStateException(e); } } public static String urlDecode(String param){ try { return URLDecoder.decode(param, UTF8); } catch (UnsupportedEncodingException e) { throw new IllegalStateException(e); } } }