Skip to content
Browse files

Basic authentication integrated, setup user authorization model

  • Loading branch information...
1 parent c7448b3 commit 05f357afe94196bf77c9d62ac182ece9a3798ec3 @mikel committed May 17, 2009
View
9 app/controllers/application_controller.rb
@@ -9,6 +9,15 @@ class ApplicationController < ActionController::Base
filter_parameter_logging :password, :password_confirmation
private
+
+ def admin_only
+ unless current_user.member_of?(:admin)
+ flash[:notice] = "You must be an administrator to access this page"
+ redirect_to root_path
+ return false
+ end
+ end
+
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
View
2 app/controllers/home_controller.rb
@@ -1,5 +1,7 @@
class HomeController < ApplicationController
+ before_filter :require_user
+
def index
end
View
1 app/controllers/user_sessions_controller.rb
@@ -1,4 +1,5 @@
class UserSessionsController < ApplicationController
+
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => :destroy
View
10 app/controllers/users_controller.rb
@@ -0,0 +1,10 @@
+class UsersController < ApplicationController
+
+ before_filter :require_user
+ before_filter :admin_only, :except => [:show, :update, :edit]
+
+ def index
+ @users = User.find(:all)
+ end
+
+end
View
2 app/helpers/users_helper.rb
@@ -0,0 +1,2 @@
+module UsersHelper
+end
View
6 app/models/membership.rb
@@ -0,0 +1,6 @@
+class Membership < ActiveRecord::Base
+
+ belongs_to :user
+ belongs_to :role
+
+end
View
7 app/models/role.rb
@@ -0,0 +1,7 @@
+class Role < ActiveRecord::Base
+
+ has_many :memberships
+ has_many :users, :through => :memberships
+
+
+end
View
15 app/models/user.rb
@@ -1,3 +1,18 @@
class User < ActiveRecord::Base
acts_as_authentic
+
+ has_many :memberships
+ has_many :roles, :through => :memberships
+
+ # Makes this user a member of the administrator group
+ def add_role!(role_name)
+ role = Role.find_by_name!(role_name.to_s)
+ self.roles << role
+ end
+
+ # Returns true if this user is an administrator
+ def member_of?(role_name)
+ !!self.roles.find_by_name(role_name.to_s)
+ end
+
end
View
2 app/views/user_sessions/new.html.erb
@@ -1,5 +1,5 @@
<h1>Login</h1>
-
+
<% form_for @user_session do |f| %>
<%= f.error_messages %>
<%= f.label :login %><br />
View
3 app/views/users/index.html.erb
@@ -0,0 +1,3 @@
+<%- @users.each do |user| -%>
+<%= user.login %>
+<%- end -%>
View
4 config/routes.rb
@@ -36,7 +36,9 @@
# Note: These default routes make all actions in every controller accessible via GET requests. You should
# consider removing the them or commenting them out if you're using named routes and resources.
+ map.resources :users
map.resources :user_sessions
- map.root :controller => 'home', :action => :index
+
+ map.root :controller => 'home', :action => "index"
end
View
14 db/migrate/20090505030940_create_memberships.rb
@@ -0,0 +1,14 @@
+class CreateMemberships < ActiveRecord::Migration
+ def self.up
+ create_table :memberships do |t|
+ t.integer :user_id
+ t.integer :role_id
+
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :memberships
+ end
+end
View
13 db/migrate/20090510015902_create_roles.rb
@@ -0,0 +1,13 @@
+class CreateRoles < ActiveRecord::Migration
+ def self.up
+ create_table :roles do |t|
+ t.string :name
+
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :roles
+ end
+end
View
15 db/schema.rb
@@ -9,7 +9,20 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20090502124658) do
+ActiveRecord::Schema.define(:version => 20090510015902) do
+
+ create_table "memberships", :force => true do |t|
+ t.integer "user_id"
+ t.integer "role_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ create_table "roles", :force => true do |t|
+ t.string "name"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
create_table "users", :force => true do |t|
t.string "login", :null => false
View
7 features/manage_sessions.feature
@@ -31,4 +31,9 @@ Feature: Manage sessions
And I press "Login"
Then I should see "Login successful!"
Then I should be on the homepage
-
+
+ Scenario: Staying logged in
+ Given I am logged in
+ When I go to the homepage
+ Then I should be on the homepage
+
View
28 features/manage_users.feature
@@ -0,0 +1,28 @@
+Feature: Managing users
+ In order to get people to use the software
+ As an administrator
+ I want the ability to add, edit and delete users
+
+ Scenario: Trying to access the users page when not an admin
+ Given I am logged in
+ When I go to the users page
+ Then I should be on the homepage
+ And I should see "You must be an administrator to access this page"
+
+ Scenario: Only the admin user defined
+ Given I am logged in as an admin
+ When I go to the users page
+ Then I should see "Bob"
+
+ Scenario: One user plus the admin user in the system
+ Given I am logged in as an admin
+ And a user with username "Charles" and password "PassWord"
+ When I go to the users page
+ Then I should see "Charles"
+ And I should see "Bob"
+
+ Scenario: Editing a user in the system
+ Given I am logged in as an admin
+ When I go to the users page
+ And I follow "edit"
+ Then I should be on the edit user page for "Bob"
View
16 features/step_definitions/global_steps.rb
@@ -0,0 +1,16 @@
+Given /^I am logged in$/ do
+ user = login_user
+ visit path_to("the new user sessions page")
+ fill_in("Login", :with => user.login)
+ fill_in("password", :with => user.password)
+ click_button("Login")
+end
+
+Given /^I am logged in as an admin$/ do
+ user = login_user(:make_administrator)
+ visit path_to("the new user sessions page")
+ fill_in("Login", :with => user.login)
+ fill_in("password", :with => user.password)
+ click_button("Login")
+end
+
View
8 features/step_definitions/manage_users_steps.rb
@@ -0,0 +1,8 @@
+Then /^I should see 1 user account$/ do
+ pending
+end
+
+Given /^a user with username "([^\"]*)" and password "([^\"]*)"$/ do |login, password|
+ Factory(:user, :login => login, :password => password)
+end
+
View
20 features/support/authentication.rb
@@ -0,0 +1,20 @@
+module AuthenticationHelpers
+ # Provides basic authentication helpers for logging in and out
+
+ def login_user(params = [])
+ params = [params] unless params.respond_to?(:each)
+ user = Factory(:user)
+ params.each do |param|
+ send(param, user)
+ end
+ user
+ end
+
+ def make_administrator(user)
+ role = Factory(:admin_role)
+ user.add_role!(:admin)
+ end
+
+end
+
+World(AuthenticationHelpers)
View
2 features/support/env.rb
@@ -15,3 +15,5 @@
require 'cucumber/rails/rspec'
require 'webrat/core/matchers'
+require "authlogic/test_case"
+
View
7 features/support/paths.rb
@@ -20,6 +20,13 @@ def path_to(page_name)
when /the new user sessions page/
new_user_session_path
+ when /the edit user page for "(\w+)"/
+ user = User.find_by_login($1)
+ edit_user_path(user.id)
+
+ when /the users page/
+ users_path
+
# Add more page name => path mappings here
else
View
16 spec/controllers/users_controller_spec.rb
@@ -0,0 +1,16 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe UsersController do
+
+ it "should get a collection of users when asked for index" do
+ User.should_receive(:find).with(:all)
+ get :index
+ end
+
+ it "should assign the users to the view" do
+ User.stub!(:find).and_return(['user'])
+ get :index
+ assigns(:users).should == ['user']
+ end
+
+end
View
6 spec/factories.rb
@@ -1,6 +0,0 @@
-Factory.define :user do |f|
- f.login 'bob'
- f.password 'PassWord'
- f.password_confirmation 'PassWord'
- f.email 'bob@someplace.com'
-end
View
9 spec/factories/role_factory.rb
@@ -0,0 +1,9 @@
+Factory.define :role do |u|
+ u.name 'role'
+end
+
+Factory.define :admin_role, :class => :role do |u|
+ u.name 'admin'
+end
+
+
View
10 spec/factories/user_factory.rb
@@ -0,0 +1,10 @@
+Factory.define :user do |u|
+ u.login "Bob"
+ u.password "PassWord"
+ u.password_confirmation { |a| a.password }
+ u.email { |a| "#{a.login}@someplace.com" }
+end
+
+Factory.define :admin_user, :parent => :user do |a|
+
+end
View
9 spec/fixtures/memberships.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+
+one:
+ user_id: 1
+ role_id: 1
+
+two:
+ user_id: 1
+ role_id: 1
View
7 spec/fixtures/roles.yml
@@ -0,0 +1,7 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+
+one:
+ name: MyString
+
+two:
+ name: MyString
View
11 spec/helpers/users_helper_spec.rb
@@ -0,0 +1,11 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe UsersHelper do
+
+ #Delete this example and add some real ones or delete this file
+ it "should be included in the object returned by #helper" do
+ included_modules = (class << helper; self; end).send :included_modules
+ included_modules.should include(UsersHelper)
+ end
+
+end
View
20 spec/models/membership_spec.rb
@@ -0,0 +1,20 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe Membership do
+ before(:each) do
+ @valid_attributes = {
+ :user_id => 1,
+ :role_id => 1
+ }
+ end
+
+ it "should create a new instance given valid attributes" do
+ Membership.create!(@valid_attributes)
+ end
+
+ it "should add a given membership to a user" do
+ user = Factory(:user)
+ Membership.should respond_to(:add_membership!)
+ end
+
+end
View
13 spec/models/role_spec.rb
@@ -0,0 +1,13 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe Role do
+ before(:each) do
+ @valid_attributes = {
+ :name => "value for name"
+ }
+ end
+
+ it "should create a new instance given valid attributes" do
+ Role.create!(@valid_attributes)
+ end
+end
View
27 spec/models/user_spec.rb
@@ -1,12 +1,27 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe User do
- before(:each) do
- @valid_attributes = {
- }
- end
- it "should create a new instance given valid attributes" do
- User.create!(@valid_attributes)
+ describe "memberships interface" do
+ it "should add itself to the admin role" do
+ user = Factory(:user)
+ role = Factory(:admin_role)
+ user.add_role!(:admin)
+ user.roles.should include(role)
+ end
+
+ it "should say if it is an admin" do
+ user = Factory(:user)
+ role = Factory(:admin_role)
+ user.add_role!(:admin)
+ user.member_of?(:admin).should be_true
+ end
+
+ it "should raise an error if the role was not found" do
+ user = Factory(:user)
+ doing {user.add_role!(:user)}.should raise_error(ActiveRecord::RecordNotFound, "Couldn't find Role with name = user")
+ end
+
end
+
end
View
4 spec/spec_helper.rb
@@ -45,3 +45,7 @@
#
# For more information take a look at Spec::Runner::Configuration and Spec::Runner
end
+
+require ‘authlogic/test_case’
+
+alias :doing :lambda
View
2 spec/views/users/index.html.erb_spec.rb
@@ -0,0 +1,2 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+

0 comments on commit 05f357a

Please sign in to comment.
Something went wrong with that request. Please try again.