/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.frontend.web.controllers; import java.util.HashMap; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.orcid.core.manager.UserConnectionManager; import org.orcid.frontend.spring.web.social.config.SocialContext; import org.orcid.frontend.spring.web.social.config.SocialType; import org.orcid.persistence.jpa.entities.UserconnectionEntity; import org.orcid.persistence.jpa.entities.UserconnectionPK; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.social.facebook.api.Facebook; import org.springframework.social.facebook.api.User; import org.springframework.social.google.api.Google; import org.springframework.social.google.api.plus.Person; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; /** * @author Shobhit Tyagi */ @Controller @RequestMapping("/social") public class SocialController extends BaseController { @Autowired private SocialContext socialContext; @Resource private AuthenticationManager authenticationManager; //@Resource //private UserConnectionDao userConnectionDao; @Resource private UserConnectionManager userConnectionManager; @RequestMapping(value = { "/access" }, method = RequestMethod.GET) public ModelAndView signinHandler(HttpServletRequest request, HttpServletResponse response) { SocialType connectionType = socialContext.isSignedIn(request, response); if (connectionType != null) { Map<String, String> userMap = retrieveUserDetails(connectionType); String providerId = connectionType.value(); String userId = socialContext.getUserId(); UserconnectionEntity userConnectionEntity = userConnectionManager.findByProviderIdAndProviderUserId(userMap.get("providerUserId"), providerId); if (userConnectionEntity != null) { if (userConnectionEntity.isLinked()) { UserconnectionPK pk = new UserconnectionPK(userId, providerId, userMap.get("providerUserId")); userConnectionManager.updateLoginInformation(pk); String aCredentials = new StringBuffer(providerId).append(":").append(userMap.get("providerUserId")).toString(); PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken(userConnectionEntity.getOrcid(), aCredentials); token.setDetails(new WebAuthenticationDetails(request)); Authentication authentication = authenticationManager.authenticate(token); SecurityContextHolder.getContext().setAuthentication(authentication); return new ModelAndView("redirect:" + calculateRedirectUrl(request, response)); } else { ModelAndView mav = new ModelAndView(); mav.setViewName("social_link_signin"); mav.addObject("providerId", providerId); mav.addObject("accountId", getAccountIdForDisplay(userMap)); mav.addObject("linkType", "social"); mav.addObject("emailId", (userMap.get("email") == null) ? "" : userMap.get("email")); mav.addObject("firstName", (userMap.get("firstName") == null) ? "" : userMap.get("firstName")); mav.addObject("lastName", (userMap.get("lastName") == null) ? "" : userMap.get("lastName")); return mav; } } else { throw new UsernameNotFoundException("Could not find an orcid account associated with the email id."); } } else { throw new UsernameNotFoundException("Could not find an orcid account associated with the email id."); } } private Map<String, String> retrieveUserDetails(SocialType connectionType) { Map<String, String> userMap = new HashMap<String, String>(); if (SocialType.FACEBOOK.equals(connectionType)) { Facebook facebook = socialContext.getFacebook(); User user = facebook.fetchObject("me", User.class, "id", "email", "name", "first_name", "last_name"); userMap.put("providerUserId", user.getId()); userMap.put("userName", user.getName()); userMap.put("email", user.getEmail()); userMap.put("firstName", user.getFirstName()); userMap.put("lastName", user.getLastName()); } else if (SocialType.GOOGLE.equals(connectionType)) { Google google = socialContext.getGoogle(); Person person = google.plusOperations().getGoogleProfile(); userMap.put("providerUserId", person.getId()); userMap.put("userName", person.getDisplayName()); userMap.put("email", person.getAccountEmail()); userMap.put("firstName", person.getGivenName()); userMap.put("lastName", person.getFamilyName()); } return userMap; } private String getAccountIdForDisplay(Map<String, String> userMap) { if (userMap.get("email") != null) { return userMap.get("email"); } if (userMap.get("userName") != null) { return userMap.get("userName"); } return userMap.get("providerUserId"); } }