Author: [email protected]
Date: Tue Aug 9 14:54:12 2011
New Revision: 1300
Log:
Modified:
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/osgi/Activator.java
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterClient.java
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterServiceImpl.java
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterServiceProvider.java
Modified:
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/osgi/Activator.java
==============================================================================
---
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/osgi/Activator.java
(original)
+++
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/osgi/Activator.java
Tue Aug 9 14:54:12 2011
@@ -21,7 +21,6 @@
import org.amdatu.auth.example.oauth.twitter.TwitterService;
import org.amdatu.auth.example.oauth.twitter.service.TwitterGadgetImpl;
import org.amdatu.auth.example.oauth.twitter.service.TwitterServiceImpl;
-import org.amdatu.auth.example.oauth.twitter.service.TwitterServiceProvider;
import org.amdatu.libraries.utilities.osgi.ServiceDependentActivator;
import org.amdatu.opensocial.gadgetmanagement.GadgetManagement;
import org.amdatu.web.dispatcher.DispatcherService;
@@ -81,8 +80,7 @@
manager.add(createComponent()
.setInterface(TwitterService.class.getName(), null)
.setImplementation(TwitterServiceImpl.class)
-
.add(createServiceDependency().setService(LogService.class).setRequired(true))
-
.add(createServiceDependency().setService(TwitterServiceProvider.class).setRequired(true)));
+
.add(createServiceDependency().setService(LogService.class).setRequired(true)));
}
@Override
Modified:
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterClient.java
==============================================================================
---
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterClient.java
(original)
+++
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterClient.java
Tue Aug 9 14:54:12 2011
@@ -17,7 +17,7 @@
import java.util.Map;
-import org.amdatu.authentication.oauth.api.OAuthServiceConsumer;
+import org.amdatu.auth.oauth.api.OAuthServiceConsumer;
/**
* This class implements the example Twitter client and represents an OAuth
Service consumer
@@ -60,6 +60,9 @@
public String getCallbackUrl() {
return OAUTH_CALLBACK_URL;
}
+
+ public void setCallbackUrl(String callbackUrl) {
+ }
public Map<String, String> getProperties() {
return null;
Modified:
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterServiceImpl.java
==============================================================================
---
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterServiceImpl.java
(original)
+++
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterServiceImpl.java
Tue Aug 9 14:54:12 2011
@@ -16,6 +16,7 @@
package org.amdatu.auth.example.oauth.twitter.service;
import java.io.BufferedReader;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -24,7 +25,6 @@
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
-import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
@@ -38,25 +38,28 @@
import javax.ws.rs.core.Response;
import net.oauth.OAuth;
-import net.oauth.OAuthAccessor;
import net.oauth.OAuthException;
import net.oauth.OAuthMessage;
+import net.oauth.ParameterStyle;
import org.amdatu.auth.example.oauth.twitter.TwitterService;
-import org.amdatu.authentication.oauth.api.OAuthAccess;
-import org.amdatu.authentication.oauth.client.OAuthServiceConsumerClient;
+import org.amdatu.auth.oauth.api.OAuthAccessor;
+import org.amdatu.auth.oauth.client.OAuthHttpRequest;
+import org.amdatu.auth.oauth.client.OAuthServiceConsumerClient;
import org.apache.http.HttpStatus;
-import org.json.JSONException;
import org.osgi.service.log.LogService;
/**
- * This class implements the actual Tweet REST service.
+ * This class implements the actual Twitter REST service.
* Steps involved in a regular 3-legged OAuth dance:
- *
- * 1. Retrieve a request token from the service provider
+ *
+ * 1. Obtain a request token from the service provider
* 2. Store the token secret associated with the retrieved request token
* 3. Redirect the user to the authorization URL, defined by the service
provider
- *
+ * 4. Callback URL is invoked by the service provider
+ * 5. The service consumer invokes the service provider to exchange the
request token for an access token
+ * 6. Access the protected resource with the acquired access token
+ *
* @author ivol
*/
@Path("example/twitter")
@@ -83,12 +86,16 @@
private Map<String, String> m_tokens = new HashMap<String, String>();
public void start() {
- m_logService.log(LogService.LOG_INFO, "Tweet service started");
+ // We set the encryption method to HMAC SHA1, but since this is also
the default its is not
+ // really necessary
+ m_oauthClient.setSignatureMethod(OAuth.HMAC_SHA1);
+
+ m_logService.log(LogService.LOG_INFO, "Twitter service started");
}
/**
* This method can be used to check the availability of the Twitter
Service.
- *
+ *
* @return The text "Twitter service online"
*/
@GET
@@ -99,23 +106,31 @@
}
/**
- * This method will Twitter a message on the users behalf. So we use the
OAuth protected Twitter API to do so.
+ * This method will Twitter a message on the users behalf. Since the
Twitter API is protected using
+ * OAuth we need to start the OAuth dance here, starting with retrieving a
request token and redirecting
+ * the user to Twitter's authorization page where he can authorize us to
exchange our request token for
+ * an access token.
*/
@POST
@Path("tweet")
public Response tweet() {
try {
- // Step 1. Get a request token and token secret from Twitter
- OAuthAccess accessor = m_oauthClient.generateRequestToken();
- m_logService.log(LogService.LOG_INFO, "Request token received: " +
accessor.getRequestToken() + ", token secret="
+ // Step 1. Obtain a request token and token secret from Twitter
+ OAuthAccessor accessor = m_oauthClient.obtainRequestToken();
+ m_logService.log(LogService.LOG_INFO, "Request token received: " +
accessor.getRequestToken()
+ + ", token secret="
+ accessor.getTokenSecret());
-
+
// Step 2: Remember the token secret associated with this request
token
m_tokens.put(accessor.getRequestToken(),
accessor.getTokenSecret());
- // Step 3: Let the user redirect to the authorize URL
+ // Step 3: Let the user redirect to the authorize URL. The
authorize URL is determines by the
+ // service provider, twitter in our case. When the authorize token
is invoked, also a callback URL
+ // is passed, which is determined by the service consumer (our
Twitter client). This determines the
+ // URL to which the user is redirected after completing the
authorization step.
+ // In our case, the callback will invoke this very same REST
service, method 'oAuthCallback'.
// a. Generate the authorization URL
- URI authorizeURL =
m_oauthClient.generateAuthorizeTokenURL(accessor);
+ URI authorizeURL = m_oauthClient.getAuthorizeTokenURL(accessor);
// b. Send client-side redirect to the authorize URL
return
Response.status(HttpStatus.SC_MOVED_TEMPORARILY).location(authorizeURL).build();
@@ -125,116 +140,130 @@
}
}
+ /**
+ * Implementation of the callback URL, invoked by the service provider
(Twitter) after the user
+ * completed the authorize step.
+ *
+ * @param request
+ * The HTTP request, containing the request token that was
authorized and the
+ * verifier code.
+ */
@GET
@Path("oauthcallback")
@Produces({MediaType.TEXT_PLAIN})
public Response oAuthCallback(@Context final HttpServletRequest request) {
try {
- String token = request.getParameter("oauth_token");
-
- // It seems that not passing the verifier works like a charm, so
Twitter does support the
- // oauth verifier but leaves it up to the application if it
implements it.
- // but authorioze page displayed consumer so that should be OK. it
would only fail if I
- // write a malicious twitter app and find a victim that is willing
to accept that this
- // malicious app has access to his account. Doesn't sound like a
real security issue.
+ // Step 4: Get the request token and verifier from the HTTP
request and create the accessor
+ // NB: not passing the verifier works like a charm. Twitter leaves
it up to the
+ // application if it wants to pass the verifier or not. Without
passing the verifier
+ // however, it could be vulnerable to session fixation attacks.
+ // The user did specifically authorize the application to access
its resources
+ // on its behalf. At that point the user 'trusts' the application.
This trust includes
+ // the assumption that it was well programmed, not being
vulnerable to obvious attacks
+ // like this one.
+ String requestToken = request.getParameter("oauth_token");
+ String tokenSecret = m_tokens.get(requestToken);
String verifier = request.getParameter("oauth_verifier");
+ OAuthAccessor accessor =
m_oauthClient.createAccessor(requestToken, tokenSecret, verifier);
- // Create the accessor
- OAuthAccessor accessor =
m_oauthClient.getAccessor(m_twitterClient, m_twitterServer);
- accessor.requestToken = token;
- accessor.tokenSecret = m_tokens.get(token);
- accessor.setProperty(OAuth.OAUTH_VERIFIER, verifier);
-
- // Exchange request token for access token
- OAuthMessage message = m_oauthClient.getAccessToken(accessor);
- String accessToken = message.getToken();
+ // Step 5: Exchange request token for access token
+ OAuthMessage message =
m_oauthClient.exchangeRequestTokenForAccessToken(accessor);
+ // Log the token received, for example purposes (should not be
done in production of course)
String msg = "Exchanged request token for access token:\r\n";
- msg += " Access token = " + accessToken + "\r\n";
- msg += " Token secret = " +
message.getParameter("oauth_token_secret") + "\r\n";
+ msg += " Access token = " + accessor.getAccessToken() + "\r\n";
+ msg += " Token secret = " + accessor.getTokenSecret() + "\r\n";
msg += " User id = " + message.getParameter("user_id") + "\r\n";
msg += " User name = " + message.getParameter("screen_name") +
"\r\n";
m_logService.log(LogService.LOG_INFO, msg);
- // Update the accessor
- accessor.requestToken = null;
- accessor.accessToken = accessToken;
- accessor.tokenSecret = message.getParameter("oauth_token_secret");
-
+ // Step 6: Access the resource(s) with the acquired access token
m_logService.log(LogService.LOG_INFO, "Account Totals: " +
getAccountTotals(accessor));
m_logService.log(LogService.LOG_INFO, "Account Verify Credentials:
"
+ getAccountVerifyCredentials(accessor));
-
m_logService.log(LogService.LOG_INFO, "Result: " +
tweetMessage(accessor));
+ m_logService.log(LogService.LOG_INFO, "Update profile image: " +
updateProfileImage(accessor));
- // Redirect to twitter such that we can see the Tweet
+ // In this example we redirect the user to twitter such that he
can see the new Tweet
return Response.seeOther(new URI("http://twitter.com/")).build();
-
- // return Response.ok("OK").build();
}
catch (Exception e) {
return Response.serverError().entity(e.toString()).build();
}
}
- private OAuthAccess createRequestToken() throws IOException,
OAuthException,
- URISyntaxException {
- OAuthAccess accessor = m_oauthClient.generateRequestToken();
- String requestToken = accessor.getRequestToken();
- String tokenSecret = accessor.getTokenSecret();
- m_logService.log(LogService.LOG_INFO, "Request token received: " +
requestToken + ", token secret="
- + tokenSecret);
- return accessor;
- }
-
private String tweetMessage(OAuthAccessor accessor) throws Exception {
- String url = "https://api.twitter.com/1/statuses/update.json";
- url += "?status=" + URLEncoder.encode(TWEET_MSG, "UTF-8");
- OAuthMessage message = m_oauthClient.accessResource(accessor, url,
"POST");
+ OAuthHttpRequest request = new OAuthHttpRequest()
+ .setHttpMethod(OAuthMessage.POST)
+ .setUrl("https://api.twitter.com/1/statuses/update.json")
+ .setAccessor(accessor);
+
+ // Append to oAuth parameters. The parameter will be added to the list
of oAuth parameters
+ // (like signature method, token and signature) and send along with
the request in the specified
+ // style (which is query string, authorize header or message body)
+ request.addParameter("status", TWEET_MSG);
+ request.addParameter("lat", "51.826039");
+ request.addParameter("long", "5.796382");
+ request.addParameter("display_coordinates", "true");
+
+ // NB: signing the request with some signature method is completely
handled by the OAuth client
+ // Unless specified otherwise, HMAC SHA1 encryption is used
+ // Timestamp, nonce and OAuth version are all set automatically.
+ OAuthMessage message = m_oauthClient.invoke(request);
return convertStreamToString(message.getBodyAsStream());
}
private String getAccountTotals(OAuthAccessor accessor) throws
IOException, URISyntaxException, OAuthException {
- String url = "http://api.twitter.com/1/account/totals.json";
- OAuthMessage message = m_oauthClient.accessResource(accessor, url,
"GET");
- return convertStreamToString(message.getBodyAsStream());
- }
-
- private String getAccountSettings(OAuthAccessor accessor) throws
IOException, URISyntaxException, OAuthException {
- String url = "http://api.twitter.com/1/account/settings.json";
- OAuthMessage message = m_oauthClient.accessResource(accessor, url,
"GET");
+ OAuthHttpRequest request = new OAuthHttpRequest()
+ .setHttpMethod(OAuthMessage.GET)
+ .setUrl("http://api.twitter.com/1/account/totals.json")
+ .setAccessor(accessor);
+ OAuthMessage message = m_oauthClient.invoke(request);
return convertStreamToString(message.getBodyAsStream());
}
private String getAccountVerifyCredentials(OAuthAccessor accessor) throws
IOException, URISyntaxException,
OAuthException {
- String url =
"http://api.twitter.com/1/account/verify_credentials.json";
- OAuthMessage message = m_oauthClient.accessResource(accessor, url,
"GET");
+ OAuthHttpRequest request = new OAuthHttpRequest()
+ .setHttpMethod(OAuthMessage.GET)
+ .setUrl("http://api.twitter.com/1/account/verify_credentials.json")
+ .setAccessor(accessor);
+ OAuthMessage message = m_oauthClient.invoke(request);
return convertStreamToString(message.getBodyAsStream());
}
- private String updateProfile(OAuthAccessor accessor) throws IOException,
URISyntaxException, OAuthException,
- JSONException {
- String url = "http://api.twitter.com/1/account/update_profile.json";
- url += "?location=Nijmegen";
- OAuthMessage message = m_oauthClient.accessResource(accessor, url,
"POST");
- return convertStreamToString(message.getBodyAsStream());
+ private final static String imagePath =
"C:\\temp\\amdatu-logo-64x64-transpare.png";
+
+ private String updateProfileImage(OAuthAccessor accessor) throws
OAuthException {
+ OAuthHttpRequest request = new OAuthHttpRequest()
+ .setHttpMethod(OAuthMessage.POST)
+
.setUrl("https://api.twitter.com/1/account/update_profile_image.json")
+ .setAccessor(accessor);
+
+ // Add the image as file part (making it a multipart request)
+ request.addFilePart("image", new File(imagePath));
+
+ // Set the parameter style of this request to authorization header. By
default,
+ // OAuth parameters are send using the body of the request, but we
need the
+ // body to send the image.
+ request.setParameterStyle(ParameterStyle.AUTHORIZATION_HEADER);
+
+ OAuthMessage message = m_oauthClient.invoke(request);
+ try {
+ return convertStreamToString(message.getBodyAsStream());
+ }
+ catch (IOException e) {
+ throw new OAuthException("Could not upload profile image", e);
+ }
+
}
public String convertStreamToString(InputStream is) throws IOException {
- /*
- * To convert the InputStream to String we use the
- * Reader.read(char[] buffer) method. We iterate until the
- * Reader return -1 which means there's no more data to
- * read. We use the StringWriter class to produce the string.
- */
if (is != null) {
Writer writer = new StringWriter();
-
char[] buffer = new char[1024];
try {
- Reader reader = new BufferedReader(
- new InputStreamReader(is, "UTF-8"));
+ Reader reader = new BufferedReader(new InputStreamReader(is,
"UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
Modified:
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterServiceProvider.java
==============================================================================
---
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterServiceProvider.java
(original)
+++
sandbox/ivol/twitter-example/src/main/java/org/amdatu/auth/example/oauth/twitter/service/TwitterServiceProvider.java
Tue Aug 9 14:54:12 2011
@@ -15,7 +15,7 @@
*/
package org.amdatu.auth.example.oauth.twitter.service;
-import org.amdatu.authentication.oauth.api.OAuthServiceProvider;
+import org.amdatu.auth.oauth.api.OAuthServiceProvider;
/**
* This class represents the Twitter service we will invoke from the client.
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits