You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ofbiz.apache.org by Jacques Le Roux <ja...@les7arts.com> on 2015/10/04 11:06:22 UTC

Re: svn commit: r1706654 [1/2] - in /ofbiz/branches/release12.04: ./ specialpurpose/ specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/ specialpurpose/ecommerce/widget/ specialpurpose/passport/ specialpurpose/passport/build/ specialpurpose/passport/build/c...

Hi Jinghai,

Wait, we don't do such things: we don't add new features to released branches. This should go only in trunk and interested persons using released 
branches should handle themselves the backport...

Please revert and fix in trunk if necessary

Thanks

Jacques

Le 04/10/2015 10:40, shijh@apache.org a écrit :
> Author: shijh
> Date: Sun Oct  4 08:40:40 2015
> New Revision: 1706654
>
> URL: http://svn.apache.org/viewvc?rev=1706654&view=rev
> Log:
> OFBIZ-6659 When i working with Login with Linkedin In of biz the it is not showing UI part
>
> 1. Added passport component to release-12.04 branch.
> 2. Fixed groovy and java errors caused by findByAnd method.
> 3. The third party login section is displayed on  /ecommerce/control/checkLogin page (see README for details).
>
> Added:
>      ofbiz/branches/release12.04/specialpurpose/passport/
>      ofbiz/branches/release12.04/specialpurpose/passport/README   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/build/
>      ofbiz/branches/release12.04/specialpurpose/passport/build.xml   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/build/classes/
>      ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/
>      ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/
>      ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/passport/
>      ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/passport/event/
>      ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/passport/user/
>      ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/passport/util/
>      ofbiz/branches/release12.04/specialpurpose/passport/build/lib/
>      ofbiz/branches/release12.04/specialpurpose/passport/config/
>      ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/data/
>      ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/entitydef/
>      ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/src/
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/LinkedInEvents.java   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubAuthenticator.java   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubUserGroupMapper.java   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInAuthenticator.java   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInUserGroupMapper.java   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/util/
>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/util/PassportUtil.java   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/actions/
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/controller-passport.xml   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/alipay.png   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/github.png   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/linkedin.png   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/paypal.png   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/qq.png   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/renren.png   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/taobao.png   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/weibo.png   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/weixin.png   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/login/
>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/login/thirdPartyLogins.ftl   (with props)
>      ofbiz/branches/release12.04/specialpurpose/passport/widget/
>      ofbiz/branches/release12.04/specialpurpose/passport/widget/PassportScreens.xml   (with props)
> Modified:
>      ofbiz/branches/release12.04/.classpath
>      ofbiz/branches/release12.04/specialpurpose/build.xml
>      ofbiz/branches/release12.04/specialpurpose/component-load.xml
>      ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
>      ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml
>
> Modified: ofbiz/branches/release12.04/.classpath
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/.classpath?rev=1706654&r1=1706653&r2=1706654&view=diff
> ==============================================================================
> --- ofbiz/branches/release12.04/.classpath (original)
> +++ ofbiz/branches/release12.04/.classpath Sun Oct  4 08:40:40 2015
> @@ -214,6 +214,7 @@
>       <classpathentry excluding="org/enhydra/|org/ofbiz/" kind="src" path="specialpurpose/shark/src"/>
>       <classpathentry kind="src" path="specialpurpose/webpos/src"/>
>       <classpathentry kind="src" path="specialpurpose/workflow/src"/>
> +    <classpathentry kind="src" path="specialpurpose/passport/src"/>
>       <classpathentry exported="true" kind="con" path="GROOVY_DSL_SUPPORT"/>
>       <classpathentry kind="output" path="bin"/>
>   </classpath>
>
> Modified: ofbiz/branches/release12.04/specialpurpose/build.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/build.xml?rev=1706654&r1=1706653&r2=1706654&view=diff
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/build.xml (original)
> +++ ofbiz/branches/release12.04/specialpurpose/build.xml Sun Oct  4 08:40:40 2015
> @@ -36,7 +36,8 @@
>           crowd/build.xml,
>           webpos/build.xml
>           googlecheckout/build.xml,
> -        example/build.xml
> +        example/build.xml,
> +        passport/build.xml
>       "/>
>       <!-- For the old OFBiz Workflow Engine add "workflow/build.xml" to the list above -->
>       <!-- For Shark add "shark/build.xml" to the list above, in the specialpurpose-builds list (after workflow) -->
>
> Modified: ofbiz/branches/release12.04/specialpurpose/component-load.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/component-load.xml?rev=1706654&r1=1706653&r2=1706654&view=diff
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/component-load.xml (original)
> +++ ofbiz/branches/release12.04/specialpurpose/component-load.xml Sun Oct  4 08:40:40 2015
> @@ -39,6 +39,7 @@ under the License.
>       <load-component component-location="webpos"/>
>       <load-component component-location="example"/>
>       <load-component component-location="exampleext"/>
> +    <load-component component-location="passport"/>
>       <!-- The component below are not maintained by the community, or at least not very actively
>           Still they are functional (or at least should be).
>           So if you need them simply uncomment and have a look also in the build file -->
>
> Modified: ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml?rev=1706654&r1=1706653&r2=1706654&view=diff
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml (original)
> +++ ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml Sun Oct  4 08:40:40 2015
> @@ -20,6 +20,9 @@ under the License.
>   
>   <site-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>           xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/site-conf.xsd">
> +    <!--
> +    <include location="component://passport/webapp/passport/WEB-INF/controller-passport.xml"/>
> +     -->
>       <description>OFBiz: eCommerce Controller Configuration File</description>
>       <errorpage>/error/error.jsp</errorpage>
>   
> @@ -81,7 +84,7 @@ under the License.
>           <description>Verify a user is logged in.</description>
>           <security https="true" auth="false"/>
>           <event type="java" path="org.ofbiz.securityext.login.LoginEvents" invoke="storeCheckLogin"/>
> -        <response name="success" type="view-last" value="main"/>
> +        <response name="success" type="view" value="main"/>
>           <response name="error" type="view" value="login"/>
>       </request-map>
>       <request-map uri="login">
> @@ -851,7 +854,7 @@ under the License.
>       </request-map>
>       <request-map uri="category">
>           <security https="false" auth="false"/>
> -        <response name="success" type="view" value="category" save-current-view="true"/>
> +        <response name="success" type="view" value="category"/>
>       </request-map>
>       <request-map uri="product">
>           <security https="false" auth="false"/>
> @@ -1027,7 +1030,7 @@ under the License.
>       <request-map uri="deleteContactMech">
>           <security https="true" auth="true"/>
>           <event type="service" invoke="deletePartyContactMech"/>
> -        <response name="success" type="view" value="viewprofile"/>
> +        <response name="success" type="view" value="editcontactmech"/>
>           <response name="error" type="view" value="editcontactmech"/>
>       </request-map>
>   
> @@ -1320,20 +1323,20 @@ under the License.
>       <request-map uri="signUpForContactList">
>           <security https="false" auth="false"/>
>           <event type="service" invoke="signUpForContactList"/>
> -        <response name="success" type="view-last"/>
> -        <response name="error" type="view-last" value="main"/>
> +        <response name="success" type="view" value="main"/>
> +        <response name="error" type="view" value="main"/>
>       </request-map>
>       <request-map uri="unsubscribeContactListParty">
>           <security https="false" auth="false"/>
>           <event type="service" invoke="unsubscribeContactListParty"/>
> -        <response name="success" type="view-last"/>
> -        <response name="error" type="view-last" value="main"/>
> +        <response name="success" type="view" value="main"/>
> +        <response name="error" type="view" value="main"/>
>       </request-map>
>       <request-map uri="unsubscribeContactListPartyContachMech">
>           <security https="false" auth="false"/>
>           <event type="service" invoke="unsubscribeContactListPartyContachMech"/>
> -        <response name="success" type="view-last"/>
> -        <response name="error" type="view-last" value="main"/>
> +        <response name="success" type="view" value="main"/>
> +        <response name="error" type="view" value="main"/>
>       </request-map>
>       <request-map uri="contactListOptOut" track-serverhit="false" track-visit="false">
>           <security https="false" auth="false"/>
> @@ -1940,7 +1943,7 @@ under the License.
>       
>       <request-map uri="ProductUomDropDownOnly">
>           <security auth="false" https="false"/>
> -        <response name="success" type="view" value="ProductUomDropDownOnly" save-current-view="false" />
> +        <response name="success" type="view" value="ProductUomDropDownOnly" save-last-view="true"/>
>       </request-map>
>       
>       <!-- Captcha: Image request, the captcha code is stored in the session using _CAPTCHA_CODE_ as the key -->
>
> Modified: ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml?rev=1706654&r1=1706653&r2=1706654&view=diff
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml (original)
> +++ ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml Sun Oct  4 08:40:40 2015
> @@ -334,6 +334,9 @@ under the License.
>                           <platform-specific>
>                               <html><html-template location="component://ecommerce/webapp/ecommerce/login.ftl"/></html>
>                           </platform-specific>
> +                        <!--
> +                        <include-screen name="ListThirdPartyLogins" location="component://passport/widget/PassportScreens.xml"/>
> +                         -->
>                           <platform-specific>
>                               <html><html-template location="component://ecommerce/webapp/ecommerce/order/startanoncheckout.ftl"/></html>
>                           </platform-specific>
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/README
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/README?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/README (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/README Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,98 @@
> +========================
> +OFBiz Passport Component
> +========================
> +The passport component is to support users to login with a third party OAuth2 authentication such as GitHub, LinkedIn and etc.
> +
> +
> +
> +---------------------------------------
> +GitHub OAuth2 Configuration Quick Start
> +---------------------------------------
> +To learn the whole GitHub OAuth, please read https://developer.github.com/v3/oauth/.
> +Here are the steps for a quick start in OFBiz trunk:
> +
> +------ GitHub Side ------
> +1. Register a GitHub account if you don't have one.
> +
> +2. Login GitHub.
> +
> +3. Visit Settings->Applications->Developer applications, click "Register new application" button.
> +
> +4. In "Register a new OAuth application", fill in your OFBiz website information. Here the
> +Authorization callback URL: https://YourWebSiteOrInternetIp:8443/ecommerce/control/githubResponse
> +[Note] As you want to use GitHub to authorize your users, your OFBiz should be able to be visited on internet so that GitHub can forward the users back after OAuth login.
> +
> +5. Click "Register application" button.
> +You'll get your Client ID and Client Secret, write them down for later configuration.
> +
> +------ OFBiz Side ------
> +6. Edit specialpurpose/passport/data/OAuth2GitHubSeedData.xml, fill in the Client ID in clientId, Client Secret in clientSecret and the Authorization callback URL in returnUrl.
> +
> +7. Login to OFBiz webtools, in "XML Data Import" page, import specialpurpose/passport/data/OAuth2GitHubSeedData.xml.
> +
> +8. Edit specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml, uncomment
> +   <include location="component://passport/webapp/passport/WEB-INF/controller-passport.xml"/>
> +
> +9. Edit specialpurpose/ecommerce/widget/CommonScreens.xml, uncomment
> +   <include-screen name="ListThirdPartyLogins" location="component://passport/widget/PassportScreens.xml"/>
> +
> +10. Visit https://YourWebSiteOrInternetIp:8443/ecommerce/control/checkLogin, click GitHub icon in the "Third Party Login" area. You will be forwarded to GitHub OAuth2 login page. After logging in successfully, you will be logged in OFBiz.
> +
> +11. The parameters in specialpurpose/passport/config/gitHubAuth.properties:
> +github.env.prefix: test or live, default is test. This value will be store in envPrefix field of GitHubUser entity when a user logged in by GitHub OAuth2.
> +github.authenticator.enabled: true or false, default is true. This parameter is for future extension.
> +
> +
> +
> +-----------------------------------------
> +LinkedIn OAuth2 Configuration Quick Start
> +-----------------------------------------
> +To learn the whole LinkedIn OAuth, please read https://developer.linkedin.com/docs/oauth2.
> +Here are the steps for a quick start in OFBiz trunk:
> +
> +------ LinkedIn Side ------
> +1. Register a LinkedIn account if you don't have one.
> +
> +2. Visit https://www.linkedin.com/developer/apps, login LinkedIn.
> +
> +3. Click "Create Application" button.
> +
> +4. In "Create a New Application", fill in your OFBiz website information. Here the
> +Authorization callback URL: https://YourWebSiteOrInternetIp:8443/ecommerce/control/linkedInResponse
> +[Note] As you want to use LinkedIn to authorize your users, your OFBiz should be able to be visited on internet so that LinkedIn can forward the users back after OAuth login.
> +
> +5. Click "Submit" button.
> +You'll get your Client ID and Client Secret, write them down for later configuration. You should also select r_basicprofile and r_emailaddress in "Default Application Permissions" section.
> +
> +6. In "Application Settings" page, you can select Application Status to be Development or Live.
> +
> +------ OFBiz Side ------
> +7. Edit specialpurpose/passport/data/OAuth2LinkedInSeedData.xml, fill in the Client ID in apiKey, Client Secret in secretKey and the Authorization callback URL in testReturnUrl and/or liveReturnUrl.
> +
> +8. Login to OFBiz webtools, in "XML Data Import" page, import specialpurpose/passport/data/OAuth2LinkedInSeedData.xml.
> +
> +9. Edit specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml, uncomment
> +   <include location="component://passport/webapp/passport/WEB-INF/controller-passport.xml"/>
> +
> +10. Edit specialpurpose/ecommerce/widget/CommonScreens.xml, uncomment
> +   <include-screen name="ListThirdPartyLogins" location="component://passport/widget/PassportScreens.xml"/>
> +
> +11. Visit https://YourWebSiteOrInternetIp:8443/ecommerce/control/checkLogin, click LinkedIn icon in the "Third Party Login" area. You will be forwarded to LinkedIn OAuth2 login page. After logging in successfully, you will be logged in OFBiz.
> +
> +12. The parameters in specialpurpose/passport/config/linkedInAuth.properties:
> +linkedin.env.prefix: test or live, default is test. This value will be store in envPrefix field of LinkedInUser entity when a user logged in by LinkedIn OAuth2.
> +                     If the value is test, you should set your Application Status to Development, and the "Authorized Redirect URLs" to the same as the testReturnUrl.
> +                     If the value is live, you should set your Application Status to Live, and the "Authorized Redirect URLs" to the same as the liveReturnUrl.
> +linkedin.authenticator.enabled: true or false, default is true. This parameter is for future extension.
> +
> +
> +---------------
> +     Q&A
> +---------------
> +Q. I think my configures are right, why there's no third party login in my /ecommerce/control/checkLogin page?
> +A. Please check whether the productStoreId in ThirdPartyLogin and OAuth2GitHub/OAuth2LinkedIn is the same as your web store.
> +
> +Q. How could I extend this component to support other OAuth2 providers?
> +A. 1st, you have to read the providers OAuth2 documents. 2nd, add some new entities. 3rd, add seed data. 4th, add the icon file under specialpurpose/passport/webapp/passport/images/.
> +   5th, add redirect and response request in controller-passport.xml. 6th, add java files to implement the redirect and response.
> +
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/README
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/README
> ------------------------------------------------------------------------------
>      svn:mime-type = text/plain
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/build.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/build.xml?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/build.xml (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/build.xml Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,52 @@
> +<?xml version="1.0"?>
> +<!--
> +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.
> +-->
> +
> +<project name="OFBiz - Passport Component" default="jar" basedir=".">
> +    <import file="../../common.xml"/>
> +
> +    <!-- ================================================================== -->
> +    <!-- Initialization of all property settings                            -->
> +    <!-- ================================================================== -->
> +
> +    <property name="desc" value="Ecommerce Passport"/>
> +    <property name="name" value="ofbiz-passport"/>
> +    <property name="ofbiz.home.dir" value="../.."/>
> +
> +    <path id="local.class.path">
> +        <fileset dir="../../framework/base/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/base/lib/j2eespecs" includes="*.jar"/>
> +        <fileset dir="../../framework/base/build/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/entity/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/entity/build/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/security/build/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/service/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/service/build/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/minilang/build/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/common/build/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/webapp/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/webapp/build/lib" includes="*.jar"/>
> +        <fileset dir="../../applications/party/build/lib" includes="*.jar"/>
> +        <fileset dir="../../applications/product/build/lib" includes="*.jar"/>
> +        <fileset dir="../../applications/marketing/build/lib" includes="*.jar"/>
> +        <fileset dir="../../applications/order/build/lib" includes="*.jar"/>
> +        <fileset dir="../../applications/accounting/build/lib" includes="*.jar"/>
> +        <fileset dir="../../applications/securityext/build/lib" includes="*.jar"/>
> +    </path>
> +</project>
> \ No newline at end of file
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/build.xml
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/build.xml
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/build.xml
> ------------------------------------------------------------------------------
>      svn:mime-type = text/xml
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,94 @@
> +<?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.
> +-->
> +
> +<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
> +    <property key="PassportApplication">
> +        <value xml:lang="en">Passport Third Party Auth Application</value>
> +        <value xml:lang="zh">第三方认证应用程序</value>
> +    </property>
> +    <property key="ThirdPartyLogin">
> +        <value xml:lang="en">Third Party Login</value>
> +        <value xml:lang="zh">第三方登录</value>
> +    </property>
> +
> +    <!-- LinkedIn labels -->
> +    <property key="LinkedInFailedToMatchState">
> +        <value xml:lang="en">Failed to match the state parameter in LinkedIn response. Just try to login again.</value>
> +        <value xml:lang="zh">领英响应中的state参数不一致。重试登录即可。</value>
> +    </property>
> +    <property key="RedirectToLinkedInOAuth2NullException">
> +        <value xml:lang="en">Error while redirecting to LinkedIn authorization URL. Please use other login method for now.</value>
> +        <value xml:lang="zh">转到领英认证网址时出错。请先使用其它登录方式。</value>
> +    </property>
> +    <property key="RedirectToLinkedInOAuth2Error">
> +        <value xml:lang="en">Error while redirecting to LinkedIn authorization URL: ${errorMessage}</value>
> +        <value xml:lang="zh">转到领英认证网址时出错:${errorMessage}。</value>
> +    </property>
> +    <property key="FailedToGetLinkedInAuthorizationCode">
> +        <value xml:lang="en">Failed to get LinkedIn authorization code.&lt;br&gt;Error: ${error}&lt;br&gt;Error description: ${error_description}</value>
> +        <value xml:lang="zh">èŽ·å–é¢†è‹±æŽˆæƒç æ—¶å‡ºé”™ã€‚&lt;br&gt;错误: ${error}&lt;br&gt;错误描述: ${error_description}</value>
> +    </property>
> +    <property key="GetLinkedInAuthorizationCodeError">
> +        <value xml:lang="en">Failed to get LinkedIn authorization code.</value>
> +        <value xml:lang="zh">èŽ·å–é¢†è‹±æŽˆæƒç æ—¶å‡ºé”™ã€‚</value>
> +    </property>
> +    <property key="GetOAuth2LinkedInConfigError">
> +        <value xml:lang="en">Failed to get LinkedIn configuration. Please check whether OAuth2LinkedIn entity has your productStoreId configured.</value>
> +        <value xml:lang="zh">获取领英配置时出错。请检查OAuth2LinkedInå®žä½“ä¸­æ˜¯å¦é…ç½®äº†ä½ çš„åº—é“ºæ ‡è¯†(productStoreId)。</value>
> +    </property>
> +    <property key="GetOAuth2LinkedInAccessTokenError">
> +        <value xml:lang="en">Failed to get LinkedIn access token.</value>
> +        <value xml:lang="zh">获取领英访问令牌时出错。</value>
> +    </property>
> +    <property key="GetOAuth2LinkedInError">
> +        <value xml:lang="en">Failed to get OAuth2LinkedIn entity: ${errorMessage}</value>
> +        <value xml:lang="zh">获取OAuth2LinkedIn实体时出错:${errorMessage}</value>
> +    </property>
> +
> +    <!-- GitHub labels -->
> +    <property key="RedirectToGitHubOAuth2NullException">
> +        <value xml:lang="en">Error while redirecting to GitHub authorization URL. Please use other login method for now.</value>
> +        <value xml:lang="zh">转到GitHub认证网址时出错。请先使用其它登录方式。</value>
> +    </property>
> +    <property key="RedirectToGitHubOAuth2Error">
> +        <value xml:lang="en">Error while redirecting to GitHub authorization URL: ${errorMessage}</value>
> +        <value xml:lang="zh">转到GitHub认证网址时出错:${errorMessage}。</value>
> +    </property>
> +    <property key="GitHubFailedToMatchState">
> +        <value xml:lang="en">Failed to match the state parameter in GitHub response. Just try to login again.</value>
> +        <value xml:lang="zh">GitHub响应中的state参数不一致。重试登录即可。</value>
> +    </property>
> +    <property key="GetGitHubAuthorizationCodeError">
> +        <value xml:lang="en">Failed to get GitHub authorization code.</value>
> +        <value xml:lang="zh">获取GitHubæŽˆæƒç æ—¶å‡ºé”™ã€‚</value>
> +    </property>
> +    <property key="GetOAuth2GitHubConfigError">
> +        <value xml:lang="en">Failed to get GitHub configuration. Please check whether OAuth2GitHub entity has your productStoreId configured.</value>
> +        <value xml:lang="zh">获取GitHub配置时出错。请检查OAuth2GitHubå®žä½“ä¸­æ˜¯å¦é…ç½®äº†ä½ çš„åº—é“ºæ ‡è¯†(productStoreId)。</value>
> +    </property>
> +    <property key="GetOAuth2GitHubAccessTokenError">
> +        <value xml:lang="en">Failed to get GitHub access token: ${error}</value>
> +        <value xml:lang="zh">获取GitHub访问令牌时出错:${error}</value>
> +    </property>
> +    <property key="GetOAuth2GitHubError">
> +        <value xml:lang="en">Failed to get OAuth2GitHub entity: ${errorMessage}</value>
> +        <value xml:lang="zh">获取OAuth2GitHub实体时出错:${errorMessage}</value>
> +    </property>
> +</resource>
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
> ------------------------------------------------------------------------------
>      svn:mime-type = text/xml
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,24 @@
> +###############################################################################
> +# 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.
> +###############################################################################
> +
> +github.env.prefix=test
> +
> +github.authenticator.enabled=true
> +
> +# github.group.map.1=github-user=FULLADMIN
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
> ------------------------------------------------------------------------------
>      svn:mime-type = text/plain
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,24 @@
> +###############################################################################
> +# 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.
> +###############################################################################
> +
> +linkedin.env.prefix=test
> +
> +linkedin.authenticator.enabled=true
> +
> +# linkedin.group.map.1=linkedin-user=FULLADMIN
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
> ------------------------------------------------------------------------------
>      svn:mime-type = text/plain
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,28 @@
> +<?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.
> +-->
> +
> +<entity-engine-xml>
> +
> +    <EnumerationType description="Passport Login Method Type" enumTypeId="ppLoginMethType" hasTable="N" parentTypeId=""/>
> +    <EnumerationType description="Passport Login Provider" enumTypeId="ppLoginProvider" hasTable="N" parentTypeId=""/>
> +
> +    <EnumerationType description="OAuth2 Login Method Type" enumTypeId="OAuth2" hasTable="N" parentTypeId="ppLoginMethType"/>
> +
> +</entity-engine-xml>
> \ No newline at end of file
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
> ------------------------------------------------------------------------------
>      svn:mime-type = text/xml
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,34 @@
> +<?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.
> +-->
> +
> +<entity-engine-xml>
> +
> +    <EnumerationType description="GitHub Login" enumTypeId="GitHub" hasTable="N" parentTypeId="ppLoginProvider"/>
> +
> +    <ThirdPartyLogin productStoreId="9000" loginMethTypeId="OAuth2" loginProviderId="GitHub" fromDate="2011-01-01 00:00:00.0" thruDate="" sequenceNum=""/>
> +
> +    <OAuth2GitHub productStoreId="9000"
> +                    clientId="" clientSecret=""
> +                    returnUrl=""
> +                    localRedirectUri="/ecomseo/gitHubRedirect"
> +                    iconUrl="/passport/images/github.png" fromDate="2011-01-01 00:00:00.0" thruDate=""/>
> +    <!-- The returnUrl, i.e. https://yourWebSiteOrIp:8443/ecomseo/githubResponse -->
> +
> +</entity-engine-xml>
> \ No newline at end of file
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
> ------------------------------------------------------------------------------
>      svn:mime-type = text/xml
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,36 @@
> +<?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.
> +-->
> +
> +<entity-engine-xml>
> +
> +    <EnumerationType description="LinkedIn Login" enumTypeId="LinkedIn" hasTable="N" parentTypeId="ppLoginProvider"/>
> +
> +    <ThirdPartyLogin productStoreId="9000" loginMethTypeId="OAuth2" loginProviderId="LinkedIn" fromDate="2011-01-01 00:00:00.0" thruDate="" sequenceNum=""/>
> +
> +    <OAuth2LinkedIn productStoreId="9000"
> +                    apiKey="" secretKey=""
> +                    testReturnUrl=""
> +                    liveReturnUrl=""
> +                    localRedirectUri="/ecommerce/control/linkedInRedirect"
> +                    iconUrl="/passport/images/linkedin.png" fromDate="2011-01-01 00:00:00.0" thruDate=""/>
> +    <!-- The testReturnUrl, i.e. https://yourTestWebSiteOrIp:8443/ecomseo/linkedInResponse -->
> +    <!-- The liveReturnUrl, i.e. https://yourLiveWebSiteOrIp:8443/ecomseo/linkedInResponse -->
> +
> +</entity-engine-xml>
> \ No newline at end of file
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
> ------------------------------------------------------------------------------
>      svn:mime-type = text/xml
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,119 @@
> +<?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.
> +-->
> +
> +<entitymodel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/entitymodel.xsd">
> +    <title>Entity of Passport Component</title>
> +    <description>Data Model Enhancements For Passport</description>
> +    <version>1.0</version>
> +
> +    <entity entity-name="ThirdPartyLogin"
> +            package-name="org.ofbiz.passport"
> +            title="Third party logins for a specific product store"
> +            default-resource-name="PassportEntityLabels">
> +        <field name="productStoreId" type="id-ne"></field>
> +        <field name="loginMethTypeId" type="id-ne"></field><!-- i.e. OAuth2 -->
> +        <field name="loginProviderId" type="id-ne"></field><!-- i.e. GitHub -->
> +        <field name="fromDate" type="date-time"></field>
> +        <field name="thruDate" type="date-time"></field>
> +        <field name="sequenceNum" type="numeric"></field>
> +        <prim-key field="productStoreId"/>
> +        <prim-key field="loginMethTypeId"/>
> +        <prim-key field="loginProviderId"/>
> +        <prim-key field="fromDate"/>
> +        <relation type="one" fk-name="PROD_STORE_LOGINS" rel-entity-name="ProductStore">
> +            <key-map field-name="productStoreId"/>
> +        </relation>
> +        <relation type="many" rel-entity-name="EnumerationType">
> +            <key-map field-name="loginMethTypeId" rel-field-name="enumTypeId"/>
> +            <key-map field-name="loginProviderId" rel-field-name="enumTypeId"/>
> +        </relation>
> +    </entity>
> +
> +    <!-- GitHub OAuth -->
> +    <entity entity-name="OAuth2GitHub"
> +            package-name="org.ofbiz.passport"
> +            title="GitHub OAuth Login Config"
> +            default-resource-name="PassportEntityLabels">
> +        <field name="productStoreId" type="id-ne"></field>
> +        <field name="clientId" type="short-varchar"></field>
> +        <field name="clientSecret" type="short-varchar"></field>
> +        <field name="returnUrl" type="value"></field>
> +        <field name="localRedirectUri" type="short-varchar"></field>
> +        <field name="iconUrl" type="url"></field>
> +        <field name="fromDate" type="date-time"></field>
> +        <field name="thruDate" type="date-time"></field>
> +        <prim-key field="productStoreId"/>
> +        <prim-key field="fromDate"/>
> +        <relation type="one" fk-name="STORE_OAUTH_GITHUB" rel-entity-name="ProductStore">
> +            <key-map field-name="productStoreId"/>
> +        </relation>
> +    </entity>
> +
> +    <entity entity-name="GitHubUser"
> +            package-name="org.ofbiz.passport"
> +            title="Store GitHub access token for user"
> +            default-resource-name="PassportEntityLabels">
> +        <field name="gitHubUserId" type="id-vlong-ne"></field>
> +        <field name="productStoreId" type="id-ne"></field>
> +        <field name="envPrefix" type="short-varchar"></field>
> +        <field name="tokenType" type="short-varchar"></field>
> +        <field name="accessToken" type="value"></field>
> +        <prim-key field="gitHubUserId"/>
> +        <relation type="one" fk-name="GITHUB_USER_STORE" rel-entity-name="ProductStore">
> +            <key-map field-name="productStoreId"/>
> +        </relation>
> +    </entity>
> +
> +    <!-- LinkedIn OAuth -->
> +    <entity entity-name="OAuth2LinkedIn"
> +            package-name="org.ofbiz.passport"
> +            title="LinkedIn OAuth Login Config"
> +            default-resource-name="PassportEntityLabels">
> +        <field name="productStoreId" type="id-ne"></field>
> +        <field name="apiKey" type="short-varchar"></field>
> +        <field name="secretKey" type="short-varchar"></field>
> +        <field name="liveReturnUrl" type="value"></field>
> +        <field name="testReturnUrl" type="value"></field>
> +        <field name="localRedirectUri" type="short-varchar"></field>
> +        <field name="iconUrl" type="url"></field>
> +        <field name="fromDate" type="date-time"></field>
> +        <field name="thruDate" type="date-time"></field>
> +        <prim-key field="productStoreId"/>
> +        <prim-key field="fromDate"/>
> +        <relation type="one" fk-name="OAUTH2_LINKEDIN" rel-entity-name="ProductStore">
> +            <key-map field-name="productStoreId"/>
> +        </relation>
> +    </entity>
> +
> +    <entity entity-name="LinkedInUser"
> +            package-name="org.ofbiz.passport"
> +            title="Store LinkedIn access token for user"
> +            default-resource-name="PassportEntityLabels">
> +        <field name="linkedInUserId" type="id-vlong-ne"></field>
> +        <field name="productStoreId" type="id-ne"></field>
> +        <field name="envPrefix" type="short-varchar"></field>
> +        <field name="accessToken" type="value"></field>
> +        <prim-key field="linkedInUserId"/>
> +        <relation type="one" fk-name="LINKEDIN_USER" rel-entity-name="ProductStore">
> +            <key-map field-name="productStoreId"/>
> +        </relation>
> +    </entity>
> +
> +</entitymodel>
> \ No newline at end of file
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
> ------------------------------------------------------------------------------
>      svn:mime-type = text/xml
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,34 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<ofbiz-component name="passport"
> +        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> +        xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd">
> +    <!-- define resource loaders; most common is to use the component resource loader -->
> +    <resource-loader name="main" type="component"/>
> +
> +    <!-- place the config directory on the classpath to access configuration files -->
> +    <classpath type="dir" location="config"/>
> +
> +    <!-- load single or multiple external libraries -->
> +    <classpath type="jar" location="build/lib/*"/>
> +
> +    <!-- entity resources: model(s), eca(s), group, and data definitions -->
> +    <entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel.xml"/>
> +
> +    <!-- Seed Data -->
> +    <entity-resource type="data" reader-name="seed" loader="main" location="data/OAuth2CommonSeedData.xml"/>
> +    <entity-resource type="data" reader-name="demo" loader="main" location="data/OAuth2LinkedInSeedData.xml"/>
> +    <entity-resource type="data" reader-name="demo" loader="main" location="data/OAuth2GitHubSeedData.xml"/>
> +
> +    <!-- service resources: model(s), eca(s) and group definitions -->
> +    <!--
> +    <service-resource type="model" loader="main" location="servicedef/services.xml"/>
> +     -->
> +
> +    <!-- web applications; will be mounted when using the embedded container -->
> +    <webapp name="passport"
> +            title="OFBiz Passport"
> +            server="default-server"
> +            location="webapp/passport"
> +            mount-point="/passport"
> +            app-bar-display="false" />
> +</ofbiz-component>
> \ No newline at end of file
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
> ------------------------------------------------------------------------------
>      svn:mime-type = text/xml
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,315 @@
> +/*******************************************************************************
> + * 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.event;
> +
> +import java.io.IOException;
> +import java.io.UnsupportedEncodingException;
> +import java.net.URLDecoder;
> +import java.net.URLEncoder;
> +import java.util.Map;
> +import java.util.Random;
> +
> +import javax.servlet.http.HttpServletRequest;
> +import javax.servlet.http.HttpServletResponse;
> +
> +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.methods.PostMethod;
> +import org.apache.commons.httpclient.params.HttpMethodParams;
> +import org.ofbiz.passport.user.GitHubAuthenticator;
> +import org.ofbiz.passport.util.PassportUtil;
> +import org.ofbiz.base.crypto.HashCrypt;
> +import net.sf.json.JSONObject;
> +import org.ofbiz.base.util.Debug;
> +import org.ofbiz.base.util.UtilHttp;
> +import org.ofbiz.base.util.UtilMisc;
> +import org.ofbiz.base.util.UtilProperties;
> +import org.ofbiz.base.util.UtilValidate;
> +import org.ofbiz.common.authentication.api.AuthenticatorException;
> +import org.ofbiz.common.login.LoginServices;
> +import org.ofbiz.entity.Delegator;
> +import org.ofbiz.entity.GenericEntityException;
> +import org.ofbiz.entity.GenericValue;
> +import org.ofbiz.entity.util.EntityUtil;
> +import org.ofbiz.product.store.ProductStoreWorker;
> +import org.ofbiz.service.LocalDispatcher;
> +
> +/**
> + * GitHubEvents - Events for GitHub login.
> + *
> + * Refs: https://developer.github.com/v3/oauth/
> + *
> + */
> +public class GitHubEvents {
> +
> +    public static final String module = GitHubEvents.class.getName();
> +
> +    public static final String resource = "PassportUiLabels";
> +
> +    public static final String AuthorizeUri = "/login/oauth/authorize";
> +
> +    public static final String TokenServiceUri = "/login/oauth/access_token";
> +
> +    public static final String UserApiUri = "/user";
> +
> +    public static final String DEFAULT_SCOPE = "user,gist";
> +
> +    public static final String ApiEndpoint = "https://api.github.com";
> +
> +    public static final String TokenEndpoint = "https://github.com";
> +
> +    public static final String SESSION_GITHUB_STATE = "_GITHUB_STATE_";
> +
> +    public static final String envPrefix = UtilProperties.getPropertyValue(GitHubAuthenticator.props, "github.env.prefix", "test");
> +
> +    /**
> +     * Redirect to GitHub login page.
> +     *
> +     * @return
> +     */
> +    public static String gitHubRedirect(HttpServletRequest request, HttpServletResponse response) {
> +        GenericValue oauth2GitHub = getOAuth2GitHubConfig(request);
> +        if (UtilValidate.isEmpty(oauth2GitHub)) {
> +            return "error";
> +        }
> +
> +        String clientId = oauth2GitHub.getString(PassportUtil.COMMON_CLIENT_ID);
> +        String returnURI = oauth2GitHub.getString(PassportUtil.COMMON_RETURN_RUL);
> +
> +        // Get user authorization code
> +        try {
> +            String state = System.currentTimeMillis() + String.valueOf((new Random(10)).nextLong());
> +            request.getSession().setAttribute(SESSION_GITHUB_STATE, state);
> +            String redirectUrl = TokenEndpoint + AuthorizeUri
> +                    + "?client_id=" + clientId
> +                    + "&scope=" + DEFAULT_SCOPE
> +                    + "&redirect_uri=" + URLEncoder.encode(returnURI, "UTF-8")
> +                    + "&state=" + state;
> +            Debug.logInfo("Request to GitHub: " + redirectUrl, module);
> +            response.sendRedirect(redirectUrl);
> +        } catch (NullPointerException e) {
> +            String errMsg = UtilProperties.getMessage(resource, "RedirectToGitHubOAuth2NullException", UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        } catch (IOException e) {
> +            Map<String, String> messageMap = UtilMisc.toMap("errorMessage", e.toString());
> +            String errMsg = UtilProperties.getMessage(resource, "RedirectToGitHubOAuth2Error", messageMap, UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        }
> +
> +        return "success";
> +    }
> +
> +    /**
> +     * Parse GitHub login response and login the user if possible.
> +     *
> +     * @return
> +     */
> +    public static String parseGitHubResponse(HttpServletRequest request, HttpServletResponse response) {
> +        String authorizationCode = request.getParameter(PassportUtil.COMMON_CODE);
> +        String state = request.getParameter(PassportUtil.COMMON_STATE);
> +        if (!state.equals(request.getSession().getAttribute(SESSION_GITHUB_STATE))) {
> +            String errMsg = UtilProperties.getMessage(resource, "GitHubFailedToMatchState", UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        }
> +        if (UtilValidate.isEmpty(authorizationCode)) {
> +            String error = request.getParameter(PassportUtil.COMMON_ERROR);
> +            String errorDescpriton = request.getParameter(PassportUtil.COMMON_ERROR_DESCRIPTION);
> +            String errMsg = null;
> +            try {
> +                errMsg = UtilProperties.getMessage(resource, "FailedToGetGitHubAuthorizationCode", UtilMisc.toMap(PassportUtil.COMMON_ERROR, error, PassportUtil.COMMON_ERROR_DESCRIPTION, URLDecoder.decode(errorDescpriton, "UTF-8")), UtilHttp.getLocale(request));
> +            } catch (UnsupportedEncodingException e) {
> +                errMsg = UtilProperties.getMessage(resource, "GetGitHubAuthorizationCodeError", UtilHttp.getLocale(request));
> +            }
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        }
> +        Debug.logInfo("GitHub authorization code: " + authorizationCode, module);
> +
> +        GenericValue oauth2GitHub = getOAuth2GitHubConfig(request);
> +        if (UtilValidate.isEmpty(oauth2GitHub)) {
> +            String errMsg = UtilProperties.getMessage(resource, "GetOAuth2GitHubConfigError", UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        }
> +        String clientId = oauth2GitHub.getString(PassportUtil.COMMON_CLIENT_ID);
> +        String secret = oauth2GitHub.getString(PassportUtil.COMMON_CLIENT_SECRET);
> +        String returnURI = oauth2GitHub.getString(PassportUtil.COMMON_RETURN_RUL);
> +
> +        // Grant token from authorization code and oauth2 token
> +        // Use the authorization code to obtain an access token
> +        String accessToken = null;
> +        String tokenType = null;
> +
> +        HttpClient jsonClient = new HttpClient();
> +        PostMethod postMethod = new PostMethod(TokenEndpoint + TokenServiceUri);
> +        try {
> +            HttpMethodParams params = new HttpMethodParams();
> +            String queryString = "client_id=" + clientId
> +                    + "&client_secret=" + secret
> +                    + "&code=" + authorizationCode
> +                    + "&redirect_uri=" + URLEncoder.encode(returnURI, "UTF-8");
> +            // Debug.logInfo("GitHub get access token query string: " + queryString, module);
> +            postMethod.setQueryString(queryString);
> +            params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
> +            postMethod.setParams(params);
> +            postMethod.setRequestHeader(PassportUtil.ACCEPT_HEADER, "application/json");
> +            jsonClient.executeMethod(postMethod);
> +            // Debug.logInfo("GitHub get access token response code: " + postMethod.getStatusCode(), module);
> +            // Debug.logInfo("GitHub get access token response content: " + postMethod.getResponseBodyAsString(1024), module);
> +            if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
> +                // Debug.logInfo("Json Response from GitHub: " + postMethod.getResponseBodyAsString(1024), module);
> +                JSONObject jsonObject = JSONObject.fromObject(postMethod.getResponseBodyAsString(1024));
> +                accessToken = jsonObject.getString("access_token");
> +                tokenType = jsonObject.getString("token_type");
> +                // Debug.logInfo("Generated Access Token : " + accessToken, module);
> +                // Debug.logInfo("Token Type: " + tokenType, module);
> +            } else {
> +                String errMsg = UtilProperties.getMessage(resource, "GetOAuth2GitHubAccessTokenError", UtilMisc.toMap("error", postMethod.getResponseBodyAsString()), UtilHttp.getLocale(request));
> +                request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +                return "error";
> +            }
> +        } catch (UnsupportedEncodingException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (HttpException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (IOException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } finally {
> +            postMethod.releaseConnection();
> +        }
> +
> +        // Get User Profile
> +        GetMethod getMethod = new GetMethod(ApiEndpoint + UserApiUri);
> +        Map<String, Object> userInfo = null;
> +        try {
> +            userInfo = GitHubAuthenticator.getUserInfo(getMethod, accessToken, tokenType, UtilHttp.getLocale(request));
> +        } catch (HttpException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (IOException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (AuthenticatorException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } finally {
> +            getMethod.releaseConnection();
> +        }
> +        // Debug.logInfo("GitHub User Info:" + userInfo, module);
> +
> +        // Store the user info and check login the user
> +        return checkLoginGitHubUser(request, userInfo, accessToken);
> +    }
> +
> +    private static String checkLoginGitHubUser(HttpServletRequest request, Map<String, Object> userInfo, String accessToken) {
> +        Delegator delegator = (Delegator) request.getAttribute("delegator");
> +        LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
> +        String productStoreId = ProductStoreWorker.getProductStoreId(request);
> +        String gitHubUserId = (String) userInfo.get("login");
> +        GenericValue gitHubUser = null;
> +        try {
> +            gitHubUser = delegator.findOne("GitHubUser", UtilMisc.toMap("gitHubUserId", gitHubUserId), false);
> +        } catch (GenericEntityException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
> +            return "error";
> +        }
> +        if (UtilValidate.isNotEmpty(gitHubUser)) {
> +            boolean dataChanged = false;
> +            if (!accessToken.equals(gitHubUser.getString("accessToken"))) {
> +                gitHubUser.set("accessToken", accessToken);
> +                dataChanged = true;
> +            }
> +            if (!envPrefix.equals(gitHubUser.getString("envPrefix"))) {
> +                gitHubUser.set("envPrefix", envPrefix);
> +                dataChanged = true;
> +            }
> +            if (!productStoreId.equals(gitHubUser.getString("productStoreId"))) {
> +                gitHubUser.set("productStoreId", productStoreId);
> +                dataChanged = true;
> +            }
> +            if (dataChanged) {
> +                try {
> +                    gitHubUser.store();
> +                } catch (GenericEntityException e) {
> +                    Debug.logError(e.getMessage(), module);
> +                }
> +            }
> +        } else {
> +            gitHubUser = delegator.makeValue("GitHubUser", UtilMisc.toMap("accessToken", accessToken,
> +                                                                          "productStoreId", productStoreId,
> +                                                                          "envPrefix", envPrefix,
> +                                                                          "gitHubUserId", gitHubUserId));
> +            try {
> +                gitHubUser.create();
> +            } catch (GenericEntityException e) {
> +                Debug.logError(e.getMessage(), module);
> +            }
> +        }
> +        try {
> +            GenericValue userLogin = EntityUtil.getFirst(delegator.findByAnd("UserLogin", UtilMisc.toMap("externalAuthId", gitHubUserId)));
> +            GitHubAuthenticator authn = new GitHubAuthenticator();
> +            authn.initialize(dispatcher);
> +            if (UtilValidate.isEmpty(userLogin)) {
> +                String userLoginId = authn.createUser(userInfo);
> +                userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", userLoginId), false);
> +            }
> +            String password = PassportUtil.randomString();
> +            boolean useEncryption = "true".equals(UtilProperties.getPropertyValue("security.properties", "password.encrypt"));
> +            userLogin.set("currentPassword", useEncryption ? HashCrypt.cryptPassword(LoginServices.getHashType(), password) : password);
> +            userLogin.store();
> +            request.setAttribute("USERNAME", userLogin.getString("userLoginId"));
> +            request.setAttribute("PASSWORD", password);
> +        } catch (GenericEntityException e) {
> +            Debug.logError(e.getMessage(), module);
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (AuthenticatorException e) {
> +            Debug.logError(e.getMessage(), module);
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        }
> +        return "success";
> +    }
> +
> +    public static GenericValue getOAuth2GitHubConfig(HttpServletRequest request) {
> +        Delegator delegator = (Delegator) request.getAttribute("delegator");
> +        String productStoreId = ProductStoreWorker.getProductStoreId(request);
> +        try {
> +            return getOAuth2GitHubConfig(delegator, productStoreId);
> +        } catch (GenericEntityException e) {
> +            Map<String, String> messageMap = UtilMisc.toMap("errorMessage", e.toString());
> +            String errMsg = UtilProperties.getMessage(resource, "GetOAuth2GitHubError", messageMap, UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +        }
> +        return null;
> +    }
> +
> +    public static GenericValue getOAuth2GitHubConfig(Delegator delegator, String productStoreId) throws GenericEntityException {
> +        return EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("OAuth2GitHub", UtilMisc.toMap("productStoreId", productStoreId))));
> +    }
> +}
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java
> ------------------------------------------------------------------------------
>      svn:mime-type = text/plain
>
> Added: ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/LinkedInEvents.java
> URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/LinkedInEvents.java?rev=1706654&view=auto
> ==============================================================================
> --- ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/LinkedInEvents.java (added)
> +++ ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/LinkedInEvents.java Sun Oct  4 08:40:40 2015
> @@ -0,0 +1,319 @@
> +/*******************************************************************************
> + * 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.event;
> +
> +import java.io.IOException;
> +import java.io.UnsupportedEncodingException;
> +import java.net.URLDecoder;
> +import java.net.URLEncoder;
> +import java.util.Map;
> +import java.util.Random;
> +
> +import javax.servlet.http.HttpServletRequest;
> +import javax.servlet.http.HttpServletResponse;
> +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.methods.PostMethod;
> +import org.apache.commons.httpclient.params.HttpMethodParams;
> +import org.ofbiz.passport.user.LinkedInAuthenticator;
> +import org.ofbiz.passport.util.PassportUtil;
> +import org.ofbiz.base.crypto.HashCrypt;
> +import net.sf.json.JSONObject;
> +import org.ofbiz.base.util.Debug;
> +import org.ofbiz.base.util.UtilHttp;
> +import org.ofbiz.base.util.UtilMisc;
> +import org.ofbiz.base.util.UtilProperties;
> +import org.ofbiz.base.util.UtilValidate;
> +import org.ofbiz.common.authentication.api.AuthenticatorException;
> +import org.ofbiz.common.login.LoginServices;
> +import org.ofbiz.entity.Delegator;
> +import org.ofbiz.entity.GenericEntityException;
> +import org.ofbiz.entity.GenericValue;
> +import org.ofbiz.entity.util.EntityUtil;
> +import org.ofbiz.product.store.ProductStoreWorker;
> +import org.ofbiz.service.LocalDispatcher;
> +import org.w3c.dom.Document;
> +import org.xml.sax.SAXException;
> +
> +/**
> + * LinkedEvents - Events for LinkedIn login.
> + *
> + * Refs: https://developer.linkedin.com/documents/authentication
> + *
> + */
> +public class LinkedInEvents {
> +
> +    public static final String module = LinkedInEvents.class.getName();
> +
> +    public static final String resource = "PassportUiLabels";
> +
> +    public static final String AuthorizeUri = "/uas/oauth2/authorization";
> +
> +    public static final String TokenServiceUri = "/uas/oauth2/accessToken";
> +
> +    public static final String UserApiUri = "/v1/people/~";
> +
> +    public static final String DEFAULT_SCOPE = "r_basicprofile%20r_emailaddress";
> +
> +    public static final String TokenEndpoint = "https://www.linkedin.com";
> +
> +    public static final String SESSION_LINKEDIN_STATE = "_LINKEDIN_STATE_";
> +
> +    public static final String envPrefix = UtilProperties.getPropertyValue(LinkedInAuthenticator.props, "linkedin.env.prefix", "test");
> +
> +    /**
> +     * Redirect to LinkedIn login page.
> +     *
> +     * @return
> +     */
> +    public static String linkedInRedirect(HttpServletRequest request, HttpServletResponse response) {
> +        GenericValue oauth2LinkedIn = getOAuth2LinkedInConfig(request);
> +        if (UtilValidate.isEmpty(oauth2LinkedIn)) {
> +            return "error";
> +        }
> +
> +        String clientId = oauth2LinkedIn.getString(PassportUtil.ApiKeyLabel);
> +        String returnURI = oauth2LinkedIn.getString(envPrefix + PassportUtil.ReturnUrlLabel);
> +
> +        // Get user authorization code
> +        try {
> +            String state = System.currentTimeMillis() + String.valueOf((new Random(10)).nextLong());
> +            request.getSession().setAttribute(SESSION_LINKEDIN_STATE, state);
> +            String redirectUrl = TokenEndpoint + AuthorizeUri
> +                    + "?client_id=" + clientId
> +                    + "&response_type=code"
> +                    + "&scope=" + DEFAULT_SCOPE
> +                    + "&redirect_uri=" + URLEncoder.encode(returnURI, "UTF-8")
> +                    + "&state=" + state;
> +            response.sendRedirect(redirectUrl);
> +        } catch (NullPointerException e) {
> +            String errMsg = UtilProperties.getMessage(resource, "RedirectToLinkedInOAuth2NullException", UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        } catch (IOException e) {
> +            Map<String, String> messageMap = UtilMisc.toMap("errorMessage", e.toString());
> +            String errMsg = UtilProperties.getMessage(resource, "RedirectToLinkedInOAuth2Error", messageMap, UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        }
> +
> +        return "success";
> +    }
> +
> +    /**
> +     * Parse LinkedIn login response and login the user if possible.
> +     *
> +     * @return
> +     */
> +    public static String parseLinkedInResponse(HttpServletRequest request, HttpServletResponse response) {
> +        String authorizationCode = request.getParameter(PassportUtil.COMMON_CODE);
> +        String state = request.getParameter(PassportUtil.COMMON_STATE);
> +        if (!state.equals(request.getSession().getAttribute(SESSION_LINKEDIN_STATE))) {
> +            String errMsg = UtilProperties.getMessage(resource, "LinkedInFailedToMatchState", UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        }
> +        if (UtilValidate.isEmpty(authorizationCode)) {
> +            String error = request.getParameter(PassportUtil.COMMON_ERROR);
> +            String errorDescpriton = request.getParameter(PassportUtil.COMMON_ERROR_DESCRIPTION);
> +            String errMsg = null;
> +            try {
> +                errMsg = UtilProperties.getMessage(resource, "FailedToGetLinkedInAuthorizationCode", UtilMisc.toMap(PassportUtil.COMMON_ERROR, error, PassportUtil.COMMON_ERROR_DESCRIPTION, URLDecoder.decode(errorDescpriton, "UTF-8")), UtilHttp.getLocale(request));
> +            } catch (UnsupportedEncodingException e) {
> +                errMsg = UtilProperties.getMessage(resource, "GetLinkedInAuthorizationCodeError", UtilHttp.getLocale(request));
> +            }
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        }
> +        // Debug.logInfo("LinkedIn authorization code: " + authorizationCode, module);
> +
> +        GenericValue oauth2LinkedIn = getOAuth2LinkedInConfig(request);
> +        if (UtilValidate.isEmpty(oauth2LinkedIn)) {
> +            String errMsg = UtilProperties.getMessage(resource, "GetOAuth2LinkedInConfigError", UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +            return "error";
> +        }
> +        String clientId = oauth2LinkedIn.getString(PassportUtil.ApiKeyLabel);
> +        String secret = oauth2LinkedIn.getString(PassportUtil.SecretKeyLabel);
> +        String returnURI = oauth2LinkedIn.getString(envPrefix + PassportUtil.ReturnUrlLabel);
> +
> +        // Grant token from authorization code and oauth2 token
> +        // Use the authorization code to obtain an access token
> +        String accessToken = null;
> +
> +        HttpClient jsonClient = new HttpClient();
> +        PostMethod postMethod = new PostMethod(TokenEndpoint + TokenServiceUri);
> +        try {
> +            HttpMethodParams params = new HttpMethodParams();
> +            String queryString = "client_id=" + clientId
> +                    + "&client_secret=" + secret
> +                    + "&grant_type=authorization_code"
> +                    + "&code=" + authorizationCode
> +                    + "&redirect_uri=" + URLEncoder.encode(returnURI, "UTF-8");
> +            // Debug.logInfo("LinkedIn get access token query string: " + queryString, module);
> +            postMethod.setQueryString(queryString);
> +            params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
> +            postMethod.setParams(params);
> +            jsonClient.executeMethod(postMethod);
> +            // Debug.logInfo("LinkedIn get access token response code: " + postMethod.getStatusCode(), module);
> +            // Debug.logInfo("LinkedIn get access token response content: " + postMethod.getResponseBodyAsString(1024), module);
> +            if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
> +                // Debug.logInfo("Json Response from LinkedIn: " + postMethod.getResponseBodyAsString(1024), module);
> +                JSONObject jsonObject = JSONObject.fromObject(postMethod.getResponseBodyAsString(1024));
> +                accessToken = jsonObject.getString("access_token");
> +                // Debug.logInfo("Generated Access Token : " + accessToken, module);
> +            } else {
> +                String errMsg = UtilProperties.getMessage(resource, "GetOAuth2LinkedInAccessTokenError", UtilMisc.toMap("error", postMethod.getResponseBodyAsString()), UtilHttp.getLocale(request));
> +                request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +                return "error";
> +            }
> +        } catch (UnsupportedEncodingException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (HttpException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (IOException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } finally {
> +            postMethod.releaseConnection();
> +        }
> +
> +        // Get User Profile
> +        GetMethod getMethod = new GetMethod(TokenEndpoint + UserApiUri + "?oauth2_access_token=" + accessToken);
> +        Document userInfo = null;
> +        try {
> +            userInfo = LinkedInAuthenticator.getUserInfo(getMethod, UtilHttp.getLocale(request));
> +        } catch (HttpException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (IOException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (AuthenticatorException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (SAXException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (ParserConfigurationException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } finally {
> +            getMethod.releaseConnection();
> +        }
> +        // Debug.logInfo("LinkedIn User Info:" + userInfo, module);
> +
> +        // Store the user info and check login the user
> +        return checkLoginLinkedInUser(request, userInfo, accessToken);
> +    }
> +
> +    private static String checkLoginLinkedInUser(HttpServletRequest request, Document userInfo, String accessToken) {
> +        Delegator delegator = (Delegator) request.getAttribute("delegator");
> +        LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
> +        String productStoreId = ProductStoreWorker.getProductStoreId(request);
> +        String linkedInUserId = LinkedInAuthenticator.getLinkedInUserId(userInfo);
> +        GenericValue linkedInUser = null;
> +        try {
> +            linkedInUser = delegator.findOne("LinkedInUser", UtilMisc.toMap("linkedInUserId", linkedInUserId), false);
> +        } catch (GenericEntityException e) {
> +            request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
> +            return "error";
> +        }
> +        if (UtilValidate.isNotEmpty(linkedInUser)) {
> +            boolean dataChanged = false;
> +            if (!accessToken.equals(linkedInUser.getString("accessToken"))) {
> +                linkedInUser.set("accessToken", accessToken);
> +                dataChanged = true;
> +            }
> +            if (!envPrefix.equals(linkedInUser.getString("envPrefix"))) {
> +                linkedInUser.set("envPrefix", envPrefix);
> +                dataChanged = true;
> +            }
> +            if (!productStoreId.equals(linkedInUser.getString("productStoreId"))) {
> +                linkedInUser.set("productStoreId", productStoreId);
> +                dataChanged = true;
> +            }
> +            if (dataChanged) {
> +                try {
> +                    linkedInUser.store();
> +                } catch (GenericEntityException e) {
> +                    Debug.logError(e.getMessage(), module);
> +                }
> +            }
> +        } else {
> +            linkedInUser = delegator.makeValue("LinkedInUser", UtilMisc.toMap("accessToken", accessToken,
> +                                                                          "productStoreId", productStoreId,
> +                                                                          "envPrefix", envPrefix,
> +                                                                          "linkedInUserId", linkedInUserId));
> +            try {
> +                linkedInUser.create();
> +            } catch (GenericEntityException e) {
> +                Debug.logError(e.getMessage(), module);
> +            }
> +        }
> +        try {
> +            GenericValue userLogin = EntityUtil.getFirst(delegator.findByAnd("UserLogin", UtilMisc.toMap("externalAuthId", linkedInUserId)));
> +            LinkedInAuthenticator authn = new LinkedInAuthenticator();
> +            authn.initialize(dispatcher);
> +            if (UtilValidate.isEmpty(userLogin)) {
> +                String userLoginId = authn.createUser(userInfo);
> +                userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", userLoginId), false);
> +            }
> +            String password = PassportUtil.randomString();
> +            boolean useEncryption = "true".equals(UtilProperties.getPropertyValue("security.properties", "password.encrypt"));
> +            userLogin.set("currentPassword", useEncryption ? HashCrypt.cryptPassword(LoginServices.getHashType(), password) : password);
> +            userLogin.store();
> +            request.setAttribute("USERNAME", userLogin.getString("userLoginId"));
> +            request.setAttribute("PASSWORD", password);
> +        } catch (GenericEntityException e) {
> +            Debug.logError(e.getMessage(), module);
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        } catch (AuthenticatorException e) {
> +            Debug.logError(e.getMessage(), module);
> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
> +            return "error";
> +        }
> +        return "success";
> +    }
> +
> +    public static GenericValue getOAuth2LinkedInConfig(HttpServletRequest request) {
> +        Delegator delegator = (Delegator) request.getAttribute("delegator");
> +        String productStoreId = ProductStoreWorker.getProductStoreId(request);
> +        try {
> +            return getOAuth2LinkedInConfig(delegator, productStoreId);
> +        } catch (GenericEntityException e) {
> +            Map<String, String> messageMap = UtilMisc.toMap("errorMessage", e.toString());
> +            String errMsg = UtilProperties.getMessage(resource, "GetOAuth2LinkedInError", messageMap, UtilHttp.getLocale(request));
> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
> +        }
> +        return null;
> +    }
> +
> +    public static GenericValue getOAuth2LinkedInConfig(Delegator delegator, String productStoreId) throws GenericEntityException {
> +        return EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("OAuth2LinkedIn", UtilMisc.toMap("productStoreId", productStoreId))));
> +    }
> +}
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/LinkedInEvents.java
> ------------------------------------------------------------------------------
>      svn:eol-style = native
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/LinkedInEvents.java
> ------------------------------------------------------------------------------
>      svn:keywords = Date Rev Author URL Id
>
> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/LinkedInEvents.java
> ------------------------------------------------------------------------------
>      svn:mime-type = text/plain
>
>
>
>


Re: svn commit: r1706654 [1/2] - in /ofbiz/branches/release12.04: ./ specialpurpose/ specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/ specialpurpose/ecommerce/widget/ specialpurpose/passport/ specialpurpose/passport/build/ specialpurpose/passport/build/c...

Posted by Jacopo Cappellato <ja...@hotwaxsystems.com>.
Thanks Jacques

On Sun, Oct 4, 2015 at 11:06 AM, Jacques Le Roux <
jacques.le.roux@les7arts.com> wrote:

> Hi Jinghai,
>
> Wait, we don't do such things: we don't add new features to released
> branches. This should go only in trunk and interested persons using
> released branches should handle themselves the backport...
>
> Please revert and fix in trunk if necessary
>
> Thanks
>
> Jacques
>
> Le 04/10/2015 10:40, shijh@apache.org a écrit :
>
>> Author: shijh
>> Date: Sun Oct  4 08:40:40 2015
>> New Revision: 1706654
>>
>> URL: http://svn.apache.org/viewvc?rev=1706654&view=rev
>> Log:
>> OFBIZ-6659 When i working with Login with Linkedin In of biz the it is
>> not showing UI part
>>
>> 1. Added passport component to release-12.04 branch.
>> 2. Fixed groovy and java errors caused by findByAnd method.
>> 3. The third party login section is displayed on
>> /ecommerce/control/checkLogin page (see README for details).
>>
>> Added:
>>      ofbiz/branches/release12.04/specialpurpose/passport/
>>      ofbiz/branches/release12.04/specialpurpose/passport/README   (with
>> props)
>>      ofbiz/branches/release12.04/specialpurpose/passport/build/
>>      ofbiz/branches/release12.04/specialpurpose/passport/build.xml
>>  (with props)
>>      ofbiz/branches/release12.04/specialpurpose/passport/build/classes/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/passport/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/passport/event/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/passport/user/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/build/classes/org/ofbiz/passport/util/
>>      ofbiz/branches/release12.04/specialpurpose/passport/build/lib/
>>      ofbiz/branches/release12.04/specialpurpose/passport/config/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
>>  (with props)
>>      ofbiz/branches/release12.04/specialpurpose/passport/data/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
>>  (with props)
>>      ofbiz/branches/release12.04/specialpurpose/passport/entitydef/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
>>  (with props)
>>      ofbiz/branches/release12.04/specialpurpose/passport/src/
>>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/
>>      ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/LinkedInEvents.java
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubAuthenticator.java
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/GitHubUserGroupMapper.java
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInAuthenticator.java
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/user/LinkedInUserGroupMapper.java
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/util/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/util/PassportUtil.java
>>  (with props)
>>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/
>>      ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/actions/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/actions/login/getThirdPartyLogins.groovy
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/WEB-INF/controller-passport.xml
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/alipay.png
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/github.png
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/linkedin.png
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/paypal.png
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/qq.png
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/renren.png
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/taobao.png
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/weibo.png
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/images/weixin.png
>>  (with props)
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/login/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/webapp/passport/login/thirdPartyLogins.ftl
>>  (with props)
>>      ofbiz/branches/release12.04/specialpurpose/passport/widget/
>>
>>  ofbiz/branches/release12.04/specialpurpose/passport/widget/PassportScreens.xml
>>  (with props)
>> Modified:
>>      ofbiz/branches/release12.04/.classpath
>>      ofbiz/branches/release12.04/specialpurpose/build.xml
>>      ofbiz/branches/release12.04/specialpurpose/component-load.xml
>>
>>  ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
>>
>>  ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml
>>
>> Modified: ofbiz/branches/release12.04/.classpath
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/.classpath?rev=1706654&r1=1706653&r2=1706654&view=diff
>>
>> ==============================================================================
>> --- ofbiz/branches/release12.04/.classpath (original)
>> +++ ofbiz/branches/release12.04/.classpath Sun Oct  4 08:40:40 2015
>> @@ -214,6 +214,7 @@
>>       <classpathentry excluding="org/enhydra/|org/ofbiz/" kind="src"
>> path="specialpurpose/shark/src"/>
>>       <classpathentry kind="src" path="specialpurpose/webpos/src"/>
>>       <classpathentry kind="src" path="specialpurpose/workflow/src"/>
>> +    <classpathentry kind="src" path="specialpurpose/passport/src"/>
>>       <classpathentry exported="true" kind="con"
>> path="GROOVY_DSL_SUPPORT"/>
>>       <classpathentry kind="output" path="bin"/>
>>   </classpath>
>>
>> Modified: ofbiz/branches/release12.04/specialpurpose/build.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/build.xml?rev=1706654&r1=1706653&r2=1706654&view=diff
>>
>> ==============================================================================
>> --- ofbiz/branches/release12.04/specialpurpose/build.xml (original)
>> +++ ofbiz/branches/release12.04/specialpurpose/build.xml Sun Oct  4
>> 08:40:40 2015
>> @@ -36,7 +36,8 @@
>>           crowd/build.xml,
>>           webpos/build.xml
>>           googlecheckout/build.xml,
>> -        example/build.xml
>> +        example/build.xml,
>> +        passport/build.xml
>>       "/>
>>       <!-- For the old OFBiz Workflow Engine add "workflow/build.xml" to
>> the list above -->
>>       <!-- For Shark add "shark/build.xml" to the list above, in the
>> specialpurpose-builds list (after workflow) -->
>>
>> Modified: ofbiz/branches/release12.04/specialpurpose/component-load.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/component-load.xml?rev=1706654&r1=1706653&r2=1706654&view=diff
>>
>> ==============================================================================
>> --- ofbiz/branches/release12.04/specialpurpose/component-load.xml
>> (original)
>> +++ ofbiz/branches/release12.04/specialpurpose/component-load.xml Sun
>> Oct  4 08:40:40 2015
>> @@ -39,6 +39,7 @@ under the License.
>>       <load-component component-location="webpos"/>
>>       <load-component component-location="example"/>
>>       <load-component component-location="exampleext"/>
>> +    <load-component component-location="passport"/>
>>       <!-- The component below are not maintained by the community, or at
>> least not very actively
>>           Still they are functional (or at least should be).
>>           So if you need them simply uncomment and have a look also in
>> the build file -->
>>
>> Modified:
>> ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml?rev=1706654&r1=1706653&r2=1706654&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
>> (original)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
>> Sun Oct  4 08:40:40 2015
>> @@ -20,6 +20,9 @@ under the License.
>>     <site-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>           xsi:noNamespaceSchemaLocation="
>> http://ofbiz.apache.org/dtds/site-conf.xsd">
>> +    <!--
>> +    <include
>> location="component://passport/webapp/passport/WEB-INF/controller-passport.xml"/>
>> +     -->
>>       <description>OFBiz: eCommerce Controller Configuration
>> File</description>
>>       <errorpage>/error/error.jsp</errorpage>
>>   @@ -81,7 +84,7 @@ under the License.
>>           <description>Verify a user is logged in.</description>
>>           <security https="true" auth="false"/>
>>           <event type="java"
>> path="org.ofbiz.securityext.login.LoginEvents" invoke="storeCheckLogin"/>
>> -        <response name="success" type="view-last" value="main"/>
>> +        <response name="success" type="view" value="main"/>
>>           <response name="error" type="view" value="login"/>
>>       </request-map>
>>       <request-map uri="login">
>> @@ -851,7 +854,7 @@ under the License.
>>       </request-map>
>>       <request-map uri="category">
>>           <security https="false" auth="false"/>
>> -        <response name="success" type="view" value="category"
>> save-current-view="true"/>
>> +        <response name="success" type="view" value="category"/>
>>       </request-map>
>>       <request-map uri="product">
>>           <security https="false" auth="false"/>
>> @@ -1027,7 +1030,7 @@ under the License.
>>       <request-map uri="deleteContactMech">
>>           <security https="true" auth="true"/>
>>           <event type="service" invoke="deletePartyContactMech"/>
>> -        <response name="success" type="view" value="viewprofile"/>
>> +        <response name="success" type="view" value="editcontactmech"/>
>>           <response name="error" type="view" value="editcontactmech"/>
>>       </request-map>
>>   @@ -1320,20 +1323,20 @@ under the License.
>>       <request-map uri="signUpForContactList">
>>           <security https="false" auth="false"/>
>>           <event type="service" invoke="signUpForContactList"/>
>> -        <response name="success" type="view-last"/>
>> -        <response name="error" type="view-last" value="main"/>
>> +        <response name="success" type="view" value="main"/>
>> +        <response name="error" type="view" value="main"/>
>>       </request-map>
>>       <request-map uri="unsubscribeContactListParty">
>>           <security https="false" auth="false"/>
>>           <event type="service" invoke="unsubscribeContactListParty"/>
>> -        <response name="success" type="view-last"/>
>> -        <response name="error" type="view-last" value="main"/>
>> +        <response name="success" type="view" value="main"/>
>> +        <response name="error" type="view" value="main"/>
>>       </request-map>
>>       <request-map uri="unsubscribeContactListPartyContachMech">
>>           <security https="false" auth="false"/>
>>           <event type="service"
>> invoke="unsubscribeContactListPartyContachMech"/>
>> -        <response name="success" type="view-last"/>
>> -        <response name="error" type="view-last" value="main"/>
>> +        <response name="success" type="view" value="main"/>
>> +        <response name="error" type="view" value="main"/>
>>       </request-map>
>>       <request-map uri="contactListOptOut" track-serverhit="false"
>> track-visit="false">
>>           <security https="false" auth="false"/>
>> @@ -1940,7 +1943,7 @@ under the License.
>>             <request-map uri="ProductUomDropDownOnly">
>>           <security auth="false" https="false"/>
>> -        <response name="success" type="view"
>> value="ProductUomDropDownOnly" save-current-view="false" />
>> +        <response name="success" type="view"
>> value="ProductUomDropDownOnly" save-last-view="true"/>
>>       </request-map>
>>             <!-- Captcha: Image request, the captcha code is stored in
>> the session using _CAPTCHA_CODE_ as the key -->
>>
>> Modified:
>> ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml?rev=1706654&r1=1706653&r2=1706654&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml
>> (original)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/ecommerce/widget/CommonScreens.xml
>> Sun Oct  4 08:40:40 2015
>> @@ -334,6 +334,9 @@ under the License.
>>                           <platform-specific>
>>                               <html><html-template
>> location="component://ecommerce/webapp/ecommerce/login.ftl"/></html>
>>                           </platform-specific>
>> +                        <!--
>> +                        <include-screen name="ListThirdPartyLogins"
>> location="component://passport/widget/PassportScreens.xml"/>
>> +                         -->
>>                           <platform-specific>
>>                               <html><html-template
>> location="component://ecommerce/webapp/ecommerce/order/startanoncheckout.ftl"/></html>
>>                           </platform-specific>
>>
>> Added: ofbiz/branches/release12.04/specialpurpose/passport/README
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/README?rev=1706654&view=auto
>>
>> ==============================================================================
>> --- ofbiz/branches/release12.04/specialpurpose/passport/README (added)
>> +++ ofbiz/branches/release12.04/specialpurpose/passport/README Sun Oct  4
>> 08:40:40 2015
>> @@ -0,0 +1,98 @@
>> +========================
>> +OFBiz Passport Component
>> +========================
>> +The passport component is to support users to login with a third party
>> OAuth2 authentication such as GitHub, LinkedIn and etc.
>> +
>> +
>> +
>> +---------------------------------------
>> +GitHub OAuth2 Configuration Quick Start
>> +---------------------------------------
>> +To learn the whole GitHub OAuth, please read
>> https://developer.github.com/v3/oauth/.
>> +Here are the steps for a quick start in OFBiz trunk:
>> +
>> +------ GitHub Side ------
>> +1. Register a GitHub account if you don't have one.
>> +
>> +2. Login GitHub.
>> +
>> +3. Visit Settings->Applications->Developer applications, click "Register
>> new application" button.
>> +
>> +4. In "Register a new OAuth application", fill in your OFBiz website
>> information. Here the
>> +Authorization callback URL:
>> https://YourWebSiteOrInternetIp:8443/ecommerce/control/githubResponse
>> +[Note] As you want to use GitHub to authorize your users, your OFBiz
>> should be able to be visited on internet so that GitHub can forward the
>> users back after OAuth login.
>> +
>> +5. Click "Register application" button.
>> +You'll get your Client ID and Client Secret, write them down for later
>> configuration.
>> +
>> +------ OFBiz Side ------
>> +6. Edit specialpurpose/passport/data/OAuth2GitHubSeedData.xml, fill in
>> the Client ID in clientId, Client Secret in clientSecret and the
>> Authorization callback URL in returnUrl.
>> +
>> +7. Login to OFBiz webtools, in "XML Data Import" page, import
>> specialpurpose/passport/data/OAuth2GitHubSeedData.xml.
>> +
>> +8. Edit
>> specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml, uncomment
>> +   <include
>> location="component://passport/webapp/passport/WEB-INF/controller-passport.xml"/>
>> +
>> +9. Edit specialpurpose/ecommerce/widget/CommonScreens.xml, uncomment
>> +   <include-screen name="ListThirdPartyLogins"
>> location="component://passport/widget/PassportScreens.xml"/>
>> +
>> +10. Visit
>> https://YourWebSiteOrInternetIp:8443/ecommerce/control/checkLogin, click
>> GitHub icon in the "Third Party Login" area. You will be forwarded to
>> GitHub OAuth2 login page. After logging in successfully, you will be logged
>> in OFBiz.
>> +
>> +11. The parameters in
>> specialpurpose/passport/config/gitHubAuth.properties:
>> +github.env.prefix: test or live, default is test. This value will be
>> store in envPrefix field of GitHubUser entity when a user logged in by
>> GitHub OAuth2.
>> +github.authenticator.enabled: true or false, default is true. This
>> parameter is for future extension.
>> +
>> +
>> +
>> +-----------------------------------------
>> +LinkedIn OAuth2 Configuration Quick Start
>> +-----------------------------------------
>> +To learn the whole LinkedIn OAuth, please read
>> https://developer.linkedin.com/docs/oauth2.
>> +Here are the steps for a quick start in OFBiz trunk:
>> +
>> +------ LinkedIn Side ------
>> +1. Register a LinkedIn account if you don't have one.
>> +
>> +2. Visit https://www.linkedin.com/developer/apps, login LinkedIn.
>> +
>> +3. Click "Create Application" button.
>> +
>> +4. In "Create a New Application", fill in your OFBiz website
>> information. Here the
>> +Authorization callback URL:
>> https://YourWebSiteOrInternetIp:8443/ecommerce/control/linkedInResponse
>> +[Note] As you want to use LinkedIn to authorize your users, your OFBiz
>> should be able to be visited on internet so that LinkedIn can forward the
>> users back after OAuth login.
>> +
>> +5. Click "Submit" button.
>> +You'll get your Client ID and Client Secret, write them down for later
>> configuration. You should also select r_basicprofile and r_emailaddress in
>> "Default Application Permissions" section.
>> +
>> +6. In "Application Settings" page, you can select Application Status to
>> be Development or Live.
>> +
>> +------ OFBiz Side ------
>> +7. Edit specialpurpose/passport/data/OAuth2LinkedInSeedData.xml, fill in
>> the Client ID in apiKey, Client Secret in secretKey and the Authorization
>> callback URL in testReturnUrl and/or liveReturnUrl.
>> +
>> +8. Login to OFBiz webtools, in "XML Data Import" page, import
>> specialpurpose/passport/data/OAuth2LinkedInSeedData.xml.
>> +
>> +9. Edit
>> specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml, uncomment
>> +   <include
>> location="component://passport/webapp/passport/WEB-INF/controller-passport.xml"/>
>> +
>> +10. Edit specialpurpose/ecommerce/widget/CommonScreens.xml, uncomment
>> +   <include-screen name="ListThirdPartyLogins"
>> location="component://passport/widget/PassportScreens.xml"/>
>> +
>> +11. Visit
>> https://YourWebSiteOrInternetIp:8443/ecommerce/control/checkLogin, click
>> LinkedIn icon in the "Third Party Login" area. You will be forwarded to
>> LinkedIn OAuth2 login page. After logging in successfully, you will be
>> logged in OFBiz.
>> +
>> +12. The parameters in
>> specialpurpose/passport/config/linkedInAuth.properties:
>> +linkedin.env.prefix: test or live, default is test. This value will be
>> store in envPrefix field of LinkedInUser entity when a user logged in by
>> LinkedIn OAuth2.
>> +                     If the value is test, you should set your
>> Application Status to Development, and the "Authorized Redirect URLs" to
>> the same as the testReturnUrl.
>> +                     If the value is live, you should set your
>> Application Status to Live, and the "Authorized Redirect URLs" to the same
>> as the liveReturnUrl.
>> +linkedin.authenticator.enabled: true or false, default is true. This
>> parameter is for future extension.
>> +
>> +
>> +---------------
>> +     Q&A
>> +---------------
>> +Q. I think my configures are right, why there's no third party login in
>> my /ecommerce/control/checkLogin page?
>> +A. Please check whether the productStoreId in ThirdPartyLogin and
>> OAuth2GitHub/OAuth2LinkedIn is the same as your web store.
>> +
>> +Q. How could I extend this component to support other OAuth2 providers?
>> +A. 1st, you have to read the providers OAuth2 documents. 2nd, add some
>> new entities. 3rd, add seed data. 4th, add the icon file under
>> specialpurpose/passport/webapp/passport/images/.
>> +   5th, add redirect and response request in controller-passport.xml.
>> 6th, add java files to implement the redirect and response.
>> +
>>
>> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/README
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/README
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/plain
>>
>> Added: ofbiz/branches/release12.04/specialpurpose/passport/build.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/build.xml?rev=1706654&view=auto
>>
>> ==============================================================================
>> --- ofbiz/branches/release12.04/specialpurpose/passport/build.xml (added)
>> +++ ofbiz/branches/release12.04/specialpurpose/passport/build.xml Sun
>> Oct  4 08:40:40 2015
>> @@ -0,0 +1,52 @@
>> +<?xml version="1.0"?>
>> +<!--
>> +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.
>> +-->
>> +
>> +<project name="OFBiz - Passport Component" default="jar" basedir=".">
>> +    <import file="../../common.xml"/>
>> +
>> +    <!--
>> ================================================================== -->
>> +    <!-- Initialization of all property settings
>>     -->
>> +    <!--
>> ================================================================== -->
>> +
>> +    <property name="desc" value="Ecommerce Passport"/>
>> +    <property name="name" value="ofbiz-passport"/>
>> +    <property name="ofbiz.home.dir" value="../.."/>
>> +
>> +    <path id="local.class.path">
>> +        <fileset dir="../../framework/base/lib" includes="*.jar"/>
>> +        <fileset dir="../../framework/base/lib/j2eespecs"
>> includes="*.jar"/>
>> +        <fileset dir="../../framework/base/build/lib" includes="*.jar"/>
>> +        <fileset dir="../../framework/entity/lib" includes="*.jar"/>
>> +        <fileset dir="../../framework/entity/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../framework/security/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../framework/service/lib" includes="*.jar"/>
>> +        <fileset dir="../../framework/service/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../framework/minilang/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../framework/common/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../framework/webapp/lib" includes="*.jar"/>
>> +        <fileset dir="../../framework/webapp/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../applications/party/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../applications/product/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../applications/marketing/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../applications/order/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../applications/accounting/build/lib"
>> includes="*.jar"/>
>> +        <fileset dir="../../applications/securityext/build/lib"
>> includes="*.jar"/>
>> +    </path>
>> +</project>
>> \ No newline at end of file
>>
>> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/build.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/build.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:keywords = Date Rev Author URL Id
>>
>> Propchange: ofbiz/branches/release12.04/specialpurpose/passport/build.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/xml
>>
>> Added:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml?rev=1706654&view=auto
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
>> (added)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
>> Sun Oct  4 08:40:40 2015
>> @@ -0,0 +1,94 @@
>> +<?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.
>> +-->
>> +
>> +<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
>> +    <property key="PassportApplication">
>> +        <value xml:lang="en">Passport Third Party Auth
>> Application</value>
>> +        <value xml:lang="zh">ç¬¬ä¸‰æ–¹è®¤è¯ åº”ç”¨ç¨‹åº </value>
>> +    </property>
>> +    <property key="ThirdPartyLogin">
>> +        <value xml:lang="en">Third Party Login</value>
>> +        <value xml:lang="zh">第三方登录</value>
>> +    </property>
>> +
>> +    <!-- LinkedIn labels -->
>> +    <property key="LinkedInFailedToMatchState">
>> +        <value xml:lang="en">Failed to match the state parameter in
>> LinkedIn response. Just try to login again.</value>
>> +        <value xml:lang="zh">é¢†è‹±å“ åº”ä¸­çš„stateå ‚æ•°ä¸ ä¸€è‡´ã€‚é‡
>> è¯•ç™»å½•å ³å ¯ã€‚</value>
>> +    </property>
>> +    <property key="RedirectToLinkedInOAuth2NullException">
>> +        <value xml:lang="en">Error while redirecting to LinkedIn
>> authorization URL. Please use other login method for now.</value>
>> +        <value xml:lang="zh">è½¬åˆ°é¢†è‹±è®¤è¯ ç½‘å
>> €æ—¶å‡ºé”™ã€‚è¯·å…ˆä½¿ç”¨å…¶å®ƒç™»å½•æ–¹å¼ ã€‚</value>
>> +    </property>
>> +    <property key="RedirectToLinkedInOAuth2Error">
>> +        <value xml:lang="en">Error while redirecting to LinkedIn
>> authorization URL: ${errorMessage}</value>
>> +        <value xml:lang="zh">è½¬åˆ°é¢†è‹±è®¤è¯ ç½‘å
>> €æ—¶å‡ºé”™ï¼š${errorMessage}。</value>
>> +    </property>
>> +    <property key="FailedToGetLinkedInAuthorizationCode">
>> +        <value xml:lang="en">Failed to get LinkedIn authorization
>> code.&lt;br&gt;Error: ${error}&lt;br&gt;Error description:
>> ${error_description}</value>
>> +        <value xml:lang="zh">èŽ·å –é¢†è‹±æŽˆæ ƒç
>> 时出错。&lt;br&gt;错误: ${error}&lt;br&gt;é”™è¯¯æ  è¿°:
>> ${error_description}</value>
>> +    </property>
>> +    <property key="GetLinkedInAuthorizationCodeError">
>> +        <value xml:lang="en">Failed to get LinkedIn authorization
>> code.</value>
>> +        <value xml:lang="zh">èŽ·å –é¢†è‹±æŽˆæ ƒç  æ—¶å‡ºé”™ã€‚</value>
>> +    </property>
>> +    <property key="GetOAuth2LinkedInConfigError">
>> +        <value xml:lang="en">Failed to get LinkedIn configuration.
>> Please check whether OAuth2LinkedIn entity has your productStoreId
>> configured.</value>
>> +        <value xml:lang="zh">èŽ·å –é¢†è‹±é…
>> 置时出错。请检查OAuth2LinkedInå®žä½“ä¸­æ˜¯å ¦é… ç½®äº†ä½ çš„åº—é“ºæ
>> ‡è¯†(productStoreId)。</value>
>> +    </property>
>> +    <property key="GetOAuth2LinkedInAccessTokenError">
>> +        <value xml:lang="en">Failed to get LinkedIn access token.</value>
>> +        <value xml:lang="zh">èŽ·å –é¢†è‹±è®¿é—®ä»¤ç‰Œæ—¶å‡ºé”™ã€‚</value>
>> +    </property>
>> +    <property key="GetOAuth2LinkedInError">
>> +        <value xml:lang="en">Failed to get OAuth2LinkedIn entity:
>> ${errorMessage}</value>
>> +        <value xml:lang="zh">获å
>> –OAuth2LinkedIn实体时出错:${errorMessage}</value>
>> +    </property>
>> +
>> +    <!-- GitHub labels -->
>> +    <property key="RedirectToGitHubOAuth2NullException">
>> +        <value xml:lang="en">Error while redirecting to GitHub
>> authorization URL. Please use other login method for now.</value>
>> +        <value xml:lang="zh">转到GitHubè®¤è¯ ç½‘å
>> €æ—¶å‡ºé”™ã€‚è¯·å…ˆä½¿ç”¨å…¶å®ƒç™»å½•æ–¹å¼ ã€‚</value>
>> +    </property>
>> +    <property key="RedirectToGitHubOAuth2Error">
>> +        <value xml:lang="en">Error while redirecting to GitHub
>> authorization URL: ${errorMessage}</value>
>> +        <value xml:lang="zh">转到GitHubè®¤è¯ ç½‘å
>> €æ—¶å‡ºé”™ï¼š${errorMessage}。</value>
>> +    </property>
>> +    <property key="GitHubFailedToMatchState">
>> +        <value xml:lang="en">Failed to match the state parameter in
>> GitHub response. Just try to login again.</value>
>> +        <value xml:lang="zh">GitHubå“ åº”ä¸­çš„stateå ‚æ•°ä¸ ä¸€è‡´ã€‚é‡
>> è¯•ç™»å½•å ³å ¯ã€‚</value>
>> +    </property>
>> +    <property key="GetGitHubAuthorizationCodeError">
>> +        <value xml:lang="en">Failed to get GitHub authorization
>> code.</value>
>> +        <value xml:lang="zh">èŽ·å –GitHubæŽˆæ ƒç  æ—¶å‡ºé”™ã€‚</value>
>> +    </property>
>> +    <property key="GetOAuth2GitHubConfigError">
>> +        <value xml:lang="en">Failed to get GitHub configuration. Please
>> check whether OAuth2GitHub entity has your productStoreId
>> configured.</value>
>> +        <value xml:lang="zh">èŽ·å –GitHubé…
>> 置时出错。请检查OAuth2GitHubå®žä½“ä¸­æ˜¯å ¦é… ç½®äº†ä½ çš„åº—é“ºæ
>> ‡è¯†(productStoreId)。</value>
>> +    </property>
>> +    <property key="GetOAuth2GitHubAccessTokenError">
>> +        <value xml:lang="en">Failed to get GitHub access token:
>> ${error}</value>
>> +        <value xml:lang="zh">获å
>> –GitHub访问令牌时出错:${error}</value>
>> +    </property>
>> +    <property key="GetOAuth2GitHubError">
>> +        <value xml:lang="en">Failed to get OAuth2GitHub entity:
>> ${errorMessage}</value>
>> +        <value xml:lang="zh">获å
>> –OAuth2GitHub实体时出错:${errorMessage}</value>
>> +    </property>
>> +</resource>
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:keywords = Date Rev Author URL Id
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/PassportUiLabels.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/xml
>>
>> Added:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties?rev=1706654&view=auto
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
>> (added)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
>> Sun Oct  4 08:40:40 2015
>> @@ -0,0 +1,24 @@
>>
>> +###############################################################################
>> +# 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.
>>
>> +###############################################################################
>> +
>> +github.env.prefix=test
>> +
>> +github.authenticator.enabled=true
>> +
>> +# github.group.map.1=github-user=FULLADMIN
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
>>
>> ------------------------------------------------------------------------------
>>      svn:keywords = Date Rev Author URL Id
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/gitHubAuth.properties
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/plain
>>
>> Added:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties?rev=1706654&view=auto
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
>> (added)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
>> Sun Oct  4 08:40:40 2015
>> @@ -0,0 +1,24 @@
>>
>> +###############################################################################
>> +# 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.
>>
>> +###############################################################################
>> +
>> +linkedin.env.prefix=test
>> +
>> +linkedin.authenticator.enabled=true
>> +
>> +# linkedin.group.map.1=linkedin-user=FULLADMIN
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
>>
>> ------------------------------------------------------------------------------
>>      svn:keywords = Date Rev Author URL Id
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/config/linkedInAuth.properties
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/plain
>>
>> Added:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml?rev=1706654&view=auto
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
>> (added)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
>> Sun Oct  4 08:40:40 2015
>> @@ -0,0 +1,28 @@
>> +<?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.
>> +-->
>> +
>> +<entity-engine-xml>
>> +
>> +    <EnumerationType description="Passport Login Method Type"
>> enumTypeId="ppLoginMethType" hasTable="N" parentTypeId=""/>
>> +    <EnumerationType description="Passport Login Provider"
>> enumTypeId="ppLoginProvider" hasTable="N" parentTypeId=""/>
>> +
>> +    <EnumerationType description="OAuth2 Login Method Type"
>> enumTypeId="OAuth2" hasTable="N" parentTypeId="ppLoginMethType"/>
>> +
>> +</entity-engine-xml>
>> \ No newline at end of file
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:keywords = Date Rev Author URL Id
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2CommonSeedData.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/xml
>>
>> Added:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml?rev=1706654&view=auto
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
>> (added)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
>> Sun Oct  4 08:40:40 2015
>> @@ -0,0 +1,34 @@
>> +<?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.
>> +-->
>> +
>> +<entity-engine-xml>
>> +
>> +    <EnumerationType description="GitHub Login" enumTypeId="GitHub"
>> hasTable="N" parentTypeId="ppLoginProvider"/>
>> +
>> +    <ThirdPartyLogin productStoreId="9000" loginMethTypeId="OAuth2"
>> loginProviderId="GitHub" fromDate="2011-01-01 00:00:00.0" thruDate=""
>> sequenceNum=""/>
>> +
>> +    <OAuth2GitHub productStoreId="9000"
>> +                    clientId="" clientSecret=""
>> +                    returnUrl=""
>> +                    localRedirectUri="/ecomseo/gitHubRedirect"
>> +                    iconUrl="/passport/images/github.png"
>> fromDate="2011-01-01 00:00:00.0" thruDate=""/>
>> +    <!-- The returnUrl, i.e.
>> https://yourWebSiteOrIp:8443/ecomseo/githubResponse -->
>> +
>> +</entity-engine-xml>
>> \ No newline at end of file
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:keywords = Date Rev Author URL Id
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2GitHubSeedData.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/xml
>>
>> Added:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml?rev=1706654&view=auto
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
>> (added)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
>> Sun Oct  4 08:40:40 2015
>> @@ -0,0 +1,36 @@
>> +<?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.
>> +-->
>> +
>> +<entity-engine-xml>
>> +
>> +    <EnumerationType description="LinkedIn Login" enumTypeId="LinkedIn"
>> hasTable="N" parentTypeId="ppLoginProvider"/>
>> +
>> +    <ThirdPartyLogin productStoreId="9000" loginMethTypeId="OAuth2"
>> loginProviderId="LinkedIn" fromDate="2011-01-01 00:00:00.0" thruDate=""
>> sequenceNum=""/>
>> +
>> +    <OAuth2LinkedIn productStoreId="9000"
>> +                    apiKey="" secretKey=""
>> +                    testReturnUrl=""
>> +                    liveReturnUrl=""
>> +
>> localRedirectUri="/ecommerce/control/linkedInRedirect"
>> +                    iconUrl="/passport/images/linkedin.png"
>> fromDate="2011-01-01 00:00:00.0" thruDate=""/>
>> +    <!-- The testReturnUrl, i.e.
>> https://yourTestWebSiteOrIp:8443/ecomseo/linkedInResponse -->
>> +    <!-- The liveReturnUrl, i.e.
>> https://yourLiveWebSiteOrIp:8443/ecomseo/linkedInResponse -->
>> +
>> +</entity-engine-xml>
>> \ No newline at end of file
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:keywords = Date Rev Author URL Id
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/data/OAuth2LinkedInSeedData.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/xml
>>
>> Added:
>> ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml?rev=1706654&view=auto
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
>> (added)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
>> Sun Oct  4 08:40:40 2015
>> @@ -0,0 +1,119 @@
>> +<?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.
>> +-->
>> +
>> +<entitymodel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>> xsi:noNamespaceSchemaLocation="
>> http://ofbiz.apache.org/dtds/entitymodel.xsd">
>> +    <title>Entity of Passport Component</title>
>> +    <description>Data Model Enhancements For Passport</description>
>> +    <version>1.0</version>
>> +
>> +    <entity entity-name="ThirdPartyLogin"
>> +            package-name="org.ofbiz.passport"
>> +            title="Third party logins for a specific product store"
>> +            default-resource-name="PassportEntityLabels">
>> +        <field name="productStoreId" type="id-ne"></field>
>> +        <field name="loginMethTypeId" type="id-ne"></field><!-- i.e.
>> OAuth2 -->
>> +        <field name="loginProviderId" type="id-ne"></field><!-- i.e.
>> GitHub -->
>> +        <field name="fromDate" type="date-time"></field>
>> +        <field name="thruDate" type="date-time"></field>
>> +        <field name="sequenceNum" type="numeric"></field>
>> +        <prim-key field="productStoreId"/>
>> +        <prim-key field="loginMethTypeId"/>
>> +        <prim-key field="loginProviderId"/>
>> +        <prim-key field="fromDate"/>
>> +        <relation type="one" fk-name="PROD_STORE_LOGINS"
>> rel-entity-name="ProductStore">
>> +            <key-map field-name="productStoreId"/>
>> +        </relation>
>> +        <relation type="many" rel-entity-name="EnumerationType">
>> +            <key-map field-name="loginMethTypeId"
>> rel-field-name="enumTypeId"/>
>> +            <key-map field-name="loginProviderId"
>> rel-field-name="enumTypeId"/>
>> +        </relation>
>> +    </entity>
>> +
>> +    <!-- GitHub OAuth -->
>> +    <entity entity-name="OAuth2GitHub"
>> +            package-name="org.ofbiz.passport"
>> +            title="GitHub OAuth Login Config"
>> +            default-resource-name="PassportEntityLabels">
>> +        <field name="productStoreId" type="id-ne"></field>
>> +        <field name="clientId" type="short-varchar"></field>
>> +        <field name="clientSecret" type="short-varchar"></field>
>> +        <field name="returnUrl" type="value"></field>
>> +        <field name="localRedirectUri" type="short-varchar"></field>
>> +        <field name="iconUrl" type="url"></field>
>> +        <field name="fromDate" type="date-time"></field>
>> +        <field name="thruDate" type="date-time"></field>
>> +        <prim-key field="productStoreId"/>
>> +        <prim-key field="fromDate"/>
>> +        <relation type="one" fk-name="STORE_OAUTH_GITHUB"
>> rel-entity-name="ProductStore">
>> +            <key-map field-name="productStoreId"/>
>> +        </relation>
>> +    </entity>
>> +
>> +    <entity entity-name="GitHubUser"
>> +            package-name="org.ofbiz.passport"
>> +            title="Store GitHub access token for user"
>> +            default-resource-name="PassportEntityLabels">
>> +        <field name="gitHubUserId" type="id-vlong-ne"></field>
>> +        <field name="productStoreId" type="id-ne"></field>
>> +        <field name="envPrefix" type="short-varchar"></field>
>> +        <field name="tokenType" type="short-varchar"></field>
>> +        <field name="accessToken" type="value"></field>
>> +        <prim-key field="gitHubUserId"/>
>> +        <relation type="one" fk-name="GITHUB_USER_STORE"
>> rel-entity-name="ProductStore">
>> +            <key-map field-name="productStoreId"/>
>> +        </relation>
>> +    </entity>
>> +
>> +    <!-- LinkedIn OAuth -->
>> +    <entity entity-name="OAuth2LinkedIn"
>> +            package-name="org.ofbiz.passport"
>> +            title="LinkedIn OAuth Login Config"
>> +            default-resource-name="PassportEntityLabels">
>> +        <field name="productStoreId" type="id-ne"></field>
>> +        <field name="apiKey" type="short-varchar"></field>
>> +        <field name="secretKey" type="short-varchar"></field>
>> +        <field name="liveReturnUrl" type="value"></field>
>> +        <field name="testReturnUrl" type="value"></field>
>> +        <field name="localRedirectUri" type="short-varchar"></field>
>> +        <field name="iconUrl" type="url"></field>
>> +        <field name="fromDate" type="date-time"></field>
>> +        <field name="thruDate" type="date-time"></field>
>> +        <prim-key field="productStoreId"/>
>> +        <prim-key field="fromDate"/>
>> +        <relation type="one" fk-name="OAUTH2_LINKEDIN"
>> rel-entity-name="ProductStore">
>> +            <key-map field-name="productStoreId"/>
>> +        </relation>
>> +    </entity>
>> +
>> +    <entity entity-name="LinkedInUser"
>> +            package-name="org.ofbiz.passport"
>> +            title="Store LinkedIn access token for user"
>> +            default-resource-name="PassportEntityLabels">
>> +        <field name="linkedInUserId" type="id-vlong-ne"></field>
>> +        <field name="productStoreId" type="id-ne"></field>
>> +        <field name="envPrefix" type="short-varchar"></field>
>> +        <field name="accessToken" type="value"></field>
>> +        <prim-key field="linkedInUserId"/>
>> +        <relation type="one" fk-name="LINKEDIN_USER"
>> rel-entity-name="ProductStore">
>> +            <key-map field-name="productStoreId"/>
>> +        </relation>
>> +    </entity>
>> +
>> +</entitymodel>
>> \ No newline at end of file
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:keywords = Date Rev Author URL Id
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/entitydef/entitymodel.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/xml
>>
>> Added:
>> ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml?rev=1706654&view=auto
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
>> (added)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml Sun
>> Oct  4 08:40:40 2015
>> @@ -0,0 +1,34 @@
>> +<?xml version="1.0" encoding="UTF-8"?>
>> +<ofbiz-component name="passport"
>> +        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>> +        xsi:noNamespaceSchemaLocation="
>> http://ofbiz.apache.org/dtds/ofbiz-component.xsd">
>> +    <!-- define resource loaders; most common is to use the component
>> resource loader -->
>> +    <resource-loader name="main" type="component"/>
>> +
>> +    <!-- place the config directory on the classpath to access
>> configuration files -->
>> +    <classpath type="dir" location="config"/>
>> +
>> +    <!-- load single or multiple external libraries -->
>> +    <classpath type="jar" location="build/lib/*"/>
>> +
>> +    <!-- entity resources: model(s), eca(s), group, and data definitions
>> -->
>> +    <entity-resource type="model" reader-name="main" loader="main"
>> location="entitydef/entitymodel.xml"/>
>> +
>> +    <!-- Seed Data -->
>> +    <entity-resource type="data" reader-name="seed" loader="main"
>> location="data/OAuth2CommonSeedData.xml"/>
>> +    <entity-resource type="data" reader-name="demo" loader="main"
>> location="data/OAuth2LinkedInSeedData.xml"/>
>> +    <entity-resource type="data" reader-name="demo" loader="main"
>> location="data/OAuth2GitHubSeedData.xml"/>
>> +
>> +    <!-- service resources: model(s), eca(s) and group definitions -->
>> +    <!--
>> +    <service-resource type="model" loader="main"
>> location="servicedef/services.xml"/>
>> +     -->
>> +
>> +    <!-- web applications; will be mounted when using the embedded
>> container -->
>> +    <webapp name="passport"
>> +            title="OFBiz Passport"
>> +            server="default-server"
>> +            location="webapp/passport"
>> +            mount-point="/passport"
>> +            app-bar-display="false" />
>> +</ofbiz-component>
>> \ No newline at end of file
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:eol-style = native
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:keywords = Date Rev Author URL Id
>>
>> Propchange:
>> ofbiz/branches/release12.04/specialpurpose/passport/ofbiz-component.xml
>>
>> ------------------------------------------------------------------------------
>>      svn:mime-type = text/xml
>>
>> Added:
>> ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java?rev=1706654&view=auto
>>
>> ==============================================================================
>> ---
>> ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java
>> (added)
>> +++
>> ofbiz/branches/release12.04/specialpurpose/passport/src/org/ofbiz/passport/event/GitHubEvents.java
>> Sun Oct  4 08:40:40 2015
>> @@ -0,0 +1,315 @@
>>
>> +/*******************************************************************************
>> + * 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.event;
>> +
>> +import java.io.IOException;
>> +import java.io.UnsupportedEncodingException;
>> +import java.net.URLDecoder;
>> +import java.net.URLEncoder;
>> +import java.util.Map;
>> +import java.util.Random;
>> +
>> +import javax.servlet.http.HttpServletRequest;
>> +import javax.servlet.http.HttpServletResponse;
>> +
>> +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.methods.PostMethod;
>> +import org.apache.commons.httpclient.params.HttpMethodParams;
>> +import org.ofbiz.passport.user.GitHubAuthenticator;
>> +import org.ofbiz.passport.util.PassportUtil;
>> +import org.ofbiz.base.crypto.HashCrypt;
>> +import net.sf.json.JSONObject;
>> +import org.ofbiz.base.util.Debug;
>> +import org.ofbiz.base.util.UtilHttp;
>> +import org.ofbiz.base.util.UtilMisc;
>> +import org.ofbiz.base.util.UtilProperties;
>> +import org.ofbiz.base.util.UtilValidate;
>> +import org.ofbiz.common.authentication.api.AuthenticatorException;
>> +import org.ofbiz.common.login.LoginServices;
>> +import org.ofbiz.entity.Delegator;
>> +import org.ofbiz.entity.GenericEntityException;
>> +import org.ofbiz.entity.GenericValue;
>> +import org.ofbiz.entity.util.EntityUtil;
>> +import org.ofbiz.product.store.ProductStoreWorker;
>> +import org.ofbiz.service.LocalDispatcher;
>> +
>> +/**
>> + * GitHubEvents - Events for GitHub login.
>> + *
>> + * Refs: https://developer.github.com/v3/oauth/
>> + *
>> + */
>> +public class GitHubEvents {
>> +
>> +    public static final String module = GitHubEvents.class.getName();
>> +
>> +    public static final String resource = "PassportUiLabels";
>> +
>> +    public static final String AuthorizeUri = "/login/oauth/authorize";
>> +
>> +    public static final String TokenServiceUri =
>> "/login/oauth/access_token";
>> +
>> +    public static final String UserApiUri = "/user";
>> +
>> +    public static final String DEFAULT_SCOPE = "user,gist";
>> +
>> +    public static final String ApiEndpoint = "https://api.github.com";
>> +
>> +    public static final String TokenEndpoint = "https://github.com";
>> +
>> +    public static final String SESSION_GITHUB_STATE = "_GITHUB_STATE_";
>> +
>> +    public static final String envPrefix =
>> UtilProperties.getPropertyValue(GitHubAuthenticator.props,
>> "github.env.prefix", "test");
>> +
>> +    /**
>> +     * Redirect to GitHub login page.
>> +     *
>> +     * @return
>> +     */
>> +    public static String gitHubRedirect(HttpServletRequest request,
>> HttpServletResponse response) {
>> +        GenericValue oauth2GitHub = getOAuth2GitHubConfig(request);
>> +        if (UtilValidate.isEmpty(oauth2GitHub)) {
>> +            return "error";
>> +        }
>> +
>> +        String clientId =
>> oauth2GitHub.getString(PassportUtil.COMMON_CLIENT_ID);
>> +        String returnURI =
>> oauth2GitHub.getString(PassportUtil.COMMON_RETURN_RUL);
>> +
>> +        // Get user authorization code
>> +        try {
>> +            String state = System.currentTimeMillis() +
>> String.valueOf((new Random(10)).nextLong());
>> +            request.getSession().setAttribute(SESSION_GITHUB_STATE,
>> state);
>> +            String redirectUrl = TokenEndpoint + AuthorizeUri
>> +                    + "?client_id=" + clientId
>> +                    + "&scope=" + DEFAULT_SCOPE
>> +                    + "&redirect_uri=" + URLEncoder.encode(returnURI,
>> "UTF-8")
>> +                    + "&state=" + state;
>> +            Debug.logInfo("Request to GitHub: " + redirectUrl, module);
>> +            response.sendRedirect(redirectUrl);
>> +        } catch (NullPointerException e) {
>> +            String errMsg = UtilProperties.getMessage(resource,
>> "RedirectToGitHubOAuth2NullException", UtilHttp.getLocale(request));
>> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
>> +            return "error";
>> +        } catch (IOException e) {
>> +            Map<String, String> messageMap =
>> UtilMisc.toMap("errorMessage", e.toString());
>> +            String errMsg = UtilProperties.getMessage(resource,
>> "RedirectToGitHubOAuth2Error", messageMap, UtilHttp.getLocale(request));
>> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
>> +            return "error";
>> +        }
>> +
>> +        return "success";
>> +    }
>> +
>> +    /**
>> +     * Parse GitHub login response and login the user if possible.
>> +     *
>> +     * @return
>> +     */
>> +    public static String parseGitHubResponse(HttpServletRequest request,
>> HttpServletResponse response) {
>> +        String authorizationCode =
>> request.getParameter(PassportUtil.COMMON_CODE);
>> +        String state = request.getParameter(PassportUtil.COMMON_STATE);
>> +        if
>> (!state.equals(request.getSession().getAttribute(SESSION_GITHUB_STATE))) {
>> +            String errMsg = UtilProperties.getMessage(resource,
>> "GitHubFailedToMatchState", UtilHttp.getLocale(request));
>> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
>> +            return "error";
>> +        }
>> +        if (UtilValidate.isEmpty(authorizationCode)) {
>> +            String error =
>> request.getParameter(PassportUtil.COMMON_ERROR);
>> +            String errorDescpriton =
>> request.getParameter(PassportUtil.COMMON_ERROR_DESCRIPTION);
>> +            String errMsg = null;
>> +            try {
>> +                errMsg = UtilProperties.getMessage(resource,
>> "FailedToGetGitHubAuthorizationCode",
>> UtilMisc.toMap(PassportUtil.COMMON_ERROR, error,
>> PassportUtil.COMMON_ERROR_DESCRIPTION, URLDecoder.decode(errorDescpriton,
>> "UTF-8")), UtilHttp.getLocale(request));
>> +            } catch (UnsupportedEncodingException e) {
>> +                errMsg = UtilProperties.getMessage(resource,
>> "GetGitHubAuthorizationCodeError", UtilHttp.getLocale(request));
>> +            }
>> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
>> +            return "error";
>> +        }
>> +        Debug.logInfo("GitHub authorization code: " + authorizationCode,
>> module);
>> +
>> +        GenericValue oauth2GitHub = getOAuth2GitHubConfig(request);
>> +        if (UtilValidate.isEmpty(oauth2GitHub)) {
>> +            String errMsg = UtilProperties.getMessage(resource,
>> "GetOAuth2GitHubConfigError", UtilHttp.getLocale(request));
>> +            request.setAttribute("_ERROR_MESSAGE_", errMsg);
>> +            return "error";
>> +        }
>> +        String clientId =
>> oauth2GitHub.getString(PassportUtil.COMMON_CLIENT_ID);
>> +        String secret =
>> oauth2GitHub.getString(PassportUtil.COMMON_CLIENT_SECRET);
>> +        String returnURI =
>> oauth2GitHub.getString(PassportUtil.COMMON_RETURN_RUL);
>> +
>> +        // Grant token from authorization code and oauth2 token
>> +        // Use the authorization code to obtain an access token
>> +        String accessToken = null;
>> +        String tokenType = null;
>> +
>> +        HttpClient jsonClient = new HttpClient();
>> +        PostMethod postMethod = new PostMethod(TokenEndpoint +
>> TokenServiceUri);
>> +        try {
>> +            HttpMethodParams params = new HttpMethodParams();
>> +            String queryString = "client_id=" + clientId
>> +                    + "&client_secret=" + secret
>> +                    + "&code=" + authorizationCode
>> +                    + "&redirect_uri=" + URLEncoder.encode(returnURI,
>> "UTF-8");
>> +            // Debug.logInfo("GitHub get access token query string: " +
>> queryString, module);
>> +            postMethod.setQueryString(queryString);
>> +            params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
>> +            postMethod.setParams(params);
>> +            postMethod.setRequestHeader(PassportUtil.ACCEPT_HEADER,
>> "application/json");
>> +            jsonClient.executeMethod(postMethod);
>> +            // Debug.logInfo("GitHub get access token response code: " +
>> postMethod.getStatusCode(), module);
>> +            // Debug.logInfo("GitHub get access token response content:
>> " + postMethod.getResponseBodyAsString(1024), module);
>> +            if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
>> +                // Debug.logInfo("Json Response from GitHub: " +
>> postMethod.getResponseBodyAsString(1024), module);
>> +                JSONObject jsonObject =
>> JSONObject.fromObject(postMethod.getResponseBodyAsString(1024));
>> +                accessToken = jsonObject.getString("access_token");
>> +                tokenType = jsonObject.getString("token_type");
>> +                // Debug.logInfo("Generated Access Token : " +
>> accessToken, module);
>> +                // Debug.logInfo("Token Type: " + tokenType, module);
>> +            } else {
>> +                String errMsg = UtilProperties.getMessage(resource,
>> "GetOAuth2GitHubAccessTokenError", UtilMisc.toMap("error",
>> postMethod.getResponseBodyAsString()), UtilHttp.getLocale(request));
>> +                request.setAttribute("_ERROR_MESSAGE_", errMsg);
>> +                return "error";
>> +            }
>> +        } catch (UnsupportedEncodingException e) {
>> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
>> +            return "error";
>> +        } catch (HttpException e) {
>> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
>> +            return "error";
>> +        } catch (IOException e) {
>> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
>> +            return "error";
>> +        } finally {
>> +            postMethod.releaseConnection();
>> +        }
>> +
>> +        // Get User Profile
>> +        GetMethod getMethod = new GetMethod(ApiEndpoint + UserApiUri);
>> +        Map<String, Object> userInfo = null;
>> +        try {
>> +            userInfo = GitHubAuthenticator.getUserInfo(getMethod,
>> accessToken, tokenType, UtilHttp.getLocale(request));
>> +        } catch (HttpException e) {
>> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
>> +            return "error";
>> +        } catch (IOException e) {
>> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
>> +            return "error";
>> +        } catch (AuthenticatorException e) {
>> +            request.setAttribute("_ERROR_MESSAGE_", e.toString());
>> +            return "error";
>> +        } finally {
>> +            getMethod.releaseConnection();
>> +        }
>> +        // Debug.logInfo("GitHub User Info:" + userInfo, module);
>> +
>> +        // Store the user info and check login the user
>> +        return checkLoginGitHubUser(request, userInfo, accessToken);
>> +    }
>> +
>> +    private static String checkLoginGitHubUser(HttpServletRequest
>> request, Map<String, Object> userInfo, String accessToken) {
>
>