001/**
002 * Copyright (C) 2014  Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
003 *
004 * This file is part of Dicoogle/dicoogle.
005 *
006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * Dicoogle/dicoogle is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with Dicoogle.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package pt.ua.dicoogle.server.web.auth;
020
021import java.io.IOException;
022import javax.servlet.http.HttpServletRequest;
023import javax.servlet.http.HttpServletResponse;
024import javax.servlet.http.HttpSession;
025
026/**
027 * Handles and manages login requests and the information associated with it.
028 *
029 * @author António Novo <antonio.novo@ua.pt>
030 */
031public class Session
032{
033        /**
034         * Attemps to login using the supplied params.
035         *
036         * @param username the user name.
037         * @param password the users password.
038         * @return true if the login is successfull, false otherwise.
039         */
040        public static boolean isSuccessfulLogin(String username, String password)
041        {
042                LoggedIn result = getSuccessfulLogin(username, password);
043
044                return (result != null);
045        }
046
047        /**
048         * Attemps to login using the supplied params.
049         *
050         * @param username the user name.
051         * @param password the users password.
052         * @return a LoggedIn object if the login is successfull, null otherwise.
053         */
054        public static LoggedIn getSuccessfulLogin(String username, String password)
055        {
056                Authentication auth = Authentication.getInstance();
057                LoggedIn result = auth.login(username, password);
058
059                return result;
060        }
061
062        /**
063         * Check if there is a user logged in on the session supplied.
064         *
065         * @param session the HttpSession object of the request.
066         * @return true if there is a user logged in on the session supplied, false otherwise.
067         */
068        public static boolean isUserLoggedIn(HttpSession session)
069        {
070                return (getUserLoggedIn(session) != null);
071        }
072
073        /**
074         * Check if there is a user logged in on the session supplied and if (s)he ia an administrator.
075         *
076         * @param session the HttpSession object of the request.
077         * @return true if there is a user logged in on the session supplied and is an administrator, false otherwise.
078         */
079        public static boolean isUserLoggedInAnAdmin(HttpSession session)
080        {
081                LoggedIn login = getUserLoggedIn(session);
082                return ((login != null) && (login.isAdmin()));
083        }
084
085        /**
086         * Gets the LoggedIn object that has the information relative to user logged in on the session supplied.
087         *
088         * @param session the HttpSession object of the request.
089         * @return a LoggedIn object if there is a user logged in on the session supplied, null otherwise.
090         */
091        public static LoggedIn getUserLoggedIn(HttpSession session)
092        {
093                // if the sessio is invalid
094                if (session == null)
095                        return null;
096
097                // if the client is not yet aware of (or didn't aceepted/joined) the session
098                if (session.isNew())
099                        return null;
100
101                // if no login information was found
102                Object login = session.getAttribute("login");
103                if (login == null)
104                        return null;
105
106                // the client is currently logged in
107                return (LoggedIn) login;
108        }
109
110        /**
111         * If there is a user logged in on the current HttpSession, log out.
112         *
113         * @param session the HttpSession object of the request.
114         * @return if there was a logout action performed or not.
115         */
116        public static boolean logout(HttpServletRequest request)
117        {
118                HttpSession session = request.getSession(false);
119                try
120                {
121                        session.invalidate();
122                }
123                catch (Exception e )
124                {
125                        System.err.println("Tracking session");
126                }
127
128
129
130                // if the sessio is invalid
131                if (session == null)
132                        return false;
133
134                // if the client is not yet aware of (or didn't aceepted/joined) the session
135                if (session.isNew())
136                        return false;
137
138                // if no login information was found
139                Object login = session.getAttribute("login");
140                if (login == null)
141                        return false;
142
143                // the client is currently logged in, so logout
144                session.removeAttribute("login");
145                session.invalidate();
146                return true;
147        }
148
149        /**
150         * Checks if the request made to a servlet was made by a logged is user,
151         * or if the request carries the required login information.
152         * <br>
153         * This is done by first checking if the request has a valid
154         * (with valid login information) session (like an AJAX request from a
155         * cookies enabled browser), if not checks if the request parameters
156         * have valid login information (like made a REST[less] stand-alone
157         * application), and if none of the above situations happened send an
158         * adequate response to the client.
159         *
160         * @param requiresAdminRights if the current request requires admin rights to be served/performed.
161         * @return a LoggedIn object if the request is to be served, null otherwise.
162         */
163        public static LoggedIn servletLogin(HttpServletRequest request, HttpServletResponse response, boolean requiresAdminRights) throws IOException
164        {
165                // check if there a session and a login information attached to it
166                HttpSession session = request.getSession(false);
167                LoggedIn login = getUserLoggedIn(session);
168                if (login != null)
169                {
170                        // check if this request needs admin rights and the user has them
171                        if (requiresAdminRights)
172                        {
173                                if (login.isAdmin())
174                                        return login;
175                                else
176                                {
177                                        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Administrator rights are needed to process this request!");
178                                        return null;
179                                }
180                        }
181                        else
182                                return login;
183                }
184
185                // since the above failed, check if there is valid login information on the request parameters
186                String username = request.getParameter("username");
187                String password = request.getParameter("password");
188                login = getSuccessfulLogin(username, password);
189                if (login != null)
190                {
191                        // check if this request needs admin rights and the user has them
192                        if (requiresAdminRights)
193                        {
194                                if (login.isAdmin())
195                                        return login;
196                                else
197                                {
198                                        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Administrator rights are needed to process this request!");
199                                        return null;
200                                }
201                        }
202                        else
203                                return login;
204                }
205
206                // both situations failed
207                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "No login information found!");
208                return null;
209        }
210
211        /**
212         * Checks if the request made to a webapp was made by a logged is user,
213         * or if the request carries the required login information.
214         * <br>
215         * This is done by first checking if the request has a valid
216         * (with valid login information) session (like an AJAX request from a
217         * cookies enabled browser), if not checks if the request parameters
218         * have valid login information (like made a REST[less] stand-alone
219         * application), and if none of the above situations happened send an
220         * adequate response to the client, on most cases a redirection to the
221         * login page will be sent.
222         *
223         * @param requiresAdminRights if the current request requires admin rights to be served/performed.
224         * @return a LoggedIn object if the request is to be served, null otherwise.
225         */
226        public static LoggedInStatus webappLogin(HttpServletRequest request, HttpServletResponse response, boolean requiresAdminRights) throws IOException
227        {
228                // check if there a session and a login information attached to it
229                //HttpSession session = request.getSession(true);
230                //LoggedIn login = getUserLoggedIn(session);
231                /*if (login != null)
232                {
233                        // check if this request needs admin rights and the user has them
234                        if (requiresAdminRights && (! login.isAdmin()))
235                        {
236                                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
237                                return new LoggedInStatus(null, LoggedInStatus.S_UNAUTHORIZEDACCESS);
238                        }
239
240                        return new LoggedInStatus(login, LoggedInStatus.S_ALREADYLOGGEDIN);
241                }*/
242
243                // since the above failed, check if there is valid login information on the request parameters
244                String username = request.getParameter("username");
245                String password = request.getParameter("password");
246                LoggedIn login = getSuccessfulLogin(username, password);
247                if (login != null)
248                {
249                        // check if this request needs admin rights and the user has them
250                        if (requiresAdminRights && (! login.isAdmin()))
251                        {
252                                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
253                                return new LoggedInStatus(null, LoggedInStatus.S_UNAUTHORIZEDACCESS);
254                        }
255
256                        // add the login information to the session
257                        HttpSession session = request.getSession(true); // force the creation of a new session if there is none
258                        session.setAttribute("login", login);
259                        return new LoggedInStatus(login, LoggedInStatus.S_VALIDLOGIN);
260                }
261
262                // both situations failed
263                if ((username == null) && (password == null))
264                        return new LoggedInStatus(null, LoggedInStatus.S_NOINFORMATION);
265                else
266                        return new LoggedInStatus(null, LoggedInStatus.S_INVALIDCREDENTIALS);
267        }
268
269        /**
270         * Based on the request referer returns the address of the previously visited
271         * page or to the default main page if none.
272         *
273         * @param request the original http request object.
274         * @return a string containing the previous URL.
275         */
276        public static String getLastVisitedURL(HttpServletRequest request)
277        {
278                String result = "/index.jsp";
279
280                if (request == null)
281                        return result;
282
283                result = request.getHeader("Referer");
284                if (result == null)
285                        result = "/index.jsp";
286
287                return result;
288        }
289}