Commit 9651e0bcae09f224db69df907f281a39f3f1ae06

  • Tree SHA1: 7f00c2a
  • Parent SHA1: 2ae97ad (Set the embedded profile as the default profile to simplify startup in development. GREENHOUSE-489.)
  • raw diff | raw patch
First steps toward using Spring Social's connection module, per SOCIAL-17.
pom.xml
(32 / 1)
  
1919 <org.springframework-version>3.1.0.BUILD-SNAPSHOT</org.springframework-version>
2020 <org.springframework.security-version>3.0.3.RELEASE</org.springframework.security-version> <!-- 3.1.0.CI-SNAPSHOT once compatible with OAuth -->
2121 <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>
2223 <org.aspectj-version>1.6.9</org.aspectj-version>
2324 <org.slf4j-version>1.6.1</org.slf4j-version>
2425 </properties>
110110 </dependency>
111111 <dependency>
112112 <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>
113118 <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>
115145 </dependency>
116146 <dependency>
117147 <groupId>org.springframework.mobile</groupId>
src/main/java/com/springsource/greenhouse/config/ServiceProvidersApiConfiguration.java
(1 / 1)
  
1919import org.springframework.context.annotation.Bean;
2020import org.springframework.context.annotation.Scope;
2121import org.springframework.context.annotation.ScopedProxyMode;
22import org.springframework.social.connect.ServiceProvider;
2223import org.springframework.social.facebook.FacebookOperations;
2324import org.springframework.social.linkedin.LinkedInOperations;
2425import org.springframework.social.tripit.TripItOperations;
2526import org.springframework.social.twitter.TwitterOperations;
2627
2728import com.springsource.greenhouse.account.Account;
28import com.springsource.greenhouse.connect.ServiceProvider;
2929
3030/**
3131 * 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 */
16package com.springsource.greenhouse.connect;
17
18import java.util.List;
19
20import org.scribe.extractors.BaseStringExtractorImpl;
21import org.scribe.extractors.HeaderExtractorImpl;
22import org.scribe.extractors.TokenExtractorImpl;
23import org.scribe.model.OAuthConfig;
24import org.scribe.model.Token;
25import org.scribe.model.Verb;
26import org.scribe.model.Verifier;
27import org.scribe.oauth.OAuth10aServiceImpl;
28import org.scribe.oauth.OAuthService;
29import org.scribe.services.HMACSha1SignatureService;
30import org.scribe.services.TimestampServiceImpl;
31import org.springframework.transaction.annotation.Transactional;
32
33import com.springsource.greenhouse.account.Account;
34import 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 */
41public 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 */
16package com.springsource.greenhouse.connect;
17
18import java.util.List;
19
20import com.springsource.greenhouse.account.Account;
21import 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 */
28public 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 */
16package 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 */
25public 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)
  
2222
2323import org.springframework.beans.factory.annotation.Value;
2424import org.springframework.core.GenericTypeResolver;
25import org.springframework.social.connect.AuthorizedRequestToken;
26import org.springframework.social.connect.OAuthToken;
27import org.springframework.social.connect.ServiceProvider;
28import org.springframework.social.connect.ServiceProviderFactory;
2529import org.springframework.stereotype.Controller;
2630import org.springframework.util.LinkedMultiValueMap;
2731import org.springframework.util.MultiValueMap;
src/main/java/com/springsource/greenhouse/connect/ConnectInterceptor.java
(1 / 0)
  
1515 */
1616package com.springsource.greenhouse.connect;
1717
18import org.springframework.social.connect.ServiceProvider;
1819import org.springframework.web.context.request.WebRequest;
1920
2021import 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 */
16package com.springsource.greenhouse.connect;
17
18import java.sql.ResultSet;
19import java.sql.SQLException;
20import java.util.HashMap;
21import java.util.List;
22import java.util.Map;
23
24import org.springframework.dao.EmptyResultDataAccessException;
25import org.springframework.jdbc.core.JdbcTemplate;
26import org.springframework.jdbc.core.RowMapper;
27import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
28import org.springframework.security.encrypt.StringEncryptor;
29import org.springframework.stereotype.Repository;
30
31import com.springsource.greenhouse.account.Account;
32import com.springsource.greenhouse.account.AccountMapper;
33import 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
40public 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 */
16package com.springsource.greenhouse.connect;
17
18import java.lang.reflect.Constructor;
19import java.sql.ResultSet;
20import java.sql.SQLException;
21
22import org.springframework.beans.BeanUtils;
23import org.springframework.beans.factory.annotation.Autowired;
24import org.springframework.jdbc.core.JdbcTemplate;
25import org.springframework.jdbc.core.RowMapper;
26import org.springframework.security.encrypt.StringEncryptor;
27import org.springframework.stereotype.Repository;
28import org.springframework.util.ClassUtils;
29
30import 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
37public 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 */
16package 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 */
24public 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 */
16package com.springsource.greenhouse.connect;
17
18import java.util.List;
19
20import com.springsource.greenhouse.account.Account;
21import 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 */
31public 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&lt;FacebookOperations&gt; 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 */
16package com.springsource.greenhouse.connect;
17
18/**
19 * Factory for obtaining ServiceProviders by name.
20 * @author Keith Donald
21 */
22public 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 */
16package com.springsource.greenhouse.connect;
17
18import 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 */
25public 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)
  
2121import javax.servlet.http.HttpServletRequest;
2222
2323import org.springframework.security.core.Authentication;
24import org.springframework.social.connect.ServiceProvider;
2425import org.springframework.social.facebook.FacebookAccessToken;
2526import org.springframework.social.facebook.FacebookLink;
2627import org.springframework.social.facebook.FacebookOperations;
3434import org.springframework.web.flash.FlashMap;
3535
3636import com.springsource.greenhouse.account.Account;
37import com.springsource.greenhouse.connect.ServiceProvider;
3837import com.springsource.greenhouse.members.ProfilePictureService;
3938
4039/**
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 */
16package com.springsource.greenhouse.connect.providers;
17
18import org.springframework.social.facebook.FacebookOperations;
19import org.springframework.social.facebook.FacebookTemplate;
20
21import com.springsource.greenhouse.connect.AbstractServiceProvider;
22import com.springsource.greenhouse.connect.AccountConnectionRepository;
23import com.springsource.greenhouse.connect.ServiceProviderParameters;
24import com.springsource.greenhouse.connect.OAuthToken;
25
26/**
27 * Facebook ServiceProvider implementation.
28 * @author Keith Donald
29 */
30public 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 */
16package com.springsource.greenhouse.connect.providers;
17
18import org.springframework.social.linkedin.LinkedInOperations;
19import org.springframework.social.linkedin.LinkedInTemplate;
20
21import com.springsource.greenhouse.connect.AbstractServiceProvider;
22import com.springsource.greenhouse.connect.AccountConnectionRepository;
23import com.springsource.greenhouse.connect.ServiceProviderParameters;
24import com.springsource.greenhouse.connect.OAuthToken;
25
26/**
27 * LinkedIn ServiceProvider implementation.
28 * @author Keith Donald
29 */
30public 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 */
16package com.springsource.greenhouse.connect.providers;
17
18import org.springframework.social.tripit.TripItOperations;
19import org.springframework.social.tripit.TripItTemplate;
20
21import com.springsource.greenhouse.connect.AbstractServiceProvider;
22import com.springsource.greenhouse.connect.AccountConnectionRepository;
23import com.springsource.greenhouse.connect.ServiceProviderParameters;
24import com.springsource.greenhouse.connect.OAuthToken;
25
26/**
27 * TripIt ServiceProvider implementation.
28 * @author Craig Walls
29 */
30public 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 */
16package com.springsource.greenhouse.connect.providers;
17
18import java.util.Properties;
19
20import twitter4j.Twitter;
21import twitter4j.TwitterException;
22import twitter4j.TwitterFactory;
23import twitter4j.conf.Configuration;
24import twitter4j.conf.PropertyConfiguration;
25import twitter4j.http.AccessToken;
26import twitter4j.http.Authorization;
27import twitter4j.http.OAuthAuthorization;
28
29import com.springsource.greenhouse.connect.AbstractServiceProvider;
30import com.springsource.greenhouse.connect.AccountConnectionRepository;
31import com.springsource.greenhouse.connect.ServiceProviderParameters;
32import com.springsource.greenhouse.connect.OAuthToken;
33
34/**
35 * Twitter ServiceProvider that uses the Twitter4J API.
36 * @author Craig Walls
37 */
38public 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)
  
1515 */
1616package com.springsource.greenhouse.connect.providers;
1717
18import org.springframework.social.connect.ServiceProvider;
1819import org.springframework.social.twitter.DuplicateTweetException;
1920import org.springframework.social.twitter.TwitterOperations;
2021import org.springframework.util.StringUtils;
2122import org.springframework.web.context.request.WebRequest;
2223
2324import com.springsource.greenhouse.account.Account;
24import com.springsource.greenhouse.connect.ServiceProvider;
2525import com.springsource.greenhouse.connect.ConnectInterceptor;
2626
2727/**
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 */
16package com.springsource.greenhouse.connect.providers;
17
18import org.springframework.social.twitter.TwitterOperations;
19import org.springframework.social.twitter.TwitterTemplate;
20
21import com.springsource.greenhouse.connect.AbstractServiceProvider;
22import com.springsource.greenhouse.connect.AccountConnectionRepository;
23import com.springsource.greenhouse.connect.ServiceProviderParameters;
24import com.springsource.greenhouse.connect.OAuthToken;
25
26/**
27 * Twitter ServiceProvider implementation.
28 * @author Keith Donald
29 * @author Craig Walls
30 */
31public 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)
  
2020
2121import javax.inject.Inject;
2222
23import org.springframework.social.connect.ServiceProvider;
2324import org.springframework.social.facebook.FacebookOperations;
2425import org.springframework.stereotype.Controller;
2526import org.springframework.ui.Model;
3030import org.springframework.web.flash.FlashMap;
3131
3232import com.springsource.greenhouse.account.Account;
33import com.springsource.greenhouse.connect.ServiceProvider;
3433
3534/**
3635 * UI Controller for inviting Facebook friends to join our community.
5959 public void friendFinder(Model model, Account account) {
6060 if (facebookProvider.isConnected(account.getId())) {
6161 List<String> providerAccountIds = facebookProvider.getServiceOperations(account.getId()).getFriendIds();
62 model.addAttribute("friends", facebookProvider.findMembersConnectedTo(providerAccountIds));
62 // model.addAttribute("friends",
63 // facebookProvider.findMembersConnectedTo(providerAccountIds));
6364 } else {
6465 model.addAttribute("friends", Collections.emptySet());
6566 }
src/main/java/com/springsource/greenhouse/invite/TwitterInviteController.java
(3 / 2)
  
1919
2020import javax.inject.Inject;
2121
22import org.springframework.social.connect.ServiceProvider;
2223import org.springframework.social.twitter.TwitterOperations;
2324import org.springframework.stereotype.Controller;
2425import org.springframework.ui.Model;
2929import org.springframework.web.bind.annotation.RequestParam;
3030
3131import com.springsource.greenhouse.account.Account;
32import com.springsource.greenhouse.connect.ServiceProvider;
3332
3433/**
3534 * UI Controller for the Twitter invite page.
6767 public String findFriends(@RequestParam String username, Account account, Model model) {
6868 if (StringUtils.hasText(username)) {
6969 List<String> screenNames = twitterProvider.getServiceOperations(account.getId()).getFriends(username);
70 model.addAttribute("friends", twitterProvider.findMembersConnectedTo(screenNames));
70 // model.addAttribute("friends",
71 // twitterProvider.findMembersConnectedTo(screenNames));
7172 }
7273 return "invite/twitterFriends";
7374 }
src/main/java/com/springsource/greenhouse/signin/FacebookSigninController.java
(12 / 18)
  
1717
1818import javax.inject.Inject;
1919
20import org.springframework.social.facebook.FacebookAccessToken;
20import org.springframework.social.connect.ServiceProvider;
2121import org.springframework.social.facebook.FacebookOperations;
2222import org.springframework.social.facebook.FacebookProfile;
23import org.springframework.social.facebook.FacebookTemplate;
2423import org.springframework.stereotype.Controller;
25import org.springframework.web.bind.annotation.RequestMapping;
26import org.springframework.web.bind.annotation.RequestMethod;
2724import org.springframework.web.flash.FlashMap;
2825
29import com.springsource.greenhouse.account.Account;
3026import com.springsource.greenhouse.account.AccountRepository;
31import com.springsource.greenhouse.account.AccountUtils;
3227import com.springsource.greenhouse.account.SignInNotFoundException;
33import com.springsource.greenhouse.connect.ServiceProvider;
34import com.springsource.greenhouse.connect.NoSuchAccountConnectionException;
3528
3629/**
3730 * UI Controller that allows you to signin with your Facebook account, if your local member account has been connected to Facebook.
5050 * For sign-in to succeed, the submitted access token must match a Facebook accessToken on file in our system.
5151 * Notifies the user if the access token is invalid.
5252 */
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 // }
6364
6465 // internal helpers
6566
src/main/resources/com/springsource/greenhouse/database/install/data/AccountProviders.sql
(4 / 4)
  
1insert 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');
2insert into ServiceProvider (name, displayName, implementation, apiKey, secret, appId) values ('facebook', 'Facebook', 'com.springsource.greenhouse.connect.providers.FacebookServiceProvider', 'db89ecfed3c7f3e212e01b3fc919838ff04049503d8402034b7148d5d3b7976fe4a314a31db0a42d', 'f85145c9f11fd9d920759b89a29c8e3f4ca05864257eeb4e394557f21588ad41a5f44f16242b14d7', 140372495981006);
3insert 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');
4insert 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');
1insert 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');
2insert into ServiceProvider (name, displayName, implementation, apiKey, secret, appId) values ('facebook', 'Facebook', 'org.springframework.social.connect.providers.FacebookServiceProvider', 'db89ecfed3c7f3e212e01b3fc919838ff04049503d8402034b7148d5d3b7976fe4a314a31db0a42d', 'f85145c9f11fd9d920759b89a29c8e3f4ca05864257eeb4e394557f21588ad41a5f44f16242b14d7', 140372495981006);
3insert 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');
4insert 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)
  
1414insert into AppDeveloper (app, member) values (1, 3);
1515
1616-- ServiceProvider Testers
17insert 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');
18insert into ServiceProvider (name, displayName, implementation, apiKey, secret, appId) values ('facebook', 'Facebook', 'com.springsource.greenhouse.connect.providers.FacebookServiceProvider', '21aa96c8bc23259d0dd2ab99e496c306', 'f9f627194d471fb915dfbc856d347288', 157702280911244);
19insert 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');
20insert 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');
17insert 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');
18insert into ServiceProvider (name, displayName, implementation, apiKey, secret, appId) values ('facebook', 'Facebook', 'org.springframework.social.connect.providers.FacebookServiceProvider', '21aa96c8bc23259d0dd2ab99e496c306', 'f9f627194d471fb915dfbc856d347288', 157702280911244);
19insert 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');
20insert 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');
2121
2222-- Mock Upcoming Event Data: SpringOne2gx 2011
2323insert 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)
  
2525 <beans:bean class="com.springsource.greenhouse.signin.AccountExposingHandlerInterceptor" />
2626 <beans:bean class="com.springsource.greenhouse.home.DateTimeZoneHandlerInterceptor" />
2727 <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" />
2929 </interceptors>
3030
3131 <!-- Maps view names to Tiles Definitions -->
src/main/webapp/WEB-INF/spring/security-oauth-consumer.xml
(1 / 1)
  
44 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
55
66 <!-- 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"/>
88
99 <!-- Twitter -->
1010 <bean id="twitterProvider" parent="serviceProvider">
src/test/java/com/springsource/greenhouse/connect/JdbcAccountConnectionRepositoryTest.java
(0 / 119)
  
1package com.springsource.greenhouse.connect;
2
3import static java.util.Arrays.asList;
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertFalse;
6import static org.junit.Assert.assertNotNull;
7import static org.junit.Assert.assertNull;
8import static org.junit.Assert.assertTrue;
9
10import java.util.List;
11
12import org.junit.After;
13import org.junit.Before;
14import org.junit.Test;
15import org.springframework.jdbc.core.JdbcTemplate;
16import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
17import org.springframework.security.encrypt.SearchableStringEncryptor;
18import org.springframework.security.encrypt.StringEncryptor;
19import org.springframework.social.twitter.TwitterOperations;
20
21import com.springsource.greenhouse.account.AccountMapper;
22import com.springsource.greenhouse.account.ProfileReference;
23import com.springsource.greenhouse.account.StubFileStorage;
24import 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
27public 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)
  
1package com.springsource.greenhouse.connect;
2
3import static org.junit.Assert.assertEquals;
4
5import org.junit.After;
6import org.junit.Before;
7import org.junit.Test;
8import org.springframework.jdbc.core.JdbcTemplate;
9import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
10import org.springframework.security.encrypt.SearchableStringEncryptor;
11import org.springframework.security.encrypt.StringEncryptor;
12import org.springframework.social.facebook.FacebookOperations;
13import org.springframework.social.twitter.TwitterOperations;
14
15import com.springsource.greenhouse.account.AccountMapper;
16import com.springsource.greenhouse.account.StubFileStorage;
17import com.springsource.greenhouse.database.GreenhouseTestDatabaseBuilder;
18
19public 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)
  
11package com.springsource.greenhouse.connect;
22
3import static org.junit.Assert.assertNotNull;
4import static org.junit.Assert.assertNull;
5import static org.junit.Assert.assertTrue;
6import static org.mockito.Matchers.anyLong;
7import static org.mockito.Mockito.mock;
8import static org.mockito.Mockito.never;
9import static org.mockito.Mockito.verify;
10import static org.mockito.Mockito.when;
3import static org.junit.Assert.*;
4import static org.mockito.Matchers.*;
5import static org.mockito.Mockito.*;
116
127import org.junit.Before;
138import org.junit.Test;
149import org.springframework.mock.web.MockHttpServletRequest;
10import org.springframework.social.connect.ServiceProvider;
1511import org.springframework.social.twitter.TwitterOperations;
1612import org.springframework.web.context.request.ServletWebRequest;
1713import org.springframework.web.context.request.WebRequest;

Comments

Add a new comment:

Login or create an account to post a comment

Add your comment