easy_auth 0.0.1.alpha.0 → 0.0.1.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # EasyAuth #
2
+
3
+ [![Build Status](http://travis-ci.org/dockyard/easy_auth.png)](http://travis-ci.org/dockyard/easy_auth)
4
+
5
+ Dead simple drop in authentication for Rails
6
+
7
+ ## Installation ##
8
+
9
+ In your Gemfile add the following:
10
+
11
+ ```ruby
12
+ gem 'easy_auth'
13
+ ```
14
+
15
+ After running Bundler you'll need to install the migrations
16
+
17
+ ```ruby
18
+ rake easy_auth:install:migrations
19
+ ```
20
+
21
+ Then run your migrations.
22
+
23
+ ## Authors ##
24
+
25
+ [Brian Cardarella](http://twitter.com/bcardarella)
26
+
27
+ ## Versioning ##
28
+
29
+ This gem follows [Semantic Versioning](http://semver.org)
30
+
31
+ ## Want to help? ##
32
+
33
+ Stable branches are created based upon each minor version. Please make
34
+ pull requests to specific branches rather than master.
35
+
36
+ Please make sure you include tests!
37
+
38
+ Unles Rails drops support for Ruby 1.8.7 we will continue to use the
39
+ hash-rocket syntax. Please respect this.
40
+
41
+ Don't use tabs to indent, two spaces are the standard.
42
+
43
+ ## Legal ##
44
+
45
+ [DockYard](http://dockyard.com), LLC © 2012
46
+
47
+ [@dockyard](http://twitter.com/dockyard)
48
+
49
+ [Licensed under the MIT license](http://www.opensource.org/licenses/mit-license.php)
@@ -0,0 +1,3 @@
1
+ class AuthenticatedController < ApplicationController
2
+ include EasyAuth::Controllers::Authenticated
3
+ end
@@ -0,0 +1,3 @@
1
+ class PasswordResetController < ApplicationController
2
+ include EasyAuth::Controllers::PasswordReset
3
+ end
@@ -0,0 +1,3 @@
1
+ class SessionsController < ApplicationController
2
+ include EasyAuth::Controllers::Sessions
3
+ end
@@ -0,0 +1,4 @@
1
+ class PasswordResetMailer < ActionMailer::Base
2
+ include EasyAuth::Mailers::PasswordReset
3
+ default from: "from@example.com"
4
+ end
@@ -0,0 +1,14 @@
1
+ module EasyAuth::Controllers::Authenticated
2
+ def self.included(base)
3
+ base.before_filter :attempt_to_authenticate
4
+ end
5
+
6
+ private
7
+
8
+ def attempt_to_authenticate
9
+ if user_not_signed_in?
10
+ session[:requested_path] = request.path
11
+ redirect_to main_app.sign_in_path
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,55 @@
1
+ module EasyAuth::Controllers::PasswordReset
2
+ def self.included(base)
3
+ base.instance_eval do
4
+ before_filter :find_identity_from_reset_token, :only => [:edit, :update]
5
+ end
6
+ end
7
+
8
+ def new
9
+ @identity = EasyAuth.identity_model.new
10
+ end
11
+
12
+ def create
13
+ if @identity = EasyAuth.identity_model.where(:username => params[:identity][:username]).first
14
+ @identity.password_reset
15
+ else
16
+ @identity = EasyAuth.identity_model.new(params[:identity])
17
+ end
18
+
19
+ flash.now[:notice] = I18n.t('easy_auth.password_reset.create.notice')
20
+ render :new
21
+ end
22
+
23
+ def update
24
+ if @identity.update_attributes(scope_to_password_params(:identity))
25
+ after_successful_password_reset(@identity)
26
+ else
27
+ after_failed_sign_in(@identity)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def scope_to_password_params(key)
34
+ params[key].select { |k, v| ['password', 'password_confirmation'].include?(k) }
35
+ end
36
+
37
+ def find_identity_from_reset_token
38
+ @identity = EasyAuth.identity_model.where(:reset_token => params[:reset_token]).first
39
+ end
40
+
41
+ def after_successful_password_reset(identity)
42
+ session[:session_token] = identity.generate_session_token!
43
+ identity.update_attribute(:reset_token, nil)
44
+ redirect_to after_successful_password_reset_path(identity), :notice => I18n.t('easy_auth.password_reset.update.notice')
45
+ end
46
+
47
+ def after_successful_password_reset_path(identity)
48
+ identity.account
49
+ end
50
+
51
+ def after_failed_password_reset(identity)
52
+ flash.now[:error] = I18n.t('easy_auth.password_reset.update.error')
53
+ render :new
54
+ end
55
+ end
@@ -0,0 +1,39 @@
1
+ module EasyAuth::Controllers::Sessions
2
+ def new
3
+ @identity = EasyAuth.identity_model.new
4
+ end
5
+
6
+ def create
7
+ if identity = EasyAuth.identity_model.authenticate(params[:identity])
8
+ session[:session_token] = identity.generate_session_token!
9
+ after_successful_sign_in(identity)
10
+ else
11
+ @identity = EasyAuth.identity_model.new(params[:identity])
12
+ after_failed_sign_in(@identity)
13
+ end
14
+ end
15
+
16
+ def destroy
17
+ session.delete(:session_token)
18
+ after_sign_out
19
+ end
20
+
21
+ private
22
+
23
+ def after_successful_sign_in(identity)
24
+ redirect_to session.delete(:requested_path) || after_successful_sign_in_path(identity), :notice => I18n.t('easy_auth.sessions.create.notice')
25
+ end
26
+
27
+ def after_successful_sign_in_path(identity)
28
+ identity.account
29
+ end
30
+
31
+ def after_failed_sign_in(identity)
32
+ flash.now[:error] = I18n.t('easy_auth.sessions.create.error')
33
+ render :new
34
+ end
35
+
36
+ def after_sign_out
37
+ redirect_to main_app.root_path, :notice => I18n.t('easy_auth.sessions.delete.notice')
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ module EasyAuth
2
+ module Helpers
3
+ def self.included(base)
4
+ base.class_eval do
5
+ helper_method :current_account, :current_user, :account_signed_in?, :user_signed_in?, :account_not_signed_in?, :user_not_signed_in?
6
+ end
7
+ end
8
+
9
+ def current_account
10
+ if session[:session_token]
11
+ begin
12
+ @current_account ||= EasyAuth.identity_model.find_by_session_token(session[:session_token]).account
13
+ rescue
14
+ @current_account = nil
15
+ session.delete(:session_token)
16
+ end
17
+ end
18
+
19
+ @current_account
20
+ end
21
+ alias :current_user :current_account
22
+
23
+ def account_signed_in?
24
+ current_account
25
+ end
26
+ alias :user_signed_in? :account_signed_in?
27
+
28
+ def account_not_signed_in?
29
+ !account_signed_in?
30
+ end
31
+ alias :user_not_signed_in? :account_not_signed_in?
32
+
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ module EasyAuth::Mailers::PasswordReset
2
+ def self.included(base)
3
+ base.clear_action_methods!
4
+ end
5
+
6
+ def reset(id)
7
+ @identity = EasyAuth.identity_model.find(id)
8
+ @url = edit_password_url(@identity.reset_token)
9
+ mail :to => @identity.account.email, :subject => 'Password reset'
10
+ end
11
+ end
@@ -0,0 +1,45 @@
1
+ module EasyAuth::Models::Account
2
+ class NoIdentityUsernameError < StandardError; end
3
+ def self.included(base)
4
+ base.class_eval do
5
+ unless respond_to?(:identity_username_attribute)
6
+ def self.identity_username_attribute
7
+ if column_names.include?('username')
8
+ :username
9
+ elsif column_names.include?('email')
10
+ :email
11
+ else
12
+ raise EasyAuth::Models::Account::NoIdentityUsernameError, 'your model must have either a #username or #email attribute. Or you must override the .identity_username_attribute class method'
13
+ end
14
+ end
15
+ end
16
+
17
+ def identity_username_attribute
18
+ self.send(self.class.identity_username_attribute)
19
+ end
20
+
21
+ has_one :identity, :as => :account
22
+ before_create :setup_identity
23
+ before_update :update_identity
24
+
25
+ attr_accessor :password
26
+ validates :password, :presence => { :on => :create }, :confirmation => true
27
+ attr_accessible :password, :password_confirmation
28
+ validates identity_username_attribute, :presence => true
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def setup_identity
35
+ build_identity(identity_attributes)
36
+ end
37
+
38
+ def update_identity
39
+ identity.update_attributes(identity_attributes)
40
+ end
41
+
42
+ def identity_attributes
43
+ { :username => self.identity_username_attribute, :password => self.password, :password_confirmation => self.password_confirmation }
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ module EasyAuth::Models::Identity
2
+ def self.included(base)
3
+ base.class_eval do
4
+ belongs_to :account, :polymorphic => true
5
+ has_secure_password
6
+ attr_accessible :username, :password, :password_confirmation
7
+
8
+ def self.authenticate(attributes = nil)
9
+ return nil if attributes.nil?
10
+
11
+ if identity = where(arel_table[:username].matches(attributes[:username].try(&:strip))).first.try(:authenticate, attributes[:password])
12
+ identity
13
+ else
14
+ nil
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def password_reset
21
+ update_attribute(:reset_token, URI.escape(_generate_token(:reset).gsub(/[\.|\\\/]/,'')))
22
+ PasswordResetMailer.reset(self.id).deliver
23
+ end
24
+
25
+ def generate_session_token!
26
+ self.update_attribute(:session_token, _generate_token(:session))
27
+ self.session_token
28
+ end
29
+
30
+ private
31
+
32
+ def _generate_token(type)
33
+ BCrypt::Password.create("#{id}-#{type}_token-#{DateTime.current}")
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ class Identity < ActiveRecord::Base
2
+ include EasyAuth::Models::Identity
3
+ end
@@ -0,0 +1,7 @@
1
+ <%= form_for @identity, :url => main_app.edit_password_path(params[:reset_token]) do |f| %>
2
+ <%= f.label :password %>
3
+ <%= f.text_field :password %>
4
+ <%= f.label :password_confirmation %>
5
+ <%= f.text_field :password_confirmation %>
6
+ <%= f.submit 'Submit' %>
7
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <%= form_for @identity, :url => main_app.password_reset_path do |f| %>
2
+ <%= f.label :username %>
3
+ <%= f.text_field :username %>
4
+ <%= f.submit 'Submit' %>
5
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= link_to 'Reset password', @url %>
@@ -0,0 +1 @@
1
+ Reset password: <%= @url %>
@@ -0,0 +1,7 @@
1
+ <%= form_for @identity, :url => main_app.sign_in_path do |f| %>
2
+ <%= f.label :username %>
3
+ <%= f.text_field :username %>
4
+ <%= f.label :password %>
5
+ <%= f.password_field :password %>
6
+ <%= f.submit 'Submit' %>
7
+ <% end %>
@@ -0,0 +1,14 @@
1
+ en:
2
+ easy_auth:
3
+ sessions:
4
+ create:
5
+ notice: 'You have been signed in.'
6
+ error: 'Could not sign you in. Please check your credentials.'
7
+ delete:
8
+ notice: 'You have been signed out.'
9
+ password_reset:
10
+ create:
11
+ notice: 'Please check your email for your password reset link.'
12
+ update:
13
+ notice: 'Your password has been updated.'
14
+ error: 'There was an issue updating your password.'
@@ -0,0 +1,17 @@
1
+ class CreateIdentities < ActiveRecord::Migration
2
+ def change
3
+ create_table :identities do |t|
4
+ t.string :username
5
+ t.string :password_digest
6
+ t.string :account_type
7
+ t.integer :account_id
8
+ t.string :reset_token
9
+ t.string :session_token
10
+ t.timestamps
11
+ end
12
+
13
+ [:username, :reset_token, :session_token].each do |column|
14
+ add_index :identities, column
15
+ end
16
+ end
17
+ end
@@ -1,5 +1,14 @@
1
1
  module EasyAuth
2
2
  class Engine < ::Rails::Engine
3
3
  isolate_namespace EasyAuth
4
+
5
+ initializer 'filter_parameters' do |app|
6
+ app.config.filter_parameters += [:password]
7
+ app.config.filter_parameters.uniq!
8
+ end
9
+
10
+ config.generators do |g|
11
+ g.test_framework :rspec, :view_specs => false
12
+ end
4
13
  end
5
14
  end
@@ -0,0 +1,21 @@
1
+ module ActionDispatch::Routing
2
+ class Mapper
3
+ def easy_auth_routes
4
+ easy_auth_session_routes
5
+ easy_auth_password_reset_routes
6
+ end
7
+
8
+ def easy_auth_session_routes
9
+ get '/sign_out' => 'sessions#destroy', :as => :sign_out
10
+ get '/sign_in' => 'sessions#new', :as => :sign_in
11
+ post '/sign_in' => 'sessions#create'
12
+ end
13
+
14
+ def easy_auth_password_reset_routes
15
+ get '/password_reset' => 'password_reset#new', :as => :password_reset
16
+ post '/password_reset' => 'password_reset#create'
17
+ get '/password_reset/:reset_token' => 'password_reset#edit', :as => :edit_password
18
+ put '/password_reset/:reset_token' => 'password_reset#update'
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module EasyAuth
2
- VERSION = '0.0.1.alpha.0'
2
+ VERSION = '0.0.1.alpha.1'
3
3
  end
data/lib/easy_auth.rb CHANGED
@@ -1,4 +1,8 @@
1
- require "easy_auth/engine"
1
+ require 'easy_auth/engine'
2
+ require 'easy_auth/routes'
2
3
 
3
4
  module EasyAuth
5
+ def self.identity_model
6
+ Identity
7
+ end
4
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.alpha.0
4
+ version: 0.0.1.alpha.1
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-19 00:00:00.000000000Z
12
+ date: 2012-05-07 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70170282857740 !ruby/object:Gem::Requirement
16
+ requirement: &70277957196260 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,98 @@ dependencies:
21
21
  version: 3.2.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70170282857740
24
+ version_requirements: *70277957196260
25
+ - !ruby/object:Gem::Dependency
26
+ name: bcrypt-ruby
27
+ requirement: &70277957194540 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70277957194540
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: sqlite3
27
- requirement: &70170282851920 !ruby/object:Gem::Requirement
38
+ requirement: &70277957192280 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70277957192280
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec-rails
49
+ requirement: &70277957175740 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70277957175740
58
+ - !ruby/object:Gem::Dependency
59
+ name: capybara
60
+ requirement: &70277957173520 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70277957173520
69
+ - !ruby/object:Gem::Dependency
70
+ name: capybara-email
71
+ requirement: &70277957172440 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70277957172440
80
+ - !ruby/object:Gem::Dependency
81
+ name: valid_attribute
82
+ requirement: &70277957171180 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70277957171180
91
+ - !ruby/object:Gem::Dependency
92
+ name: factory_girl_rails
93
+ requirement: &70277957169080 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70277957169080
102
+ - !ruby/object:Gem::Dependency
103
+ name: bourne
104
+ requirement: &70277957167740 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70277957167740
113
+ - !ruby/object:Gem::Dependency
114
+ name: debugger
115
+ requirement: &70277957165780 !ruby/object:Gem::Requirement
28
116
  none: false
29
117
  requirements:
30
118
  - - ! '>='
@@ -32,8 +120,8 @@ dependencies:
32
120
  version: '0'
33
121
  type: :development
34
122
  prerelease: false
35
- version_requirements: *70170282851920
36
- description: EasyAuth.
123
+ version_requirements: *70277957165780
124
+ description: EasyAuth
37
125
  email:
38
126
  - brian@dockyard.com
39
127
  - bcardarella@gmail.com
@@ -41,19 +129,35 @@ executables: []
41
129
  extensions: []
42
130
  extra_rdoc_files: []
43
131
  files:
44
- - app/assets/javascripts/easy_auth/application.js
45
- - app/assets/stylesheets/easy_auth/application.css
46
- - app/controllers/easy_auth/application_controller.rb
47
- - app/helpers/easy_auth/application_helper.rb
132
+ - app/controllers/authenticated_controller.rb
133
+ - app/controllers/password_reset_controller.rb
134
+ - app/controllers/sessions_controller.rb
135
+ - app/mailers/password_reset_mailer.rb
136
+ - app/mixins/easy_auth/controllers/authenticated.rb
137
+ - app/mixins/easy_auth/controllers/password_reset.rb
138
+ - app/mixins/easy_auth/controllers/sessions.rb
139
+ - app/mixins/easy_auth/helpers.rb
140
+ - app/mixins/easy_auth/mailers/password_reset.rb
141
+ - app/mixins/easy_auth/models/account.rb
142
+ - app/mixins/easy_auth/models/identity.rb
143
+ - app/models/identity.rb
48
144
  - app/views/layouts/easy_auth/application.html.erb
145
+ - app/views/password_reset/edit.html.erb
146
+ - app/views/password_reset/new.html.erb
147
+ - app/views/password_reset_mailer/reset.html.erb
148
+ - app/views/password_reset_mailer/reset.text.erb
149
+ - app/views/sessions/new.html.erb
150
+ - config/locales/en.yml
49
151
  - config/routes.rb
152
+ - db/migrate/20120227014023_create_identities.rb
50
153
  - lib/easy_auth/engine.rb
154
+ - lib/easy_auth/routes.rb
51
155
  - lib/easy_auth/version.rb
52
156
  - lib/easy_auth.rb
53
157
  - lib/tasks/easy_auth_tasks.rake
54
158
  - MIT-LICENSE
55
159
  - Rakefile
56
- - README.rdoc
160
+ - README.md
57
161
  homepage: https://github.com/dockyard/easy_auth
58
162
  licenses: []
59
163
  post_install_message:
@@ -68,7 +172,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
172
  version: '0'
69
173
  segments:
70
174
  - 0
71
- hash: 3680409662779058770
175
+ hash: -3970848794038147418
72
176
  required_rubygems_version: !ruby/object:Gem::Requirement
73
177
  none: false
74
178
  requirements:
@@ -80,5 +184,5 @@ rubyforge_project:
80
184
  rubygems_version: 1.8.15
81
185
  signing_key:
82
186
  specification_version: 3
83
- summary: EasyAuth.
187
+ summary: EasyAuth
84
188
  test_files: []
data/README.rdoc DELETED
@@ -1,3 +0,0 @@
1
- = EasyAuth
2
-
3
- This project rocks and uses MIT-LICENSE.
@@ -1,15 +0,0 @@
1
- // This is a manifest file that'll be compiled into application.js, which will include all the files
2
- // listed below.
3
- //
4
- // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
- // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
- //
7
- // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
- // the compiled file.
9
- //
10
- // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
- // GO AFTER THE REQUIRES BELOW.
12
- //
13
- //= require jquery
14
- //= require jquery_ujs
15
- //= require_tree .
@@ -1,13 +0,0 @@
1
- /*
2
- * This is a manifest file that'll be compiled into application.css, which will include all the files
3
- * listed below.
4
- *
5
- * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
- * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
- *
8
- * You're free to add application-wide styles to this file and they'll appear at the top of the
9
- * compiled file, but it's generally better to create a new file per style scope.
10
- *
11
- *= require_self
12
- *= require_tree .
13
- */
@@ -1,4 +0,0 @@
1
- module EasyAuth
2
- class ApplicationController < ActionController::Base
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module EasyAuth
2
- module ApplicationHelper
3
- end
4
- end