Created
January 21, 2012 13:26
-
-
Save zaneli/1652772 to your computer and use it in GitHub Desktop.
「mixi アプリで試す OpenSocial」ブログ用
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.oauth; | |
import java.io.IOException; | |
import java.security.GeneralSecurityException; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import org.apache.http.HttpResponse; | |
import org.apache.http.client.HttpClient; | |
import org.apache.http.client.methods.HttpGet; | |
import org.apache.http.impl.client.DefaultHttpClient; | |
public class OAuthClient { | |
private final String consumerKey; | |
private final String secretAccessKey; | |
private final SignatureMethod signatureMethod; | |
private final String appUrl; | |
private final Map<String, String> queryParams = new HashMap<String, String>(); | |
public OAuthClient( | |
String consumerKey, String secretAccessKey, String appUrl, Map<String, String> queryParams) { | |
this(consumerKey, secretAccessKey, SignatureMethod.HMAC_SHA1, appUrl, queryParams); | |
} | |
public OAuthClient( | |
String consumerKey, | |
String secretAccessKey, | |
SignatureMethod signatureMethod, | |
String appUrl, | |
Map<String, String> queryParams) { | |
this.consumerKey = consumerKey; | |
this.secretAccessKey = secretAccessKey; | |
this.signatureMethod = signatureMethod; | |
this.appUrl = appUrl; | |
this.queryParams.putAll(queryParams); | |
} | |
public HttpResponse execute() throws GeneralSecurityException, IOException { | |
HttpGet get = new HttpGet(createQueryUrl(appUrl, queryParams)); | |
OauthParams oauthParam = new OauthParams(consumerKey, signatureMethod); | |
SignatureBuilder signatureBuilder = new SignatureBuilder( | |
queryParams, oauthParam, secretAccessKey, get.getMethod(), appUrl, signatureMethod); | |
String signature = signatureBuilder.build(); | |
get.addHeader(oauthParam.getAuthorizationHeaderParam(signature)); | |
HttpClient httpClient = new DefaultHttpClient(); | |
return httpClient.execute(get); | |
} | |
private String createQueryUrl(String url, Map<String, String> queryParams) { | |
StringBuilder sb = new StringBuilder(url); | |
boolean addAmp = false; | |
for (Entry<String, String> entry : queryParams.entrySet()) { | |
if (addAmp) { | |
sb.append('&'); | |
} else { | |
sb.append('?'); | |
addAmp = true; | |
} | |
sb.append(entry.getKey()).append('=').append(entry.getValue()); | |
} | |
return sb.toString(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.oauth; | |
import java.util.HashMap; | |
import java.util.Map.Entry; | |
import org.apache.commons.lang.RandomStringUtils; | |
import org.apache.http.Header; | |
import org.apache.http.message.BasicHeader; | |
@SuppressWarnings("serial") | |
class OauthParams extends HashMap<String, String>{ | |
private static final String CONSUMER_KEY = "oauth_consumer_key"; | |
private static final String SIGNATURE_METHOD = "oauth_signature_method"; | |
private static final String TIMESTAMP = "oauth_timestamp"; | |
private static final String NONCE = "oauth_nonce"; | |
private static final String VERSION = "oauth_version"; | |
private static final String SIGNATURE = "oauth_signature"; | |
OauthParams(String consumerKey, SignatureMethod signatureMethod) { | |
put(CONSUMER_KEY, consumerKey); | |
put(SIGNATURE_METHOD, signatureMethod.getName()); | |
put(TIMESTAMP, createUnixTimestamp()); | |
put(NONCE, createNonce()); | |
put(VERSION, "1.0"); | |
} | |
Header getAuthorizationHeaderParam(String signature) { | |
StringBuilder sb = new StringBuilder(); | |
sb.append("OAuth"); | |
for (Entry<String, String> entry : entrySet()) { | |
sb.append(entry.getKey() + "=" + entry.getValue() + ","); | |
} | |
sb.append(SIGNATURE + "=" + signature); | |
return new BasicHeader("Authorization", sb.toString()); | |
} | |
private static String createUnixTimestamp() { | |
return Long.toString((System.currentTimeMillis() / 1000)); | |
} | |
private static String createNonce() { | |
return RandomStringUtils.randomAlphabetic(20); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.oauth; | |
import java.io.IOException; | |
import java.io.UnsupportedEncodingException; | |
import java.net.URLEncoder; | |
import java.security.GeneralSecurityException; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import java.util.TreeMap; | |
import javax.crypto.Mac; | |
import javax.crypto.spec.SecretKeySpec; | |
import org.apache.commons.codec.binary.Base64; | |
class SignatureBuilder { | |
private static final String ENCODE = "UTF-8"; | |
private final Map<String, String> params; | |
private final String secretAccessKey; | |
private final String httpMethod; | |
private final String appUrl; | |
private final SignatureMethod signatureMethod; | |
SignatureBuilder( | |
Map<String, String> queryParams, | |
Map<String, String> oauthParams, | |
String secretAccessKey, | |
String httpMethod, | |
String appUrl, | |
SignatureMethod signatureMethod) { | |
this.params = new TreeMap<String, String>(); | |
this.params.putAll(queryParams); | |
this.params.putAll(oauthParams); | |
this.secretAccessKey = secretAccessKey; | |
this.httpMethod = httpMethod; | |
this.appUrl = appUrl; | |
this.signatureMethod = signatureMethod; | |
} | |
String build() throws GeneralSecurityException, IOException { | |
String baseString = buildBaseString(); | |
Mac mac = Mac.getInstance(signatureMethod.getAlgorithm()); | |
mac.init(new SecretKeySpec((secretAccessKey + '&').getBytes(ENCODE), signatureMethod.getAlgorithm())); | |
byte signature[] = mac.doFinal(baseString.getBytes(ENCODE)); | |
return URLEncoder.encode(new String(Base64.encodeBase64(signature)), ENCODE); | |
} | |
private String buildBaseString() throws UnsupportedEncodingException { | |
StringBuilder sb = new StringBuilder(); | |
sb.append(URLEncoder.encode(httpMethod, ENCODE)).append('&'); | |
sb.append(URLEncoder.encode(appUrl, ENCODE)).append('&'); | |
sb.append(URLEncoder.encode(buildQueryString(), ENCODE)); | |
return sb.toString(); | |
} | |
private String buildQueryString() throws UnsupportedEncodingException { | |
StringBuilder sb = new StringBuilder(); | |
boolean addAmp = false; | |
for (Entry<String, String> entry : params.entrySet()) { | |
if (addAmp) { | |
sb.append('&'); | |
} else { | |
addAmp = true; | |
} | |
sb.append(entry.getKey()).append('=').append(entry.getValue()); | |
} | |
return sb.toString(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.oauth; | |
public enum SignatureMethod { | |
HMAC_SHA1("HMAC-SHA1", "HmacSHA1"); | |
private final String name; | |
private final String algorithm; | |
SignatureMethod(String name, String algorithm) { | |
this.name = name; | |
this.algorithm = algorithm; | |
} | |
String getName() { | |
return name; | |
} | |
String getAlgorithm() { | |
return algorithm; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<Module> | |
<ModulePrefs title="Hello, world!"> | |
<Require feature="opensocial-0.8" /> | |
</ModulePrefs> | |
<Content type="html"><![CDATA[ | |
<h4>プロフィール</h4> | |
<dl> | |
<dt>ユーザID</dt><dd id="userId"></dd> | |
<dt>ユーザ名</dt><dd id="userName"></dd> | |
<dt>プロフィール写真</dt><dd id="userThumbUrl"></dd> | |
</dl> | |
<h4>フレンド</h4> | |
<p id="friendSummary"></p> | |
<div id="friendNames"></div> | |
<script type="text/javascript"> | |
function init() { | |
getProfileData(); | |
getFriendDatas(0); | |
} | |
// プロフィールから ID, 表示名, サムネイルの URL を取得して表示 | |
function getProfileData() { | |
var req = opensocial.newDataRequest(); | |
req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), "viewer"); | |
req.send(function(data) { | |
if (!data.hadError()) { | |
var viewer = data.get("viewer").getData(); | |
var id = viewer.getId(); | |
var name = viewer.getDisplayName(); | |
var thumbUrl = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL); | |
document.getElementById("userId").innerHTML = id; | |
document.getElementById("userName").innerHTML = name; | |
document.getElementById("userThumbUrl").innerHTML = "<img src=\"" + thumbUrl + "\"/>"; | |
} | |
}); | |
} | |
// 初期表示時、[前へ][次へ]ボタン押下時にフレンドリストを 20 件ずつ取得して表示 | |
function getFriendDatas(first) { | |
var max = 20; | |
var req = opensocial.newDataRequest(); | |
var params = {}; | |
params[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER; | |
params[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS"; | |
params[opensocial.DataRequest.PeopleRequestFields.MAX] = max; | |
params[opensocial.DataRequest.PeopleRequestFields.FIRST] = first; | |
var idSpec = opensocial.newIdSpec(params); | |
var req = opensocial.newDataRequest(); | |
req.add(req.newFetchPeopleRequest(idSpec, params), "friends"); | |
req.send(function(data) { | |
if (!data.hadError()) { | |
var friendNames = document.getElementById("friendNames"); | |
clearOldFriendList(friendNames); | |
var friendList = document.createElement("ul"); | |
friendList.id = "friendList"; | |
friendNames.appendChild(friendList); | |
var friends = data.get("friends").getData(); | |
var offset = parseInt(friends.getOffset()); | |
var total = parseInt(friends.getTotalSize()); | |
var lastIndex = parseInt(friends.size()) + offset; | |
var friendSummary = document.getElementById("friendSummary"); | |
friendSummary.innerHTML = total + "件中 " + (offset + 1) + " - " + lastIndex + " 件を表示"; | |
friends.each(function(friend) { | |
var friendName = document.createElement("li"); | |
friendName.innerHTML = friend.getDisplayName(); | |
friendList.appendChild(friendName); | |
}); | |
if (offset > 0) { | |
var prev = offset - max; | |
friendNames.appendChild(createPagingButton("prevBtn", "前へ", prev)); | |
} | |
if (total > lastIndex) { | |
var next = offset + max; | |
friendNames.appendChild(createPagingButton("nextBtn", "次へ", next)); | |
} | |
} | |
}); | |
} | |
// [前へ][次へ]ボタン押下時に前回表示されていたフレンドリストをクリア | |
function clearOldFriendList(friendNames) { | |
var friendList = document.getElementById("friendList"); | |
if (friendList) { | |
friendNames.removeChild(friendList); | |
} | |
var prevBtn = document.getElementById("prevBtn"); | |
if (prevBtn) { | |
friendNames.removeChild(prevBtn); | |
} | |
var nextBtn = document.getElementById("nextBtn"); | |
if (nextBtn) { | |
friendNames.removeChild(nextBtn); | |
} | |
} | |
// [前へ][次へ]ボタンを作成 | |
function createPagingButton(idValue, dispValue, first) { | |
var button = document.createElement("input"); | |
button.id = idValue; | |
button.setAttribute("type", "button"); | |
button.setAttribute("value", dispValue); | |
button.setAttribute("onclick", "getFriendDatas(" + first + ")"); | |
return button; | |
} | |
// ガジェットがブラウザに読み込まれたタイミングで実行される関数(init)を登録 | |
gadgets.util.registerOnLoadHandler(init); | |
</script> | |
]]></Content> | |
</Module> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment