package com.za.session.auth; import java.util.*; import com.cku.core.ZAErrorCode; import com.cku.core.LogObject; import com.cku.core.ZAException; import com.cku.util.Debugger; import com.za.session.conf.ServerConfig; public class TokenMap extends LogObject { private Map _tokenMap; private Set _deleteList; private Object _lock = new Object(); private boolean _debug = false; private static final long VALID_CLOCK = 60 * 60 * 1000; private Thread _checkTokenThread = new Thread(this::_checkToken); private void _checkToken() { while (true) { try { synchronized (this._lock) { this._logDebug("Removing %d invalid tokens", this._deleteList.size()); for (String t : this._deleteList) { this._tokenMap.remove(t); } this._deleteList.clear(); this._deleteList.addAll(this._tokenMap.keySet()); } } catch (Exception e) { this._logE(e, "Invalid token operation"); } try { Thread.sleep(VALID_CLOCK); /* Check it during half an hour. */ } catch (Exception e) { break; } } } private TokenMap() { this._tokenMap = new HashMap(); this._deleteList = new HashSet(); int debugLevel = ServerConfig.instance().get_prop().get_debugLevel(); if (debugLevel >= 5) { this._debug = true; } this._checkTokenThread.setDaemon(true); this._checkTokenThread.start(); } public Token verifyTokenUser(String token,String loginType) throws ZAException { Token t = this.getTokenUser(token,loginType); Debugger.doAssert(t != null, ZAErrorCode.ZA_ERC_ACCESS_DENIED, "Failed to verify token user"); return t; } public Token getTokenUser(String token, String loginType) { if (this._debug) { Token tok = new Token(Long.parseLong(token), token,loginType); return tok; } Token t = null; synchronized (this._lock) { t = this._tokenMap.getOrDefault(token, null); if (t != null) { this._deleteList.remove(t.get_tokenStr()); return t; } } return null; } public void invalidToken(String token) { synchronized (this._lock) { this._tokenMap.remove(token); this._deleteList.remove(token); } } private static String _createRandomString(int number, char[] charList) { Random rand = new Random(); char[] charArr = new char[number]; for (int i = 0; i < number; ++i) { int x = rand.nextInt(charList.length); charArr[i] = charList[x]; } return new String(charArr); } public String registerToken(long userId,String loginType) { while (true) { String tokenStr = _createRandomString(30, s_tokenCharList); synchronized (this._lock) { if (!this._tokenMap.containsKey(tokenStr)) { Token token = new Token(userId, tokenStr,loginType); this._tokenMap.put(tokenStr, token); return tokenStr; } } } } private static TokenMap s_tokenMap = new TokenMap(); private static TokenMap s_sslTokenMap = new TokenMap(); private static char[] s_tokenCharList = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; public static TokenMap instance() { return s_tokenMap; } public static TokenMap ssl_instance() { return s_sslTokenMap; } }