Package gotnames.web

Source Code of gotnames.web.GotNamesServlet$UserAuthenticator

package gotnames.web;

import gotnames.Utils;
import gotnames.dm.KTrans;
import gotnames.dm.QueryBuilder;
import gotnames.dm.User;
import gotnames.web.Facebook.FbNotAuthorizedException;
import gotnames.web.st.GotNamesTask;

import java.io.IOException;
import java.util.Map;
import java.util.logging.Logger;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.medallia.spider.SpiderServlet;
import com.medallia.tiny.Clock;
import com.medallia.tiny.Empty;
import com.medallia.tiny.ObjectProvider;
import com.medallia.tiny.ObjectProvider.ObjectFactory;

/**
* Extension of {@link SpiderServlet} for Got Names.
* {@link #registerObjects(ObjectProvider, RequestHandler)} is overridden to
* register the objects available to tasks.
* <p>
* The class {@link GotNamesTask} is the parent class of most tasks in Got Names
* (except for tasks where the user is not yet logged in).
*/
public class GotNamesServlet extends SpiderServlet {
  private static final Logger LOG = Utils.getLog();
 
  private static final String FACEBOOK_DEV_APP_ID = "121767821223439";
  private static final String FACEBOOK_PROD_APP_ID = "183954231614743";
 
  private String serverInfo;
  private boolean development;
 
  private static final PersistenceManagerFactory PM_FACTORY = JDOHelper.getPersistenceManagerFactory("transactions-optional");
 
  @Override public void init(ServletConfig cfg) throws ServletException {
    super.init(cfg);
    serverInfo = getServletContext().getServerInfo();
    development = serverInfo.contains("Development");
    setDebugMode(development);
  }
 
  /** Thrown if a {@link User} object is requested by a task, but the user is not authenticated */
  private static class NoAuthException extends RuntimeException {
   
  }
 
  @Override protected void handleException(HttpServletRequest req, HttpServletResponse res, Throwable t) throws IOException {
    if (t instanceof NoAuthException) {
      res.sendRedirect("/" + getDefaultURI());
    } else if (t instanceof FbNotAuthorizedException) {
      res.sendRedirect("/facebookProfilePic");
    } else {
      LOG.severe("Unexpected exception: " + t.getMessage());
      super.handleException(req, res, t);
    }
  }
 
  /** Object which handles authentication of a {@link User} */
  public interface UserAuthenticator {
    /**
     * @return true if the user with the given token was successfully
     *         authenticated and the web session has been updated
     */
    boolean authenticate(String token);

    /**
     * Method which should be called if the {@link User} object of the
     * currently logged in user is changed since it is cached in the session
     */
    void userUpdated(User user);
    /**
     * Logoff the currently logged on user.
     */
    void logout();
  }
 
  private static final String USER_SESSION_KEY = User.class.getCanonicalName();

  /**
   * The available objects to tasks are:
   * <ul>
   *
   * <li> {@link PersistenceManager}
   * <li> {@link User} (if the user is logged in, otherwise redirects to the start page)
   * <li> {@link UserAuthenticator}
   * <li> {@link Facebook}
   * </ul>
   */
  @Override protected void registerObjects(final ObjectProvider injector, final RequestHandler rh) {
    injector
      .registerFactory(new ObjectFactory<PersistenceManager>() {
        @Override public PersistenceManager make() {
          PersistenceManager pm = PM_FACTORY.getPersistenceManager();
          return pm;
        }
      })
      .registerFactory(new ObjectFactory<User>() {
        @Override public User make() {
          HttpSession session = rh.getSession();
         
          // check if there is an auth token
          String authToken = rh.getInput("t", String.class);
          User user;
          if (authToken != null) {
            PersistenceManager pm = PM_FACTORY.getPersistenceManager();
            user = attemptLogon(pm, session, authToken);
          } else {
            user = (User) session.getAttribute(USER_SESSION_KEY);
          }
         
          if (user == null)
            throw new NoAuthException();
          return user;
        }
      })
      .register(new UserAuthenticator() {
        @Override public boolean authenticate(String token) {
          User user = attemptLogon(PM_FACTORY.getPersistenceManager(), rh.getSession(), token);
          return user != null;
        }
        @Override public void userUpdated(User user) {
          rh.getSession().setAttribute(USER_SESSION_KEY, user);
        }
        @Override public void logout() {
          rh.getSession().removeAttribute(USER_SESSION_KEY);
        }
      })
      .registerFactory(new ObjectFactory<Facebook>() {
        @Override public Facebook make() {
          String appId = development ? FACEBOOK_DEV_APP_ID : FACEBOOK_PROD_APP_ID;
          final String cookieName = "fbs_" + appId;
         
          return new Facebook(appId, getAccessToken(cookieName, rh)) {
            @Override public void logout() {
              rh.removeCookieValue(cookieName);
              rh.getSession().invalidate();
            }
          };
        }
        private String getAccessToken(String cookieName, RequestHandler rh) {
          String str = rh.getCookieValue(cookieName);
          if (str == null)
            return null;
         
          Map<String, String> cookies = Empty.hashMap();
          for (String cv : str.split("&")) {
            String[] kv = cv.split("=");
            if (kv.length == 2)
              cookies.put(kv[0], kv[1]);
          }
         
          return cookies.get("access_token");
        }
      })
    ;
  }
 
  private User attemptLogon(PersistenceManager pm, HttpSession session, String authToken) {
    final User user = QueryBuilder.begin(pm, User.class).getSingleByField("authToken", authToken);
    if (user == null)
      return null;
   
    new KTrans.Void(pm) {
      @Override protected void run() {
        user.setLastLogin(Clock.now());
        pm.makePersistent(user);
      }
    }.go();
   
    session.setAttribute(USER_SESSION_KEY, user);
   
    return user;
  }

  @Override protected String getDefaultURI() {
    return "register";
  }
 
}
TOP

Related Classes of gotnames.web.GotNamesServlet$UserAuthenticator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.