Added: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubAuthenticator.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubAuthenticator.java?rev=1688503&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubAuthenticator.java (added) +++ ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubAuthenticator.java Tue Jun 30 18:38:16 2015 @@ -0,0 +1,416 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.ofbiz.passport.user; + +import java.util.Locale; +import java.util.Map; +import java.io.IOException; +import java.io.Serializable; +import java.sql.Timestamp; + +import javax.transaction.Transaction; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.cookie.CookiePolicy; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.params.HttpMethodParams; +import org.ofbiz.passport.event.GitHubEvents; +import org.ofbiz.passport.user.GitHubUserGroupMapper; +import org.ofbiz.passport.util.PassportUtil; +import org.ofbiz.common.authentication.api.Authenticator; +import org.ofbiz.common.authentication.api.AuthenticatorException; +import org.ofbiz.service.LocalDispatcher; +import org.ofbiz.service.GenericServiceException; +import org.ofbiz.service.ServiceUtil; +import org.ofbiz.entity.Delegator; +import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.GenericEntityException; +import org.ofbiz.entity.transaction.TransactionUtil; +import org.ofbiz.entity.transaction.GenericTransactionException; +import org.ofbiz.entity.util.EntityUtil; +import org.ofbiz.base.conversion.ConversionException; +import org.ofbiz.base.conversion.JSONConverters.JSONToMap; +import org.ofbiz.base.lang.JSON; +import org.ofbiz.base.util.UtilProperties; +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.UtilMisc; +import org.ofbiz.base.util.UtilDateTime; +import org.ofbiz.base.util.UtilValidate; + +import javolution.util.FastMap; + +/** + * GitHub OFBiz Authenticator + */ +public class GitHubAuthenticator implements Authenticator { + + private static final String module = GitHubAuthenticator.class.getName(); + + public static final String props = "gitHubAuth.properties"; + + public static final String resource = "PassportUiLabels"; + + protected LocalDispatcher dispatcher; + + protected Delegator delegator; + + /** + * Method called when authenticator is first initialized (the delegator + * object can be obtained from the LocalDispatcher) + * + * @param dispatcher The ServiceDispatcher to use for this Authenticator + */ + public void initialize(LocalDispatcher dispatcher) { + this.dispatcher = dispatcher; + this.delegator = dispatcher.getDelegator(); + } + + /** + * Method to authenticate a user. + * + * For GitHub users, we only check if the username(userLoginId) exists an + * externalAuthId, and the externalAuthId has a valid accessToken in + * GitHubUser entity. + * + * @param username User's username + * @param password User's password + * @param isServiceAuth true if authentication is for a service call + * @return true if the user is authenticated + * @throws org.ofbiz.common.authentication.api.AuthenticatorException + * when a fatal error occurs during authentication + */ + public boolean authenticate(String userLoginId, String password, boolean isServiceAuth) throws AuthenticatorException { + Map<String, Object> user = null; + GetMethod getMethod = null; + try { + GenericValue userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", userLoginId), false); + String externalAuthId = userLogin.getString("externalAuthId"); + GenericValue gitHubUser = delegator.findOne("GitHubUser", UtilMisc.toMap("gitHubUserId", externalAuthId), false); + if (UtilValidate.isNotEmpty(gitHubUser)) { + String accessToken = gitHubUser.getString("accessToken"); + String tokenType = gitHubUser.getString("tokenType"); + if (UtilValidate.isNotEmpty(accessToken)) { + getMethod = new GetMethod(GitHubEvents.ApiEndpoint + GitHubEvents.UserApiUri); + user = GitHubAuthenticator.getUserInfo(getMethod, accessToken, tokenType, Locale.getDefault()); + } + } + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (HttpException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (IOException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (AuthenticatorException e) { + throw new AuthenticatorException(e.getMessage(), e); + } finally { + if (getMethod != null) { + getMethod.releaseConnection(); + } + } + + Debug.logInfo("GitHub auth called; returned user info: " + user, module); + return user != null; + } + + /** + * Logs a user out + * + * @param username User's username + * @throws org.ofbiz.common.authentication.api.AuthenticatorException + * when logout fails + */ + public void logout(String username) throws AuthenticatorException { + } + + /** + * Reads user information and syncs it to OFBiz (i.e. UserLogin, Person, etc) + * + * @param userLoginId + * @throws org.ofbiz.common.authentication.api.AuthenticatorException + * user synchronization fails + */ + public void syncUser(String userLoginId) throws AuthenticatorException { + Map<String, Object> userMap = getGitHubUserinfo(userLoginId); + GenericValue system; + try { + system = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", "system"), true); + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + + GenericValue userLogin; + try { + userLogin = EntityUtil.getFirst(delegator.findByAnd("UserLogin", UtilMisc.toMap("externalAuthId", (String) userMap.get("id")), null, false)); + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + + // suspend the current transaction and load the user + Transaction parentTx = null; + boolean beganTransaction = false; + + try { + try { + parentTx = TransactionUtil.suspend(); + } catch (GenericTransactionException e) { + Debug.logError(e, "Could not suspend transaction: " + e.getMessage(), module); + } + + try { + beganTransaction = TransactionUtil.begin(); + + if (userLogin == null) { + // create the user + createUser(userMap, system); + } else { + // update the user information + updateUser(userMap, system, userLogin); + } + + } catch (GenericTransactionException e) { + Debug.logError(e, "Could not suspend transaction: " + e.getMessage(), module); + } finally { + try { + TransactionUtil.commit(beganTransaction); + } catch (GenericTransactionException e) { + Debug.logError(e, "Could not commit nested transaction: " + e.getMessage(), module); + } + } + } finally { + // resume/restore parent transaction + if (parentTx != null) { + try { + TransactionUtil.resume(parentTx); + Debug.logVerbose("Resumed the parent transaction.", module); + } catch (GenericTransactionException e) { + Debug.logError(e, "Could not resume parent nested transaction: " + e.getMessage(), module); + } + } + } + } + + private Map<String, Object> getGitHubUserinfo(String userLoginId) throws AuthenticatorException { + Map<String, Object> user = null; + GetMethod getMethod = null; + try { + GenericValue userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", userLoginId), false); + String externalAuthId = userLogin.getString("externalAuthId"); + GenericValue gitHubUser = delegator.findOne("GitHubUser", UtilMisc.toMap("gitHubUserId", externalAuthId), false); + if (UtilValidate.isNotEmpty(gitHubUser)) { + String accessToken = gitHubUser.getString("accessToken"); + String tokenType = gitHubUser.getString("tokenType"); + if (UtilValidate.isNotEmpty(accessToken)) { + getMethod = new GetMethod(GitHubEvents.ApiEndpoint + GitHubEvents.UserApiUri); + user = getUserInfo(getMethod, accessToken, tokenType, Locale.getDefault()); + } + } + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (HttpException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (IOException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (AuthenticatorException e) { + throw new AuthenticatorException(e.getMessage(), e); + } finally { + if (getMethod != null) { + getMethod.releaseConnection(); + } + } + return user; + } + + public String createUser(Map<String, Object> userMap) throws AuthenticatorException { + GenericValue system; + try { + system = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", "system"), true); + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + return createUser(userMap, system); + } + + private String createUser(Map<String, Object> userMap, GenericValue system) throws AuthenticatorException { + // create person + userLogin + Map<String, Serializable> createPersonUlMap = FastMap.newInstance(); + String userLoginId = delegator.getNextSeqId("UserLogin"); + if (userMap.containsKey("name")) { + // use github's name as OFBiz's lastName + createPersonUlMap.put("lastName", (String) userMap.get("name")); + } + if (userMap.containsKey("login")) { + createPersonUlMap.put("externalAuthId", (String) userMap.get("login")); + } + // createPersonUlMap.put("externalId", user.getUserId()); + createPersonUlMap.put("userLoginId", userLoginId); + createPersonUlMap.put("currentPassword", "[EXTERNAL]"); + createPersonUlMap.put("currentPasswordVerify", "[EXTERNAL]"); + createPersonUlMap.put("userLogin", system); + Map<String, Object> createPersonResult; + try { + createPersonResult = dispatcher.runSync("createPersonAndUserLogin", createPersonUlMap); + } catch (GenericServiceException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + if (ServiceUtil.isError(createPersonResult)) { + throw new AuthenticatorException(ServiceUtil.getErrorMessage(createPersonResult)); + } + String partyId = (String) createPersonResult.get("partyId"); + + // give this person a role of CUSTOMER + GenericValue partyRole = delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", partyId, "roleTypeId", "CUSTOMER")); + try { + delegator.create(partyRole); + } catch (GenericEntityException e) { + Debug.logError(e, module); + throw new AuthenticatorException(e.getMessage(), e); + } + + // create email + if (userMap.containsKey("email")) { + Map<String, Serializable> createEmailMap = FastMap.newInstance(); + createEmailMap.put("emailAddress", (String) userMap.get("email")); + createEmailMap.put("contactMechPurposeTypeId", "PRIMARY_EMAIL"); + createEmailMap.put("partyId", partyId); + createEmailMap.put("userLogin", system); + Map<String, Object> createEmailResult; + try { + createEmailResult = dispatcher.runSync("createPartyEmailAddress", createEmailMap); + } catch (GenericServiceException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + if (ServiceUtil.isError(createEmailResult)) { + throw new AuthenticatorException(ServiceUtil.getErrorMessage(createEmailResult)); + } + } + + // create security group(s) + Timestamp now = UtilDateTime.nowTimestamp(); + for (String securityGroup : (new GitHubUserGroupMapper(new String[] {(String) userMap.get("type")}).getSecurityGroups())) { + // check and make sure the security group exists + GenericValue secGroup = null; + try { + secGroup = delegator.findOne("SecurityGroup", UtilMisc.toMap("groupId", securityGroup), true); + } catch (GenericEntityException e) { + Debug.logError(e, e.getMessage(), module); + } + + // add it to the user if it exists + if (secGroup != null) { + Map<String, Serializable> createSecGrpMap = FastMap.newInstance(); + createSecGrpMap.put("userLoginId", userLoginId); + createSecGrpMap.put("groupId", securityGroup); + createSecGrpMap.put("fromDate", now); + createSecGrpMap.put("userLogin", system); + + Map<String, Object> createSecGrpResult; + try { + createSecGrpResult = dispatcher.runSync("addUserLoginToSecurityGroup", createSecGrpMap); + } catch (GenericServiceException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + if (ServiceUtil.isError(createSecGrpResult)) { + throw new AuthenticatorException(ServiceUtil.getErrorMessage(createSecGrpResult)); + } + } + } + return userLoginId; + } + + private void updateUser(Map<String, Object> userMap, GenericValue system, GenericValue userLogin) throws AuthenticatorException { + // TODO implement me + } + + /** + * Updates a user's password. + * + * @param username User's username + * @param password User's current password + * @param newPassword User's new password + * @throws org.ofbiz.common.authentication.api.AuthenticatorException + * when update password fails + */ + public void updatePassword(String username, String password, String newPassword) throws AuthenticatorException { + Debug.logInfo("Calling GitHub:updatePassword() - ignored!!!", module); + } + + /** + * Weight of this authenticator (lower weights are run first) + * + * @return the weight of this Authenicator + */ + public float getWeight() { + return 1; + } + + /** + * Is the user synchronzied back to OFBiz + * + * @return true if the user record is copied to the OFB database + */ + public boolean isUserSynchronized() { + return true; + } + + /** + * Is this expected to be the only authenticator, if so errors will be thrown when users cannot be found + * + * @return true if this is expected to be the only Authenticator + */ + public boolean isSingleAuthenticator() { + return false; + } + + /** + * Flag to test if this Authenticator is enabled + * + * @return true if the Authenticator is enabled + */ + public boolean isEnabled() { + return "true".equalsIgnoreCase(UtilProperties.getPropertyValue(props, "github.authenticator.enabled", "true")); + } + + public static Map<String, Object> getUserInfo(GetMethod getMethod, String accessToken, String tokenType, Locale locale) throws HttpException, IOException, AuthenticatorException { + JSON userInfo = null; + HttpClient jsonClient = new HttpClient(); + HttpMethodParams params = new HttpMethodParams(); + params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); + getMethod.setParams(params); + getMethod.setRequestHeader(PassportUtil.AUTHORIZATION_HEADER, tokenType + " " + accessToken); + getMethod.setRequestHeader(PassportUtil.ACCEPT_HEADER, "application/json"); + jsonClient.executeMethod(getMethod); + if (getMethod.getStatusCode() == HttpStatus.SC_OK) { + Debug.logInfo("Json Response from GitHub: " + getMethod.getResponseBodyAsString(), module); + userInfo = JSON.from(getMethod.getResponseBodyAsString()); + } else { + String errMsg = UtilProperties.getMessage(resource, "GetOAuth2AccessTokenError", UtilMisc.toMap("error", getMethod.getResponseBodyAsString()), locale); + throw new AuthenticatorException(errMsg); + } + JSONToMap jsonMap = new JSONToMap(); + Map<String, Object> userMap; + try { + userMap = jsonMap.convert(userInfo); + } catch (ConversionException e) { + throw new AuthenticatorException(e.getMessage()); + } + return userMap; + } +} Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubAuthenticator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubAuthenticator.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubAuthenticator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubUserGroupMapper.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubUserGroupMapper.java?rev=1688503&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubUserGroupMapper.java (added) +++ ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubUserGroupMapper.java Tue Jun 30 18:38:16 2015 @@ -0,0 +1,72 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.ofbiz.passport.user; + +import java.util.List; +import java.util.Properties; +import java.util.Arrays; +import java.util.Set; + +import org.ofbiz.base.util.UtilProperties; + +import javolution.util.FastList; +import javolution.util.FastSet; + +/** + * GitHub UserGroupMapper + */ +public class GitHubUserGroupMapper { + + protected List<String> groups; + + public GitHubUserGroupMapper(String[] groups) { + this.groups = Arrays.asList(groups); + } + + public GitHubUserGroupMapper(String group) { + if (groups == null) { + groups = FastList.newInstance(); + } + groups.add(group); + } + + public Set<String> getSecurityGroups() { + Properties props = UtilProperties.getProperties(GitHubAuthenticator.props); + + Set<String> secGroups = FastSet.newInstance(); + boolean running = true; + int index = 1; + + while (running) { + String groupStr = (String) props.get("github.group.map." + index); + if (groupStr == null) { + running = false; + } else { + String[] groupSplit = groupStr.split("="); + if (groupSplit.length == 2) { + if (groups.contains(groupSplit[0])) { + secGroups.add(groupSplit[1]); + } + } + } + index++; + } + return secGroups; + } +} Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubUserGroupMapper.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubUserGroupMapper.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubUserGroupMapper.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInAuthenticator.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInAuthenticator.java?rev=1688503&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInAuthenticator.java (added) +++ ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInAuthenticator.java Tue Jun 30 18:38:16 2015 @@ -0,0 +1,471 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.ofbiz.passport.user; + +import java.util.Locale; +import java.util.Map; +import java.io.IOException; +import java.io.Serializable; +import java.sql.Timestamp; + +import javax.transaction.Transaction; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.cookie.CookiePolicy; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.params.HttpMethodParams; +import org.ofbiz.passport.event.LinkedInEvents; +import org.ofbiz.common.authentication.api.Authenticator; +import org.ofbiz.common.authentication.api.AuthenticatorException; +import org.ofbiz.service.LocalDispatcher; +import org.ofbiz.service.GenericServiceException; +import org.ofbiz.service.ServiceUtil; +import org.ofbiz.entity.Delegator; +import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.GenericEntityException; +import org.ofbiz.entity.transaction.TransactionUtil; +import org.ofbiz.entity.transaction.GenericTransactionException; +import org.ofbiz.entity.util.EntityUtil; +import org.ofbiz.base.util.UtilProperties; +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.UtilMisc; +import org.ofbiz.base.util.UtilDateTime; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.UtilXml; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javolution.util.FastMap; + +/** + * LinkedIn OFBiz Authenticator + */ +public class LinkedInAuthenticator implements Authenticator { + + private static final String module = LinkedInAuthenticator.class.getName(); + + public static final String props = "linkedInAuth.properties"; + + public static final String resource = "PassportUiLabels"; + + protected LocalDispatcher dispatcher; + + protected Delegator delegator; + + /** + * Method called when authenticator is first initialized (the delegator + * object can be obtained from the LocalDispatcher) + * + * @param dispatcher The ServiceDispatcher to use for this Authenticator + */ + public void initialize(LocalDispatcher dispatcher) { + this.dispatcher = dispatcher; + this.delegator = dispatcher.getDelegator(); + } + + /** + * Method to authenticate a user. + * + * For LinkedIn users, we only check if the username(userLoginId) exists an + * externalAuthId, and the externalAuthId has a valid accessToken in + * LinkedInUser entity. + * + * @param username User's username + * @param password User's password + * @param isServiceAuth true if authentication is for a service call + * @return true if the user is authenticated + * @throws org.ofbiz.common.authentication.api.AuthenticatorException + * when a fatal error occurs during authentication + */ + public boolean authenticate(String userLoginId, String password, boolean isServiceAuth) throws AuthenticatorException { + Document user = null; + GetMethod getMethod = null; + try { + GenericValue userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", userLoginId), false); + String externalAuthId = userLogin.getString("externalAuthId"); + GenericValue linkedInUser = delegator.findOne("LinkedInUser", UtilMisc.toMap("linedInUserId", externalAuthId), false); + if (UtilValidate.isNotEmpty(linkedInUser)) { + String accessToken = linkedInUser.getString("accessToken"); + if (UtilValidate.isNotEmpty(accessToken)) { + getMethod = new GetMethod(LinkedInEvents.TokenEndpoint + LinkedInEvents.UserApiUri + "?oauth2_access_token=" + accessToken); + user = LinkedInAuthenticator.getUserInfo(getMethod, Locale.getDefault()); + } + } + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (HttpException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (IOException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (AuthenticatorException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (SAXException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (ParserConfigurationException e) { + throw new AuthenticatorException(e.getMessage(), e); + } finally { + if (getMethod != null) { + getMethod.releaseConnection(); + } + } + + Debug.logInfo("LinkedIn auth called; returned user info: " + user, module); + return user != null; + } + + /** + * Logs a user out + * + * @param username User's username + * @throws org.ofbiz.common.authentication.api.AuthenticatorException + * when logout fails + */ + public void logout(String username) throws AuthenticatorException { + } + + /** + * Reads user information and syncs it to OFBiz (i.e. UserLogin, Person, etc) + * + * @param userLoginId + * @throws org.ofbiz.common.authentication.api.AuthenticatorException + * user synchronization fails + */ + public void syncUser(String userLoginId) throws AuthenticatorException { + Document user = getLinkedInUserinfo(userLoginId); + + GenericValue system; + try { + system = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", "system"), true); + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + + GenericValue userLogin; + try { + userLogin = EntityUtil.getFirst(delegator.findByAnd("UserLogin", UtilMisc.toMap("externalAuthId", getLinkedInUserId(user)), null, false)); + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + + // suspend the current transaction and load the user + Transaction parentTx = null; + boolean beganTransaction = false; + + try { + try { + parentTx = TransactionUtil.suspend(); + } catch (GenericTransactionException e) { + Debug.logError(e, "Could not suspend transaction: " + e.getMessage(), module); + } + + try { + beganTransaction = TransactionUtil.begin(); + + if (userLogin == null) { + // create the user + createUser(user, system); + } else { + // update the user information + updateUser(user, system, userLogin); + } + + } catch (GenericTransactionException e) { + Debug.logError(e, "Could not suspend transaction: " + e.getMessage(), module); + } finally { + try { + TransactionUtil.commit(beganTransaction); + } catch (GenericTransactionException e) { + Debug.logError(e, "Could not commit nested transaction: " + e.getMessage(), module); + } + } + } finally { + // resume/restore parent transaction + if (parentTx != null) { + try { + TransactionUtil.resume(parentTx); + Debug.logVerbose("Resumed the parent transaction.", module); + } catch (GenericTransactionException e) { + Debug.logError(e, "Could not resume parent nested transaction: " + e.getMessage(), module); + } + } + } + } + + private Document getLinkedInUserinfo(String userLoginId) throws AuthenticatorException { + Document user = null; + GetMethod getMethod = null; + try { + GenericValue userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", userLoginId), false); + String externalAuthId = userLogin.getString("externalAuthId"); + GenericValue linkedInUser = delegator.findOne("LinkedInUser", UtilMisc.toMap("linkedInUserId", externalAuthId), false); + if (UtilValidate.isNotEmpty(linkedInUser)) { + String accessToken = linkedInUser.getString("accessToken"); + if (UtilValidate.isNotEmpty(accessToken)) { + getMethod = new GetMethod(LinkedInEvents.TokenEndpoint + LinkedInEvents.UserApiUri + "?oauth2_access_token=" + accessToken); + user = getUserInfo(getMethod, Locale.getDefault()); + } + } + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (HttpException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (IOException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (AuthenticatorException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (SAXException e) { + throw new AuthenticatorException(e.getMessage(), e); + } catch (ParserConfigurationException e) { + throw new AuthenticatorException(e.getMessage(), e); + } finally { + if (getMethod != null) { + getMethod.releaseConnection(); + } + } + return user; + } + + public String createUser(Document user) throws AuthenticatorException { + GenericValue system; + try { + system = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", "system"), true); + } catch (GenericEntityException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + return createUser(user, system); + } + + private String createUser(Document user, GenericValue system) throws AuthenticatorException { + Map<String, String> userInfo = parseLinkedInUserInfo(user); + + // create person + userLogin + Map<String, Serializable> createPersonUlMap = FastMap.newInstance(); + String userLoginId = delegator.getNextSeqId("UserLogin"); + if (userInfo.containsKey("firstName")) { + createPersonUlMap.put("firstName", userInfo.get("firstName")); + } + if (userInfo.containsKey("lastName")) { + createPersonUlMap.put("lastName", userInfo.get("lastName")); + } + if (userInfo.containsKey("userId")) { + createPersonUlMap.put("externalAuthId", userInfo.get("userId")); + } + // createPersonUlMap.put("externalId", user.getUserId()); + createPersonUlMap.put("userLoginId", userLoginId); + createPersonUlMap.put("currentPassword", "[EXTERNAL]"); + createPersonUlMap.put("currentPasswordVerify", "[EXTERNAL]"); + createPersonUlMap.put("userLogin", system); + Map<String, Object> createPersonResult; + try { + createPersonResult = dispatcher.runSync("createPersonAndUserLogin", createPersonUlMap); + } catch (GenericServiceException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + if (ServiceUtil.isError(createPersonResult)) { + throw new AuthenticatorException(ServiceUtil.getErrorMessage(createPersonResult)); + } + String partyId = (String) createPersonResult.get("partyId"); + + // give this person a role of CUSTOMER + GenericValue partyRole = delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", partyId, "roleTypeId", "CUSTOMER")); + try { + delegator.create(partyRole); + } catch (GenericEntityException e) { + Debug.logError(e, module); + throw new AuthenticatorException(e.getMessage(), e); + } + + // create email + if (userInfo.containsKey("emailAddress")) { + Map<String, Serializable> createEmailMap = FastMap.newInstance(); + createEmailMap.put("emailAddress", userInfo.get("emailAddress")); + createEmailMap.put("contactMechPurposeTypeId", "PRIMARY_EMAIL"); + createEmailMap.put("partyId", partyId); + createEmailMap.put("userLogin", system); + Map<String, Object> createEmailResult; + try { + createEmailResult = dispatcher.runSync("createPartyEmailAddress", createEmailMap); + } catch (GenericServiceException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + if (ServiceUtil.isError(createEmailResult)) { + throw new AuthenticatorException(ServiceUtil.getErrorMessage(createEmailResult)); + } + } + + // create security group(s) + Timestamp now = UtilDateTime.nowTimestamp(); + for (String securityGroup : (new LinkedInUserGroupMapper(new String[] {"person"}).getSecurityGroups())) { + // check and make sure the security group exists + GenericValue secGroup = null; + try { + secGroup = delegator.findOne("SecurityGroup", UtilMisc.toMap("groupId", securityGroup), true); + } catch (GenericEntityException e) { + Debug.logError(e, e.getMessage(), module); + } + + // add it to the user if it exists + if (secGroup != null) { + Map<String, Serializable> createSecGrpMap = FastMap.newInstance(); + createSecGrpMap.put("userLoginId", userLoginId); + createSecGrpMap.put("groupId", securityGroup); + createSecGrpMap.put("fromDate", now); + createSecGrpMap.put("userLogin", system); + + Map<String, Object> createSecGrpResult; + try { + createSecGrpResult = dispatcher.runSync("addUserLoginToSecurityGroup", createSecGrpMap); + } catch (GenericServiceException e) { + throw new AuthenticatorException(e.getMessage(), e); + } + if (ServiceUtil.isError(createSecGrpResult)) { + throw new AuthenticatorException(ServiceUtil.getErrorMessage(createSecGrpResult)); + } + } + } + return userLoginId; + } + + private void updateUser(Document user, GenericValue system, GenericValue userLogin) throws AuthenticatorException { + // TODO implement me + } + + /** + * Updates a user's password. + * + * @param username User's username + * @param password User's current password + * @param newPassword User's new password + * @throws org.ofbiz.common.authentication.api.AuthenticatorException + * when update password fails + */ + public void updatePassword(String username, String password, String newPassword) throws AuthenticatorException { + Debug.logInfo("Calling LinkedIn:updatePassword() - ignored!!!", module); + } + + /** + * Weight of this authenticator (lower weights are run first) + * + * @return the weight of this Authenicator + */ + public float getWeight() { + return 1; + } + + /** + * Is the user synchronzied back to OFBiz + * + * @return true if the user record is copied to the OFB database + */ + public boolean isUserSynchronized() { + return true; + } + + /** + * Is this expected to be the only authenticator, if so errors will be thrown when users cannot be found + * + * @return true if this is expected to be the only Authenticator + */ + public boolean isSingleAuthenticator() { + return false; + } + + /** + * Flag to test if this Authenticator is enabled + * + * @return true if the Authenticator is enabled + */ + public boolean isEnabled() { + return "true".equalsIgnoreCase(UtilProperties.getPropertyValue(props, "linked.authenticator.enabled", "true")); + } + + public static Document getUserInfo(GetMethod getMethod, Locale locale) throws HttpException, IOException, AuthenticatorException, SAXException, ParserConfigurationException { + Document userInfo = null; + HttpClient jsonClient = new HttpClient(); + HttpMethodParams params = new HttpMethodParams(); + params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); + getMethod.setParams(params); + jsonClient.executeMethod(getMethod); + if (getMethod.getStatusCode() == HttpStatus.SC_OK) { + Debug.logInfo("Json Response from LinkedIn: " + getMethod.getResponseBodyAsString(), module); + userInfo = UtilXml.readXmlDocument(getMethod.getResponseBodyAsString()); + } else { + String errMsg = UtilProperties.getMessage(resource, "GetOAuth2AccessTokenError", UtilMisc.toMap("error", getMethod.getResponseBodyAsString()), locale); + throw new AuthenticatorException(errMsg); + } + return userInfo; + } + + public static String getLinkedInUserId(Document userInfo) { + NodeList persons = userInfo.getElementsByTagName("person"); + if (UtilValidate.isEmpty(persons) || persons.getLength() <= 0) { + return null; + } + Element standardProfileRequest = UtilXml.firstChildElement((Element) persons.item(0), "site-standard-profile-request"); + Element url = UtilXml.firstChildElement(standardProfileRequest, "url"); + if (UtilValidate.isNotEmpty(url)) { + String urlContent = url.getTextContent(); + if (UtilValidate.isNotEmpty(urlContent)) { + String id = urlContent.substring(urlContent.indexOf("?id=")); + id = id.substring(0, id.indexOf("&")); + Debug.logInfo("LinkedIn user id: " + id, module); + return id; + } + } + return null; + } + + public static Map<String, String> parseLinkedInUserInfo(Document userInfo) { + Map<String, String> results = FastMap.newInstance(); + NodeList persons = userInfo.getElementsByTagName("person"); + if (UtilValidate.isEmpty(persons) || persons.getLength() <= 0) { + return results; + } + Element person = (Element) persons.item(0); + Element standardProfileRequest = UtilXml.firstChildElement(person, "site-standard-profile-request"); + Element url = UtilXml.firstChildElement(standardProfileRequest, "url"); + if (UtilValidate.isNotEmpty(url)) { + String urlContent = url.getTextContent(); + if (UtilValidate.isNotEmpty(urlContent)) { + String id = urlContent.substring(urlContent.indexOf("?id=")); + id = id.substring(0, id.indexOf("&")); + Debug.logInfo("LinkedIn user id: " + id, module); + results.put("userId", id); + } + } + Element firstNameElement = UtilXml.firstChildElement(person, "first-name"); + if (UtilValidate.isNotEmpty(firstNameElement) && UtilValidate.isNotEmpty(firstNameElement.getTextContent())) { + results.put("firstName", firstNameElement.getTextContent()); + } + Element lastNameElement = UtilXml.firstChildElement(person, "last-name"); + if (UtilValidate.isNotEmpty(lastNameElement) && UtilValidate.isNotEmpty(lastNameElement.getTextContent())) { + results.put("lastName", lastNameElement.getTextContent()); + } + Element emailElement = UtilXml.firstChildElement(person, "email-address"); + if (UtilValidate.isNotEmpty(emailElement) && UtilValidate.isNotEmpty(emailElement.getTextContent())) { + results.put("emailAddress", emailElement.getTextContent()); + } + return results; + } +} Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInAuthenticator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInAuthenticator.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInAuthenticator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInUserGroupMapper.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInUserGroupMapper.java?rev=1688503&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInUserGroupMapper.java (added) +++ ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInUserGroupMapper.java Tue Jun 30 18:38:16 2015 @@ -0,0 +1,72 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.ofbiz.passport.user; + +import java.util.List; +import java.util.Properties; +import java.util.Arrays; +import java.util.Set; + +import org.ofbiz.base.util.UtilProperties; + +import javolution.util.FastList; +import javolution.util.FastSet; + +/** + * LinkedIn UserGroupMapper + */ +public class LinkedInUserGroupMapper { + + protected List<String> groups; + + public LinkedInUserGroupMapper(String[] groups) { + this.groups = Arrays.asList(groups); + } + + public LinkedInUserGroupMapper(String group) { + if (groups == null) { + groups = FastList.newInstance(); + } + groups.add(group); + } + + public Set<String> getSecurityGroups() { + Properties props = UtilProperties.getProperties(LinkedInAuthenticator.props); + + Set<String> secGroups = FastSet.newInstance(); + boolean running = true; + int index = 1; + + while (running) { + String groupStr = (String) props.get("linkedin.group.map." + index); + if (groupStr == null) { + running = false; + } else { + String[] groupSplit = groupStr.split("="); + if (groupSplit.length == 2) { + if (groups.contains(groupSplit[0])) { + secGroups.add(groupSplit[1]); + } + } + } + index++; + } + return secGroups; + } +} Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInUserGroupMapper.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInUserGroupMapper.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInUserGroupMapper.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/util/PassportUtil.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/util/PassportUtil.java?rev=1688503&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/util/PassportUtil.java (added) +++ ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/util/PassportUtil.java Tue Jun 30 18:38:16 2015 @@ -0,0 +1,196 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.ofbiz.passport.util; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import javax.servlet.http.HttpServletRequest; + +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLContextBuilder; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.ofbiz.base.util.Debug; + +public class PassportUtil { + + public static final String module = PassportUtil.class.getName(); + + public static final String ClientIdLabel = "ClientId"; + + public static final String SecretLabel = "Secret"; + + public static final String ReturnUrlLabel = "ReturnUrl"; + + public static final String TokenEndpointLabel = "TokenEndpoint"; + + public static final String GrantTypeLabel = "grantType"; + + public static final String ContentTypeLabel = "contentType"; + + public static final String AUTHORIZATION_HEADER = "Authorization"; + + public static final String UserProfileUrlLabel = "UserProfileUrl"; + + public static final String GrantTypeParam = "grant_type"; + + public static final String ContentTypeParam = "Content-Type"; + + public static final String ACCEPT_HEADER = "Accept"; + + public static final String APPLICATION_JSON = "application/json"; + + public static final String RESTApiEndpointLabel = "RESTApiEndpoint"; + + public static final String COMMON_CODE = "code"; + + public static final String COMMON_SCOPE = "scope"; + + public static final String AuthorizationCodeGrantType = "authorization_code"; + + public static final String COMMON_STATE = "state"; + + public static final String COMMON_ERROR = "error"; + + public static final String COMMON_ERROR_DESCRIPTION = "error_description"; + + public static final String ApiKeyLabel = "apiKey"; + + public static final String SecretKeyLabel = "secretKey"; + + public static final String COMMON_CLIENT_ID = "clientId"; + + public static final String COMMON_RETURN_RUL = "returnUrl"; + + public static final String COMMON_CLIENT_SECRET = "clientSecret"; + + public static final String ApiIdLabel = "apiId"; + + public static final String AppKeyLabel = "appKey"; + + public static final String AppSecretLabel = "appSecret"; + + public static final String AppIdLabel = "appId"; + + public static final String COMMON_APP_KEY = "AppKey"; + + public static final String COMMON_APP_SECRET = "AppSecret"; + + protected PassportUtil() { + // empty constructor + } + + public static PassportUtil getInstance() { + return new PassportUtil(); + } + + public static String getEnvPrefixByHost(HttpServletRequest request) { + String prefix ="test"; + try { + InetAddress[] addresses = InetAddress.getAllByName(request.getServerName()); + for (InetAddress address : addresses) { + if (address.isAnyLocalAddress() || address.isLinkLocalAddress() || address.isLoopbackAddress()) { + return prefix; + } + } + prefix = "live"; + } catch (UnknownHostException e) { + Debug.logError(e.getMessage(), module); + } + return prefix; + } + + private static String randomString(int lo, int hi) { + int n = rand(lo, hi); + byte b[] = new byte[n]; + for (int i = 0; i < n; i++) { + b[i] = (byte)rand('a', 'z'); + } + return new String(b); + } + + private static int rand(int lo, int hi) { + java.util.Random rn = new java.util.Random(); + int n = hi - lo + 1; + int i = rn.nextInt() % n; + if (i < 0) + i = -i; + return lo + i; + } + + public static String randomString() { + return randomString(8, 15); + } + + public CloseableHttpClient getAllowAllHttpClient() { + try { + SSLContextBuilder builder = new SSLContextBuilder(); + builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); + SSLConnectionSocketFactory sf = new AllowAllSSLSocketFactory(builder.build()); + CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sf).build(); + return httpclient; + } catch (Exception e) { + return HttpClients.createDefault(); + } + } + + public class AllowAllSSLSocketFactory extends SSLConnectionSocketFactory { + SSLContext sslContext = SSLContext.getInstance("TLS"); + + public AllowAllSSLSocketFactory(SSLContext sslContext) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { + super(sslContext); + + TrustManager tm = new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + + sslContext.init(null, new TrustManager[] { tm }, null); + } + + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { + return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); + } + + public Socket createSocket() throws IOException { + return sslContext.getSocketFactory().createSocket(); + } + } + +} \ No newline at end of file Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/util/PassportUtil.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/util/PassportUtil.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/passport/src/org/ofbiz/passport/util/PassportUtil.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy?rev=1688503&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy (added) +++ ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy Tue Jun 30 18:38:16 2015 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.ofbiz.passport; + +import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.util.EntityUtil; +import org.ofbiz.base.util.Debug; +import org.ofbiz.product.store.ProductStoreWorker; + +final String module = "getThirdPartyLogins.groovy" + +adminErrorInfo = context.adminErrorInfo; +productStoreId = context.productStoreId; +if (!productStoreId) { + productStore = ProductStoreWorker.getProductStore(request); + productStoreId = productStore.productStoreId; +} + +if (!adminErrorInfo || !adminErrorInfo.hasError()) { + storePassportLoginMethList = null; + // Get lists of passport login methods + if (productStoreId) { + storePassportLoginMethList = delegator.findByAnd("ThirdPartyLogin", ["productStoreId": productStoreId], ["sequenceNum ASC"], false); + storePassportLoginMethList = EntityUtil.filterByDate(storePassportLoginMethList); + } + + // Extra data preparation for each login method. + if (storePassportLoginMethList) { + storeLoginMethList = [] + for (storeLoginMeth in storePassportLoginMethList) { + storeLoginMethDetail = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd(storeLoginMeth.loginMethTypeId + storeLoginMeth.loginProviderId, ["productStoreId": productStoreId], null, false))); + storeLoginMethList.add(storeLoginMethDetail) + } + context.storeLoginMethList = storeLoginMethList + } +} Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/controller-passport.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/controller-passport.xml?rev=1688503&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/controller-passport.xml (added) +++ ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/controller-passport.xml Tue Jun 30 18:38:16 2015 @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<site-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/site-conf.xsd"> + + <!-- GitHub requests --> + <request-map uri="gitHubRedirect"> + <security https="true" auth="false"/> + <event type="java" path="org.ofbiz.passport.event.GitHubEvents" invoke="gitHubRedirect"/> + <response name="success" type="view" value="main"/> + <response name="error" type="view" value="login"/> + </request-map> + + <request-map uri="githubResponse"> + <security https="true" auth="false"/> + <event type="java" path="org.ofbiz.passport.event.GitHubEvents" invoke="parseGitHubResponse"/> + <response name="success" type="request" value="login"> + <redirect-parameter name="USERNAME"/> + <redirect-parameter name="PASSWORD"/> + </response> + <response name="error" type="view" value="login"/> + </request-map> + + <!-- LinkedIn requests --> + <request-map uri="linkedInRedirect"> + <security https="true" auth="false"/> + <event type="java" path="org.ofbiz.passport.event.LinkedInEvents" invoke="linkedInRedirect"/> + <response name="success" type="view" value="main"/> + <response name="error" type="view" value="login"/> + </request-map> + + <request-map uri="linkedInResponse"> + <security https="true" auth="false"/> + <event type="java" path="org.ofbiz.passport.event.LinkedInEvents" invoke="parseLinkedInResponse"/> + <response name="success" type="request" value="login"> + <redirect-parameter name="USERNAME"/> + <redirect-parameter name="PASSWORD"/> + </response> + <response name="error" type="view" value="login"/> + </request-map> + +</site-conf> Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/controller-passport.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/controller-passport.xml ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/WEB-INF/controller-passport.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/alipay.png URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/images/alipay.png?rev=1688503&view=auto ============================================================================== Binary file - no diff available. Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/alipay.png ------------------------------------------------------------------------------ svn:mime-type = image/png Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/github.png URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/images/github.png?rev=1688503&view=auto ============================================================================== Binary file - no diff available. Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/github.png ------------------------------------------------------------------------------ svn:mime-type = image/png Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/linkedin.png URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/images/linkedin.png?rev=1688503&view=auto ============================================================================== Binary file - no diff available. Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/linkedin.png ------------------------------------------------------------------------------ svn:mime-type = image/png Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/paypal.png URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/images/paypal.png?rev=1688503&view=auto ============================================================================== Binary file - no diff available. Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/paypal.png ------------------------------------------------------------------------------ svn:mime-type = image/png Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/qq.png URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/images/qq.png?rev=1688503&view=auto ============================================================================== Binary file - no diff available. Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/qq.png ------------------------------------------------------------------------------ svn:mime-type = image/png Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/renren.png URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/images/renren.png?rev=1688503&view=auto ============================================================================== Binary file - no diff available. Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/renren.png ------------------------------------------------------------------------------ svn:mime-type = image/png Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/taobao.png URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/images/taobao.png?rev=1688503&view=auto ============================================================================== Binary file - no diff available. Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/taobao.png ------------------------------------------------------------------------------ svn:mime-type = image/png Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/weibo.png URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/images/weibo.png?rev=1688503&view=auto ============================================================================== Binary file - no diff available. Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/weibo.png ------------------------------------------------------------------------------ svn:mime-type = image/png Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/weixin.png URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/images/weixin.png?rev=1688503&view=auto ============================================================================== Binary file - no diff available. Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/images/weixin.png ------------------------------------------------------------------------------ svn:mime-type = image/png Added: ofbiz/trunk/specialpurpose/passport/webapp/passport/login/thirdPartyLogins.ftl URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/webapp/passport/login/thirdPartyLogins.ftl?rev=1688503&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/passport/webapp/passport/login/thirdPartyLogins.ftl (added) +++ ofbiz/trunk/specialpurpose/passport/webapp/passport/login/thirdPartyLogins.ftl Tue Jun 30 18:38:16 2015 @@ -0,0 +1,29 @@ +<#-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<#if storeLoginMethList?exists && storeLoginMethList?has_content> +<div class="screenlet"> + <div class="screenlet-title-bar"><h3>${uiLabelMap.ThirdPartyLogin}</h3></div> + <div class="screenlet-body"> + <#list storeLoginMethList as storeLoginMeth> + <span><a href="${storeLoginMeth.localRedirectUri!}"><img src="${storeLoginMeth.iconUrl!}"></a></span> + </#list> + </div> +</div> +</#if> Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/login/thirdPartyLogins.ftl ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/login/thirdPartyLogins.ftl ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/passport/webapp/passport/login/thirdPartyLogins.ftl ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/specialpurpose/passport/widget/PassportScreens.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/passport/widget/PassportScreens.xml?rev=1688503&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/passport/widget/PassportScreens.xml (added) +++ ofbiz/trunk/specialpurpose/passport/widget/PassportScreens.xml Tue Jun 30 18:38:16 2015 @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/widget-screen.xsd"> + + + <!-- ++++++ Third Party Logins ++++++ --> + <screen name="ListThirdPartyLogins"> + <section> + <actions> + <property-map resource="PassportUiLabels" map-name="uiLabelMap" global="true"/> + <script location="component://passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy"/> + </actions> + <widgets> + <platform-specific> + <html> + <html-template location="component://passport/webapp/passport/login/thirdPartyLogins.ftl"/> + </html> + </platform-specific> + </widgets> + </section> + </screen> + +</screens> \ No newline at end of file Propchange: ofbiz/trunk/specialpurpose/passport/widget/PassportScreens.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/passport/widget/PassportScreens.xml ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/passport/widget/PassportScreens.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml |
Free forum by Nabble | Edit this page |