TodoList: access_control は必要無かった2007年01月03日 09時43分17秒

アクセス制限の実験をしてみる。

何に制限をかけようかと迷ったが、所属団体 (Organization) にすることにした。一般ユーザに、勝手に作られても困るので、編集は特権階級のみが出来ることにする。


class OrganizationController < ApplicationController
  scaffold :organization
  include AccessControl
  #access_control :all, :if => false
  access_control :show, :list, :if => true
  access_control :new, :edit, :destroy, :role => 'admin'
end

admin ユーザの uyota でアクセスすると問題ないが、user 権限を持つ uyota_user で http://localhost:3000/todo/list にアクセスしても表示されない。log/development.log を覗いてみる。

まず、以下のログが見つかった。


Processing OrganizationController#list (for 127.0.0.1 at 2006-12-29 13:07:30) [GET]
  Session ID: be7119e0113bed0af55c46c5b02b5a3b
    Parameters: {"action"=>"list", "controller"=>"organization"
    required_perm is organization/list
      ESC[4;36;1mPermission Load (0.010409)ESC[0m   ESC[0;1mSELECT DISTINCT permissions.*
      FROM permissions, roles,
       permissions_roles, users_roles,
        users
        WHERE users.id = 2
        AND users.id = users_roles.user_id
        AND users_roles.role_id = roles.id
        AND roles.id = permissions_roles.role_id
        AND permissions_roles.permission_id = permissions.id
        AND permissions.controller = 'organization'
        AND permissions.action = 'list'
        ESC[0m
  ESC[4;35;1mPermission Columns (0.010521)ESC[0m   ESC[0mSHOW FIELDS FROM permis
  sionsESC[0m
    ESC[4;36;1mPermission Load (0.005501)ESC[0m   ESC[0;1mSELECT * FROM permissions
  WHERE (permissions.`controller` = 'organization' AND permissions.`action`
= 'list' ) LIMIT 1ESC[0m
    Redirected to http://localhost:3000/user/home

http://localhost:3000/organization/list へのアクセス権限を調べている様である。アクセス権限が無いと判断されて、user/home に転送されているそうだ。

その後に、


Processing UserController#home (for 127.0.0.1 at 2006-12-29 13:07:31) [GET]
  Session ID: be7119e0113bed0af55c46c5b02b5a3b
    Parameters: {"action"=>"home", "controller"=>"user"}
    required_perm is user/home
      ESC[4;35;1mPermission Load (0.040347)ESC[0m   ESC[0mSELECT DISTINCT permissions.*
FROM permissions, roles,
 permissions_roles, users_roles,
  users
  WHERE users.id = 2
  AND users.id = users_roles.user_id
  AND users_roles.role_id = roles.id
  AND roles.id = permissions_roles.role_id
  AND permissions_roles.permission_id = permissions.id
  AND permissions.controller = 'user'
  AND permissions.action = 'home'

とあった。こちらは user/home へのアクセス制限を調べていて、権限があると判断されていた。

ログの中で、今まで覗いたことが無いテーブルがあるのに気が付いた。login_engine と user_engine がたくさんテーブルを作るので、どんなテーブルがあるのかは気にしていなかった。users や roles などのテーブルは、気になったときに見ていたが permissions は覗いたことはない。

今までの中では、一番レコードの数が多いが以下のが SQL の結果だ。


mysql> select * from permissions;
+----+------------+--------------------------+-------------+
| id | controller | action                   | description |
+----+------------+--------------------------+-------------+
|  1 | role       | new                      | NULL        |
|  2 | role       | list                     | NULL        |
|  3 | role       | edit                     | NULL        |
|  4 | role       | destroy                  | NULL        |
|  5 | role       | index                    | NULL        |
|  6 | role       | show                     | NULL        |
|  7 | permission | new                      | NULL        |
|  8 | permission | list                     | NULL        |
|  9 | permission | edit                     | NULL        |
| 10 | permission | destroy                  | NULL        |
| 11 | permission | index                    | NULL        |
| 12 | permission | show                     | NULL        |
| 13 | user       | delete                   | NULL        |
| 14 | user       | new                      | NULL        |
| 15 | user       | list                     | NULL        |
| 16 | user       | forgot_password          | NULL        |
| 17 | user       | restore_deleted          | NULL        |
| 18 | user       | delete_user              | NULL        |
| 19 | user       | logout                   | NULL        |
| 20 | user       | edit                     | NULL        |
| 21 | user       | change_password_for_user | NULL        |
| 22 | user       | edit_user                | NULL        |
| 23 | user       | signup                   | NULL        |
| 24 | user       | show                     | NULL        |
| 25 | user       | edit_roles               | NULL        |
| 26 | user       | login                    | NULL        |
| 27 | user       | home                     | NULL        |
| 28 | user       | change_password          | NULL        |
| 29 | todo       | new                      | NULL        |
| 30 | todo       | list                     | NULL        |
| 31 | todo       | edit                     | NULL        |
| 32 | todo       | destroy                  | NULL        |
| 33 | todo       | create                   | NULL        |
| 34 | todo       | index                    | NULL        |
| 35 | todo       | show                     | NULL        |
| 36 | todo       | update                   | NULL        |
+----+------------+--------------------------+-------------+
36 rows in set (0.01 sec)

permissions.controller に organization が無いのが、少なくても一つの原因のようだ。

さて、permission を作らなければいけないのは分かった。なお、この SQL と同じ結果は http://localhost:3000/permission/list で見られる。つまり http://localhost:3000/permission/new で新しいレコードを作れるわけだ。しかし、面倒臭い。もちろん、そんなことはやってられない。なんとかして自動で生成する方法を見つけねば。

ここで不思議に思ったのが todo は入っていることだ。そこで、ruby script/generate controller organization をやっていなかったために無いのかと思い調べてみると、ユーザの所属先を作る時にやっていた。

そうなると、怪しいのは user_engine となる。そこで、vendor/plugins/user_engine/README を読むと、


% rake sync_permissions
(in /export/home/uyota/rails/Todo)

をやると、このアクセス制限のレコードが作られると書いてあった。このコマンドはレコードを消すことは絶対無いそうだ。

同様にして、http://localhost:3000/organization/list が表示される様になるまで、log/development.log の SQL を追跡した。最終的には http://localhost:3000/role/edit/3 にて、organization の中の list が選ばれていないといけないようだ。roles テーブルの id=3 は User だ。

つまり、user_engine がページ毎のアクセス制御はやってくれているわけだ。ただ単に、organization/edit などのページにアクセスさせたくないのであれば、user_engine で事が足りていたのだ。user_engine の README でも、読み直すことにする。しかし、:if などの条件によるアクセス制御には興味があるので、また後で access_control を試すかも知れない。

前回次回

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://uyota.asablo.jp/blog/2007/01/03/1088808/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。