2010/02/17


TwitterのBasic認証APIは6月で廃止される予定なのですが、OAuthという認証方法はブラウザを起動してユーザに認証して貰わなければなりません。一見flickrアプリケーションの様な認証方法を想定しますが、OAuthはflickr認証の様にサーバから貰ったトークンをブラウザから渡して認証させる様な物ではありません。
今回OAuthの問題を解決すべくOAuthを拡張した認証方式であるxAuthが取り入れられました。
詳しくはAPIドキュメントか以下のサイトが分かりやすいかと思います。
s-take Blog.: Twitterによる簡易版OAuth: "xAuth"

従来のOAuth認証ではまずアプリケーション(OAuthコンシューマ)がTwitterに接続してRequest Tokenを取得し、認証画面を開いてRequest Tokenを承認させ、承認されたRequest Tokenを使ってAccess TokenとToken Secretを取得することによって各APIにアクセスできるようになります。しかしこれはアプリケーション側の実装が複雑になる上、デスクトップアプリケーションの場合はわざわざWebブラウザへ切り替えなければならず(ブラウザを内包するものもありますが)、ユーザにとっても面倒なものです。

http://s-take.blogspot.com/2010/02/twitteroauth-xauth.html
the.hackerConundrum: Sneak peek at Twitter's browserless OAuth credentials exchange method

Over the past couple of months the Twitter API Google Group has been overflowing with more and more disgruntled developers complaining about lack of bug fixes, slow rollout of promised features, no mobile interface for OAuth, etc. (The list goes on and on) Well I'm happy to say Twitter appears to be almost done with one much requested feature: browserless OAuth credentials exchange. It was hinted that Seesmic Look was using said exchange so today I took a peek at how Look worked behind the scenes.

http://the.hackerconundrum.com/2010/02/sneak-peek-at-twitters-browserless.html
実装だと
Maraigue風。:[Ruby][Twitter] OAuthのアクセストークンを、ブラウザなしで、Twitterのユーザ名およびパスワードのみを用いて取得する(通称:xAuth)ためのRubyのコード
http://blog.livedoor.jp/maraigue/archives/1109122.html
とか
pastebin - 誰か - post number 1796209
http://ja.pastebin.ca/1796209
あとOAuthな話ですが
あまやどり: OAuthで認証してTwitterでつぶやいてみた
http://petitbanca.blogspot.com/2009/11/oauthtwitter.html
あたりが参考になります。今日はpythonを使ってxAuthするサンプルを書いてみました。pythonにも元々oauthライブラリはあるのですが、今回は分かりやすく使わず書いてみました。
以下ソース。
from pit import Pit
from random import getrandbits
from time import time
import hmac, hashlib
import sys
import urllib
import urllib2
import urlparse

consumer_key = 'YOUR-CONSUMER-KEY'
consumer_secret = 'YOUR-CONSUMER-SECRET'
user = Pit.get('twitter.com', {'require' : {
  'username' : 'your username in twitter.com',
  'password' : 'your password in twitter.com',
}})
message = sys.argv[1]
access_url = 'https://api.twitter.com/oauth/access_token'
post_url = 'http://twitter.com/statuses/update.json'

# build parameter to get access token
params = {
  'oauth_consumer_key' : consumer_key,
  'oauth_signature_method' : 'HMAC-SHA1',
  'oauth_timestamp' : str(int(time())),
  'oauth_nonce' : str(getrandbits(64)),
  'oauth_version' : '1.0',
  'x_auth_mode' : 'client_auth',
  'x_auth_username' : user['username'],
  'x_auth_password' : user['password'],
}
params['oauth_signature'] = hmac.new(
  '%s&%s' % (consumer_secret, ''),
  '&'.join([
      'POST',
      urllib.quote(access_url, ''),
      urllib.quote('&'.join(['%s=%s' % (x, params[x])
          for x in sorted(params)]), '')
  ]),
  hashlib.sha1).digest().encode('base64').strip()

# get access token
req = urllib2.Request(access_url, data = urllib.urlencode(params))
res = urllib2.urlopen(req)
token = urlparse.parse_qs(res.read())
token_key = token['oauth_token'][0]
token_secret = token['oauth_token_secret'][0]

# build parameters to post
params = {
  'oauth_consumer_key' : consumer_key,
  'oauth_signature_method' : 'HMAC-SHA1',
  'oauth_timestamp' : str(int(time())),
  'oauth_nonce' : str(getrandbits(64)),
  'oauth_version' : '1.0',
  'oauth_token' : token_key,
}
params['status'] = urllib.quote(message, '')
params['oauth_signature'] = hmac.new(
  '%s&%s' % (consumer_secret, token_secret),
  '&'.join([
      'POST',
      urllib.quote(post_url, ''),
      urllib.quote('&'.join(['%s=%s' % (x, params[x])
          for x in sorted(params)]), '')
  ]),
  hashlib.sha1).digest().encode('base64').strip()
del params['status']

# post with oauth token
req = urllib2.Request(post_url, data = urllib.urlencode(params))
req.add_data(urllib.urlencode({'status' : message}))
req.add_header('Authorization', 'OAuth %s' % ', '.join(
  ['%s="%s"' % (x, urllib.quote(params[x], '')) for x in params]))

# done!
print urllib2.urlopen(req).read()
生の処理で書いてあるので、oauthライブラリに依存させたくない様な移植には参考になるかもしれません。
ところで今回GtkTwitterというC言語で書いたTwitterクライアントのBasic認証を止めようと思っていてこの件を調べ始めたのですが, どうやらTwitterに登録するOAuthアプリケーションには「Twitter」という文言を使ってはいけない事が今日分かりました。まぁGtkTwitterはクライアントアプリが名前登録出来た頃に書いた物なので、あの頃はOKだったのかも知れません。
しかしまぁ...どうせぃっちゅうねん!

どうしましょ。Gtkほにゃらら...何がいいやろ。困った。
Posted at by



2010/02/05


darcs github流行ってますね。オープンソース開発者にとってgitは必須アイテムでもあり登竜門的な技術要素になってきました。しばらくはgitが一般的なVCS(version control system)になっていくんだろうなと思います。まぁLinus氏が飽きればまた次のが流行るのかな。
ちょっと前からgoのgtkバインディングを開発していますが、先日とある方がforkしてpull requestしてくれました。
David Roundy氏。知っている人は知っている、darcsのauthorです。ちょっと久しくdarcsを触って無かったので思い立ってバージョンを上げ、試してみました。
commitじゃなくてrecordだったり、logじゃなくchangesだったりと少しgitやsvnと違和感があったりもしますが、とても単一モジュールで動いているとは思えない程の機能を持ち合わせています。
昨日iratqqさんがmpc(Music Player Client: Client for Music Player Daemon)のhttpd版をHaskellで書いてたので試そうと思い、リポジトリを見たらpatch-tag.comというSCMサイトでした。これまたサービス自体もHaskellで書かれているとの事で、Haskellなんかまともに書けない私が参加して良いものだろうかとか考えながら登録してみました。
さて、darcsも内部では(デフォルトは)ssh通信を行うので、使うにはgitの時と同じ様に
Big Sky :: SSHポートが通らなくてもgithub.comにpushする方法

pushはsshを使うのでport 22が開いてないとpush出来ない物と信じ込んでいました。が、今日解決しました。

http://mattn.kaoriya.net/software/20081029172540.htm

Big Sky :: SSH/Gitの設定を修正しなくてもファイアウォール内からgithub.comにpushする方法

Gitはトランスポート層が選択出来るのは知っていたけど、まさかこんな書き方出来るとは思ってなかった。

http://mattn.kaoriya.net/software/20090624103050.htm
こんな手順を踏まなきゃ駄目なのは分かってたんですが、なんとなしに「ssh.patch-tag.com」というキーワードでググってたら...見つけました!
How to get around firewalls using Patch-Tag « the Patch-Tag blog

We have been tweaking the retrieval parameters for repository access via SSH. Did you know you can get around firewalls that block port 22? Thats right, we have now added support for this.

http://blog.patch-tag.com/2009/02/25/how-to-get-around-firewalls-using-patch-tag/
github.comがssh.github.com:443を開けているのと同じ様にpatch-tag.comもssh.patch-tag.com:443でsshを開けているとの事。ここに書かれている手順通りでも良いのですが、リポジトリ名を修正しなくても使える方法を今日はご紹介。
gitの時の手順と同じ様に、ssh/configファイルを使い、patch-tag.comへのsshアクセスをssh.patch-tag.comの443ポートへと繋ぎ変えます。 Host patch-tag.com
    Hostname ssh.patch-tag.com
    Port 443
    IdentityFile c:/docume~1/mattn/.ssh/id_rsa
    TCPKeepAlive yes
    IdentitiesOnly yes
    ProxyCommand c:/docume~1/mattn/.ssh/connect -h ssh.patch-tag.com 443

proxyでFirewallを越えるのでProxyCommandを使います。connectはここにある物をコンパイルして使います。
さて、これでokと思ったのですが1点問題が発生しました。何度やってもsshのログインプロンプトが表示されません。おかしいなと思い色々調べていたら
Wiki - WindowsConfiguration

If you want to use darcs over ssh you need to set up passwordless ssh login (password-based authentification is currently broken on windows).

http://wiki.darcs.net/WindowsConfiguration
おーまいがっ!
Windows版は現状壊れてるのでパスワード無しでないと駄目らしい。それは痛い。puttyを使いたくない派には残酷なお知らせ。
諦めかけたその時思い出した。
Big Sky :: Windowsでもssh-agentとssh-addを使ってパスフレーズ入力を省略する。

開発を始める前にコマンドプロンプトで1回これを動かすとパスフレーズを聞かれ、1回入力すれば以降は聞かれない様になる。

http://mattn.kaoriya.net/software/20081106192615.htm
ちなみに手元の最新版ssh-env.batは以下の様になってます。
@echo off
if "%1" == "-f" goto force
if not "%SSH_AGENT_PID%" == "" goto end
:force
for /f "eol=; tokens=1,2 delims==;" %%1 in ('ssh-agent.exe') do (
 if "%%1" == "SSH_AUTH_SOCK" set SSH_AUTH_SOCK=%%2
 if "%%1" == "SSH_AGENT_PID" set SSH_AGENT_PID=%%2
)
ssh-add
:end
強制フラグ付けただけですが...。
これをコマンドプロンプトで1回実行した後にdarcsを実行します。
C:¥TEMP>ssh-env
Enter passphrase for /c/docume~1/mattn/.ssh/id_rsa:
Identity added: /c/docume~1/mattn/.ssh/id_rsa (/c/docume~1/mattn/.ssh/id_rsa)

C:¥temp>darcs get mattn@patch-tag.com:/r/mattn/mattn-testproject
Copying patches, to get lazy repository hit ctrl-C...
Finished getting.

C:¥temp>
うぉーーー!でけた。ちなみにチェックアウトしたファイルに変更を加えてdarcs pushもうまく動いています。

これでdarcsライフも満喫出来そうです。gitとは少し違ったVCS味わってみませんか。
Posted at by




なんでか分かんないけど、今日突然Google Chromeがクラッシュして落ちた。まぁdevチャネルつかってるからしょうがないかとは思ったんだけど、再起動したら1秒で「はてなブックマーク拡張」が落ちる様になった。いろいろ調べてもダメで、どうやら拡張が使ってるストレージが壊れた様子。
調べた結果 C:¥Documents and Settings¥ユーザ名¥Local Settings¥Application Data¥Google¥Chrome¥User Data¥Default¥Local Storage には「chrome-extension_拡張ID」から始まるsqlite3のファイルがあり、どうやらこれが書き込まれている最中にクラッシュした為、読み込み出来なくなったみたい。
「はてなブックマーク拡張」はローカルストレージ自身に重要性は無かったので chrome-extension_dnlfpnhinnjdgmjfpccajboogcjocdla_0.localstorage をためらい無しに削除、そして再起動。
見事復活出来ました。

ちなみにUNIX系だと $HOME/.config/google-chrome/Default/Local Storage にあります。
Posted at by