eu.smartenit.unada.web.ui.UnadaSessionBean.java Source code

Java tutorial

Introduction

Here is the source code for eu.smartenit.unada.web.ui.UnadaSessionBean.java

Source

/**
 * Copyright (C) 2014 The SmartenIT consortium (http://www.smartenit.eu)
 *
 * 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 eu.smartenit.unada.web.ui;

import com.restfb.DefaultFacebookClient;
import com.restfb.FacebookClient;
import com.restfb.FacebookClient.AccessToken;
import com.restfb.types.User;

import eu.smartenit.unada.commons.commands.ARP;
import eu.smartenit.unada.commons.constants.UnadaConstants;
import eu.smartenit.unada.db.dao.util.DAOFactory;
import eu.smartenit.unada.db.dto.Owner;
import eu.smartenit.unada.db.dto.TrustedUser;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * The UnadaSessionBean class. It handles the facebook login and access token retrieval.
 * 
 * @author George Petropoulos
 * @version 2.0
 * 
 */
@ManagedBean
@SessionScoped
public class UnadaSessionBean {

    private static final Logger logger = LoggerFactory.getLogger(UnadaSessionBean.class);

    public String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * The init() method that initializes the ConfigurationBean.
     * It checks for valid sessions, retrieves user's token and checks 
     * whether he is the machine owner and also retrieves stored 
     * uNaDa configuration parameters.
     * 
     */
    @PostConstruct
    public void init() {
        HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext()
                .getRequest();

        boolean validSession = req.getRequestedSessionId() != null && !req.isRequestedSessionIdValid();

        boolean noFacebook = false;
        try {
            noFacebook = (Boolean) FacesContext.getCurrentInstance().getExternalContext().getApplicationMap()
                    .get("noFacebook");
            if (noFacebook) {
                name = "admin";
                return;
            }
        } catch (Exception e) {
            // do nothing
        }

        // check if session has expired
        if (!validSession) {
            String error = req.getParameter("error_reason");
            if (error != null) {
                redirectToLoginPage();
            }

            String code = req.getParameter("code");
            if (code != null) {
                String token = null;
                try {
                    token = retrieveToken(code);
                } catch (Exception e) {
                    logger.error("Error while retrieving token: " + e.getMessage());
                    redirectToLoginPage();
                }
                if (token != null) {
                    Owner owner = DAOFactory.getOwnerDAO().findLast();
                    Owner currentUser = getOwner(token);

                    if (owner == null) {
                        logger.info("Currently there is no owner for this uNaDa.");
                        try {
                            //insert owner of this unada
                            getExtendedToken(currentUser);
                            DAOFactory.getOwnerDAO().insert(currentUser);

                            //add owner as trusted user and update MAC address
                            TrustedUser trustedUser = new TrustedUser();
                            trustedUser.setFacebookID(currentUser.getFacebookID());
                            String ipAddress = req.getRemoteAddr();
                            trustedUser.setMacAddress(ARP.getArpInstance().execute(ipAddress));
                            DAOFactory.getTrustedUserDAO().insert(trustedUser);

                        } catch (Exception e) {
                            logger.error("Error while inserting new owner and trusted user: " + e.getMessage());
                        }
                    } else {
                        logger.info("Current owner id = " + owner.getFacebookID());
                        if (owner.getFacebookID().equals(currentUser.getFacebookID())) {
                            logger.info(
                                    "Existing owner successfully logins to the uNaDa. " + "Updating his token.");
                            getExtendedToken(currentUser);
                            DAOFactory.getOwnerDAO().update(currentUser);
                            logger.debug("Updated token = " + currentUser.getOauthToken());

                            //update trusted user and his MAC address
                            /*
                            TrustedUser trustedUser = new TrustedUser();
                            trustedUser.setFacebookID(currentUser.getFacebookID());
                            String ipAddress = req.getRemoteAddr();
                            trustedUser.setMacAddress(ARP.getArpInstance().execute(ipAddress));
                            try {
                            DAOFactory.getTrustedUserDAO().insert(trustedUser);
                            } catch (Exception e) {
                            logger.error("Error while updating trusted user: "
                                    + e.getMessage());
                            }
                            */

                        } else {
                            redirectToLoginPage();
                        }
                    }
                } else {
                    redirectToLoginPage();
                }
            } else {
                redirectToLoginPage();
            }
        }
    }

    /**
     * The method that gets an authentication token and retrieves the user's data.
     * 
     * @param token The authentication token
     * @return The owner object, including user's data.
     */
    private Owner getOwner(String token) {
        Owner owner = new Owner();
        FacebookClient facebookClient = new DefaultFacebookClient(token);

        User user = facebookClient.fetchObject("me", User.class);
        name = user.getName();
        logger.debug("User " + name + " tries to login. ");
        logger.debug("Short lived token = " + token);

        owner.setFacebookID(user.getId());
        owner.setOauthToken(token);
        return owner;
    }

    private void getExtendedToken(Owner owner) {
        FacebookClient facebookClient = new DefaultFacebookClient(owner.getOauthToken());
        AccessToken extendedAccessToken = facebookClient.obtainExtendedAccessToken(UnadaConstants.APP_ID,
                UnadaConstants.APP_SECRET, owner.getOauthToken());
        String extendedToken = extendedAccessToken.getAccessToken();

        owner.setFacebookID(owner.getFacebookID());
        owner.setOauthToken(extendedToken);

        logger.debug("Long lived token = " + extendedToken);
    }

    /**
     * The method that retrieves user's authentication token from the Facebook API.
     * 
     * @param code The HTTP response code.
     * @return The user's authentication token. Null if there is an error.
     */
    private String retrieveToken(String code) throws Exception {
        String token = null;
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost("https://graph.facebook.com/oauth/access_token");

        try {

            String[][] parameters = { { "client_id", UnadaConstants.APP_ID },
                    { "client_secret", UnadaConstants.APP_SECRET },
                    { "redirect_uri", UnadaConstants.REDIRECT_URI + "/unada/index.xhtml" }, { "code", code } };

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);

            for (int i = 0; i < parameters.length; i++) {
                nameValuePairs.add(new BasicNameValuePair(parameters[i][0], parameters[i][1]));
            }

            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            HttpResponse resp = client.execute(post);
            BufferedReader rd = new BufferedReader(new InputStreamReader(resp.getEntity().getContent()));

            String message = "";
            String lineData;
            while ((lineData = rd.readLine()) != null) {
                message += lineData;
            }

            // Add more safety traps
            String[] params = message.split("&");
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    if (params[i].contains("access_token")) {
                        String[] B = params[i].split("=");
                        if (B != null) {
                            token = B[1];
                        }
                        break;
                    }
                }
            } else {
                return null;
            }
        } catch (Exception e) {
            logger.error("Exception while parsing token: " + e.getMessage());
            return null;
        }
        return token;
    }

    /**
     * The method that invalidates the session and redirects to login page.
     * 
     */
    private void redirectToLoginPage() {
        try {
            FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
            ((HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse())
                    .sendRedirect("login.xhtml");
        } catch (Exception e) {
            logger.error("Exception while redirecting to login page: " + e.getMessage());
        }
    }

    /**
     * The method that invalidates the user's session and logs him out 
     * the uNaDa web application.
     * 
     * @return It returns to login page.
     */
    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        return "/login.xhtml?faces-redirect=true";
    }
}