トップ 最新 追記   RSS 1.0 FEED  

Journal InTime


2005-07-01 (Fri) [長年日記]

_ [その他] JAFと警察

通勤途中、前の車が信号が青になっても進まないのでクラクションを 鳴らしたら、運転手が降りてきた。 「しまった、やられる」と思ってびくびくしていると、車が故障 したのでJAFを呼びたい、携帯を貸してほしい、とのこと。

気安く応じたものの、なかなか電話が終わらない。 片道2車線ではあるが、後ろを見ると大渋滞である。 どうもJAFに入っておらず、お金も持ってないそうで、JAFには 来てもらえないらしい。 「へえ、JAFって後払いできないんだ」 と思いつつ「警察に電話してみたらどうですか」と勧めたが、 やっぱり来てもらえないらしい。事故じゃなくてただの故障だと 対応できないとのこと。

最後は、自分が賢察に「そんなこと言ったって こんなとこに車が止まってたら交通の邪魔だから、レッカーか何かで 移動するくらいしてくださいよ」ということで、何とか来てもらう ことにしてその場を去った。

その後どうなったのかなあ。

_ [Ruby] Subversionへの移行

ruby-devとruby-coreで提案してみたが、ruby-coreの方は「いや、 あれがいい」とか「これがいい」とか出て来る、出て来る。

だんだん、もうCVSでいいやって気分になって来たな。 Subversionに移行した方がよいと思う方はruby-coreでがんばってください。

本日のツッコミ(全2件) [ツッコミを入れる]

_ ささだ [賢察?]

_ shugo [もう、いじわる。]


2005-07-02 (Sat) [長年日記]

_ [Ruby] 新しいブロックパラメータの文法

{} でくくったブロックの最初には () でくくった式が来ちゃイケナイってのは、無茶苦茶でかい仕様変更だから無理なんだろうなぁ。

[だいありーより引用]

メソッドの引数に合わせて *1、 {やdoとブロックパラメータの(の間に スペースを許さないようにするというのはどうだろう。

method(x, y) do(a, b)
  #...
end
method(x, y) {(a, b)
  #...
}

のような場合は、(a, b)をブロックパラメータとして扱って、

method(x, y) do (a, b)
  #...
end
method(x, y) { (a, b)
  #...
}

のような場合は、(a, b)をグルーピングされた式として扱う。

*1  現状ではまだ警告だけど。

_ [Ruby] Collaboa

Rubyで書かれたTracのようなもの。 しかし、ほんとにそっくりだなあ。 HTMLやCSSの流用をしてたりするんだろうか。

とりあえず、ximapdで試してみた。

<URL:http://projects.netlab.jp/ximapd/dev/>

なぜかFastCGIだとbin/ximapdのブラウズ時にエラーになるので CGIにしている。遅い...。

2点ほど細かい問題を見つけたので、New Ticketしておいた。

_ [Ruby] SubversionのRuby binding

Collaboaには、SubversionのRuby bindingがいるが、 sargeのSubversionは1.1.4でRuby bindingはない*1 ので、Subversion 1.2.0を取って来て、Ruby bindingだけインストール。

$ tar jxvf subversion-1.2.0.tar.bz2
$ cd subversion-1.2.0/
$ ./configure --with-apr=/usr/bin/apr-config --with-apr-util=/usr/bin/apu-config --with-neon=/usr/bin/neon-config
$ make check-swig-rb
# make install-swig-rb

ちなみに、Subversion 1.2.0はSubversion 1.1.4とAPI互換らしい。 新しい関数の追加だけ、というのは素晴らしいな。

*1  sidにもないか。


2005-07-03 (Sun) [長年日記]

_ [家族] 散髪

娘と散髪に。 今日は床屋で一緒に切ってもらった。

自分は仰向けで頭を洗われるのが嫌いなのだが、娘は大丈夫らしい。 床屋で仰向けなのは邪道だと思う(自分はうつぶせでやってもらった)の だが、最近の床屋が仰向けで頭を洗うのは男の髪が長くなって来た せいだろうか。

本日のツッコミ(全2件) [ツッコミを入れる]

_ なかだ [大概そうだと思ってましたが。]

_ shugo [えー。きっと何かの間違いですよ。「それでも床屋はうつぶせで頭を洗っている。」]


2005-07-05 (Tue) [長年日記]

_ [ソフトウェア] Thunderbirdでフォルダを開いた時に自動的にダウンロードしない設定

ThunderbirdはIMAPフォルダを開いただけで、勝手にそのフォルダの 全メールのダウンロードを始めてしまうので、spamフォルダを開くとなかなかつらい。

どなたか勝手にダウンロードをさせない設定を知っていたら教えてくださいm(..)m

mail.server.default.download_on_biffという設定は見つけたけど、 これは

新着確認で新しい message を download するなら true、user に新しい mail があることを通知するなら false。

ということで、ちょっと違うんだよなあ。


2005-07-06 (Wed) [長年日記]

_ [ソフトウェア] CollaboaのBrowserで日本語のテキストを表示する

ximapdをいじるつもりが、なぜかCollaboaをハックしていた。 Browserでiconvを通すようにしたので、以下のようにちゃんと日本語が表示できるようになった。

<URL:http://projects.netlab.jp/ximapd/dev/repository/file/trunk/README.ja>

svk便利だなあ。

_ [ximapd] --rebuild-index

寝入りばなにDSAで起こされたついでに、--rebuild-indexを実装。 Rastのインデックスが壊れたらお試しください。

本日のツッコミ(全2件) [ツッコミを入れる]

_ ただただし [わーい、待ってました〜 >--rebuild-index]

_ shugo [ほんとは使わなくていいはずのオプションなのですけどね(^_^;]


2005-07-14 (Thu) [長年日記]

_ [Rails] created_on/updated_on

created_onフィールドおよびupdated_onフィールドは必須ではありませんが、これらのフィールドを指定すると、Railsが自動的に保持します。

[IBM dW : linux :Ruby on RailsによるWebアプリケーションの高速開発 - Japanより引用]

そんな機能があったのか。

_ [ximapd] サイトリニューアル

Railsでサクっと作ってみた。 コンテンツはBlueClothによるMarkdown記法で書いているのだが、 Markdownってテーブルないんだっけ。 結局テーブルはHTMLで書いてしまった。 あと、言語の切替えはセッション管理でやっているのだが、これだと Googleが日本語のページを拾ってくれないような気がする。 URLにjaとかenとかが入るようにしないとだめだろうか。

実はこれのせいで本体の開発がぜんぜん進んでない。 とりあえず、0.0.2を出しとくかなあ。

_ [ximapd] 0.0.2リリース

というわけでリリースしました。

_ [仕事][言語] 強い型の言語の気持ちよさ

前日にビルド環境がなかったので、適当に書いていたコードが やはりコンパイルに失敗した。 とりあえず、コンパイルが通るようにしたところ、一発で動作。 こういう時の気持ち良さには、Rubyにはないものがあるな。

書いたコードが一発でテストに通った時がそれに近いけど、 自分で書いたテストには何となく不安があるので、通ったら 通ったで「本当にだいじょうぶかなあ」という気分になる。 結局テストをきちんと書けってことなんだけど、いろんなケースを 網羅するテストをいっぱい書くのはつらいんだよなあ。

本日のツッコミ(全6件) [ツッコミを入れる]

_ かずひこ [おぉ、しいたけアイコン!]

_ shugo [一応(洋服の)ボタンをイメージしたつもりだったのにorz...]

_ shugo [FAQに追加しときました。 http://projects.netlab.jp/ximapd/page/show/..]

_ smbd [確かにしいたけだ…]

_ しゅどう [最近、ようやくIDE (Eclipse) を使い始めたんですが、書いているそばから文法上の問題がバリバリと指摘されて..]

_ shugo [いいですねえ。 RubyでもRefactoring Browserでextract methodができるようになった..]


2005-07-15 (Fri) [長年日記]

_ [Rails] CSRF対策

0.13.0にもCSRF対策のコードはとくにないようだ。 MLの議論を追ってなかったのだが、結局アプリケーション側で対策する べしということだろうか。

まず、ApplicationControllerとApplicationHelperに以下のような記述をしておく。

app/controller/application.rb:

class ApplicationController < ActionController::Base
  private


  def validate_session
    if @params[:session_id_validation] == @session.session_id
      return true
    else
      render(:text => SESSION_VALIDATION_FAILED_HTML,
             :status => "403 Forbidden")
      return false 
    end
  end

  SESSION_VALIDATION_FAILED_HTML = <<EOF
<html>
  <head>
    <title>403 Forbidden</title>
  </head>
  <body>
    <h1>403 Forbidden</h1>
    <p>
      Session validation failed.
    </p>
  </body>
</html>
EOF
end

app/helpers/application_helper.rb:

module ApplicationHelper
  def secure_form_tag(*args)
    return start_form_tag(*args) + "\n" +
      hidden_field_tag("session_id_validation", @session.session_id)
  end
end

あとは、保護が必要な各フォームでstart_form_tagの代りにsecure_form_tagを 使い、

app/views/<controller_name>/edit.rhtml:

<h1>Edit</h1>

<%= secure_form_tag :action => 'update', :id => @model_name %>
  <%= render_partial 'form' %>
  <%= submit_tag 'Edit' %>
<%= end_form_tag %>

<%= link_to 'Show', :action => 'show', :id => @model_name %> |
<%= link_to 'Back', :action => 'list' %>

各コントローラの必要なアクションにフィルタを設定する。

app/controllers/<controller_name>_controller.rb

class <ControllerName>Controller < ApplicationController
  before_filter :validate_session, :only => [:create, :update, :destroy]

  #...
end

こんなもんかなあ。

あと、scaffoldはGETでdestoryするようなコードを出力するので、 確認画面を用意してPOSTでdestroyするようにする必要がある。

_ [Rails] Login GeneratorのSession Fixation Attack対策

今度はSession Fixation Attack(セッション固定攻撃)対策。

RailsはデフォルトでセッションIDを発行するようになっているが、 Login Generatorが生成するコードは、どうも認証後も同じセッションID を使っているようだ。

def login
  case @request.method
    when :post
    if @session[:user] = User.authenticate(@params[:user_login], @params[:user_password])

      flash['notice']  = "Login successful"
      redirect_back_or_default :action => "welcome"
    else
      flash.now['notice']  = "Login unsuccessful"

      @login = @params[:user_login]
    end
  end
end

このため、Session Fixation Attackの危険性があると思われる。

これを回避するには以下のようにセッションをリセットしてやればよい。

def login
  case @request.method
  when :post
    user = User.authenticate(@params[:user_login], @params[:user_password])
    if user
      return_to = @session[:return_to]
      @request.reset_session
      @session = @request.session
      @session[:user] = user
      @session[:return_to] = return_to if return_to
      flash['notice']  = "Login successful"
      redirect_back_or_default :controller => "page", :action => "list"
    else
      flash.now['notice']  = "Login unsuccessful"

      @login = @params[:user_login]
    end
  end
end

_ [Rails] クッキーのパス

Railsではクッキーのパスはデフォルトで/に設定されるようだ。 これは/以外の場所(たとえば/ximapd)で運用する場合は望ましくない。

変更するには以下のようにconfig/environment.rbの末尾に記述すればよい。

ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:session_path] = "/ximapd"

_ [Rails] セッションファイルの作成場所

Railsではセッションファイルの作成場所はデフォルトで/tmpになる。 *1

/tmpの直下にセッションファイルを作るのはあまり好ましくない。 なぜなら、cronなどで削除した際に、同じファイル名で偽物のセッションファイルを作成できてしまうからだ。

変更するには以下のようにconfig/environment.rbの末尾に記述すればよい。

ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:tmpdir] =
  File.expand_path("session", RAILS_ROOT)

もちろん、ディレクトリのパーミッションには注意が必要。 現在のCGI::Sessionでは、ファイル名からセッションIDを推測できないように なっているが、Railsの実行ユーザ以外はアクセスできないようにしておいた方が いいだろう。

*1  実際には環境による。

本日のツッコミ(全1件) [ツッコミを入れる]

_ TrackBack [http://shugo.net/jit/20050716.html#p01 Journal InTime [Rub..]


2005-07-16 (Sat) [長年日記]

_ [Rails] Login GeneratorのSession Fixation Attack対策(2)

これを回避するには以下のようにセッションをリセットしてやればよい。

[Journal InTime - CSRF対策 , Login GeneratorのSession Fixation Attack対策 , クッキーのパス , セッションファイルの作成場所より引用]

某所でセッションデータは引き継ぎたいという話があったのでちょっと改良。

def login
  case @request.method
  when :post
    user = User.authenticate(@params[:user_login], @params[:user_password])
    if user
      @session[:user] = user
      data = @session.instance_variable_get(:@data)
      @request.reset_session
      @session = @request.session
      for key, val in data
        @session[key] = val
      end
      flash['notice']  = "Login successful"
      redirect_back_or_default :controller => "page", :action => "list"
    else
      flash.now['notice']  = "Login unsuccessful"

      @login = @params[:user_login]
    end
  end
end

もうちょっとマシな方法はないものか。

_ [Rails] Login GeneratorのSession Fixation Attack対策(3)

しつこいようですが。

RailsではクッキーでしかセッションIDは渡されないので、session fixation は難しいのではないかという話がある。

しかし、たとえば、ホスティングサービスなどで、同一ドメイン上に信頼 できない他のウェブアプリケーションが存在する場合などは危険だ。 また、他のXSS脆弱性との合わせ技といったことも考えられるので、 対策はしておいた方がよいと思う。


2005-07-19 (Tue) [長年日記]

_ [会社] クールビズ

半袖・ノーネクタイはいつも通りなので、半ズボンで出社。

エアコンの設定温度を28度にしていたはずが、だれかが下げていたので また上げてみたりして。

_ [会社] 創立記念日 & 賞与

今年も無事この日を迎えることができました。 ありがたや。

本日のツッコミ(全1件) [ツッコミを入れる]

_   [半ズボンはクールすぎ (w]


2005-07-20 (Wed) [長年日記]

_ [言語] Rubyist のための他言語探訪 【第 1 回】 Python

次回は、Ruby に影響を与えた言語の一つ、CLU を紹介する予定です。 お楽しみに!

[Rubyist Magazine - Rubyist のための他言語探訪 【第 1 回】 Pythonより引用]

おお。

_ [言語] ECMAScript 4 Namespaces

今さらながらECMAScript 4のnamespaceの仕様を勉強。 ちょっとややこしいのが、x.nのようなプロパティ参照によって、どのように プロパティ(JavaScriptだとメソッドもプロパティ)が検索されるか。

まず、すべてのプロパティはq::nCのように修飾された名前を持つ。 ここで、qはnamespace、nは識別子、Cはクラスである。

次に、xを評価するとインスンスになるような式、Σをプロパティ参照を含むすべてのスコープの集合、QをΣのスコープでuseされているすべてのnamespaceの集合とする。

x.nのようにnamespaceを明示せずにプロパティを参照した場合、次のような探索が行われる。

  1. Aを、xが少なくとも一つのq::nA(qはQの任意の要素)という プロパティを持つ、最も派生していない(Objectに近い)クラスとする。 もし、そのようなプロパティがなければエラー。
  2. Q'を、Qに属し、xがq::nAというプロパティを持つすべてのnamespaceの集合とする。
  3. Pを、xのq::n(qはQ'の要素)というプロパティのうち最も派生的なすべての プロパティの集合とする。
  4. もし、Pがただ一つの要素pを持つ、あるいはPのすべての要素が一つのプロパティp の別名である場合、pを選択する。それ以外の場合はエラー。

興味深いのは、まず最もObjectに近いクラスに定義されたプロパティを探して、 namespaceの候補を絞りこむ点。 同じ識別子を持つプロパティでも、起源となるクラスによって区別することが できるということか。

あと、namespaceに関しては、

# String#lengthの定義
class String {
  function length() {
    ...
  }
}

# jcodeというnamespaceの定義
namespace jcode 

# jcodeにString#lengthを定義
class String {
  jcode function length() {
    ...
  }
}

# MyString#lengthを定義
class MyString {
  function length() {
    ...
  }
}

# jcodeの使用を宣言
use jcode
s = new MyString("あいうえお")
len = s.length()

とした時に、s.length()が呼び出すのが、jcodeのString#lengthなのか、 MyString#lengthなのか、というのが疑問だった。 ECMAScriptでは、デフォルトのnamespaceはpublicというnamespaceで、 明示的にuseしなくても利用できるらしい。 ということは、MyString#lengthが呼び出されるのだろうか。


2005-07-21 (Thu) [長年日記]

_ [tDiary] 2.0.2にアップデート

そして、tDiaryQuoteが使えなくなった。

Refererのチェックをしないようにして、csrf_protection_keyを tDiaryQuoteで渡せるようにすればいいかな。

_ [tDiary] tDiaryQuoteのPOST対応

とりあえず、手もとでは上記の修正で動いたけど、csrf_protection_keyをGETで送っているので、プレビュー画面から外部へのリンクをたどるとRefererでcsrf_protection_keyが洩れてしまう。

これを防ぐにはPOSTにすればいいんだけど、どうやればいいのかわからず。 ちなみに現状は、

updateUrl +=
    "?old=" + old +
    ";year=" + year +
    ";month=" + month +
    ";day=" + day +
    ";title=" +
    ";body=" + encodeURIComponent(body) +
    ";plugin_tb_url=" + encodeURIComponent(pingUrl) +
    ";plugin_tb_section=" +
    ";plugin_tb_excerpt=" +
    ";appendpreview=%A5%D7%A5%EC%A5%D3%A5%E5%A1%BC" +
    ";csrf_protection_key=" + encodeURIComponent(csrfProtectionKey);
var newTab = browser.addTab(updateUrl);
browser.selectedTab = newTab;

こんな感じ。

_ [Rails] lighttpd doesn't cope with 100-continue

lighttpdは

Expect: 100-continue

というへッダがあるとリクエストを受け付けてくれないので、.NETから ActionWebServiceを使うためには、以下のようにGetWebRequest()を オーバーライドしないといけない、という話。

using System;
using System.Net;

[System.Web.Services.WebServiceBinding(Name="PostPort",Namespace="urn:ActionWebService"),
System.Diagnostics.DebuggerStepThroughAttribute(),
System.ComponentModel.DesignerCategoryAttribute("code")]
public class BlaBlaService : Service
{
 protected override WebRequest GetWebRequest(Uri uri)
 {
     HttpWebRequest request = (HttpWebRequest) base.GetWebRequest(uri);
     ServicePoint servicePoint = request.ServicePoint;
     // lighttpd doesn't cope with 100-continue
     servicePoint.Expect100Continue = false;

     return request;
 }
}

_ [Rails] rast extension

なんてものを作ったらウケるだろうか。

class Article < ActiveRecord::Base
  has_rast_index :title
  has_rast_index :body
  has_rast_index :updated_on
end

としておくだけで勝手にRastのインデックスに登録してくれて、 検索する時は、

articles = Article.find_by_rast('ふが')
articles = Article.find_by_rast(['title : ?', 'ほげ'],
                                :order => "updated_on")

だけでいいとか。

本日のツッコミ(全2件) [ツッコミを入れる]

_ babie [ウケるウケる!(とりあえず1人には)]

_ 通りすがり [ ウケるウケる!(とりあえず2人目)]


2005-07-22 (Fri) [長年日記]

_ [Rails] acts_as_rast_indexed

とりあえず、サクっと作ってみた。 効率もtransactionも気にしない。

まず、rast_indexed.rbをlib/active_record/acts/以下に置く。

次にconfig/environment.rbに

require "active_record/acts/rast_indexed"
ActiveRecord::Base.class_eval do
  include ActiveRecord::Acts::RastIndexed
end

と書いて、準備完了。

デフォルトではRAILS_ROOT/index/RAILS_ENV/以下にインデックスを作るが、 ActiveRecord::Acts::RastIndexed.configurations=で設定もできる。

あとは、モデルに

class Page < ActiveRecord::Base
  acts_as_rast_indexed
end

のように書くだけで使える。

具体的にはこんな感じ。

page = Page.new(:name => "abc",
                :body => "This is abc")
page.save
pages = Page.find_by_rast(["body : ?",  "abc"])

fixturesを使えるようにするにはtest/test_helper.rbに以下のおまじないを。

class << Fixtures
  alias create_fixtures_without_rast_index create_fixtures

  def create_fixtures_with_rast_index(fixture_directory, *table_names)
    result = create_fixtures_without_rast_index(fixture_directory,
                                                *table_names)
    for table_name in table_names.flatten
      table_class_name = Inflector.classify(table_name)
      table_class = Object.const_get(table_class_name)
      begin
        table_class.rebuild_rast_index
      rescue NoMethodError
      end
    end
    return result
  end

  alias create_fixtures create_fixtures_with_rast_index
end
本日のツッコミ(全1件) [ツッコミを入れる]

_ TrackBack [http://d.hatena.ne.jp/babie/20050729#p4 遅レス。 [Ruby][Rails]..]