Commit 9651e0bcae09f224db69df907f281a39f3f1ae06
- Diff rendering mode:
- inline
- side by side
pom.xml
(32 / 1)
|   | |||
| 19 | 19 | <org.springframework-version>3.1.0.BUILD-SNAPSHOT</org.springframework-version> | |
| 20 | 20 | <org.springframework.security-version>3.0.3.RELEASE</org.springframework.security-version> <!-- 3.1.0.CI-SNAPSHOT once compatible with OAuth --> | |
| 21 | 21 | <org.springframework.integration-version>2.0.0.RC1</org.springframework.integration-version> | |
| 22 | <org.springframework.social-version>1.0.0.BUILD-SNAPSHOT</org.springframework.social-version> | ||
| 22 | 23 | <org.aspectj-version>1.6.9</org.aspectj-version> | |
| 23 | 24 | <org.slf4j-version>1.6.1</org.slf4j-version> | |
| 24 | 25 | </properties> | |
| … | … | ||
| 110 | 110 | </dependency> | |
| 111 | 111 | <dependency> | |
| 112 | 112 | <groupId>org.springframework.social</groupId> | |
| 113 | <artifactId>spring-social-connect</artifactId> | ||
| 114 | <version>${org.springframework.social-version}</version> | ||
| 115 | </dependency> | ||
| 116 | <dependency> | ||
| 117 | <groupId>org.springframework.social</groupId> | ||
| 113 | 118 | <artifactId>spring-social-core</artifactId> | |
| 114 | <version>1.0.0.M1</version> | ||
| 119 | <version>${org.springframework.social-version}</version> | ||
| 120 | </dependency> | ||
| 121 | <dependency> | ||
| 122 | <groupId>org.springframework.social</groupId> | ||
| 123 | <artifactId>spring-social-facebook</artifactId> | ||
| 124 | <version>${org.springframework.social-version}</version> | ||
| 125 | </dependency> | ||
| 126 | <dependency> | ||
| 127 | <groupId>org.springframework.social</groupId> | ||
| 128 | <artifactId>spring-social-linkedin</artifactId> | ||
| 129 | <version>${org.springframework.social-version}</version> | ||
| 130 | </dependency> | ||
| 131 | <dependency> | ||
| 132 | <groupId>org.springframework.social</groupId> | ||
| 133 | <artifactId>spring-social-oauth</artifactId> | ||
| 134 | <version>${org.springframework.social-version}</version> | ||
| 135 | </dependency> | ||
| 136 | <dependency> | ||
| 137 | <groupId>org.springframework.social</groupId> | ||
| 138 | <artifactId>spring-social-tripit</artifactId> | ||
| 139 | <version>${org.springframework.social-version}</version> | ||
| 140 | </dependency> | ||
| 141 | <dependency> | ||
| 142 | <groupId>org.springframework.social</groupId> | ||
| 143 | <artifactId>spring-social-twitter</artifactId> | ||
| 144 | <version>${org.springframework.social-version}</version> | ||
| 115 | 145 | </dependency> | |
| 116 | 146 | <dependency> | |
| 117 | 147 | <groupId>org.springframework.mobile</groupId> |
src/main/java/com/springsource/greenhouse/config/ServiceProvidersApiConfiguration.java
(1 / 1)
|   | |||
| 19 | 19 | import org.springframework.context.annotation.Bean; | |
| 20 | 20 | import org.springframework.context.annotation.Scope; | |
| 21 | 21 | import org.springframework.context.annotation.ScopedProxyMode; | |
| 22 | import org.springframework.social.connect.ServiceProvider; | ||
| 22 | 23 | import org.springframework.social.facebook.FacebookOperations; | |
| 23 | 24 | import org.springframework.social.linkedin.LinkedInOperations; | |
| 24 | 25 | import org.springframework.social.tripit.TripItOperations; | |
| 25 | 26 | import org.springframework.social.twitter.TwitterOperations; | |
| 26 | 27 | ||
| 27 | 28 | import com.springsource.greenhouse.account.Account; | |
| 28 | import com.springsource.greenhouse.connect.ServiceProvider; | ||
| 29 | 29 | ||
| 30 | 30 | /** | |
| 31 | 31 | * Exports a bean for each Service API used by Greenhouse. |
src/main/java/com/springsource/greenhouse/connect/AbstractServiceProvider.java
(0 / 185)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect; | ||
| 17 | |||
| 18 | import java.util.List; | ||
| 19 | |||
| 20 | import org.scribe.extractors.BaseStringExtractorImpl; | ||
| 21 | import org.scribe.extractors.HeaderExtractorImpl; | ||
| 22 | import org.scribe.extractors.TokenExtractorImpl; | ||
| 23 | import org.scribe.model.OAuthConfig; | ||
| 24 | import org.scribe.model.Token; | ||
| 25 | import org.scribe.model.Verb; | ||
| 26 | import org.scribe.model.Verifier; | ||
| 27 | import org.scribe.oauth.OAuth10aServiceImpl; | ||
| 28 | import org.scribe.oauth.OAuthService; | ||
| 29 | import org.scribe.services.HMACSha1SignatureService; | ||
| 30 | import org.scribe.services.TimestampServiceImpl; | ||
| 31 | import org.springframework.transaction.annotation.Transactional; | ||
| 32 | |||
| 33 | import com.springsource.greenhouse.account.Account; | ||
| 34 | import com.springsource.greenhouse.account.ProfileReference; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * General-purpose base class for ServiceProvider implementations. | ||
| 38 | * @author Keith Donald | ||
| 39 | * @param <S> The service API hosted by this service provider. | ||
| 40 | */ | ||
| 41 | public abstract class AbstractServiceProvider<S> implements ServiceProvider<S> { | ||
| 42 | |||
| 43 | private final ServiceProviderParameters parameters; | ||
| 44 | |||
| 45 | private final AccountConnectionRepository connectionRepository; | ||
| 46 | |||
| 47 | /** | ||
| 48 | * Creates a ServiceProvider. | ||
| 49 | * @param parameters the parameters needed to implement the behavior in this class | ||
| 50 | * @param connectionRepository a data access interface for managing account connection records | ||
| 51 | */ | ||
| 52 | public AbstractServiceProvider(ServiceProviderParameters parameters, AccountConnectionRepository connectionRepository) { | ||
| 53 | this.parameters = parameters; | ||
| 54 | this.connectionRepository = connectionRepository; | ||
| 55 | } | ||
| 56 | |||
| 57 | // provider meta-data | ||
| 58 | |||
| 59 | public String getName() { | ||
| 60 | return parameters.getName(); | ||
| 61 | } | ||
| 62 | |||
| 63 | public String getDisplayName() { | ||
| 64 | return parameters.getDisplayName(); | ||
| 65 | } | ||
| 66 | |||
| 67 | public String getApiKey() { | ||
| 68 | return parameters.getApiKey(); | ||
| 69 | } | ||
| 70 | |||
| 71 | public Long getAppId() { | ||
| 72 | return parameters.getAppId(); | ||
| 73 | } | ||
| 74 | |||
| 75 | // connection management | ||
| 76 | |||
| 77 | public OAuthToken fetchNewRequestToken(String callbackUrl) { | ||
| 78 | Token requestToken = getOAuthService(callbackUrl).getRequestToken(); | ||
| 79 | return new OAuthToken(requestToken.getToken(), requestToken.getSecret()); | ||
| 80 | } | ||
| 81 | |||
| 82 | public String buildAuthorizeUrl(String requestToken) { | ||
| 83 | return parameters.getAuthorizeUrl().expand(requestToken).toString(); | ||
| 84 | } | ||
| 85 | |||
| 86 | public void connect(Long accountId, AuthorizedRequestToken requestToken) { | ||
| 87 | OAuthToken accessToken = getAccessToken(requestToken); | ||
| 88 | S serviceOperations = createServiceOperations(accessToken); | ||
| 89 | String providerAccountId = fetchProviderAccountId(serviceOperations); | ||
| 90 | connectionRepository.addConnection(accountId, getName(), accessToken, providerAccountId, buildProviderProfileUrl(providerAccountId, serviceOperations)); | ||
| 91 | } | ||
| 92 | |||
| 93 | public void addConnection(Long accountId, String accessToken, String providerAccountId) { | ||
| 94 | OAuthToken oauthAccessToken = new OAuthToken(accessToken); | ||
| 95 | S serviceOperations = createServiceOperations(oauthAccessToken); | ||
| 96 | connectionRepository.addConnection(accountId, getName(), oauthAccessToken, providerAccountId, buildProviderProfileUrl(providerAccountId, serviceOperations)); | ||
| 97 | } | ||
| 98 | |||
| 99 | public boolean isConnected(Long accountId) { | ||
| 100 | return connectionRepository.isConnected(accountId, getName()); | ||
| 101 | } | ||
| 102 | |||
| 103 | public void disconnect(Long accountId) { | ||
| 104 | connectionRepository.disconnect(accountId, getName()); | ||
| 105 | } | ||
| 106 | |||
| 107 | @Transactional | ||
| 108 | public S getServiceOperations(Long accountId) { | ||
| 109 | if (accountId == null || !isConnected(accountId)) { | ||
| 110 | return createServiceOperations(null); | ||
| 111 | } | ||
| 112 | OAuthToken accessToken = connectionRepository.getAccessToken(accountId, getName()); | ||
| 113 | return createServiceOperations(accessToken); | ||
| 114 | } | ||
| 115 | |||
| 116 | // additional finders | ||
| 117 | |||
| 118 | public String getProviderAccountId(Long accountId) { | ||
| 119 | return connectionRepository.getProviderAccountId(accountId, getName()); | ||
| 120 | } | ||
| 121 | |||
| 122 | public Account findAccountByConnection(String accessToken) throws NoSuchAccountConnectionException { | ||
| 123 | return connectionRepository.findAccountByConnection(getName(), accessToken); | ||
| 124 | } | ||
| 125 | |||
| 126 | public List<ProfileReference> findMembersConnectedTo(List<String> providerAccountIds) { | ||
| 127 | return connectionRepository.findMembersConnectedTo(getName(), providerAccountIds); | ||
| 128 | } | ||
| 129 | |||
| 130 | // subclassing hooks | ||
| 131 | |||
| 132 | /** | ||
| 133 | * Construct the strongly-typed service API template that callers may use to invoke the service offered by this service provider. | ||
| 134 | * Subclasses should override to return their concrete service implementation. | ||
| 135 | * @param accessToken the granted access token needed to make authorized requests for protected resources | ||
| 136 | */ | ||
| 137 | protected abstract S createServiceOperations(OAuthToken accessToken); | ||
| 138 | |||
| 139 | /** | ||
| 140 | * Use the service API to fetch the id the member has been assigned in the provider's system. | ||
| 141 | * This id is stored locally to support linking to the user's connected profile page. | ||
| 142 | * It is also used for finding connected friends, see {@link #findMembersConnectedTo(List)}. | ||
| 143 | */ | ||
| 144 | protected abstract String fetchProviderAccountId(S serviceOperations); | ||
| 145 | |||
| 146 | /** | ||
| 147 | * Build the URL pointing to the member's public profile on the provider's system. | ||
| 148 | * @param providerAccountId the id the member is known by in the provider's system. | ||
| 149 | * @param serviceOperations the service API | ||
| 150 | */ | ||
| 151 | protected abstract String buildProviderProfileUrl(String providerAccountId, S serviceOperations); | ||
| 152 | |||
| 153 | /** | ||
| 154 | * The {@link #getApiKey() apiKey} secret. | ||
| 155 | */ | ||
| 156 | protected String getSecret() { | ||
| 157 | return parameters.getSecret(); | ||
| 158 | } | ||
| 159 | |||
| 160 | // internal helpers | ||
| 161 | |||
| 162 | private OAuthService getOAuthService() { | ||
| 163 | return getOAuthService(null); | ||
| 164 | } | ||
| 165 | |||
| 166 | private OAuthService getOAuthService(String callbackUrl) { | ||
| 167 | OAuthConfig config = new OAuthConfig(); | ||
| 168 | config.setRequestTokenEndpoint(parameters.getRequestTokenUrl()); | ||
| 169 | config.setAccessTokenEndpoint(parameters.getAccessTokenUrl()); | ||
| 170 | config.setAccessTokenVerb(Verb.POST); | ||
| 171 | config.setRequestTokenVerb(Verb.POST); | ||
| 172 | config.setApiKey(parameters.getApiKey()); | ||
| 173 | config.setApiSecret(parameters.getSecret()); | ||
| 174 | if (callbackUrl != null) { | ||
| 175 | config.setCallback(callbackUrl); | ||
| 176 | } | ||
| 177 | return new OAuth10aServiceImpl(new HMACSha1SignatureService(), new TimestampServiceImpl(), new BaseStringExtractorImpl(), new HeaderExtractorImpl(), new TokenExtractorImpl(), new TokenExtractorImpl(), config); | ||
| 178 | } | ||
| 179 | |||
| 180 | private OAuthToken getAccessToken(AuthorizedRequestToken requestToken) { | ||
| 181 | Token accessToken = getOAuthService().getAccessToken(new Token(requestToken.getValue(), requestToken.getSecret()), new Verifier(requestToken.getVerifier())); | ||
| 182 | return new OAuthToken(accessToken.getToken(), accessToken.getSecret()); | ||
| 183 | } | ||
| 184 | |||
| 185 | } |
src/main/java/com/springsource/greenhouse/connect/AccountConnectionRepository.java
(0 / 44)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect; | ||
| 17 | |||
| 18 | import java.util.List; | ||
| 19 | |||
| 20 | import com.springsource.greenhouse.account.Account; | ||
| 21 | import com.springsource.greenhouse.account.ProfileReference; | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Strategy for storing account connection information. | ||
| 25 | * Delegated to {@link AbstractServiceProvider} to decouple the provider implementation from any physical connection store. | ||
| 26 | * @author Keith Donald | ||
| 27 | */ | ||
| 28 | public interface AccountConnectionRepository { | ||
| 29 | |||
| 30 | void addConnection(Long accountId, String provider, OAuthToken accessToken, String providerAccountId, String providerProfileUrl); | ||
| 31 | |||
| 32 | boolean isConnected(Long accountId, String provider); | ||
| 33 | |||
| 34 | void disconnect(Long accountId, String provider); | ||
| 35 | |||
| 36 | OAuthToken getAccessToken(Long accountId, String provider); | ||
| 37 | |||
| 38 | String getProviderAccountId(Long accountId, String provider); | ||
| 39 | |||
| 40 | Account findAccountByConnection(String provider, String accessToken) throws NoSuchAccountConnectionException; | ||
| 41 | |||
| 42 | List<ProfileReference> findMembersConnectedTo(String provider, List<String> providerAccountIds); | ||
| 43 | |||
| 44 | } |
src/main/java/com/springsource/greenhouse/connect/AuthorizedRequestToken.java
(0 / 64)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect; | ||
| 17 | |||
| 18 | /** | ||
| 19 | * A OAuth request token that has been authorized by the user. | ||
| 20 | * Constructed after the user grants the consumer application access to their data hosted at the service provider. | ||
| 21 | * This is typically achieved by the user clicking "Allow" over at the provider's site. | ||
| 22 | * With OAuth 1.0, the service provider returns a Verifier string in the authorization callback that must also be submitted in the access token request. | ||
| 23 | * @author Keith Donald | ||
| 24 | */ | ||
| 25 | public class AuthorizedRequestToken { | ||
| 26 | |||
| 27 | private final OAuthToken requestToken; | ||
| 28 | |||
| 29 | private final String verifier; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * Creates an authorized request token. | ||
| 33 | * @param requestToken the request token object | ||
| 34 | * @param verifier the verifier returned by the provider after user authorization (OAuth 1.0 only) | ||
| 35 | */ | ||
| 36 | public AuthorizedRequestToken(OAuthToken requestToken, String verifier) { | ||
| 37 | this.requestToken = requestToken; | ||
| 38 | this.verifier = verifier; | ||
| 39 | } | ||
| 40 | |||
| 41 | /** | ||
| 42 | * The request token value. | ||
| 43 | */ | ||
| 44 | public String getValue() { | ||
| 45 | return requestToken.getValue(); | ||
| 46 | } | ||
| 47 | |||
| 48 | /** | ||
| 49 | * The request token secret. | ||
| 50 | * OAuth 1.0 only. | ||
| 51 | */ | ||
| 52 | public String getSecret() { | ||
| 53 | return requestToken.getSecret(); | ||
| 54 | } | ||
| 55 | |||
| 56 | /** | ||
| 57 | * The verifier string generated by the provider. | ||
| 58 | * OAuth 1.0 only. | ||
| 59 | */ | ||
| 60 | public String getVerifier() { | ||
| 61 | return verifier; | ||
| 62 | } | ||
| 63 | |||
| 64 | } |
src/main/java/com/springsource/greenhouse/connect/ConnectController.java
(4 / 0)
|   | |||
| 22 | 22 | ||
| 23 | 23 | import org.springframework.beans.factory.annotation.Value; | |
| 24 | 24 | import org.springframework.core.GenericTypeResolver; | |
| 25 | import org.springframework.social.connect.AuthorizedRequestToken; | ||
| 26 | import org.springframework.social.connect.OAuthToken; | ||
| 27 | import org.springframework.social.connect.ServiceProvider; | ||
| 28 | import org.springframework.social.connect.ServiceProviderFactory; | ||
| 25 | 29 | import org.springframework.stereotype.Controller; | |
| 26 | 30 | import org.springframework.util.LinkedMultiValueMap; | |
| 27 | 31 | import org.springframework.util.MultiValueMap; |
src/main/java/com/springsource/greenhouse/connect/ConnectInterceptor.java
(1 / 0)
|   | |||
| 15 | 15 | */ | |
| 16 | 16 | package com.springsource.greenhouse.connect; | |
| 17 | 17 | ||
| 18 | import org.springframework.social.connect.ServiceProvider; | ||
| 18 | 19 | import org.springframework.web.context.request.WebRequest; | |
| 19 | 20 | ||
| 20 | 21 | import com.springsource.greenhouse.account.Account; |
src/main/java/com/springsource/greenhouse/connect/JdbcAccountConnectionRepository.java
(0 / 120)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect; | ||
| 17 | |||
| 18 | import java.sql.ResultSet; | ||
| 19 | import java.sql.SQLException; | ||
| 20 | import java.util.HashMap; | ||
| 21 | import java.util.List; | ||
| 22 | import java.util.Map; | ||
| 23 | |||
| 24 | import org.springframework.dao.EmptyResultDataAccessException; | ||
| 25 | import org.springframework.jdbc.core.JdbcTemplate; | ||
| 26 | import org.springframework.jdbc.core.RowMapper; | ||
| 27 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; | ||
| 28 | import org.springframework.security.encrypt.StringEncryptor; | ||
| 29 | import org.springframework.stereotype.Repository; | ||
| 30 | |||
| 31 | import com.springsource.greenhouse.account.Account; | ||
| 32 | import com.springsource.greenhouse.account.AccountMapper; | ||
| 33 | import com.springsource.greenhouse.account.ProfileReference; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * Stores Account connection information in a relational database using the JDBC API. | ||
| 37 | * @author Keith Donald | ||
| 38 | */ | ||
| 39 | @Repository | ||
| 40 | public class JdbcAccountConnectionRepository implements AccountConnectionRepository { | ||
| 41 | |||
| 42 | private final JdbcTemplate jdbcTemplate; | ||
| 43 | |||
| 44 | private final StringEncryptor encryptor; | ||
| 45 | |||
| 46 | private final AccountMapper accountMapper; | ||
| 47 | |||
| 48 | public JdbcAccountConnectionRepository(JdbcTemplate jdbcTemplate, StringEncryptor encryptor, AccountMapper accountMapper) { | ||
| 49 | this.jdbcTemplate = jdbcTemplate; | ||
| 50 | this.encryptor = encryptor; | ||
| 51 | this.accountMapper = accountMapper; | ||
| 52 | } | ||
| 53 | |||
| 54 | public void addConnection(Long accountId, String provider, OAuthToken accessToken, String providerAccountId, String providerProfileUrl) { | ||
| 55 | jdbcTemplate.update(INSERT_ACCOUNT_CONNECTION, accountId, provider, encryptor.encrypt(accessToken.getValue()), encryptIfPresent(accessToken.getSecret()), providerAccountId, providerProfileUrl); | ||
| 56 | } | ||
| 57 | |||
| 58 | public boolean isConnected(Long accountId, String provider) { | ||
| 59 | return jdbcTemplate.queryForInt(SELECT_ACCOUNT_CONNECTION_COUNT, accountId, provider) == 1; | ||
| 60 | } | ||
| 61 | |||
| 62 | public void disconnect(Long accountId, String provider) { | ||
| 63 | jdbcTemplate.update(DELETE_ACCOUNT_CONNECTION, accountId, provider); | ||
| 64 | } | ||
| 65 | |||
| 66 | public OAuthToken getAccessToken(Long accountId, String provider) { | ||
| 67 | return jdbcTemplate.queryForObject(SELECT_ACCESS_TOKEN, new RowMapper<OAuthToken>() { | ||
| 68 | public OAuthToken mapRow(ResultSet rs, int rowNum) throws SQLException { | ||
| 69 | return new OAuthToken(encryptor.decrypt(rs.getString("accessToken")), decryptIfPresent(rs.getString("secret"))); | ||
| 70 | } | ||
| 71 | }, accountId, provider); | ||
| 72 | } | ||
| 73 | |||
| 74 | public String getProviderAccountId(Long accountId, String provider) { | ||
| 75 | try { | ||
| 76 | return jdbcTemplate.queryForObject(SELECT_PROVIDER_ACCOUNT_ID, String.class, accountId, provider); | ||
| 77 | } catch (EmptyResultDataAccessException e) { | ||
| 78 | return null; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | public Account findAccountByConnection(String provider, String accessToken) throws NoSuchAccountConnectionException { | ||
| 83 | try { | ||
| 84 | return jdbcTemplate.queryForObject(AccountMapper.SELECT_ACCOUNT + " where id = (select member from AccountConnection where provider = ? and accessToken = ?)", accountMapper, provider, encryptor.encrypt(accessToken)); | ||
| 85 | } catch (EmptyResultDataAccessException e) { | ||
| 86 | throw new NoSuchAccountConnectionException(accessToken); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | public List<ProfileReference> findMembersConnectedTo(String provider, List<String> providerAccountIds) { | ||
| 91 | NamedParameterJdbcTemplate namedTemplate = new NamedParameterJdbcTemplate(jdbcTemplate); | ||
| 92 | Map<String, Object> params = new HashMap<String, Object>(2, 1); | ||
| 93 | params.put("provider", provider); | ||
| 94 | params.put("providerAccountIds", providerAccountIds); | ||
| 95 | return namedTemplate.query(SELECT_ACCOUNTS_CONNECTED_TO, params, accountMapper.getReferenceMapper()); | ||
| 96 | } | ||
| 97 | |||
| 98 | // internal helpers | ||
| 99 | |||
| 100 | private String encryptIfPresent(String string) { | ||
| 101 | return string != null ? encryptor.encrypt(string) : null; | ||
| 102 | } | ||
| 103 | |||
| 104 | private String decryptIfPresent(String string) { | ||
| 105 | return string != null ? encryptor.decrypt(string) : null; | ||
| 106 | } | ||
| 107 | |||
| 108 | private static final String SELECT_PROVIDER_ACCOUNT_ID = "select accountId from AccountConnection where member = ? and provider = ?"; | ||
| 109 | |||
| 110 | private static final String SELECT_ACCOUNT_CONNECTION_COUNT = "select exists(select 1 from AccountConnection where member = ? and provider = ?)"; | ||
| 111 | |||
| 112 | private static final String INSERT_ACCOUNT_CONNECTION = "insert into AccountConnection (member, provider, accessToken, secret, accountId, profileUrl) values (?, ?, ?, ?, ?, ?)"; | ||
| 113 | |||
| 114 | private static final String DELETE_ACCOUNT_CONNECTION = "delete from AccountConnection where member = ? and provider = ?"; | ||
| 115 | |||
| 116 | private static final String SELECT_ACCESS_TOKEN = "select accessToken, secret from AccountConnection where member = ? and provider = ?"; | ||
| 117 | |||
| 118 | private static final String SELECT_ACCOUNTS_CONNECTED_TO = AccountMapper.SELECT_ACCOUNT_REFERENCE + " where id in (select member from AccountConnection where provider = :provider and accountId in ( :providerAccountIds ))"; | ||
| 119 | |||
| 120 | } |
src/main/java/com/springsource/greenhouse/connect/JdbcServiceProviderFactory.java
(0 / 93)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect; | ||
| 17 | |||
| 18 | import java.lang.reflect.Constructor; | ||
| 19 | import java.sql.ResultSet; | ||
| 20 | import java.sql.SQLException; | ||
| 21 | |||
| 22 | import org.springframework.beans.BeanUtils; | ||
| 23 | import org.springframework.beans.factory.annotation.Autowired; | ||
| 24 | import org.springframework.jdbc.core.JdbcTemplate; | ||
| 25 | import org.springframework.jdbc.core.RowMapper; | ||
| 26 | import org.springframework.security.encrypt.StringEncryptor; | ||
| 27 | import org.springframework.stereotype.Repository; | ||
| 28 | import org.springframework.util.ClassUtils; | ||
| 29 | |||
| 30 | import com.springsource.greenhouse.account.AccountMapper; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * Loads ServiceProvider records from a relational database using the JDBC API. | ||
| 34 | * @author Keith Donald | ||
| 35 | */ | ||
| 36 | @Repository | ||
| 37 | public class JdbcServiceProviderFactory implements ServiceProviderFactory { | ||
| 38 | |||
| 39 | private final JdbcTemplate jdbcTemplate; | ||
| 40 | |||
| 41 | private final StringEncryptor encryptor; | ||
| 42 | |||
| 43 | private final JdbcAccountConnectionRepository connectionRepository; | ||
| 44 | |||
| 45 | @Autowired | ||
| 46 | public JdbcServiceProviderFactory(JdbcTemplate jdbcTemplate, StringEncryptor encryptor, AccountMapper accountMapper) { | ||
| 47 | this.jdbcTemplate = jdbcTemplate; | ||
| 48 | this.encryptor = encryptor; | ||
| 49 | this.connectionRepository = new JdbcAccountConnectionRepository(jdbcTemplate, encryptor, accountMapper); | ||
| 50 | } | ||
| 51 | |||
| 52 | public ServiceProvider<?> getServiceProvider(String name) { | ||
| 53 | return jdbcTemplate.queryForObject(SELECT_SERVICE_PROVIDER_BY_NAME, new RowMapper<ServiceProvider<?>>() { | ||
| 54 | public ServiceProvider<?> mapRow(ResultSet rs, int rowNum) throws SQLException { | ||
| 55 | ServiceProviderParameters parameters = parametersMapper.mapRow(rs, rowNum); | ||
| 56 | Class<? extends ServiceProvider<?>> implementation = getImplementationClass(rs.getString("implementation")); | ||
| 57 | Constructor<? extends ServiceProvider<?>> constructor = ClassUtils.getConstructorIfAvailable(implementation, ServiceProviderParameters.class, AccountConnectionRepository.class); | ||
| 58 | return BeanUtils.instantiateClass(constructor, parameters, connectionRepository); | ||
| 59 | } | ||
| 60 | }, name); | ||
| 61 | } | ||
| 62 | |||
| 63 | @SuppressWarnings("unchecked") | ||
| 64 | public <S> ServiceProvider<S> getServiceProvider(String name, Class<S> serviceType) { | ||
| 65 | ServiceProvider<?> provider = getServiceProvider(name); | ||
| 66 | return (ServiceProvider<S>) provider; | ||
| 67 | } | ||
| 68 | |||
| 69 | // internal helpers | ||
| 70 | |||
| 71 | @SuppressWarnings("unchecked") | ||
| 72 | private Class<? extends ServiceProvider<?>> getImplementationClass(String implementation) { | ||
| 73 | try { | ||
| 74 | Class<?> clazz = ClassUtils.forName(implementation, JdbcServiceProviderFactory.class.getClassLoader()); | ||
| 75 | if (!ServiceProvider.class.isAssignableFrom(clazz)) { | ||
| 76 | throw new IllegalStateException("Implementation '" + implementation + "' does not implement the ServiceProvider interface"); | ||
| 77 | } | ||
| 78 | return (Class<? extends ServiceProvider<?>>)clazz; | ||
| 79 | } catch (ClassNotFoundException e) { | ||
| 80 | throw new IllegalStateException("The ServiceProvider implementation was not found in the classpath", e); | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | private RowMapper<ServiceProviderParameters> parametersMapper = new RowMapper<ServiceProviderParameters>() { | ||
| 85 | public ServiceProviderParameters mapRow(ResultSet rs, int rowNum) throws SQLException { | ||
| 86 | return new ServiceProviderParameters(rs.getString("name"), rs.getString("displayName"), encryptor.decrypt(rs.getString("apiKey")), encryptor.decrypt(rs.getString("secret")), | ||
| 87 | rs.getLong("appId"), rs.getString("requestTokenUrl"), rs.getString("authorizeUrl"), rs.getString("accessTokenUrl")); | ||
| 88 | } | ||
| 89 | }; | ||
| 90 | |||
| 91 | private static final String SELECT_SERVICE_PROVIDER_BY_NAME = "select name, displayName, implementation, apiKey, secret, appId, requestTokenUrl, authorizeUrl, accessTokenUrl from ServiceProvider where name = ?"; | ||
| 92 | |||
| 93 | } |
src/main/java/com/springsource/greenhouse/connect/OAuthToken.java
(0 / 55)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect; | ||
| 17 | |||
| 18 | /** | ||
| 19 | * Holds an OAuth token and secret. | ||
| 20 | * Used for both the request token and access token. | ||
| 21 | * The secret is null for OAuth2-based connections. | ||
| 22 | * @author Keith Donald | ||
| 23 | */ | ||
| 24 | public final class OAuthToken { | ||
| 25 | |||
| 26 | private final String value; | ||
| 27 | |||
| 28 | private final String secret; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Create a new OAuth token with a token value and null secret. | ||
| 32 | * Use this for OAuth 2. | ||
| 33 | */ | ||
| 34 | public OAuthToken(String value) { | ||
| 35 | this(value, null); | ||
| 36 | } | ||
| 37 | |||
| 38 | /** | ||
| 39 | * Create a new OAuth token with a token value and secret. | ||
| 40 | * Use this for OAuth 1. | ||
| 41 | */ | ||
| 42 | public OAuthToken(String value, String secret) { | ||
| 43 | this.value = value; | ||
| 44 | this.secret = secret; | ||
| 45 | } | ||
| 46 | |||
| 47 | public String getValue() { | ||
| 48 | return value; | ||
| 49 | } | ||
| 50 | |||
| 51 | public String getSecret() { | ||
| 52 | return secret; | ||
| 53 | } | ||
| 54 | |||
| 55 | } |
src/main/java/com/springsource/greenhouse/connect/ServiceProvider.java
(0 / 141)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect; | ||
| 17 | |||
| 18 | import java.util.List; | ||
| 19 | |||
| 20 | import com.springsource.greenhouse.account.Account; | ||
| 21 | import com.springsource.greenhouse.account.ProfileReference; | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Models the provider of a service that local member accounts may connect to and invoke. | ||
| 25 | * Exposes service provider metadata along with connection management operations that allow for account connections to be established. | ||
| 26 | * Also acts as a factory for a strongly-typed service API (S). | ||
| 27 | * Once a connection with this provider is established, the service API can be used by the application to invoke the service on behalf of the member. | ||
| 28 | * @author Keith Donald | ||
| 29 | * @param <S> The service API hosted by this service provider. | ||
| 30 | */ | ||
| 31 | public interface ServiceProvider<S> { | ||
| 32 | |||
| 33 | // provider meta-data | ||
| 34 | |||
| 35 | /** | ||
| 36 | * The unique name or id of the service provider e.g. twitter. | ||
| 37 | * Unique across all service providers. | ||
| 38 | */ | ||
| 39 | String getName(); | ||
| 40 | |||
| 41 | /** | ||
| 42 | * A label suitable for display in a UI, typically used to inform the user which service providers he or she has connected with / may connect with. e.g. Twitter. | ||
| 43 | */ | ||
| 44 | String getDisplayName(); | ||
| 45 | |||
| 46 | /** | ||
| 47 | * The key used to identify the local application with the remote service provider. | ||
| 48 | * Used when establishing an account connection with the service provider. | ||
| 49 | * Available as a public property to support client code that wishes to manage the service connection process itself, for example, in JavaScript. | ||
| 50 | * The term "API key" is derived from the OAuth 2 specification. | ||
| 51 | */ | ||
| 52 | String getApiKey(); | ||
| 53 | |||
| 54 | /** | ||
| 55 | * An alternate identifier for the local application in the remote service provider's system. | ||
| 56 | * May be null of no such alternate identifier exists. | ||
| 57 | * Used by ServiceProvider<FacebookOperations> to support "Like" functionality. | ||
| 58 | * @return an alternate app id, or null if no alternate id exists (null is the typical case, as the {@link #getApiKey()} is the primary means of consumer identification) | ||
| 59 | */ | ||
| 60 | Long getAppId(); | ||
| 61 | |||
| 62 | // connection management | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Begin the account connection process by fetching a new request token from this service provider. | ||
| 66 | * The new token should be stored in the member's session up until the authorization callback is made and it's time to {@link #connect(Long, AuthorizedRequestToken) connect}. | ||
| 67 | * @param callbackUrl the URL the provider should redirect to after the member authorizes the connection (may be null for OAuth 1.0-based service providers) | ||
| 68 | */ | ||
| 69 | OAuthToken fetchNewRequestToken(String callbackUrl); | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Construct the URL to redirect the member to for connection authorization. | ||
| 73 | * @param requestToken the request token value, to be encoded in the authorize URL | ||
| 74 | * @return the absolute authorize URL to redirect the member to for authorization | ||
| 75 | */ | ||
| 76 | String buildAuthorizeUrl(String requestToken); | ||
| 77 | |||
| 78 | /** | ||
| 79 | * Connects a member account to this service provider. | ||
| 80 | * Called after the user authorizes the connection at the {@link #buildAuthorizeUrl(String) authorizeUrl} and the service provider calls us back. | ||
| 81 | * Internally, exchanges the authorized request token for an access token, then stores the awarded access token with the member account. | ||
| 82 | * This access token identifies the connection between the member account and this service provider. | ||
| 83 | * <p> | ||
| 84 | * This method completes the OAuth-based account connection process. | ||
| 85 | * {@link #getServiceOperations(Long)} may now be called to get and invoke the service provider's API. | ||
| 86 | * The requestToken required during the connection handshake is no longer valid and cannot be reused. | ||
| 87 | * @param accountId the member account identifier | ||
| 88 | * @param requestToken the OAuth request token that was authorized by the member. | ||
| 89 | */ | ||
| 90 | void connect(Long accountId, AuthorizedRequestToken requestToken); | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Records an existing connection between a member account and this service provider. | ||
| 94 | * Use when the connection process happens outside of the control of this package; for example, in JavaScript. | ||
| 95 | * @param accountId the member account identifier | ||
| 96 | * @param accessToken the access token that was granted as a result of the connection | ||
| 97 | * @param providerAccountId the id of the user in the provider's system; may be an assigned number or a user-selected screen name. | ||
| 98 | */ | ||
| 99 | void addConnection(Long accountId, String accessToken, String providerAccountId); | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Returns true if the member account is connected to this provider, false otherwise. | ||
| 103 | */ | ||
| 104 | boolean isConnected(Long accountId); | ||
| 105 | |||
| 106 | /** | ||
| 107 | * Gets a handle to the API offered by this service provider. | ||
| 108 | * This API may be used by the application to invoke the service on behalf of a member. | ||
| 109 | * @param accountId the member account identifier (may be null, if so, only operations that require no authorization may be invoked) | ||
| 110 | */ | ||
| 111 | S getServiceOperations(Long accountId); | ||
| 112 | |||
| 113 | /** | ||
| 114 | * Sever the connection between the member account and this service provider. | ||
| 115 | * Has no effect if no connection is established to begin with. | ||
| 116 | */ | ||
| 117 | void disconnect(Long accountId); | ||
| 118 | |||
| 119 | // additional finders | ||
| 120 | |||
| 121 | /** | ||
| 122 | * The id of the member in the provider's system. | ||
| 123 | * May be an assigned internal identifier, such as a sequence number, or a user-selected screen name. | ||
| 124 | * Generally unique across accounts registered with this provider. | ||
| 125 | */ | ||
| 126 | String getProviderAccountId(Long accountId); | ||
| 127 | |||
| 128 | /** | ||
| 129 | * Authenticate a member Account by a connection established with this service provider. | ||
| 130 | * Used to support "Sign in using Facebook"-type scenarios, where the access token identifying a connection is available to client code, typically a cookie managed by JavaScript. | ||
| 131 | * @throws NoSuchAccountConnectionException no such connection has been established between a member and this service provider | ||
| 132 | */ | ||
| 133 | Account findAccountByConnection(String accessToken) throws NoSuchAccountConnectionException; | ||
| 134 | |||
| 135 | /** | ||
| 136 | * Find the members connected to this provider that have the specified account ids in the provider's system. | ||
| 137 | * Used to see which of your friends in the provider's network also have member accounts with the local application. | ||
| 138 | */ | ||
| 139 | List<ProfileReference> findMembersConnectedTo(List<String> providerAccountIds); | ||
| 140 | |||
| 141 | } |
src/main/java/com/springsource/greenhouse/connect/ServiceProviderFactory.java
(0 / 34)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect; | ||
| 17 | |||
| 18 | /** | ||
| 19 | * Factory for obtaining ServiceProviders by name. | ||
| 20 | * @author Keith Donald | ||
| 21 | */ | ||
| 22 | public interface ServiceProviderFactory { | ||
| 23 | |||
| 24 | /** | ||
| 25 | * Get the ServiceProvider identified by the provided name. | ||
| 26 | */ | ||
| 27 | ServiceProvider<?> getServiceProvider(String name); | ||
| 28 | |||
| 29 | /** | ||
| 30 | * Get a strongly-typed reference to the ServiceProvider identified by the provided name. | ||
| 31 | */ | ||
| 32 | <S> ServiceProvider<S> getServiceProvider(String name, Class<S> serviceType); | ||
| 33 | |||
| 34 | } |
src/main/java/com/springsource/greenhouse/connect/ServiceProviderParameters.java
(0 / 86)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect; | ||
| 17 | |||
| 18 | import org.springframework.web.util.UriTemplate; | ||
| 19 | |||
| 20 | /** | ||
| 21 | * Holder for common ServiceProvider parameters. | ||
| 22 | * Used by {@link AbstractServiceProvider} to access provider state in a manageable way. | ||
| 23 | * @author Keith Donald | ||
| 24 | */ | ||
| 25 | public class ServiceProviderParameters { | ||
| 26 | |||
| 27 | private final String name; | ||
| 28 | |||
| 29 | private final String displayName; | ||
| 30 | |||
| 31 | private final String apiKey; | ||
| 32 | |||
| 33 | private final String secret; | ||
| 34 | |||
| 35 | private final Long appId; | ||
| 36 | |||
| 37 | private final String requestTokenUrl; | ||
| 38 | |||
| 39 | private final UriTemplate authorizeUrl; | ||
| 40 | |||
| 41 | private final String accessTokenUrl; | ||
| 42 | |||
| 43 | public ServiceProviderParameters(String name, String displayName, String apiKey, String secret, Long appId, String requestTokenUrl, String authorizeUrl, String accessTokenUrl) { | ||
| 44 | this.name = name; | ||
| 45 | this.displayName = displayName; | ||
| 46 | this.apiKey = apiKey; | ||
| 47 | this.secret = secret; | ||
| 48 | this.appId = appId; | ||
| 49 | this.requestTokenUrl = requestTokenUrl; | ||
| 50 | this.authorizeUrl = authorizeUrl != null ? new UriTemplate(authorizeUrl) : null; | ||
| 51 | this.accessTokenUrl = accessTokenUrl; | ||
| 52 | } | ||
| 53 | |||
| 54 | public String getName() { | ||
| 55 | return name; | ||
| 56 | } | ||
| 57 | |||
| 58 | public String getDisplayName() { | ||
| 59 | return displayName; | ||
| 60 | } | ||
| 61 | |||
| 62 | public String getApiKey() { | ||
| 63 | return apiKey; | ||
| 64 | } | ||
| 65 | |||
| 66 | public String getSecret() { | ||
| 67 | return secret; | ||
| 68 | } | ||
| 69 | |||
| 70 | public Long getAppId() { | ||
| 71 | return appId; | ||
| 72 | } | ||
| 73 | |||
| 74 | public String getRequestTokenUrl() { | ||
| 75 | return requestTokenUrl; | ||
| 76 | } | ||
| 77 | |||
| 78 | public UriTemplate getAuthorizeUrl() { | ||
| 79 | return authorizeUrl; | ||
| 80 | } | ||
| 81 | |||
| 82 | public String getAccessTokenUrl() { | ||
| 83 | return accessTokenUrl; | ||
| 84 | } | ||
| 85 | |||
| 86 | } |
src/main/java/com/springsource/greenhouse/connect/providers/FacebookConnectController.java
(1 / 1)
|   | |||
| 21 | 21 | import javax.servlet.http.HttpServletRequest; | |
| 22 | 22 | ||
| 23 | 23 | import org.springframework.security.core.Authentication; | |
| 24 | import org.springframework.social.connect.ServiceProvider; | ||
| 24 | 25 | import org.springframework.social.facebook.FacebookAccessToken; | |
| 25 | 26 | import org.springframework.social.facebook.FacebookLink; | |
| 26 | 27 | import org.springframework.social.facebook.FacebookOperations; | |
| … | … | ||
| 34 | 34 | import org.springframework.web.flash.FlashMap; | |
| 35 | 35 | ||
| 36 | 36 | import com.springsource.greenhouse.account.Account; | |
| 37 | import com.springsource.greenhouse.connect.ServiceProvider; | ||
| 38 | 37 | import com.springsource.greenhouse.members.ProfilePictureService; | |
| 39 | 38 | ||
| 40 | 39 | /** |
src/main/java/com/springsource/greenhouse/connect/providers/FacebookServiceProvider.java
(0 / 51)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect.providers; | ||
| 17 | |||
| 18 | import org.springframework.social.facebook.FacebookOperations; | ||
| 19 | import org.springframework.social.facebook.FacebookTemplate; | ||
| 20 | |||
| 21 | import com.springsource.greenhouse.connect.AbstractServiceProvider; | ||
| 22 | import com.springsource.greenhouse.connect.AccountConnectionRepository; | ||
| 23 | import com.springsource.greenhouse.connect.ServiceProviderParameters; | ||
| 24 | import com.springsource.greenhouse.connect.OAuthToken; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Facebook ServiceProvider implementation. | ||
| 28 | * @author Keith Donald | ||
| 29 | */ | ||
| 30 | public final class FacebookServiceProvider extends AbstractServiceProvider<FacebookOperations> { | ||
| 31 | |||
| 32 | public FacebookServiceProvider(ServiceProviderParameters parameters, AccountConnectionRepository connectionRepository) { | ||
| 33 | super(parameters, connectionRepository); | ||
| 34 | } | ||
| 35 | |||
| 36 | protected FacebookOperations createServiceOperations(OAuthToken accessToken) { | ||
| 37 | if (accessToken == null) { | ||
| 38 | throw new IllegalStateException("Cannot access Facebook without an access token"); | ||
| 39 | } | ||
| 40 | return new FacebookTemplate(accessToken.getValue()); | ||
| 41 | } | ||
| 42 | |||
| 43 | protected String fetchProviderAccountId(FacebookOperations facebook) { | ||
| 44 | return facebook.getProfileId(); | ||
| 45 | } | ||
| 46 | |||
| 47 | protected String buildProviderProfileUrl(String facebookId, FacebookOperations facebook) { | ||
| 48 | return "http://www.facebook.com/profile.php?id=" + facebookId; | ||
| 49 | } | ||
| 50 | |||
| 51 | } |
src/main/java/com/springsource/greenhouse/connect/providers/LinkedInServiceProvider.java
(0 / 51)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect.providers; | ||
| 17 | |||
| 18 | import org.springframework.social.linkedin.LinkedInOperations; | ||
| 19 | import org.springframework.social.linkedin.LinkedInTemplate; | ||
| 20 | |||
| 21 | import com.springsource.greenhouse.connect.AbstractServiceProvider; | ||
| 22 | import com.springsource.greenhouse.connect.AccountConnectionRepository; | ||
| 23 | import com.springsource.greenhouse.connect.ServiceProviderParameters; | ||
| 24 | import com.springsource.greenhouse.connect.OAuthToken; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * LinkedIn ServiceProvider implementation. | ||
| 28 | * @author Keith Donald | ||
| 29 | */ | ||
| 30 | public final class LinkedInServiceProvider extends AbstractServiceProvider<LinkedInOperations> { | ||
| 31 | |||
| 32 | public LinkedInServiceProvider(ServiceProviderParameters parameters, AccountConnectionRepository connectionRepository) { | ||
| 33 | super(parameters, connectionRepository); | ||
| 34 | } | ||
| 35 | |||
| 36 | protected LinkedInOperations createServiceOperations(OAuthToken accessToken) { | ||
| 37 | if (accessToken == null) { | ||
| 38 | throw new IllegalStateException("Cannot access LinkedIn without an access token"); | ||
| 39 | } | ||
| 40 | return new LinkedInTemplate(getApiKey(), getSecret(), accessToken.getValue(), accessToken.getSecret()); | ||
| 41 | } | ||
| 42 | |||
| 43 | protected String fetchProviderAccountId(LinkedInOperations linkedIn) { | ||
| 44 | return linkedIn.getProfileId(); | ||
| 45 | } | ||
| 46 | |||
| 47 | protected String buildProviderProfileUrl(String linkedInId, LinkedInOperations linkedIn) { | ||
| 48 | return linkedIn.getProfileUrl(); | ||
| 49 | } | ||
| 50 | |||
| 51 | } |
src/main/java/com/springsource/greenhouse/connect/providers/TripItServiceProvider.java
(0 / 51)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect.providers; | ||
| 17 | |||
| 18 | import org.springframework.social.tripit.TripItOperations; | ||
| 19 | import org.springframework.social.tripit.TripItTemplate; | ||
| 20 | |||
| 21 | import com.springsource.greenhouse.connect.AbstractServiceProvider; | ||
| 22 | import com.springsource.greenhouse.connect.AccountConnectionRepository; | ||
| 23 | import com.springsource.greenhouse.connect.ServiceProviderParameters; | ||
| 24 | import com.springsource.greenhouse.connect.OAuthToken; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * TripIt ServiceProvider implementation. | ||
| 28 | * @author Craig Walls | ||
| 29 | */ | ||
| 30 | public final class TripItServiceProvider extends AbstractServiceProvider<TripItOperations> { | ||
| 31 | |||
| 32 | public TripItServiceProvider(ServiceProviderParameters parameters, AccountConnectionRepository connectionRepository) { | ||
| 33 | super(parameters, connectionRepository); | ||
| 34 | } | ||
| 35 | |||
| 36 | protected TripItOperations createServiceOperations(OAuthToken accessToken) { | ||
| 37 | if (accessToken == null) { | ||
| 38 | throw new IllegalStateException("Cannot access TripIt without an access token"); | ||
| 39 | } | ||
| 40 | return new TripItTemplate(getApiKey(), getSecret(), accessToken.getValue(), accessToken.getSecret()); | ||
| 41 | } | ||
| 42 | |||
| 43 | protected String fetchProviderAccountId(TripItOperations tripIt) { | ||
| 44 | return tripIt.getProfileId(); | ||
| 45 | } | ||
| 46 | |||
| 47 | protected String buildProviderProfileUrl(String tripItId, TripItOperations tripIt) { | ||
| 48 | return tripIt.getProfileUrl(); | ||
| 49 | } | ||
| 50 | |||
| 51 | } |
src/main/java/com/springsource/greenhouse/connect/providers/Twitter4JServiceProvider.java
(0 / 63)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect.providers; | ||
| 17 | |||
| 18 | import java.util.Properties; | ||
| 19 | |||
| 20 | import twitter4j.Twitter; | ||
| 21 | import twitter4j.TwitterException; | ||
| 22 | import twitter4j.TwitterFactory; | ||
| 23 | import twitter4j.conf.Configuration; | ||
| 24 | import twitter4j.conf.PropertyConfiguration; | ||
| 25 | import twitter4j.http.AccessToken; | ||
| 26 | import twitter4j.http.Authorization; | ||
| 27 | import twitter4j.http.OAuthAuthorization; | ||
| 28 | |||
| 29 | import com.springsource.greenhouse.connect.AbstractServiceProvider; | ||
| 30 | import com.springsource.greenhouse.connect.AccountConnectionRepository; | ||
| 31 | import com.springsource.greenhouse.connect.ServiceProviderParameters; | ||
| 32 | import com.springsource.greenhouse.connect.OAuthToken; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * Twitter ServiceProvider that uses the Twitter4J API. | ||
| 36 | * @author Craig Walls | ||
| 37 | */ | ||
| 38 | public class Twitter4JServiceProvider extends AbstractServiceProvider<Twitter> { | ||
| 39 | |||
| 40 | public Twitter4JServiceProvider(ServiceProviderParameters parameters, AccountConnectionRepository connectionRepository) { | ||
| 41 | super(parameters, connectionRepository); | ||
| 42 | } | ||
| 43 | |||
| 44 | protected Twitter createServiceOperations(OAuthToken accessToken) { | ||
| 45 | TwitterFactory twitterFactory = new TwitterFactory(); | ||
| 46 | AccessToken oauthToken = new AccessToken(accessToken.getValue(), accessToken.getSecret()); | ||
| 47 | Configuration configuration = new PropertyConfiguration(new Properties()); | ||
| 48 | Authorization authorization = new OAuthAuthorization(configuration, getApiKey(), getSecret(), oauthToken); | ||
| 49 | return accessToken != null ? twitterFactory.getInstance(authorization) : twitterFactory.getInstance(); | ||
| 50 | } | ||
| 51 | |||
| 52 | protected String fetchProviderAccountId(Twitter twitter) { | ||
| 53 | try { | ||
| 54 | return twitter.getScreenName(); | ||
| 55 | } catch (TwitterException e) { | ||
| 56 | return null; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | protected String buildProviderProfileUrl(String screenName, Twitter twitter) { | ||
| 61 | return "http://www.twitter.com/" + screenName; | ||
| 62 | } | ||
| 63 | } |
src/main/java/com/springsource/greenhouse/connect/providers/TwitterConnectInterceptor.java
(1 / 1)
|   | |||
| 15 | 15 | */ | |
| 16 | 16 | package com.springsource.greenhouse.connect.providers; | |
| 17 | 17 | ||
| 18 | import org.springframework.social.connect.ServiceProvider; | ||
| 18 | 19 | import org.springframework.social.twitter.DuplicateTweetException; | |
| 19 | 20 | import org.springframework.social.twitter.TwitterOperations; | |
| 20 | 21 | import org.springframework.util.StringUtils; | |
| 21 | 22 | import org.springframework.web.context.request.WebRequest; | |
| 22 | 23 | ||
| 23 | 24 | import com.springsource.greenhouse.account.Account; | |
| 24 | import com.springsource.greenhouse.connect.ServiceProvider; | ||
| 25 | 25 | import com.springsource.greenhouse.connect.ConnectInterceptor; | |
| 26 | 26 | ||
| 27 | 27 | /** |
src/main/java/com/springsource/greenhouse/connect/providers/TwitterServiceProvider.java
(0 / 49)
|   | |||
| 1 | /* | ||
| 2 | * Copyright 2010 the original author or authors. | ||
| 3 | * | ||
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | * you may not use this file except in compliance with the License. | ||
| 6 | * You may obtain a copy of the License at | ||
| 7 | * | ||
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | * | ||
| 10 | * Unless required by applicable law or agreed to in writing, software | ||
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | * See the License for the specific language governing permissions and | ||
| 14 | * limitations under the License. | ||
| 15 | */ | ||
| 16 | package com.springsource.greenhouse.connect.providers; | ||
| 17 | |||
| 18 | import org.springframework.social.twitter.TwitterOperations; | ||
| 19 | import org.springframework.social.twitter.TwitterTemplate; | ||
| 20 | |||
| 21 | import com.springsource.greenhouse.connect.AbstractServiceProvider; | ||
| 22 | import com.springsource.greenhouse.connect.AccountConnectionRepository; | ||
| 23 | import com.springsource.greenhouse.connect.ServiceProviderParameters; | ||
| 24 | import com.springsource.greenhouse.connect.OAuthToken; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Twitter ServiceProvider implementation. | ||
| 28 | * @author Keith Donald | ||
| 29 | * @author Craig Walls | ||
| 30 | */ | ||
| 31 | public final class TwitterServiceProvider extends AbstractServiceProvider<TwitterOperations> { | ||
| 32 | |||
| 33 | public TwitterServiceProvider(ServiceProviderParameters parameters, AccountConnectionRepository connectionRepository) { | ||
| 34 | super(parameters, connectionRepository); | ||
| 35 | } | ||
| 36 | |||
| 37 | protected TwitterOperations createServiceOperations(OAuthToken accessToken) { | ||
| 38 | return accessToken != null ? new TwitterTemplate(getApiKey(), getSecret(), accessToken.getValue(), accessToken.getSecret()) : new TwitterTemplate(); | ||
| 39 | } | ||
| 40 | |||
| 41 | protected String fetchProviderAccountId(TwitterOperations twitter) { | ||
| 42 | return twitter.getProfileId(); | ||
| 43 | } | ||
| 44 | |||
| 45 | protected String buildProviderProfileUrl(String screenName, TwitterOperations twitter) { | ||
| 46 | return "http://www.twitter.com/" + screenName; | ||
| 47 | } | ||
| 48 | |||
| 49 | } |
src/main/java/com/springsource/greenhouse/invite/FacebookInviteController.java
(3 / 2)
|   | |||
| 20 | 20 | ||
| 21 | 21 | import javax.inject.Inject; | |
| 22 | 22 | ||
| 23 | import org.springframework.social.connect.ServiceProvider; | ||
| 23 | 24 | import org.springframework.social.facebook.FacebookOperations; | |
| 24 | 25 | import org.springframework.stereotype.Controller; | |
| 25 | 26 | import org.springframework.ui.Model; | |
| … | … | ||
| 30 | 30 | import org.springframework.web.flash.FlashMap; | |
| 31 | 31 | ||
| 32 | 32 | import com.springsource.greenhouse.account.Account; | |
| 33 | import com.springsource.greenhouse.connect.ServiceProvider; | ||
| 34 | 33 | ||
| 35 | 34 | /** | |
| 36 | 35 | * UI Controller for inviting Facebook friends to join our community. | |
| … | … | ||
| 59 | 59 | public void friendFinder(Model model, Account account) { | |
| 60 | 60 | if (facebookProvider.isConnected(account.getId())) { | |
| 61 | 61 | List<String> providerAccountIds = facebookProvider.getServiceOperations(account.getId()).getFriendIds(); | |
| 62 | model.addAttribute("friends", facebookProvider.findMembersConnectedTo(providerAccountIds)); | ||
| 62 | // model.addAttribute("friends", | ||
| 63 | // facebookProvider.findMembersConnectedTo(providerAccountIds)); | ||
| 63 | 64 | } else { | |
| 64 | 65 | model.addAttribute("friends", Collections.emptySet()); | |
| 65 | 66 | } |
src/main/java/com/springsource/greenhouse/invite/TwitterInviteController.java
(3 / 2)
|   | |||
| 19 | 19 | ||
| 20 | 20 | import javax.inject.Inject; | |
| 21 | 21 | ||
| 22 | import org.springframework.social.connect.ServiceProvider; | ||
| 22 | 23 | import org.springframework.social.twitter.TwitterOperations; | |
| 23 | 24 | import org.springframework.stereotype.Controller; | |
| 24 | 25 | import org.springframework.ui.Model; | |
| … | … | ||
| 29 | 29 | import org.springframework.web.bind.annotation.RequestParam; | |
| 30 | 30 | ||
| 31 | 31 | import com.springsource.greenhouse.account.Account; | |
| 32 | import com.springsource.greenhouse.connect.ServiceProvider; | ||
| 33 | 32 | ||
| 34 | 33 | /** | |
| 35 | 34 | * UI Controller for the Twitter invite page. | |
| … | … | ||
| 67 | 67 | public String findFriends(@RequestParam String username, Account account, Model model) { | |
| 68 | 68 | if (StringUtils.hasText(username)) { | |
| 69 | 69 | List<String> screenNames = twitterProvider.getServiceOperations(account.getId()).getFriends(username); | |
| 70 | model.addAttribute("friends", twitterProvider.findMembersConnectedTo(screenNames)); | ||
| 70 | // model.addAttribute("friends", | ||
| 71 | // twitterProvider.findMembersConnectedTo(screenNames)); | ||
| 71 | 72 | } | |
| 72 | 73 | return "invite/twitterFriends"; | |
| 73 | 74 | } |
src/main/java/com/springsource/greenhouse/signin/FacebookSigninController.java
(12 / 18)
|   | |||
| 17 | 17 | ||
| 18 | 18 | import javax.inject.Inject; | |
| 19 | 19 | ||
| 20 | import org.springframework.social.facebook.FacebookAccessToken; | ||
| 20 | import org.springframework.social.connect.ServiceProvider; | ||
| 21 | 21 | import org.springframework.social.facebook.FacebookOperations; | |
| 22 | 22 | import org.springframework.social.facebook.FacebookProfile; | |
| 23 | import org.springframework.social.facebook.FacebookTemplate; | ||
| 24 | 23 | import org.springframework.stereotype.Controller; | |
| 25 | import org.springframework.web.bind.annotation.RequestMapping; | ||
| 26 | import org.springframework.web.bind.annotation.RequestMethod; | ||
| 27 | 24 | import org.springframework.web.flash.FlashMap; | |
| 28 | 25 | ||
| 29 | import com.springsource.greenhouse.account.Account; | ||
| 30 | 26 | import com.springsource.greenhouse.account.AccountRepository; | |
| 31 | import com.springsource.greenhouse.account.AccountUtils; | ||
| 32 | 27 | import com.springsource.greenhouse.account.SignInNotFoundException; | |
| 33 | import com.springsource.greenhouse.connect.ServiceProvider; | ||
| 34 | import com.springsource.greenhouse.connect.NoSuchAccountConnectionException; | ||
| 35 | 28 | ||
| 36 | 29 | /** | |
| 37 | 30 | * UI Controller that allows you to signin with your Facebook account, if your local member account has been connected to Facebook. | |
| … | … | ||
| 50 | 50 | * For sign-in to succeed, the submitted access token must match a Facebook accessToken on file in our system. | |
| 51 | 51 | * Notifies the user if the access token is invalid. | |
| 52 | 52 | */ | |
| 53 | @RequestMapping(value="/signin/facebook", method=RequestMethod.POST) | ||
| 54 | public String signin(@FacebookAccessToken String accessToken) { | ||
| 55 | try { | ||
| 56 | Account account = facebookProvider.findAccountByConnection(accessToken); | ||
| 57 | AccountUtils.signin(account); | ||
| 58 | return "redirect:/"; | ||
| 59 | } catch (NoSuchAccountConnectionException e) { | ||
| 60 | return handleNoFacebookConnection(new FacebookTemplate(accessToken).getUserProfile()); | ||
| 61 | } | ||
| 62 | } | ||
| 53 | // @RequestMapping(value="/signin/facebook", method=RequestMethod.POST) | ||
| 54 | // public String signin(@FacebookAccessToken String accessToken) { | ||
| 55 | // try { | ||
| 56 | // Account account = facebookProvider.findAccountByConnection(accessToken); | ||
| 57 | // AccountUtils.signin(account); | ||
| 58 | // return "redirect:/"; | ||
| 59 | // } catch (NoSuchAccountConnectionException e) { | ||
| 60 | // return handleNoFacebookConnection(new | ||
| 61 | // FacebookTemplate(accessToken).getUserProfile()); | ||
| 62 | // } | ||
| 63 | // } | ||
| 63 | 64 | ||
| 64 | 65 | // internal helpers | |
| 65 | 66 |
src/main/resources/com/springsource/greenhouse/database/install/data/AccountProviders.sql
(4 / 4)
|   | |||
| 1 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('twitter', 'Twitter', 'com.springsource.greenhouse.connect.providers.TwitterServiceProvider', '99126833b772fa204c0e60296208603a71803dd17e700d5c', 'bf278c8c5951763b56b540d1dfcd7c22cc716723035cdf5df1d316edd992084768d839b3e3c7cee7c349c6c17e736bd3', 'https://twitter.com/oauth/request_token', 'https://twitter.com/oauth/authorize?oauth_token={token}', 'https://twitter.com/oauth/access_token'); | ||
| 2 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, appId) values ('facebook', 'Facebook', 'com.springsource.greenhouse.connect.providers.FacebookServiceProvider', 'db89ecfed3c7f3e212e01b3fc919838ff04049503d8402034b7148d5d3b7976fe4a314a31db0a42d', 'f85145c9f11fd9d920759b89a29c8e3f4ca05864257eeb4e394557f21588ad41a5f44f16242b14d7', 140372495981006); | ||
| 3 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('linkedin', 'LinkedIn', 'com.springsource.greenhouse.connect.providers.LinkedInServiceProvider', 'b680817df13092345f63212e1509a3f657f3b4d83eb4279e457f289c141aaabad17c95f356521560cdde05637762710effd7e026801b69e2bd8f3ef2c89cb190b1952e6e20ffbdab', '3c85ee7d4ac9b101d48305989cf140395cd97b6e9113a3a1c9412672f82446cc9128cb0060c8461f7bf0b471b6386ef265f01891dac713c650d1516f07a2021c8932c1a833f8f83c', 'https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize?oauth_token={token}', 'https://api.linkedin.com/uas/oauth/accessToken'); | ||
| 4 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('tripit', 'TripIt', 'com.springsource.greenhouse.connect.providers.TripItServiceProvider', '6e995d2458c8d2e342920f0f2128852c66d63da8a14cc926b76b81e6c038311bf80753a27acd8eed1484cbcc707d3219', 'a1aef751a5512f834a45511fb30386f210ac290ddfe1af0276bf0c632ce19e3abdcaabda86da6313e13d9939521d7283', 'https://api.tripit.com/oauth/request_token', 'https://www.tripit.com/oauth/authorize?oauth_token={token}&oauth_callback=https://greenhouse.springsource.org/connect/tripit', 'https://api.tripit.com/oauth/access_token'); | ||
| 1 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('twitter', 'Twitter', 'org.springframework.social.connect.providers.TwitterServiceProvider', '99126833b772fa204c0e60296208603a71803dd17e700d5c', 'bf278c8c5951763b56b540d1dfcd7c22cc716723035cdf5df1d316edd992084768d839b3e3c7cee7c349c6c17e736bd3', 'https://twitter.com/oauth/request_token', 'https://twitter.com/oauth/authorize?oauth_token={token}', 'https://twitter.com/oauth/access_token'); | ||
| 2 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, appId) values ('facebook', 'Facebook', 'org.springframework.social.connect.providers.FacebookServiceProvider', 'db89ecfed3c7f3e212e01b3fc919838ff04049503d8402034b7148d5d3b7976fe4a314a31db0a42d', 'f85145c9f11fd9d920759b89a29c8e3f4ca05864257eeb4e394557f21588ad41a5f44f16242b14d7', 140372495981006); | ||
| 3 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('linkedin', 'LinkedIn', 'org.springframework.social.connect.providers.LinkedInServiceProvider', 'b680817df13092345f63212e1509a3f657f3b4d83eb4279e457f289c141aaabad17c95f356521560cdde05637762710effd7e026801b69e2bd8f3ef2c89cb190b1952e6e20ffbdab', '3c85ee7d4ac9b101d48305989cf140395cd97b6e9113a3a1c9412672f82446cc9128cb0060c8461f7bf0b471b6386ef265f01891dac713c650d1516f07a2021c8932c1a833f8f83c', 'https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize?oauth_token={token}', 'https://api.linkedin.com/uas/oauth/accessToken'); | ||
| 4 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('tripit', 'TripIt', 'org.springframework.social.connect.providers.TripItServiceProvider', '6e995d2458c8d2e342920f0f2128852c66d63da8a14cc926b76b81e6c038311bf80753a27acd8eed1484cbcc707d3219', 'a1aef751a5512f834a45511fb30386f210ac290ddfe1af0276bf0c632ce19e3abdcaabda86da6313e13d9939521d7283', 'https://api.tripit.com/oauth/request_token', 'https://www.tripit.com/oauth/authorize?oauth_token={token}&oauth_callback=https://greenhouse.springsource.org/connect/tripit', 'https://api.tripit.com/oauth/access_token'); |
src/main/resources/com/springsource/greenhouse/database/install/embedded/test-data.sql
(4 / 4)
|   | |||
| 14 | 14 | insert into AppDeveloper (app, member) values (1, 3); | |
| 15 | 15 | ||
| 16 | 16 | -- ServiceProvider Testers | |
| 17 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('twitter', 'Twitter', 'com.springsource.greenhouse.connect.providers.TwitterServiceProvider', 'kqAm0GiPCT2owEtyTLPsug', '3461TFWV52VJuppKeaWMi8lKOxXMZtYLPGISq4nJ5s', 'https://twitter.com/oauth/request_token', 'https://twitter.com/oauth/authorize?oauth_token={token}', 'https://twitter.com/oauth/access_token'); | ||
| 18 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, appId) values ('facebook', 'Facebook', 'com.springsource.greenhouse.connect.providers.FacebookServiceProvider', '21aa96c8bc23259d0dd2ab99e496c306', 'f9f627194d471fb915dfbc856d347288', 157702280911244); | ||
| 19 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('linkedin', 'LinkedIn', 'com.springsource.greenhouse.connect.providers.LinkedInServiceProvider', 'elcLPr8RxIXifjn5RKwaTNxKPap4dYrr9ANuJ-abZNkTjbT3mSOVT7IhSfsF27XP', 'QiMWSBRBBM43wFuqpn8XtXqdfLB6A0TJUQslBjtuQAwYCOcIdvRaotT9c50I72pk', 'https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize?oauth_token={token}', 'https://api.linkedin.com/uas/oauth/accessToken'); | ||
| 20 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('tripit', 'TripIt', 'com.springsource.greenhouse.connect.providers.TripItServiceProvider', '739681c719f545d13d2376552d182b47c79b1d35', 'b6287a592afb3eccefb9261ee87c96d3b5f39286', 'https://api.tripit.com/oauth/request_token', 'https://www.tripit.com/oauth/authorize?oauth_token={token}&oauth_callback=http://localhost:8080/greenhouse/connect/tripit', 'https://api.tripit.com/oauth/access_token'); | ||
| 17 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('twitter', 'Twitter', 'org.springframework.social.connect.providers.TwitterServiceProvider', 'kqAm0GiPCT2owEtyTLPsug', '3461TFWV52VJuppKeaWMi8lKOxXMZtYLPGISq4nJ5s', 'https://twitter.com/oauth/request_token', 'https://twitter.com/oauth/authorize?oauth_token={token}', 'https://twitter.com/oauth/access_token'); | ||
| 18 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, appId) values ('facebook', 'Facebook', 'org.springframework.social.connect.providers.FacebookServiceProvider', '21aa96c8bc23259d0dd2ab99e496c306', 'f9f627194d471fb915dfbc856d347288', 157702280911244); | ||
| 19 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('linkedin', 'LinkedIn', 'org.springframework.social.connect.providers.LinkedInServiceProvider', 'elcLPr8RxIXifjn5RKwaTNxKPap4dYrr9ANuJ-abZNkTjbT3mSOVT7IhSfsF27XP', 'QiMWSBRBBM43wFuqpn8XtXqdfLB6A0TJUQslBjtuQAwYCOcIdvRaotT9c50I72pk', 'https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize?oauth_token={token}', 'https://api.linkedin.com/uas/oauth/accessToken'); | ||
| 20 | insert into ServiceProvider (name, displayName, implementation, apiKey, secret, requestTokenUrl, authorizeUrl, accessTokenUrl) values ('tripit', 'TripIt', 'org.springframework.social.connect.providers.TripItServiceProvider', '739681c719f545d13d2376552d182b47c79b1d35', 'b6287a592afb3eccefb9261ee87c96d3b5f39286', 'https://api.tripit.com/oauth/request_token', 'https://www.tripit.com/oauth/authorize?oauth_token={token}&oauth_callback=http://localhost:8080/greenhouse/connect/tripit', 'https://api.tripit.com/oauth/access_token'); | ||
| 21 | 21 | ||
| 22 | 22 | -- Mock Upcoming Event Data: SpringOne2gx 2011 | |
| 23 | 23 | insert into Venue (name, postalAddress, latitude, longitude, locationHint, createdBy) values ('Westin Lombard Yorktown Center', '70 Yorktown Center Lombard, IL 60148', 41.8751108905486, -88.0184300761646, 'adjacent to Shopping Center', 1); |
src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml
(1 / 1)
|   | |||
| 25 | 25 | <beans:bean class="com.springsource.greenhouse.signin.AccountExposingHandlerInterceptor" /> | |
| 26 | 26 | <beans:bean class="com.springsource.greenhouse.home.DateTimeZoneHandlerInterceptor" /> | |
| 27 | 27 | <beans:bean class="com.springsource.greenhouse.home.UserLocationHandlerInterceptor" /> | |
| 28 | <beans:bean class="org.springframework.mobile.device.mvc.DeviceResolvingHandlerInterceptor" /> | ||
| 28 | <beans:bean class="org.springframework.mobile.device.mvc.DeviceResolverHandlerInterceptor" /> | ||
| 29 | 29 | </interceptors> | |
| 30 | 30 | ||
| 31 | 31 | <!-- Maps view names to Tiles Definitions --> |
src/main/webapp/WEB-INF/spring/security-oauth-consumer.xml
(1 / 1)
|   | |||
| 4 | 4 | xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> | |
| 5 | 5 | ||
| 6 | 6 | <!-- Loads ServiceProviders by name --> | |
| 7 | <bean id="serviceProviderFactory" class="com.springsource.greenhouse.connect.JdbcServiceProviderFactory" /> | ||
| 7 | <bean id="serviceProviderFactory" class="org.springframework.social.connect.JdbcServiceProviderFactory" autowire="constructor"/> | ||
| 8 | 8 | ||
| 9 | 9 | <!-- Twitter --> | |
| 10 | 10 | <bean id="twitterProvider" parent="serviceProvider"> |
src/test/java/com/springsource/greenhouse/connect/JdbcAccountConnectionRepositoryTest.java
(0 / 119)
|   | |||
| 1 | package com.springsource.greenhouse.connect; | ||
| 2 | |||
| 3 | import static java.util.Arrays.asList; | ||
| 4 | import static org.junit.Assert.assertEquals; | ||
| 5 | import static org.junit.Assert.assertFalse; | ||
| 6 | import static org.junit.Assert.assertNotNull; | ||
| 7 | import static org.junit.Assert.assertNull; | ||
| 8 | import static org.junit.Assert.assertTrue; | ||
| 9 | |||
| 10 | import java.util.List; | ||
| 11 | |||
| 12 | import org.junit.After; | ||
| 13 | import org.junit.Before; | ||
| 14 | import org.junit.Test; | ||
| 15 | import org.springframework.jdbc.core.JdbcTemplate; | ||
| 16 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; | ||
| 17 | import org.springframework.security.encrypt.SearchableStringEncryptor; | ||
| 18 | import org.springframework.security.encrypt.StringEncryptor; | ||
| 19 | import org.springframework.social.twitter.TwitterOperations; | ||
| 20 | |||
| 21 | import com.springsource.greenhouse.account.AccountMapper; | ||
| 22 | import com.springsource.greenhouse.account.ProfileReference; | ||
| 23 | import com.springsource.greenhouse.account.StubFileStorage; | ||
| 24 | import com.springsource.greenhouse.database.GreenhouseTestDatabaseBuilder; | ||
| 25 | |||
| 26 | // TODO This is testing more than just the jdbc account connection repository - factor out and focus on the data access logic | ||
| 27 | public class JdbcAccountConnectionRepositoryTest { | ||
| 28 | |||
| 29 | private EmbeddedDatabase db; | ||
| 30 | |||
| 31 | private JdbcTemplate jdbcTemplate; | ||
| 32 | |||
| 33 | private ServiceProvider<TwitterOperations> serviceProvider; | ||
| 34 | |||
| 35 | private JdbcServiceProviderFactory providerFactory; | ||
| 36 | |||
| 37 | @Before | ||
| 38 | public void setup() { | ||
| 39 | db = new GreenhouseTestDatabaseBuilder().member().connectedAccount().testData(getClass()).getDatabase(); | ||
| 40 | jdbcTemplate = new JdbcTemplate(db); | ||
| 41 | StringEncryptor encryptor = new SearchableStringEncryptor("secret", "5b8bd7612cdab5ed"); | ||
| 42 | AccountMapper accountMapper = new AccountMapper(new StubFileStorage(), "http://localhost:8080/members/{profileKey}"); | ||
| 43 | providerFactory = new JdbcServiceProviderFactory(jdbcTemplate, encryptor, accountMapper); | ||
| 44 | serviceProvider = providerFactory.getServiceProvider("twitter", TwitterOperations.class); | ||
| 45 | } | ||
| 46 | |||
| 47 | @After | ||
| 48 | public void destroy() { | ||
| 49 | if (db != null) { | ||
| 50 | db.shutdown(); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | @Test | ||
| 55 | public void addConnection() throws NoSuchAccountConnectionException { | ||
| 56 | assertFalse(serviceProvider.isConnected(2L)); | ||
| 57 | serviceProvider.addConnection(2L, "accessToken", "kdonald"); | ||
| 58 | assertTrue(serviceProvider.isConnected(2L)); | ||
| 59 | TwitterOperations api = serviceProvider.getServiceOperations(2L); | ||
| 60 | assertNotNull(api); | ||
| 61 | assertNotNull(serviceProvider.findAccountByConnection("accessToken")); | ||
| 62 | } | ||
| 63 | |||
| 64 | @Test | ||
| 65 | public void connected() { | ||
| 66 | assertTrue(serviceProvider.isConnected(1L)); | ||
| 67 | } | ||
| 68 | |||
| 69 | @Test | ||
| 70 | public void notConnected() { | ||
| 71 | assertFalse(serviceProvider.isConnected(2L)); | ||
| 72 | } | ||
| 73 | |||
| 74 | @Test | ||
| 75 | public void getApi() { | ||
| 76 | TwitterOperations api = serviceProvider.getServiceOperations(1L); | ||
| 77 | assertNotNull(api); | ||
| 78 | } | ||
| 79 | |||
| 80 | @Test | ||
| 81 | public void getApiNotConnected() { | ||
| 82 | TwitterOperations api = serviceProvider.getServiceOperations(2L); | ||
| 83 | assertNotNull(api); | ||
| 84 | } | ||
| 85 | |||
| 86 | @Test | ||
| 87 | public void getConnectedAccountId() { | ||
| 88 | assertEquals("habuma", serviceProvider.getProviderAccountId(1L)); | ||
| 89 | } | ||
| 90 | |||
| 91 | @Test | ||
| 92 | public void getConnectedAccountIdNotConnected() { | ||
| 93 | assertNull(serviceProvider.getProviderAccountId(2L)); | ||
| 94 | } | ||
| 95 | |||
| 96 | @Test | ||
| 97 | public void findAccountByConnection() throws Exception { | ||
| 98 | assertNotNull(serviceProvider.findAccountByConnection("345678901")); | ||
| 99 | } | ||
| 100 | |||
| 101 | @Test(expected = NoSuchAccountConnectionException.class) | ||
| 102 | public void accountConnectionNotFound() throws Exception { | ||
| 103 | serviceProvider.findAccountByConnection("badtoken"); | ||
| 104 | } | ||
| 105 | |||
| 106 | @Test | ||
| 107 | public void findMembersConnectedTo() throws Exception { | ||
| 108 | List<ProfileReference> profiles = serviceProvider.findMembersConnectedTo(asList("habuma", "rclarkson", "BarakObama")); | ||
| 109 | assertEquals(2, profiles.size()); | ||
| 110 | } | ||
| 111 | |||
| 112 | @Test | ||
| 113 | public void disconnect() { | ||
| 114 | assertTrue(serviceProvider.isConnected(1L)); | ||
| 115 | serviceProvider.disconnect(1L); | ||
| 116 | assertFalse(serviceProvider.isConnected(1L)); | ||
| 117 | } | ||
| 118 | |||
| 119 | } |
src/test/java/com/springsource/greenhouse/connect/JdbcServiceProviderFactoryTest.java
(0 / 70)
|   | |||
| 1 | package com.springsource.greenhouse.connect; | ||
| 2 | |||
| 3 | import static org.junit.Assert.assertEquals; | ||
| 4 | |||
| 5 | import org.junit.After; | ||
| 6 | import org.junit.Before; | ||
| 7 | import org.junit.Test; | ||
| 8 | import org.springframework.jdbc.core.JdbcTemplate; | ||
| 9 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; | ||
| 10 | import org.springframework.security.encrypt.SearchableStringEncryptor; | ||
| 11 | import org.springframework.security.encrypt.StringEncryptor; | ||
| 12 | import org.springframework.social.facebook.FacebookOperations; | ||
| 13 | import org.springframework.social.twitter.TwitterOperations; | ||
| 14 | |||
| 15 | import com.springsource.greenhouse.account.AccountMapper; | ||
| 16 | import com.springsource.greenhouse.account.StubFileStorage; | ||
| 17 | import com.springsource.greenhouse.database.GreenhouseTestDatabaseBuilder; | ||
| 18 | |||
| 19 | public class JdbcServiceProviderFactoryTest { | ||
| 20 | |||
| 21 | private EmbeddedDatabase db; | ||
| 22 | |||
| 23 | private JdbcTemplate jdbcTemplate; | ||
| 24 | |||
| 25 | private ServiceProviderFactory providerFactory; | ||
| 26 | |||
| 27 | @Before | ||
| 28 | public void setup() { | ||
| 29 | db = new GreenhouseTestDatabaseBuilder().member().connectedAccount().testData(getClass()).getDatabase(); | ||
| 30 | jdbcTemplate = new JdbcTemplate(db); | ||
| 31 | StringEncryptor encryptor = new SearchableStringEncryptor("secret", "5b8bd7612cdab5ed"); | ||
| 32 | AccountMapper accountMapper = new AccountMapper(new StubFileStorage(), "http://localhost:8080/members/{profileKey}"); | ||
| 33 | providerFactory = new JdbcServiceProviderFactory(jdbcTemplate, encryptor, accountMapper); | ||
| 34 | } | ||
| 35 | |||
| 36 | @After | ||
| 37 | public void destroy() { | ||
| 38 | if (db != null) { | ||
| 39 | db.shutdown(); | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | @Test | ||
| 44 | public void getAccountProvider() { | ||
| 45 | ServiceProvider<TwitterOperations> twitterProvider = providerFactory.getServiceProvider("twitter", TwitterOperations.class); | ||
| 46 | assertEquals("twitter", twitterProvider.getName()); | ||
| 47 | assertEquals("Twitter", twitterProvider.getDisplayName()); | ||
| 48 | assertEquals("123456789", twitterProvider.getApiKey()); | ||
| 49 | assertEquals("http://www.twitter.com/authorize?oauth_token=123456789", twitterProvider.buildAuthorizeUrl("123456789")); | ||
| 50 | |||
| 51 | ServiceProvider<FacebookOperations> facebookProvider = providerFactory.getServiceProvider("facebook", FacebookOperations.class); | ||
| 52 | assertEquals("facebook", facebookProvider.getName()); | ||
| 53 | assertEquals("Facebook", facebookProvider.getDisplayName()); | ||
| 54 | assertEquals("345678901", facebookProvider.getApiKey()); | ||
| 55 | } | ||
| 56 | |||
| 57 | @Test | ||
| 58 | public void getAccountProviderByName() { | ||
| 59 | ServiceProvider<TwitterOperations> twitterProvider = providerFactory.getServiceProvider("twitter", TwitterOperations.class); | ||
| 60 | assertEquals("twitter", twitterProvider.getName()); | ||
| 61 | assertEquals("Twitter", twitterProvider.getDisplayName()); | ||
| 62 | assertEquals("123456789", twitterProvider.getApiKey()); | ||
| 63 | assertEquals("http://www.twitter.com/authorize?oauth_token=123456789", twitterProvider.buildAuthorizeUrl("123456789")); | ||
| 64 | |||
| 65 | ServiceProvider<FacebookOperations> facebookProvider = providerFactory.getServiceProvider("facebook", FacebookOperations.class); | ||
| 66 | assertEquals("facebook", facebookProvider.getName()); | ||
| 67 | assertEquals("Facebook", facebookProvider.getDisplayName()); | ||
| 68 | assertEquals("345678901", facebookProvider.getApiKey()); | ||
| 69 | } | ||
| 70 | } |
src/test/java/com/springsource/greenhouse/connect/TwitterConnectInterceptorTest.java
(4 / 8)
|   | |||
| 1 | 1 | package com.springsource.greenhouse.connect; | |
| 2 | 2 | ||
| 3 | import static org.junit.Assert.assertNotNull; | ||
| 4 | import static org.junit.Assert.assertNull; | ||
| 5 | import static org.junit.Assert.assertTrue; | ||
| 6 | import static org.mockito.Matchers.anyLong; | ||
| 7 | import static org.mockito.Mockito.mock; | ||
| 8 | import static org.mockito.Mockito.never; | ||
| 9 | import static org.mockito.Mockito.verify; | ||
| 10 | import static org.mockito.Mockito.when; | ||
| 3 | import static org.junit.Assert.*; | ||
| 4 | import static org.mockito.Matchers.*; | ||
| 5 | import static org.mockito.Mockito.*; | ||
| 11 | 6 | ||
| 12 | 7 | import org.junit.Before; | |
| 13 | 8 | import org.junit.Test; | |
| 14 | 9 | import org.springframework.mock.web.MockHttpServletRequest; | |
| 10 | import org.springframework.social.connect.ServiceProvider; | ||
| 15 | 11 | import org.springframework.social.twitter.TwitterOperations; | |
| 16 | 12 | import org.springframework.web.context.request.ServletWebRequest; | |
| 17 | 13 | import org.springframework.web.context.request.WebRequest; |
Comments
Add your comment
Please log in to comment



Add a new comment:
Login or create an account to post a comment