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 を試すかも知れない。
最近のコメント