/* ==================================================================== * * Copyright (C) 2017 GeoSolutions S.A.S. * http://www.geo-solutions.it * * GPLv3 + Classpath exception * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. * * ==================================================================== * * This software consists of voluntary contributions made by developers * of GeoSolutions. For more information on GeoSolutions, please see * <http://www.geo-solutions.it/>. * */ package it.geosolutions.geostore.services.rest.impl; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import javax.ws.rs.core.SecurityContext; import org.springframework.beans.factory.annotation.Autowired; import it.geosolutions.geostore.core.model.User; import it.geosolutions.geostore.services.SecurityService; import it.geosolutions.geostore.services.UserSessionService; import it.geosolutions.geostore.services.dto.UserSession; import it.geosolutions.geostore.services.dto.UserSessionImpl; import it.geosolutions.geostore.services.rest.RESTSessionService; import it.geosolutions.geostore.services.rest.model.SessionToken; public class RESTSessionServiceImpl extends RESTServiceImpl implements RESTSessionService{ private static final String BEARER_TYPE = "bearer"; @Autowired UserSessionService userSessionService; private boolean autorefresh = false; public boolean isAutorefresh() { return autorefresh; } public void setAutorefresh(boolean autorefresh) { this.autorefresh = autorefresh; } private long sessionTimeout = 86400; // 1 day public UserSessionService getUserSessionService() { return userSessionService; } public void setUserSessionService(UserSessionService userSessionService) { this.userSessionService = userSessionService; } private static SimpleDateFormat expireParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); /** * Gets the User object associated to the given sessionId (if it exists). * * @param sessionId * @return */ public User getUser(String sessionId, boolean refresh) { User details = userSessionService.getUserData(sessionId); if (details != null && refresh && autorefresh) { userSessionService.refreshSession(sessionId, userSessionService.getRefreshToken(sessionId)); } return details; } /** * Gets the username associated to the given sessionId (if it exists). * * @param sessionId * @return */ public String getUserName(String sessionId, boolean refresh) { User userData = userSessionService.getUserData(sessionId); if (userData != null) { if (refresh && autorefresh) { userSessionService.refreshSession(sessionId, userSessionService.getRefreshToken(sessionId)); } return userData.getName(); } return null; } private Calendar getExpiration(String expires) throws ParseException { if (!"".equals(expires)) { return toCalendar(expires); } return null; } /** * Creates a new session for the User in SecurityContext. * * @return * @throws ParseException */ public String createSession(String expires,SecurityContext sc) throws ParseException { User user = extractAuthUser(sc); if (user != null) { Calendar expiration = getExpiration(expires); UserSession session = null; if (user instanceof User) { session = new UserSessionImpl(null, user, expiration); } return userSessionService.registerNewSession(session); } return null; } @Override public SessionToken login(SecurityContext sc) throws ParseException { Calendar expires = new GregorianCalendar(); expires.add(Calendar.SECOND, (int) getSessionTimeout()); User user = extractAuthUser(sc); if (user != null) { UserSession session = null; if (user instanceof User) { session = new UserSessionImpl(null, user, expires); session.setExpirationInterval(getSessionTimeout()); } return toSessionToken(userSessionService.registerNewSession(session), session); } return null; } private SessionToken toSessionToken(String accessToken, UserSession sessionToken) { if(sessionToken == null) { return null; } SessionToken token = new SessionToken(); token.setAccessToken(accessToken); token.setRefreshToken(sessionToken.getRefreshToken()); token.setExpires(sessionToken.getExpirationInterval()); token.setTokenType(BEARER_TYPE); return token; } @Override public SessionToken refresh(SecurityContext sc, String sessionId, String refreshToken) { return toSessionToken(sessionId, userSessionService.refreshSession(sessionId, refreshToken)); } /** * Removes the given session. * * @return */ public void removeSession(String sessionId) { userSessionService.removeSession(sessionId); } /** * Removes all sessions. * * @return */ public void clear() { userSessionService.removeAllSessions(); } /** Transform Calendar to ISO 8601 string. */ public static String fromCalendar(final Calendar calendar) { Date date = calendar.getTime(); String formatted = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(date); return formatted.substring(0, 22) + ":" + formatted.substring(22); } /** Transform ISO 8601 string to Calendar. */ public static Calendar toCalendar(final String iso8601string) throws ParseException { Calendar calendar = GregorianCalendar.getInstance(); String s = iso8601string.replace("Z", "+00:00"); try { s = s.substring(0, 22) + s.substring(23); // to get rid of the ":" } catch (IndexOutOfBoundsException e) { throw new ParseException("Invalid length", 0); } Date date = expireParser.parse(s); calendar.setTime(date); return calendar; } @Override protected SecurityService getSecurityService() { return null; } public long getSessionTimeout() { return sessionTimeout; } public void setSessionTimeout(long sessionTimeout) { this.sessionTimeout = sessionTimeout; } }