acts_as_authenticatedとrole_requirementでロール付きの認証。

消えちゃったよ。。

はてなダイアリー素人なので書いたのをなんか間違って消してしまった。。orz
後半だけクリップボードに残ってた。orz
なので、書き直した前半は適当。

acts_as_authenticatedをインストール

$ ruby script/plugin discover
$ ruby script/plugin install acts_as_authenticated

ジェネってmigration

$ ./script/generate authenticated user account
$ rake db:migrate

その他の機能はあとで

メール認証だの、アクティベーションだのはまた今度。

ログインが必要なコントローラは

before_filter :login_requiredで認証箇所のコントロール

class HogeController < ApplicationController
  include AuthenticatedSystem
  before_filter :login_required, :except => [:nologin]
  def index
    #ログイン必要
  end
  
  def nologin
    #ログイン不要
  end
  
end

ロールを追加。

どうせ必要なので。
Acts_as_authenticatedにRole機能を追加する,RoleRequirementっーのがあるみたい。

インストールしる。

$ script/plugin install http://rolerequirement.googlecode.com/svn/tags/role
_requirement/
+ ./ChangeLog
+ ./MIT-LICENSE
+ ./README
+ ./generators/role/role_generator.rb
+ ./generators/role/templates/001_add_role_to_users_migration.rb.erb
+ ./generators/role/templates/_user_functions.erb
+ ./generators/role_generator_helpers.rb
+ ./generators/roles/roles_generator.rb
+ ./generators/roles/templates/001_roles_migration.rb.erb
+ ./generators/roles/templates/_user_functions.erb
+ ./generators/roles/templates/role_model.rb.erb
+ ./generators/roles/templates/roles.yml
+ ./generators/roles/templates/roles_users.yml
+ ./generators/roles/templates/users_admin_fixture_with_roles.yml
+ ./generators/shared_templates/hijacker.rb
+ ./generators/shared_templates/role_requirement_system.rb.erb
+ ./generators/shared_templates/role_requirement_test_helper.rb.erb
+ ./init.rb
+ ./test/authenticated_system.rb
+ ./test/controller_stub.rb
+ ./test/functional/test_role_controller.rb
+ ./test/test_helper.rb
+ ./test/user_stub.rb

generate

Role:ロールのモデル名 User:ユーザのモデル名
(ユーザがいくつもロールを持つ:多対多)
script/generate roles Role User
(ユーザは一種類のロールしか持たない:一対多)
script/generate role User

多対多で作っとく。

$ script/generate roles Role User
Generating Role against User
Added the following to the top of app/models/user.rb:



  # ---------------------------------------
  # The following code has been generated by role_requirement.
  # You may wish to modify it to suit your need
  has_and_belongs_to_many :roles

  attr_protected :roles


  # has_role? simply needs to return true or false whether a user has a role or not.
  # It may be a good idea to have "admin" roles return true always
  def has_role?(role_in_question)
    @_list ||= self.roles.collect(&:name)
    return true if @_list.include?("admin")
    (@_list.include?(role_in_question.to_s) )
  end
  # ---------------------------------------




Added ApplicationController include to /home/xxxx/dev/rails/auth_test/app/controllers/application.rb
Added RoleRequirement include to /home/xxxx/dev/rails/auth_test/app/controllers/application.rb
Added RoleRequirementTestHelper include to /home/xxxx/dev/rails/auth_test/test/test_helper.rb
      create  test/fixtures/roles_users.yml
      create  test/fixtures/roles.yml
      create  app/models/role.rb
      create  lib/role_requirement_system.rb
      create  lib/role_requirement_test_helper.rb
      create  lib/hijacker.rb
      exists  db/migrate
      create  db/migrate/002_create_roles.rb

migrate

DB反映

$ rake db:migrate
(in /home/coek/dev/rails/auth_test)
== 2 CreateRoles: migrating ===================================================
-- create_table("roles")
   -> 0.1138s
-- create_table("roles_users", {:id=>false})
   -> 0.0181s
-- add_index("roles_users", "role_id")
   -> 0.0337s
-- add_index("roles_users", "user_id")
   -> 0.0298s
== 2 CreateRoles: migrated (0.1980s) ==========================================

モデルを定義

Roleモデルにhabtmを書き足す

has_and_belongs_to_many :users

ロール設定の画面scaffold

    • skip-migrationつけて
$ ruby script/generate scaffold role --skip-migration
      exists  app/models/
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/roles
      exists  app/views/layouts/
      exists  test/functional/
      exists  test/unit/
      create  app/views/roles/index.html.erb
      create  app/views/roles/show.html.erb
      create  app/views/roles/new.html.erb
      create  app/views/roles/edit.html.erb
      create  app/views/layouts/roles.html.erb
      create  public/stylesheets/scaffold.css
  dependency  model
      exists    app/models/
      exists    test/unit/
      exists    test/fixtures/
        skip    app/models/role.rb
      create    test/unit/role_test.rb
        skip    test/fixtures/roles.yml
      create  app/controllers/roles_controller.rb
      create  test/functional/roles_controller_test.rb
      create  app/helpers/roles_helper.rb
       route  map.resources :roles

スキーマ情報とらないからviewをチョコチョコ自分でなおして。。
とりあえず、adminとuserを作っておく。

試してみる

さっき作ったroles_controllerに

require_role "admin"

書いてみて、ログインしないでアクセスすると。ログイン画面に飛ばされる
adminロールを持ってないユーザーでログインしてアクセスすると、画面真っ白。。

画面真っ白がヘボイ

http://d.hatena.ne.jp/clayfish/20080101/1199195090
を参考に
applicationコントローラーに手入れるのめんどかったので
とりあえずリダイレクトだけされすようにした。

/lib/role_requirement_system.rb L110

    def access_denied
      if logged_in?
        #render :nothing => true, :status => 401
        redirect_to("/")
        return false
      else
        super
      end
    end

ロールがある場合も試す。

とりあえずconsoleでロールを与える

$ ruby script/console
Loading development environment (Rails 2.0.2)
>>
?>
?> @user = User.find_by_login('admin')
=> #<User id: 2, login: "admin", email: "xxxx@xxxxx", crypted_password: "xxxxxx", salt: "xxxxxxxx", created_at: "2008-02-12 19:35:08", updated_at: "2008-02-12 19:35:08", remember_token: nil, remember_token_expires_at: nil>
>> @user.roles << Role.find_by_name('admin')
=> [#<Role id: 1, name: "admin">]
>> @user.save
=> true
>>

で、さっきのroles_controllerにアクセスしたら、アクセスできた。