Java tutorial
/* * Copyright (c) 2013, Helome and/or its affiliates. All rights reserved. * Helome PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * Created on 2013-11-21 */ package controllers.user; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import java.util.UUID; import mobile.util.MobileUtil; import models.Gender; import models.User; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import play.Logger; import play.Logger.ALogger; import play.cache.Cache; import play.db.jpa.Transactional; import play.mvc.Http.Context; import play.mvc.Result; import utils.WSUtil; import com.fasterxml.jackson.databind.JsonNode; import common.Constants; import controllers.routes; import controllers.base.BaseApp; import controllers.base.ObjectNodeResult; import ext.sns.auth.AccessTokenResponse; import ext.sns.auth.AuthResponse; import ext.sns.model.UserOAuth; import ext.sns.service.OAuth2Service; import ext.sns.service.ProviderType; import ext.sns.service.SNSService; import ext.sns.service.UserOAuthService; import ext.sns.service.UserOAuthService.UserOAuthResult; import ext.usercenter.UserAuthService; import ext.usercenter.UserAuthURLFilter; /** * * * @ClassName: OAuthApp * @Description: ?? * @date 2013-11-21 ?3:19:23 * @author ShenTeng * */ public class OAuthApp extends BaseApp { private static final ALogger LOGGER = Logger.of(OAuthApp.class); /** * ? */ public static Result requestAuth(String provider, String referer, String type) { ClientType clientType = MobileUtil.isMobileUrlPrefix(request().path()) ? ClientType.MOBILE : ClientType.WEB; if (StringUtils.isBlank(referer)) { referer = "/"; } try { if (!OAuth2Service.checkProviderName(provider) || !ProviderType.validateType(provider, type)) { return getResult(ResultType.ILLEGAL_PARAM, clientType, referer); } if (ProviderType.isNeedLogin(type) && !UserAuthService.isLogin(session())) { return getResult(ResultType.NOT_LOGIN, clientType, referer); } OAuthRequestInfo authRequestInfo = new OAuthRequestInfo(); authRequestInfo.setReferer(referer); authRequestInfo.setClientType(clientType); authRequestInfo.setType(type); String specialParamKey = null; if (ClientType.MOBILE == clientType) { authRequestInfo.setFrom(MobileUtil.getFromByUrl(request().path())); specialParamKey = "mobileDisplay"; } else { authRequestInfo.setFrom("web"); } return redirect( OAuth2Service.getRequestAuthURI(provider, type, authRequestInfo.toMap(), specialParamKey)); } catch (Exception e) { LOGGER.error("fail to requestAuth.", e); return getResult(ResultType.AUTH_FAIL, clientType, referer); } } /** * ? */ @Transactional public static Result authBack() { try { // ?? AuthResponse authResponse = OAuth2Service.getAuthResponseByURI(request().uri()); if (null == authResponse) { LOGGER.error("authResponse"); return getResult(ResultType.AUTH_FAIL, null, null); } OAuthRequestInfo authRequestInfo = OAuthRequestInfo.create(authResponse.getBackExtInfo()); String provider = authResponse.getProviderName(); if (authResponse.isError() || null == authRequestInfo || StringUtils.isBlank(provider)) { LOGGER.error("authRequestInfo?provider?authResponseError uri = " + request().uri()); if (null == authRequestInfo) { return getResult(ResultType.AUTH_FAIL, null, null); } else { return getResult( authResponse.isAccessDeniedError() ? ResultType.ACCESS_DENIED : ResultType.AUTH_FAIL, authRequestInfo.getClientType(), authRequestInfo.getReferer()); } } ClientType clientType = authRequestInfo.getClientType(); String referer = authRequestInfo.getReferer(); String type = authRequestInfo.getType(); String from = authRequestInfo.getFrom(); if (!OAuth2Service.checkProviderName(provider) || !ProviderType.validateType(provider, type)) { LOGGER.error("providertype? uri = " + request().uri()); return getResult(ResultType.AUTH_FAIL, clientType, referer); } if (ProviderType.isNeedLogin(type) && !UserAuthService.isLogin(session())) { return getResult(ResultType.NOT_LOGIN, clientType, referer); } // ?token AccessTokenResponse accessTokenResponse = OAuth2Service.accessToken(authResponse); if (null == accessTokenResponse) { LOGGER.error("accessTokenResponse null"); return getResult(ResultType.AUTH_FAIL, clientType, referer); } // ?? UserOAuthResult userOAuthResult = UserOAuthService.saveOrUpdate(accessTokenResponse, provider); if (!userOAuthResult.isSuccess()) { LOGGER.error("UserOAuthService.saveOrUpdateuserOAuthResult.getState = " + userOAuthResult.getState()); return getResult(ResultType.AUTH_FAIL, clientType, referer); } UserOAuth userOAuth = userOAuthResult.getResult(); // ?SNS? if (type.equals(ProviderType.SNS)) { if (userOAuth.isBindUser()) { return getResult(ResultType.OTHER_USER_BIND, clientType, referer); } else { int ret = UserOAuthService.bindToUser(userOAuth, User.getFromSession(session())); if (ret != 1) { LOGGER.error("ALL:SNS:UserOAuthService.bindToUser"); return getResult(ResultType.AUTH_FAIL, clientType, referer); } } return redirect(referer); } // ?? if (ClientType.MOBILE == clientType) { // ? if (userOAuth.isBindUser()) { int ret = UserOAuthService.loginByBindUser(userOAuth); if (ret != 1) { if (ret == -1) { return getResult(ResultType.ACCOUNT_DISABLE, clientType, referer); } LOGGER.error("MOBILE:LOGIN:UserOAuthService.loginByBindUser"); return getResult(ResultType.AUTH_FAIL, clientType, referer); } } else { // ???? User newUser = UserOAuthService.registerRandomUser(userOAuth.nickname); if (null == newUser) { LOGGER.error("MOBILE:LOGIN:UserOAuthService.registerRandomUser"); return getResult(ResultType.AUTH_FAIL, clientType, referer); } int ret = UserOAuthService.bindToUser(userOAuth, newUser); if (ret != 1) { LOGGER.error("MOBILE:LOGIN:UserOAuthService.bindToUser"); User.logout(Context.current().session()); return getResult(ResultType.AUTH_FAIL, clientType, referer); } if (MobileUtil.isFromAndroid(from)) { SNSService.postMsg(userOAuth, "seagull???"); } } return redirect(referer); } else if (ClientType.WEB == clientType) { // ? if (userOAuth.isBindUser()) { int ret = UserOAuthService.loginByBindUser(userOAuth); if (ret != 1) { if (ret == -1) { return getResult(ResultType.ACCOUNT_DISABLE, clientType, referer); } LOGGER.error("MOBILE:LOGIN:UserOAuthService.loginByBindUser"); return getResult(ResultType.AUTH_FAIL, clientType, referer); } return ok(views.html.user.thirdtransfer.render("1", "", "", "")); } else { // ? String key = UUID.randomUUID().toString().replace("-", ""); Cache.set(Constants.CACHE_USEROAUTH_ID + key, userOAuth.id, 600); return ok(views.html.user.thirdtransfer.render("0", key, userOAuth.avatarUrl, userOAuth.nickname)); } } return redirect(referer); } catch (Exception e) { LOGGER.error("authBack", e); return getResult(ResultType.AUTH_FAIL, null, null); } } /** * ??? */ @Transactional public static Result directLogin() { JsonNode param = getJson(); if (null == param) { return illegalParameters(); } String key = param.path("key").asText(); if (StringUtils.isBlank(key)) { return illegalParameters(); } ObjectNodeResult result = new ObjectNodeResult(); Long userOAuthId = (Long) Cache.get(Constants.CACHE_USEROAUTH_ID + key); UserOAuth userOAuth = UserOAuthService.getById(userOAuthId); if (null == userOAuth) { return ok(result.errorkey("useroauth.login.notfoundauth").getObjectNode()); } Cache.remove(Constants.CACHE_USEROAUTH_ID + key); // ??? User newUser = UserOAuthService.registerRandomUser(userOAuth.nickname); if (null == newUser) { LOGGER.error("directLogin:UserOAuthService.registerRandomUser"); return ok(result.errorkey("useroauth.login.fail").getObjectNode()); } int ret = UserOAuthService.bindToUser(userOAuth, newUser); if (ret != 1) { LOGGER.error("directLogin:UserOAuthService.bindToUser"); User.logout(Context.current().session()); return ok(result.errorkey("useroauth.login.fail").getObjectNode()); } return ok(result.getObjectNode()); } /** * ???? */ @Transactional public static Result bindAccountLogin() { JsonNode param = getJson(); if (null == param) { return illegalParameters(); } String key = param.path("key").asText(); String email = param.path("email").asText(); String password = param.path("password").asText(); if (StringUtils.isBlank(key) || StringUtils.isBlank(email) || StringUtils.isBlank(password)) { return illegalParameters(); } ObjectNodeResult result = new ObjectNodeResult(); Long userOAuthId = (Long) Cache.get(Constants.CACHE_USEROAUTH_ID + key); UserOAuth userOAuth = UserOAuthService.getById(userOAuthId); if (null == userOAuth) { return ok(result.errorkey("useroauth.login.notfoundauth").getObjectNode()); } // ??? result = User.login(email, password, false); if (!result.isSuccess()) { return ok(result.getObjectNode()); } Cache.remove(Constants.CACHE_USEROAUTH_ID + key); int ret = UserOAuthService.bindToUser(userOAuth, result.getUser()); if (ret != 1) { LOGGER.error("bindAccountLogin:UserOAuthService.bindToUser"); User.logout(Context.current().session()); return ok(result.errorkey("useroauth.login.fail").getObjectNode()); } return ok(result.getObjectNode()); } /** * ?????? */ @Transactional public static Result newAccountLogin() { JsonNode param = getJson(); if (null == param) { return illegalParameters(); } String key = param.path("key").asText(); String email = param.path("email").asText(); String password = param.path("password").asText(); String captcha = param.path("captcha").asText(); String cpKey = param.path("t").asText(); if (StringUtils.isBlank(key) || StringUtils.isBlank(email) || StringUtils.isBlank(password) || StringUtils.isBlank(captcha) || StringUtils.isBlank(cpKey)) { return illegalParameters(); } ObjectNodeResult result = new ObjectNodeResult(); Long userOAuthId = (Long) Cache.get(Constants.CACHE_USEROAUTH_ID + key); UserOAuth userOAuth = UserOAuthService.getById(userOAuthId); if (null == userOAuth) { return ok(result.errorkey("useroauth.login.notfoundauth").getObjectNode()); } // ???? result = User.register(email, password, Gender.MAN, captcha, cpKey); if (!result.isSuccess()) { return ok(result.getObjectNode()); } Cache.remove(Constants.CACHE_USEROAUTH_ID + key); int ret = UserOAuthService.bindToUser(userOAuth, result.getUser()); if (ret != 1) { LOGGER.error("newAccountLogin:UserOAuthService.bindToUser"); User.logout(Context.current().session()); return ok(result.errorkey("useroauth.login.fail").getObjectNode()); } return ok(result.getObjectNode()); } /** * ?? */ @Transactional public static Result revokeAuth(String providerName, String referer) { if (!OAuth2Service.checkProviderName(providerName)) { return errorInfo("??"); } User user = User.getFromSession(session()); UserOAuthService.revokeAuthorize(user, providerName); return redirect(referer); } private static Result getResult(ResultType resultType, ClientType clientType, String referer) { if (resultType == ResultType.ILLEGAL_PARAM) { if (clientType == ClientType.MOBILE) { return mobileErrorRedirect(referer, "???", "100005"); } else if (clientType == ClientType.WEB) { return errorInfo("??"); } } else if (resultType == ResultType.NOT_LOGIN) { if (clientType == ClientType.MOBILE) { return mobileErrorRedirect(referer, "", "100002"); } else if (clientType == ClientType.WEB) { return redirect(UserAuthURLFilter.getNoLoginRedirectURI(referer)); } } else if (resultType == ResultType.AUTH_FAIL) { if (clientType == ClientType.MOBILE) { return mobileErrorRedirect(referer, "?", "267001"); } else if (clientType == ClientType.WEB) { return errorInfo("?", referer, "?"); } else { return internalServerError("????"); } } else if (resultType == ResultType.ACCESS_DENIED) { return getAccessDeniedResult(clientType, referer); } else if (resultType == ResultType.OTHER_USER_BIND) { if (clientType == ClientType.MOBILE) { return mobileErrorRedirect(referer, "??", "267002"); } else if (clientType == ClientType.WEB) { return errorInfo("??", referer, "?"); } } else if (resultType == ResultType.ACCOUNT_DISABLE) { if (clientType == ClientType.MOBILE) { return mobileErrorRedirect(referer, "?", "267004"); } else if (clientType == ClientType.WEB) { String url = routes.Application.loginskip().url(); return jumpForWeb(referer, url); } } return null; } private static Result jumpForWeb(String referer, String url) { if (!referer.startsWith("window:")) { return redirect(referer); } else { StringBuilder contentBuilder = new StringBuilder(); contentBuilder.append( "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"); contentBuilder.append("<html xmlns=\"http://www.w3.org/1999/xhtml\" >"); contentBuilder.append("<head>"); contentBuilder.append("<title></title>"); contentBuilder.append("</head>"); contentBuilder.append("<body>"); contentBuilder.append("<script type=\"text/javascript\">"); contentBuilder.append("window.onload = function(){"); contentBuilder.append("window.close();"); if (StringUtils.isNotBlank(url)) { contentBuilder.append("window.opener.location.href = \"" + url + "\""); } contentBuilder.append("};"); contentBuilder.append("</script>"); contentBuilder.append("</body>"); contentBuilder.append("</html>"); return ok(contentBuilder.toString()).as("text/html"); } } private static Result getAccessDeniedResult(ClientType clientType, String referer) { if (clientType == ClientType.MOBILE) { return mobileErrorRedirect(referer, "???", "267003"); } else if (clientType == ClientType.WEB) { return jumpForWeb(referer, null); } else { return internalServerError("access_denied"); } } private static Result mobileErrorRedirect(String referer, String error, String errorCode) { try { return redirect(referer + WSUtil.getURIQueryStringPrefix(referer) + "errorCode=" + errorCode + "&error=" + URLEncoder.encode(error, "utf-8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } /** * */ private enum ResultType { /** ?? */ ILLEGAL_PARAM, /** */ NOT_LOGIN, /** ? */ AUTH_FAIL, /** ?? */ ACCESS_DENIED, /** */ OTHER_USER_BIND, /** ??? **/ ACCOUNT_DISABLE } private enum ClientType { WEB, MOBILE; public static ClientType getByName(String name) { for (ClientType c : ClientType.values()) { if (c.name().equals(name)) { return c; } } return null; } } private static class OAuthRequestInfo { private String referer; private ClientType clientType; private String from; private String type; public static OAuthRequestInfo create(Map<String, String> map) { if (MapUtils.isEmpty(map)) { return null; } String referer = map.get("r"); ClientType clientType = ClientType.getByName(map.get("c")); String from = map.get("f"); String type = map.get("t"); if (StringUtils.isBlank(referer) || null == clientType || StringUtils.isBlank(from) || StringUtils.isBlank(type)) { return null; } OAuthRequestInfo info = new OAuthRequestInfo(); info.setReferer(referer); info.setClientType(clientType); info.setFrom(from); info.setType(type); return info; } public Map<String, String> toMap() { Map<String, String> param = new HashMap<String, String>(); param.put("r", referer); param.put("c", clientType.name()); param.put("f", from); param.put("t", type); return param; } public String getReferer() { return referer; } public void setReferer(String referer) { this.referer = referer; } public ClientType getClientType() { return clientType; } public void setClientType(ClientType clientType) { this.clientType = clientType; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getType() { return type; } public void setType(String type) { this.type = type; } } }