// // Copyright 2010 Cinch Logic Pty Ltd. // // http://www.chililog.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 org.chililog.server.workbench.workers; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.UUID; import org.apache.commons.lang.StringUtils; import org.chililog.server.common.AppProperties; import org.chililog.server.common.ChiliLogException; import org.chililog.server.common.CryptoUtils; import org.chililog.server.common.JsonTranslator; import org.chililog.server.data.UserBO; import org.chililog.server.workbench.Strings; import org.chililog.server.workbench.workers.AuthenticationAO.ExpiryType; /** * <p> * Authentication API Object is used for login * </p> * * @author vibul * */ /** * @author vibul * */ public class AuthenticationTokenAO { private String _id; private String _userID; private ExpiryType _expiryType; private int _expirySeconds; private Date _expiresOn; /** * Basic constructor */ public AuthenticationTokenAO() { return; } /** * Constructor using the details of a validated user * * @param userBO * Authenticated user * @param authenticationApiObject * authentication object with the user's details */ public AuthenticationTokenAO(UserBO userBO, AuthenticationAO authenticationApiObject) { _id = UUID.randomUUID().toString(); _userID = userBO.getDocumentID().toString(); _expiryType = authenticationApiObject.getExpiryType(); _expirySeconds = authenticationApiObject.getExpirySeconds(); updateExpiresOn(); return; } /** * Updates the expiry date of the token to the current time + number of expiry seconds. */ public void updateExpiresOn() { GregorianCalendar cal = new GregorianCalendar(); cal.add(Calendar.SECOND, _expirySeconds); _expiresOn = cal.getTime(); } /** * Unique id for this session */ public String getId() { return _id; } public void setId(String id) { _id = id; } /** * The user's mongoDB document id */ public String getUserID() { return _userID; } public void setUserID(String userID) { _userID = userID; } /** * Method used to determine when the issued authentication token expires. See {@link ExpiryType} */ public ExpiryType getExpiryType() { return _expiryType; } public void setExpiryType(ExpiryType expiryType) { _expiryType = expiryType; } /** * Number of seconds before the issued authentication token expires */ public int getExpirySeconds() { return _expirySeconds; } public void setExpirySeconds(int expirySeconds) { _expirySeconds = expirySeconds; } /** * The date and time when this token expires */ public Date getExpiresOn() { return _expiresOn; } public void setExpiresOn(Date expiresOn) { _expiresOn = expiresOn; } /** * <p> * Convert the token to a string. * </p> * <p> * Format is <code>json(AuthenticationTokenAO) + ~~~ + hash(json(AuthenticationTokenAO))</code> * </p> */ @Override public String toString() { try { AppProperties appProperties = AppProperties.getInstance(); String json = JsonTranslator.getInstance().toJson(this).replace("\n", ""); StringBuilder sb = new StringBuilder(); sb.append(json); sb.append("~~~"); sb.append(CryptoUtils.createSHA512Hash(json, appProperties.getWorkbenchApiAuthenticationHashSalt(), false)); return sb.toString(); } catch (Exception ex) { throw new RuntimeException("Error creating authentication token.", ex); } } /** * <p> * Loads from an encrypted token * </p> * <p> * Format is <code>json(AuthenticationTokenAO) + ~~~ + hash(json(AuthenticationTokenAO))</code> * </p> * * @param tokenString * String representation of a token as returned by <code>toString()</code>. * @throws ChiliLogException * If token is invalid, errorCode set to Strings.AUTHENTICAITON_TOKEN_INVALID_ERROR. If token is * expired, errorCode set to Strings.AUTHENTICAITON_TOKEN_EXPIRED_ERROR. */ public static AuthenticationTokenAO fromString(String tokenString) throws ChiliLogException { if (StringUtils.isBlank(tokenString)) { throw new ChiliLogException(Strings.AUTHENTICAITON_TOKEN_INVALID_ERROR); } AppProperties appProperties = AppProperties.getInstance(); int separatorIndex = tokenString.indexOf("~~~"); if (separatorIndex < 0) { throw new ChiliLogException(Strings.AUTHENTICAITON_TOKEN_INVALID_ERROR); } String json = tokenString.substring(0, separatorIndex); String hash = tokenString.substring(separatorIndex + 3); if (!CryptoUtils.verifyHash(json, appProperties.getWorkbenchApiAuthenticationHashSalt(), hash)) { throw new ChiliLogException(Strings.AUTHENTICAITON_TOKEN_INVALID_ERROR); } AuthenticationTokenAO token = JsonTranslator.getInstance().fromJson(json, AuthenticationTokenAO.class); if (token.getExpiresOn().getTime() < new Date().getTime()) { throw new ChiliLogException(Strings.AUTHENTICAITON_TOKEN_EXPIRED_ERROR); } return token; } }