simple_auth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.markdown ADDED
@@ -0,0 +1,136 @@
1
+ Simple Auth
2
+ ===========
3
+
4
+ SimpleAuth is an authentication library to be used when Authlogic & Devise are just too complicated.
5
+
6
+ This library only supports in-site authentication and won't implement OpenID, Facebook Connect and like.
7
+
8
+ Installation
9
+ ------------
10
+
11
+ As plugin:
12
+
13
+ script/plugin install git://github.com/fnando/simple_auth.git
14
+
15
+ As gem:
16
+
17
+ sudo gem install simple_auth
18
+
19
+ Then run `script/generate simple_auth` to copy the initializer file.
20
+
21
+ Usage
22
+ -----
23
+
24
+ Your user model should have the attributes `password_hash` and `password_salt`. The credential field can be anything you want, but SimpleAuth uses `[:email, :login]` by default.
25
+
26
+ class CreateUsers < ActiveRecord::Migration
27
+ def self.up
28
+ create_table :users do |t|
29
+ t.string :email
30
+ t.string :login
31
+ t.string :password_hash
32
+ t.string :password_salt
33
+
34
+ t.timestamps
35
+ end
36
+
37
+ add_index :users, :email
38
+ add_index :users, :login
39
+ add_index :users, [:email, :login]
40
+ end
41
+
42
+ def self.down
43
+ drop_table :users
44
+ end
45
+ end
46
+
47
+ If your user model is other than `User`, you have to set it in your `config/initializer/simple_auth.rb` initializer file.
48
+ You can also set up the credentials attributes.
49
+
50
+ SimpleAuth.setup do |config|
51
+ config.model = :account
52
+ config.credentials = [:username]
53
+ end
54
+
55
+ On your model, call the method `has_authentication`.
56
+
57
+ class User < ActiveRecord::Base
58
+ has_authentication
59
+ end
60
+
61
+ This will add some callbacks and password validations.
62
+
63
+ After you set up the model, you can go the controller.
64
+
65
+ class SessionsController < ApplicationController
66
+ def new
67
+ @user_session = SimpleAuth::Session.new
68
+ end
69
+
70
+ def create
71
+ @user_session = SimpleAuth::Session.new(params[:session])
72
+
73
+ if @user_session.save
74
+ redirect_to dashboard_path
75
+ else
76
+ flash[:warning] = "Invalid username or password"
77
+ render :new
78
+ end
79
+ end
80
+
81
+ def destroy
82
+ current_session.destroy if logged_in?
83
+ redirect_to root_path
84
+ end
85
+ end
86
+
87
+ There are some helpers:
88
+
89
+ logged_in? # controller & views
90
+ current_user # controller & views
91
+ current_session # controller & views
92
+ when_logged(&block) # views
93
+
94
+ Troubleshooting
95
+ ---------------
96
+
97
+ You may receive strange errors related to `can't dup NilClass` or `You have a nil object when you didn't expect it!`. This will occur only on development mode and is an ActiveRecord bug that hasn't been fixed. Open the ActiveRecord file `activerecord-2.3.5/lib/active_record/base.rb` and comment the lines 411-412:
98
+
99
+ klass.instance_variables.each { |var| klass.send(:remove_instance_variable, var) }
100
+ klass.instance_methods(false).each { |m| klass.send :undef_method, m }
101
+
102
+ Dirty, but it works. Here's the ticket for this issue: [LINK TO LIGHTHOUSE TICKET]
103
+
104
+ To-Do
105
+ -----
106
+
107
+ * Write README
108
+
109
+ Maintainer
110
+ ----------
111
+
112
+ * Nando Vieira (<http://simplesideias.com.br>)
113
+
114
+ License:
115
+ --------
116
+
117
+ (The MIT License)
118
+
119
+ Permission is hereby granted, free of charge, to any person obtaining
120
+ a copy of this software and associated documentation files (the
121
+ 'Software'), to deal in the Software without restriction, including
122
+ without limitation the rights to use, copy, modify, merge, publish,
123
+ distribute, sublicense, and/or sell copies of the Software, and to
124
+ permit persons to whom the Software is furnished to do so, subject to
125
+ the following conditions:
126
+
127
+ The above copyright notice and this permission notice shall be
128
+ included in all copies or substantial portions of the Software.
129
+
130
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
131
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
132
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
133
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
134
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
135
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
136
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+
4
+ require 'jeweler'
5
+ require File.dirname(__FILE__) + '/lib/simple_auth/version'
6
+
7
+
8
+ desc 'Default: run specs.'
9
+ task :default => :spec
10
+
11
+ desc 'Run the specs'
12
+ Spec::Rake::SpecTask.new(:spec) do |t|
13
+ t.spec_opts = ['--colour --format specdoc --loadby mtime --reverse']
14
+ t.spec_files = FileList['spec/**/*_spec.rb']
15
+ end
16
+
17
+ JEWEL = Jeweler::Tasks.new do |gem|
18
+ gem.name = "simple_auth"
19
+ gem.version = SimpleAuth::Version::STRING
20
+ gem.summary = "A simple authentication system for Rails apps"
21
+ gem.description = <<-TXT
22
+ When Authlogic & Devise are just too much.
23
+ TXT
24
+
25
+ gem.authors = ["Nando Vieira"]
26
+ gem.email = "fnando.vieira@gmail.com"
27
+ gem.homepage = "http://github.com/fnando/simple_auth"
28
+
29
+ gem.has_rdoc = false
30
+ gem.files = %w(Rakefile simple_auth.gemspec init.rb VERSION README.markdown) + Dir["{generators,lib,spec,app,config}/**/*"]
31
+ end
32
+
33
+ desc "Generate gemspec and build gem"
34
+ task :build_gem do
35
+ File.open("VERSION", "w+") {|f| f << SimpleAuth::Version::STRING }
36
+
37
+ Rake::Task["gemspec"].invoke
38
+ Rake::Task["build"].invoke
39
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,10 @@
1
+ module SimpleAuthHelper
2
+ # Renders the specified block for logged users.
3
+ #
4
+ # <% when_logged do %>
5
+ # <!-- content for logged users -->
6
+ # <% end %>
7
+ def when_logged(&block)
8
+ capture(&block) if logged_in?
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ en:
2
+ simple_auth:
3
+ sessions:
4
+ need_to_be_logged: "You need to be logged"
5
+ invalid_credentials: "Invalid username or password"
@@ -0,0 +1,11 @@
1
+ pt: &pt
2
+ simple_auth:
3
+ sessions:
4
+ need_to_be_logged: "Você precisa estar logado"
5
+ invalid_credentials: "Usuário ou senha inválidos"
6
+
7
+ pt-BR:
8
+ <<: *pt
9
+
10
+ pt-PT:
11
+ <<: *pt
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Create an initializer file for SimpleAuth library.
3
+
4
+ Examples:
5
+ script/generate simple_auth
@@ -0,0 +1,7 @@
1
+ class SimpleAuthGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.file "simple_auth.rb", "config/initializers/simple_auth.rb"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ # Use this file to setup SimpleAuth.
2
+ SimpleAuth.setup do |config|
3
+ # Generate the password hash. The specified block should expected
4
+ # the plain password and the password hash as block parameters.
5
+ # config.crypter = proc {|password, salt| Digest::SHA256.hexdigest("#{password}--#{salt}") }
6
+
7
+ # Generate the password salt. The specified block should expect
8
+ # the ActiveRecord instance as block parameter.
9
+ # config.salt = proc {|r| Digest::SHA256.hexdigest("#{Time.now.to_s}--#{r.email}")}
10
+
11
+ # Set which attributes will be used for authentication.
12
+ config.credentials = [:email, :login]
13
+
14
+ # Set the User model that should be used
15
+ config.model = :user
16
+
17
+ # Set the login url
18
+ config.redirect_to = proc { login_path }
19
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require "simple_auth"
@@ -0,0 +1,18 @@
1
+ require "digest/sha2"
2
+ require "simple_auth/config"
3
+ require "simple_auth/active_record"
4
+ require "simple_auth/session"
5
+ require "simple_auth/version"
6
+
7
+ module SimpleAuth
8
+ class NotAuthorized < Exception; end
9
+ end
10
+
11
+ ActiveRecord::Base.send :include, SimpleAuth::ActiveRecord::InstanceMethods
12
+ ActiveRecord::Base.send :extend, SimpleAuth::ActiveRecord::ClassMethods
13
+
14
+ ActionController::Base.send :include, SimpleAuth::ActionController::Implementation
15
+ ActionController::Base.send :include, SimpleAuth::ActionController::InstanceMethods
16
+ ActionController::Base.send :extend, SimpleAuth::ActionController::ClassMethods
17
+
18
+ I18n.load_path += Dir[File.dirname(__FILE__) + "/../config/locales/*.yml"]
@@ -0,0 +1,81 @@
1
+ module SimpleAuth
2
+ module ActionController
3
+ module Implementation
4
+ def self.included(klass)
5
+ klass.prepend_before_filter :activate_simple_auth
6
+ klass.helper_method :current_user, :current_session, :logged_in?
7
+ end
8
+ end
9
+
10
+ module InstanceMethods
11
+ private
12
+ def current_session
13
+ @current_session ||= SimpleAuth::Session.find
14
+ end
15
+
16
+ def current_user
17
+ current_session && current_session.record
18
+ end
19
+
20
+ def authorized?
21
+ true
22
+ end
23
+
24
+ def logged_in?
25
+ current_user != nil
26
+ end
27
+
28
+ def activate_simple_auth
29
+ SimpleAuth::Config.controller = self
30
+ end
31
+
32
+ def simple_auth_path(controller, path)
33
+ path ||= SimpleAuth::Config.redirect_to
34
+ path = controller.instance_eval(&path) if path.kind_of?(Proc)
35
+ path
36
+ end
37
+ end
38
+
39
+ module ClassMethods
40
+ # Redirect unlogged users to the specified :to path
41
+ #
42
+ # require_logged_user :to => proc { login_path }
43
+ # require_logged_user :to => {:controller => "session", :action => "new"}
44
+ # require_logged_user :only => [:index], :to => login_path
45
+ # require_logged_user :except => [:public], :to => login_path
46
+ #
47
+ # You can set :to globally:
48
+ #
49
+ # SimpleAuth::Config.redirect_to = {:controller => "session", :action => "new"}
50
+ # SimpleAuth::Config.redirect_to = proc { login_path }
51
+ def require_logged_user(options = {})
52
+ before_filter(options.except(:to)) do |c|
53
+ c.instance_eval do
54
+ path = simple_auth_path(c, options[:to])
55
+
56
+ unless logged_in? && authorized?
57
+ flash[:warning] = I18n.translate("simple_auth.sessions.need_to_be_logged")
58
+ session[:return_to] = request.request_uri if request.get?
59
+ redirect_to path
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ # Redirect logged users to the specified :to path
66
+ #
67
+ # redirect_logged_user :to => proc { login_path }
68
+ # redirect_logged_user :to => {:controller => "dashboard"}
69
+ # redirect_logged_user :only => [:index], :to => login_path
70
+ # redirect_logged_user :except => [:public], :to => login_path
71
+ def redirect_logged_user(options = {})
72
+ before_filter(options.except(:to)) do |c|
73
+ c.instance_eval do
74
+ path = simple_auth_path(c, options[:to])
75
+ redirect_to path if logged_in?
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,80 @@
1
+ module SimpleAuth
2
+ module ActiveRecord
3
+ module InstanceMethods
4
+ private
5
+ def encrypt_password
6
+ self.password_salt = SimpleAuth::Config.salt.call(self)
7
+ self.password_hash = SimpleAuth::Config.crypter.call(password, password_salt)
8
+ end
9
+
10
+ def erase_password
11
+ self.password = nil
12
+ self.password_confirmation = nil
13
+ end
14
+
15
+ def validate_password?
16
+ new_record? || password.present?
17
+ end
18
+ end
19
+
20
+ module ClassMethods
21
+ # Receive a credential and a password and try to authenticate the specified user.
22
+ # If the credential is valid, then an user is returned; otherwise nil is returned.
23
+ #
24
+ # User.authenticate "johndoe", "test"
25
+ # User.authenticate "john@doe.com", "test"
26
+ def authenticate(credential, password)
27
+ # Build a hash that will be passed to the finder
28
+ options = {:conditions => [[], {}]}
29
+
30
+ # Iterate each attribute that should be used as credential
31
+ # and set it to the finder conditions hash
32
+ SimpleAuth::Config.credentials.each do |attr_name|
33
+ options[:conditions][0] << "#{attr_name} = :#{attr_name}"
34
+ options[:conditions][1][attr_name] = credential
35
+ end
36
+
37
+ # Join the attributes in OR query
38
+ options[:conditions][0] = options[:conditions][0].join(" OR ")
39
+
40
+ # Find the record using the conditions we built
41
+ record = SimpleAuth::Config.model_class.first(options)
42
+
43
+ # If no record has been found
44
+ return nil unless record
45
+
46
+ # Compare password
47
+ return nil unless record.password_hash == SimpleAuth::Config.crypter.call(password, record.password_salt)
48
+
49
+ return record
50
+ end
51
+
52
+ # Set virtual attributes, callbacks and acts as a wrapper for
53
+ # SimpleAuth::Config if a block is provided.
54
+ #
55
+ # class User < ActiveRecord::Base
56
+ # has_authentication
57
+ # end
58
+ #
59
+ # class User < ActiveRecord::Base
60
+ # has_authentication do |config|
61
+ # config.credentials = [:email]
62
+ # end
63
+ # end
64
+ def has_authentication(&block)
65
+ attr_accessor :password
66
+ attr_accessor :password_confirmation
67
+
68
+ SimpleAuth.setup(&block)
69
+
70
+ before_save :encrypt_password, :if => :validate_password?
71
+ after_save :erase_password
72
+
73
+ validates_presence_of :password, :if => :validate_password?
74
+ validates_length_of :password, :if => :validate_password?, :minimum => 4, :allow_blank => true
75
+ validates_presence_of :password_confirmation, :if => :validate_password?
76
+ validates_confirmation_of :password, :if => :validate_password?
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,46 @@
1
+ module SimpleAuth
2
+ # Add a shortcut to Authorization::Config
3
+ def self.setup(&block)
4
+ yield SimpleAuth::Config if block_given?
5
+ end
6
+
7
+ class Config
8
+ # Generate the password hash. The specified block should expected
9
+ # the plain password and the password hash as block parameters.
10
+ cattr_accessor :crypter
11
+ @@crypter = proc do |password, salt|
12
+ Digest::SHA256.hexdigest [password, salt].join("--")
13
+ end
14
+
15
+ # Generate the password salt. The specified block should expect
16
+ # the ActiveRecord instance as block parameter.
17
+ cattr_accessor :salt
18
+ @@salt = proc do |record|
19
+ Digest::SHA256.hexdigest [Time.to_s, ActiveSupport::SecureRandom.hex(32)].join("--")
20
+ end
21
+
22
+ # Set which attributes will be used for authentication.
23
+ cattr_accessor :credentials
24
+ @@credentials = [:email, :login]
25
+
26
+ # Set the user model
27
+ cattr_accessor :model
28
+ @@model = :user
29
+
30
+ # Set the current controller object
31
+ cattr_accessor :controller
32
+ @@controller = nil
33
+
34
+ # Set the login url
35
+ cattr_accessor :redirect_to
36
+ @@redirect_to = proc { login_path }
37
+
38
+ # Reset session before saving the user session
39
+ cattr_accessor :reset_session
40
+ @@reset_session = false
41
+
42
+ def self.model_class
43
+ model.to_s.classify.constantize
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,114 @@
1
+ module SimpleAuth
2
+ class Session
3
+ attr_accessor :credential
4
+ attr_accessor :password
5
+ attr_accessor :model
6
+ attr_accessor :controller
7
+ attr_accessor :record
8
+ attr_accessor :errors
9
+
10
+ class Errors
11
+ attr_accessor :errors
12
+
13
+ def add_to_base(message)
14
+ @errors << message
15
+ end
16
+
17
+ def initialize
18
+ @errors = []
19
+ end
20
+
21
+ def on(attr_name)
22
+ nil
23
+ end
24
+
25
+ def full_messages
26
+ @errors
27
+ end
28
+
29
+ def empty?
30
+ @errors.empty?
31
+ end
32
+ end
33
+
34
+ def self.find
35
+ session = new
36
+ session.record = session.model.find_by_id(session.controller.session[:record_id])
37
+
38
+ if session.record
39
+ session
40
+ else
41
+ nil
42
+ end
43
+ end
44
+
45
+ def self.create(options = {})
46
+ returning new(options) do |session|
47
+ session.save
48
+ end
49
+ end
50
+
51
+ def self.create!(options = {})
52
+ returning new(options) do |session|
53
+ session.save!
54
+ end
55
+ end
56
+
57
+ def self.destroy!
58
+ controller = SimpleAuth::Config.controller
59
+ controller.session[:record_id] = nil
60
+ controller.instance_variable_set("@current_user", nil)
61
+ controller.instance_variable_set("@current_session", nil)
62
+ true
63
+ end
64
+
65
+ def initialize(options = {})
66
+ @credential = options[:credential]
67
+ @password = options[:password]
68
+ @controller = SimpleAuth::Config.controller
69
+ @model = SimpleAuth::Config.model_class
70
+ @errors = Errors.new
71
+ end
72
+
73
+ def new_record?
74
+ record.nil?
75
+ end
76
+
77
+ def valid?
78
+ if record
79
+ true
80
+ else
81
+ errors.add_to_base I18n.translate("simple_auth.sessions.invalid_credentials")
82
+ false
83
+ end
84
+ end
85
+
86
+ def record
87
+ @record ||= model.authenticate(credential, password)
88
+ end
89
+
90
+ def save
91
+ if valid?
92
+ controller.send(:reset_session) if SimpleAuth::Config.reset_session
93
+ controller.session[:record_id] = record.id
94
+ end
95
+
96
+ controller.session[:record_id] != nil
97
+ end
98
+
99
+ def save!
100
+ if valid?
101
+ save
102
+ else
103
+ raise SimpleAuth::NotAuthorized
104
+ end
105
+ end
106
+
107
+ def destroy
108
+ @record = nil
109
+ @credential = nil
110
+ @password = nil
111
+ self.class.destroy!
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,8 @@
1
+ module SimpleAuth
2
+ module Version
3
+ MAJOR = "0"
4
+ MINOR = "1"
5
+ PATCH = "0"
6
+ STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
+ end
8
+ end
@@ -0,0 +1,74 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{simple_auth}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Nando Vieira"]
12
+ s.date = %q{2010-01-04}
13
+ s.description = %q{When Authlogic & Devise are just too much.
14
+ }
15
+ s.email = %q{fnando.vieira@gmail.com}
16
+ s.extra_rdoc_files = [
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ "README.markdown",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "app/helpers/simple_auth_helper.rb",
24
+ "config/locales/en.yml",
25
+ "config/locales/pt.yml",
26
+ "generators/simple_auth/USAGE",
27
+ "generators/simple_auth/simple_auth_generator.rb",
28
+ "generators/simple_auth/templates/simple_auth.rb",
29
+ "init.rb",
30
+ "lib/simple_auth.rb",
31
+ "lib/simple_auth/action_controller.rb",
32
+ "lib/simple_auth/active_record.rb",
33
+ "lib/simple_auth/config.rb",
34
+ "lib/simple_auth/session.rb",
35
+ "lib/simple_auth/version.rb",
36
+ "simple_auth.gemspec",
37
+ "spec/resources/controllers.rb",
38
+ "spec/resources/user.rb",
39
+ "spec/schema.rb",
40
+ "spec/simple_auth/action_controller_spec.rb",
41
+ "spec/simple_auth/active_record_spec.rb",
42
+ "spec/simple_auth/config_spec.rb",
43
+ "spec/simple_auth/session_spec.rb",
44
+ "spec/simple_auth/simple_auth_helper_spec.rb",
45
+ "spec/spec_helper.rb"
46
+ ]
47
+ s.homepage = %q{http://github.com/fnando/simple_auth}
48
+ s.rdoc_options = ["--charset=UTF-8"]
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = %q{1.3.5}
51
+ s.summary = %q{A simple authentication system for Rails apps}
52
+ s.test_files = [
53
+ "spec/resources/controllers.rb",
54
+ "spec/resources/user.rb",
55
+ "spec/schema.rb",
56
+ "spec/simple_auth/action_controller_spec.rb",
57
+ "spec/simple_auth/active_record_spec.rb",
58
+ "spec/simple_auth/config_spec.rb",
59
+ "spec/simple_auth/session_spec.rb",
60
+ "spec/simple_auth/simple_auth_helper_spec.rb",
61
+ "spec/spec_helper.rb"
62
+ ]
63
+
64
+ if s.respond_to? :specification_version then
65
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
+ s.specification_version = 3
67
+
68
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
69
+ else
70
+ end
71
+ else
72
+ end
73
+ end
74
+
@@ -0,0 +1,31 @@
1
+ # Add routes
2
+ ActionController::Routing::Routes.add_route "/:controller/:action/:id"
3
+ ActionController::Routing::Routes.add_named_route :login, "/login", :controller => "session", :action => "new"
4
+ ActionController::Routing::Routes.add_named_route :dashboard, "/dashboard", :controller => "dashboard", :action => "index"
5
+
6
+ class SampleController < ActionController::Base
7
+ end
8
+
9
+ class SessionController < ActionController::Base
10
+ redirect_logged_user :to => {:controller => "dashboard"}
11
+
12
+ def new
13
+ @user_session = SimpleAuth::Session.new
14
+ end
15
+
16
+ def create
17
+ @user_session = SimpleAuth::Session.new(params[:session])
18
+
19
+ if @user_session.save
20
+ redirect_to session.delete(:return_to) || dashboard_path
21
+ else
22
+ flash[:warning] = "Invalid login/password."
23
+ render :new
24
+ end
25
+ end
26
+ end
27
+
28
+ class DashboardController < ActionController::Base
29
+ def index
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ has_authentication
3
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,5 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :users do |t|
3
+ t.string :email, :login, :password_hash, :password_salt, :username
4
+ end
5
+ end
@@ -0,0 +1,103 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe SimpleAuth::ActionController, :type => :controller do
4
+ before do
5
+ @user = User.create(
6
+ :login => "johndoe",
7
+ :email => "john@doe.com",
8
+ :password => "test",
9
+ :password_confirmation => "test"
10
+ )
11
+ end
12
+
13
+ describe "require_logged_user" do
14
+ controller_name :dashboard
15
+
16
+ context "unlogged user" do
17
+ before do
18
+ DashboardController.filter_chain.pop if DashboardController.filter_chain.count > 1
19
+ end
20
+
21
+ context "return to" do
22
+ before do
23
+ DashboardController.require_logged_user :to => "/login"
24
+ end
25
+
26
+ it "should set return to" do
27
+ get :index
28
+ session[:return_to].should == "/dashboard"
29
+ end
30
+
31
+ it "should set warning message" do
32
+ get :index
33
+ flash[:warning].should == "You need to be logged"
34
+ end
35
+
36
+ it "should redirect when user is not authorized" do
37
+ controller.should_receive(:logged_in?).and_return(true)
38
+ controller.should_receive(:authorized?).and_return(false)
39
+
40
+ get :index
41
+ response.should redirect_to("/login")
42
+ end
43
+ end
44
+
45
+ it "should be redirected [hash]" do
46
+ DashboardController.require_logged_user :to => {:controller => "session", :action => "new"}
47
+
48
+ get :index
49
+ response.should redirect_to("/session/new")
50
+ end
51
+
52
+ it "should be redirected [block]" do
53
+ DashboardController.require_logged_user :to => proc { login_path }
54
+
55
+ get :index
56
+ response.should redirect_to("/login")
57
+ end
58
+
59
+ it "should be redirected [string]" do
60
+ DashboardController.require_logged_user :to => "/login"
61
+
62
+ get :index
63
+ response.should redirect_to("/login")
64
+ end
65
+ end
66
+
67
+ context "logged user" do
68
+ before do
69
+ session[:record_id] = @user.id
70
+ get :index
71
+ end
72
+
73
+ it "should render page" do
74
+ response.should render_template(:index)
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "redirect_logged_users" do
80
+ controller_name :session
81
+
82
+ context "unlogged user" do
83
+ before do
84
+ get :new
85
+ end
86
+
87
+ it "should render page" do
88
+ response.should render_template(:new)
89
+ end
90
+ end
91
+
92
+ context "logged user" do
93
+ before do
94
+ session[:record_id] = @user.id
95
+ get :new
96
+ end
97
+
98
+ it "should be redirected" do
99
+ response.should redirect_to("/dashboard")
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe SimpleAuth::ActiveRecord do
4
+ context "new record" do
5
+ subject { User.new }
6
+
7
+ before do
8
+ subject.should_not be_valid
9
+ end
10
+
11
+ it "should require password" do
12
+ subject.should have(1).error_on(:password)
13
+ end
14
+
15
+ it "should require password to be at least 4-chars long" do
16
+ subject.password = "123"
17
+ subject.should_not be_valid
18
+ subject.should have(1).error_on(:password)
19
+ end
20
+
21
+ it "should require password confirmation not to be empty" do
22
+ subject.password_confirmation = ""
23
+ subject.should have(1).error_on(:password_confirmation)
24
+ end
25
+
26
+ it "should require password confirmation not to be nil" do
27
+ subject.password_confirmation = nil
28
+ subject.should have(1).error_on(:password_confirmation)
29
+ end
30
+
31
+ it "should unset password after saving" do
32
+ subject = User.new(:password => "test", :password_confirmation => "test")
33
+ subject.save(false)
34
+ subject.password.should be_nil
35
+ subject.password_confirmation.should be_nil
36
+ end
37
+ end
38
+
39
+ context "existing record" do
40
+ subject {
41
+ User.new(
42
+ :email => "john@doe.com",
43
+ :login => "johndoe",
44
+ :password => "test",
45
+ :password_confirmation => "test",
46
+ :username => "john"
47
+ )
48
+ }
49
+
50
+ before do
51
+ subject.save!
52
+ end
53
+
54
+ it "should not require password when it hasn't changed" do
55
+ subject.login = "john"
56
+ subject.should be_valid
57
+ end
58
+
59
+ it "should not require password confirmation when it has changed" do
60
+ subject.password = "newpass"
61
+ subject.should have(1).error_on(:password_confirmation)
62
+ end
63
+
64
+ it "should authenticate using email" do
65
+ User.authenticate("john@doe.com", "test").should == subject
66
+ end
67
+
68
+ it "should authenticate using login" do
69
+ User.authenticate("johndoe", "test").should == subject
70
+ end
71
+
72
+ it "should authenticate using custom attribute" do
73
+ SimpleAuth::Config.credentials = [:username]
74
+ User.authenticate("john", "test").should == subject
75
+ end
76
+
77
+ it "should not authenticate using invalid credential" do
78
+ User.authenticate("invalid", "test").should be_nil
79
+ end
80
+
81
+ it "should not authenticate using wrong password" do
82
+ User.authenticate("johndoe", "invalid").should be_nil
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe SimpleAuth::Config do
4
+ it "should yield SimpleAuth::Config class" do
5
+ SimpleAuth.setup do |config|
6
+ config.should == SimpleAuth::Config
7
+ end
8
+ end
9
+
10
+ it "should use [:email, :login] as credential attributes" do
11
+ SimpleAuth::Config.credentials.should == [:email, :login]
12
+ end
13
+
14
+ it "should use User as default model" do
15
+ SimpleAuth::Config.model.should == :user
16
+ end
17
+
18
+ specify "crypter should expect 2 block arguments" do
19
+ SimpleAuth::Config.crypter.arity.should == 2
20
+ end
21
+
22
+ specify "salt should expect 1 block argument" do
23
+ SimpleAuth::Config.salt.arity.should == 1
24
+ end
25
+
26
+ specify "salt should return a 64-char long salt" do
27
+ SimpleAuth::Config.salt.call(nil).size.should == 64
28
+ end
29
+ end
@@ -0,0 +1,140 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe SimpleAuth::Session do
4
+ before do
5
+ @user = User.create!(
6
+ :login => "johndoe",
7
+ :email => "john@doe.com",
8
+ :password => "test",
9
+ :password_confirmation => "test"
10
+ )
11
+
12
+ @session = Hash.new
13
+ @controller = SampleController.new
14
+ @controller.session = @session
15
+
16
+ SimpleAuth::Config.controller = @controller
17
+ @user_session = SimpleAuth::Session.new(:credential => "johndoe", :password => "test")
18
+ end
19
+
20
+ context "valid credentials" do
21
+ before do
22
+ @user_session.save!
23
+ end
24
+
25
+ it "should return existing session" do
26
+ @user_session = SimpleAuth::Session.find
27
+ @user_session.should be_valid
28
+ @user_session.record.should == @user
29
+ end
30
+
31
+ it "should not be new record" do
32
+ @user_session.should_not be_new_record
33
+ end
34
+
35
+ it "should find record" do
36
+ @user_session.record.should == @user
37
+ end
38
+
39
+ it "should be a valid session" do
40
+ @user_session.should be_valid
41
+ end
42
+
43
+ it "should set record_id on session" do
44
+ @session[:record_id].should == @user.id
45
+ end
46
+
47
+ it "should be saved" do
48
+ @user_session.save.should be_true
49
+ end
50
+
51
+ it "should automatically save session when calling create!" do
52
+ @user_session = SimpleAuth::Session.create!(:credential => "johndoe", :password => "test")
53
+ @user_session.should be_valid
54
+ @user_session.record.should == @user
55
+ @session[:record_id].should == @user.id
56
+ end
57
+
58
+ it "should reset session" do
59
+ SimpleAuth::Config.reset_session = true
60
+ SimpleAuth::Config.controller.should_receive(:reset_session)
61
+ @user_session.save
62
+ end
63
+
64
+ it "should destroy session" do
65
+ @user_session.destroy.should be_true
66
+ @user_session.record.should be_nil
67
+ @session[:record_id].should be_nil
68
+ end
69
+ end
70
+
71
+ context "invalid credentials" do
72
+ before do
73
+ @user_session.credential = "invalid"
74
+ @user_session.save
75
+ end
76
+
77
+ it "should be new record" do
78
+ SimpleAuth::Session.new.should be_new_record
79
+ @user_session.should be_new_record
80
+ end
81
+
82
+ it "should have error message" do
83
+ @user_session.errors.full_messages[0].should == "Invalid username or password"
84
+ end
85
+
86
+ it "should not return error messages for attributes" do
87
+ @user_session.errors.on(:credential).should be_nil
88
+ @user_session.errors.on(:password).should be_nil
89
+ end
90
+
91
+ it "should have errors" do
92
+ @user_session.errors.should_not be_empty
93
+ end
94
+
95
+ it "should not find existing session" do
96
+ SimpleAuth::Session.find.should be_nil
97
+ end
98
+
99
+ it "should not find record" do
100
+ @user_session.record.should be_nil
101
+ end
102
+
103
+ it "should not be a valid session" do
104
+ @user_session.should_not be_valid
105
+ end
106
+
107
+ it "should unset record_id from session" do
108
+ @session[:record_id].should be_nil
109
+ end
110
+
111
+ it "should not be saved" do
112
+ @user_session.save.should be_false
113
+ end
114
+
115
+ it "should raise error with save!" do
116
+ doing { @user_session.save! }.should raise_error(SimpleAuth::NotAuthorized)
117
+ end
118
+
119
+ it "should raise error with create!" do
120
+ doing { SimpleAuth::Session.create!({}) }.should raise_error(SimpleAuth::NotAuthorized)
121
+ end
122
+ end
123
+
124
+ context "destroying valid session" do
125
+ before do
126
+ @user_session.save!
127
+ @user_session.destroy
128
+ end
129
+
130
+ it "should unset record_id from session" do
131
+ @session[:record_id].should be_nil
132
+ end
133
+
134
+ it "should unset current_user instance variable" do
135
+ SimpleAuth::Config.controller.send(:current_user).should be_nil
136
+ SimpleAuth::Config.controller.instance_variable_get("@current_user").should be_nil
137
+ SimpleAuth::Config.controller.instance_variable_get("@current_session").should be_nil
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe SimpleAuthHelper, :type => :helper do
4
+ it "should render block when user is logged" do
5
+ helper.should_receive(:logged_in?).and_return(true)
6
+ helper.when_logged { "logged" }.should == "logged"
7
+ end
8
+
9
+ it "should not render block when user is unlogged" do
10
+ helper.should_receive(:logged_in?).and_return(false)
11
+ helper.when_logged { "logged" }.should be_nil
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ # Load application RSpec helper
2
+ begin
3
+ require File.dirname(__FILE__) + "/../../../../spec/spec_helper"
4
+ rescue LoadError
5
+ puts "Your application hasn't been bootstraped with RSpec.\nI'll do it on my own!\n\n"
6
+ system "cd '#{File.dirname(__FILE__) + "/../../../../"}' && script/generate rspec"
7
+ puts "\n\nRun `rake spec` again."
8
+ exit
9
+ end
10
+
11
+ # Establish connection with in memory SQLite 3 database
12
+ ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => ":memory:"
13
+
14
+ # Load database schema
15
+ load File.dirname(__FILE__) + "/schema.rb"
16
+
17
+ # Create an alias for lambda
18
+ alias :doing :lambda
19
+
20
+ # Load resources
21
+ require File.dirname(__FILE__) + "/resources/user"
22
+ require File.dirname(__FILE__) + "/resources/controllers"
23
+
24
+ # Restore default configuration
25
+ Spec::Runner.configure do |config|
26
+ config.before :each do
27
+ load File.dirname(__FILE__) + "/../lib/simple_auth/config.rb"
28
+ SimpleAuth::Config.model = :user
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_auth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nando Vieira
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-04 00:00:00 -02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: |
17
+ When Authlogic & Devise are just too much.
18
+
19
+ email: fnando.vieira@gmail.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files:
25
+ - README.markdown
26
+ files:
27
+ - README.markdown
28
+ - Rakefile
29
+ - VERSION
30
+ - app/helpers/simple_auth_helper.rb
31
+ - config/locales/en.yml
32
+ - config/locales/pt.yml
33
+ - generators/simple_auth/USAGE
34
+ - generators/simple_auth/simple_auth_generator.rb
35
+ - generators/simple_auth/templates/simple_auth.rb
36
+ - init.rb
37
+ - lib/simple_auth.rb
38
+ - lib/simple_auth/action_controller.rb
39
+ - lib/simple_auth/active_record.rb
40
+ - lib/simple_auth/config.rb
41
+ - lib/simple_auth/session.rb
42
+ - lib/simple_auth/version.rb
43
+ - simple_auth.gemspec
44
+ - spec/resources/controllers.rb
45
+ - spec/resources/user.rb
46
+ - spec/schema.rb
47
+ - spec/simple_auth/action_controller_spec.rb
48
+ - spec/simple_auth/active_record_spec.rb
49
+ - spec/simple_auth/config_spec.rb
50
+ - spec/simple_auth/session_spec.rb
51
+ - spec/simple_auth/simple_auth_helper_spec.rb
52
+ - spec/spec_helper.rb
53
+ has_rdoc: true
54
+ homepage: http://github.com/fnando/simple_auth
55
+ licenses: []
56
+
57
+ post_install_message:
58
+ rdoc_options:
59
+ - --charset=UTF-8
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ version:
74
+ requirements: []
75
+
76
+ rubyforge_project:
77
+ rubygems_version: 1.3.5
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: A simple authentication system for Rails apps
81
+ test_files:
82
+ - spec/resources/controllers.rb
83
+ - spec/resources/user.rb
84
+ - spec/schema.rb
85
+ - spec/simple_auth/action_controller_spec.rb
86
+ - spec/simple_auth/active_record_spec.rb
87
+ - spec/simple_auth/config_spec.rb
88
+ - spec/simple_auth/session_spec.rb
89
+ - spec/simple_auth/simple_auth_helper_spec.rb
90
+ - spec/spec_helper.rb