mori 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e216ffc7bd86384021962479ecd4fc801a2c820e
4
- data.tar.gz: 2a15f5d7f9d804ce568dbcc5d80a52ed31ba6648
3
+ metadata.gz: c64de49116a019d10f064bf237a0b8049b886007
4
+ data.tar.gz: 8dcf44b0ec535b9ac2db5e9d05a1eb6302a4af63
5
5
  SHA512:
6
- metadata.gz: 05baff8ea62aac281ca8e652328ef7cec128d6bfb7544bc61b277f265020d850a1f1a6b524cf4e52cf3a548f33dd6d5f07faf09e40eddc5f5308649f4e26c123
7
- data.tar.gz: ea8d7b8ff05f4fa0c51a6e4a9e1f3f2691341f8b18b4627fea78192b4819d0d079aaaf1d036e99e1f1c57a5ceebade50c5f42546fc6f0190c4650239897c1d62
6
+ metadata.gz: e574dc90eef8c8a93d92d4289031d2fb09b1b7bca380dbe17fe3ff101311a102fe03b170520823949cfda1ecbfacc6cdcee7c05a4194b3dbb3cd521c218df8b4
7
+ data.tar.gz: bc6a6a5881df6fd20d634838d76277f3b969d3604c7076e59f6039a2c24ab8298cd62d1ca7b0c5963b288c3d218c55d28f91475df90bd6b78ccc2f3aeeec51aa
@@ -1,3 +1,16 @@
1
+ # This controller is used as a baseline for all Mori Controllers
1
2
  class Mori::BaseController < ApplicationController
3
+
4
+ before_filter :mori_config, :set_token
2
5
  layout 'mori/application'
6
+
7
+ def mori_config
8
+ @config = Mori.configuration
9
+ end
10
+ def set_token
11
+ token, user = params[:token], params[:user]
12
+ if token or user
13
+ @token = token || user[:token]
14
+ end
15
+ end
3
16
  end
@@ -1,7 +1,8 @@
1
+ # Mori::InvitesController handles the sending and acceping of invitations
1
2
  class Mori::InvitesController < Mori::BaseController
2
3
  before_filter :authenticate!, :only => [:new, :send]
3
4
  def show
4
- @user = Mori.configuration.user_model.find_by_invitation_token(params[:id])
5
+ @user = @config.user_model.find_by_invitation_token(params[:id])
5
6
  if @user
6
7
  render :template => 'invites/show'
7
8
  else
@@ -14,24 +15,28 @@ class Mori::InvitesController < Mori::BaseController
14
15
  end
15
16
 
16
17
  def accept
17
- config = Mori.configuration
18
- valid, message = config.user_model.accept_invitation(user_params[:invitation_token], user_params[:password], user_params[:password_confirmation])
19
- flash[:notice] = message
20
- if valid
18
+ user = @config.user_model.find_by_invitation_token(@token)
19
+ if invitation_conditions(user)
20
+ user.accept_invitation(user_params[:password])
21
21
  warden.authenticate!
22
- redirect_to config.dashboard_path
22
+ redirect_to @config.dashboard_path, :notice => I18n.t('flashes.logged_in')
23
23
  else
24
- redirect_to invite_path(user_params[:invitation_token])
24
+ flash[:notice] = I18n.t('flashes.invalid_invitation_token')
25
+ redirect_to invite_path(@token)
25
26
  end
26
27
  end
27
28
 
28
29
  def send_user
29
- valid, message = Mori.configuration.user_model.invite(params[:email])
30
+ valid, message = @config.user_model.invite(params[:email])
30
31
  flash[:notice] = message
31
32
  if valid
32
- redirect_to Mori.configuration.dashboard_path
33
+ redirect_to @config.dashboard_path
33
34
  else
34
35
  render :template => 'invites/new'
35
36
  end
36
37
  end
38
+
39
+ def invitation_conditions(user)
40
+ user.invitation_sent > Mori::Token.expiration_date
41
+ end
37
42
  end
@@ -1,9 +1,10 @@
1
+ # Mori::PasswordsController is responsible for changing and resetting passwords
1
2
  class Mori::PasswordsController < Mori::BaseController
2
3
  before_filter :authenticate!, :only => :change
3
4
  def forgot
4
5
  # View for sending password reset
5
6
  if current_user
6
- redirect_to Mori.configuration.dashboard_path
7
+ redirect_to @config.dashboard_path
7
8
  else
8
9
  render :template => 'passwords/forgot'
9
10
  end
@@ -15,8 +16,7 @@ class Mori::PasswordsController < Mori::BaseController
15
16
  end
16
17
 
17
18
  def reset
18
- redirect_to root_path unless params[:token]
19
- @user = Mori.configuration.user_model.find_by_password_reset_token(params[:token])
19
+ @user = @config.user_model.find_by_password_reset_token(@token) unless @token.blank?
20
20
  if @user
21
21
  render :template => 'passwords/reset'
22
22
  else
@@ -26,34 +26,39 @@ class Mori::PasswordsController < Mori::BaseController
26
26
 
27
27
  def send_reset
28
28
  # Send Password Reset to User
29
- if !Mori.configuration.user_model.forgot_password(params[:email])
30
- render :template => 'passwords/forgot'
31
- else
29
+ if user = @config.user_model.find_by_normalized_email(params[:email])
30
+ user.forgot_password
32
31
  render :template => 'passwords/send_reset'
32
+ else
33
+ render :template => 'passwords/forgot'
33
34
  end
34
35
  end
35
36
 
36
37
  def update
37
38
  # Update their password
38
- valid, message = current_user.change_password(params[:password], params[:new_password], params[:new_password_confirmation])
39
- if valid
39
+ if password_change_conditions
40
+ current_user.change_password(params[:new_password])
40
41
  flash[:notice] = t('flashes.password_changed_successfully')
41
- redirect_to Mori.configuration.dashboard_path
42
+ redirect_to @config.dashboard_path
42
43
  else
43
- flash[:notice] = message
44
+ flash[:notice] = I18n.t('flashes.password_change_failed')
44
45
  render :template => 'passwords/change'
45
46
  end
46
47
  end
47
48
 
48
49
  def reset_password
49
- valid, message = Mori.configuration.user_model.reset_password(user_params[:password_reset_token], user_params[:password], user_params[:password_confirmation])
50
- flash[:notice] = message
51
- if valid
52
- warden.authenticate!
53
- redirect_to Mori.configuration.dashboard_path
50
+ user = @config.user_model.find_by_password_reset_token @token
51
+ if @token != user.password_reset_token or user.password_reset_sent < Mori::Token.expiration_date
52
+ flash[:notice] = t('flashes.invalid_password_reset_token')
53
+ redirect_to "/passwords/reset?token=#{@token}"
54
54
  else
55
- flash[:notice] = message
56
- redirect_to "/passwords/reset?token=#{user_params[:password_reset_token]}"
55
+ user.reset_password(params[:new_password])
56
+ warden.authenticate!
57
+ redirect_to @config.dashboard_path
57
58
  end
58
59
  end
60
+
61
+ def password_change_conditions
62
+ current_user.authenticate(params[:password]) && params[:new_password] == params[:new_password_confirmation]
63
+ end
59
64
  end
@@ -1,9 +1,10 @@
1
+ # Mori::RegistrationsController is responsible for signing up new users
1
2
  class Mori::RegistrationsController < Mori::BaseController
2
3
  def new
3
4
  if current_user
4
- redirect_to Mori.configuration.dashboard_path
5
+ redirect_to @config.dashboard_path
5
6
  else
6
- @user = Mori.configuration.user_model.new
7
+ @user = @config.user_model.new
7
8
  render :template => 'registrations/new'
8
9
  end
9
10
  end
@@ -11,21 +12,22 @@ class Mori::RegistrationsController < Mori::BaseController
11
12
  def create
12
13
  @user = user_from_params
13
14
  if @user.save
14
- warden.set_user(@user)
15
- redirect_to Mori.configuration.after_sign_up_path
15
+ warden.authenticate!
16
+ redirect_to @config.after_sign_up_path
16
17
  else
17
- flash[:notice] = @user.errors.map { |k, v| "#{k} #{v}" }.join(' and ').humanize
18
+ flash[:notice] = @user.errors.map { |key, val| "#{key} #{val}" }.join(' and ').humanize
18
19
  render :template => 'registrations/new'
19
20
  end
20
21
  end
21
22
 
22
23
  def confirmation
23
- valid, message = Mori.configuration.user_model.confirm_email(params[:token])
24
- if valid
25
- flash[:notice] = message
26
- redirect_to Mori.configuration.dashboard_path
24
+ user = @config.user_model.find_by_confirmation_token(@token)
25
+ if confirmation_conditions(user)
26
+ user.confirm_email
27
+ flash[:notice] = I18n.t('flashes.email_confirmed')
28
+ redirect_to @config.dashboard_path
27
29
  else
28
- flash[:notice] = message
30
+ flash[:notice] = I18n.t('flashes.invalid_confirmation_token')
29
31
  redirect_to root_path
30
32
  end
31
33
  end
@@ -36,7 +38,7 @@ class Mori::RegistrationsController < Mori::BaseController
36
38
  email = user_params.delete(:email)
37
39
  password = user_params.delete(:password)
38
40
 
39
- Mori.configuration.user_model.new().tap do |user|
41
+ @config.user_model.new().tap do |user|
40
42
  user.email = email
41
43
  user.password = password
42
44
  end
@@ -45,4 +47,12 @@ class Mori::RegistrationsController < Mori::BaseController
45
47
  def user_params
46
48
  params[:user] || Hash.new
47
49
  end
50
+
51
+ def confirmation_conditions(user)
52
+ begin
53
+ user.confirmation_sent > Mori::Token.expiration_date
54
+ rescue
55
+ return false
56
+ end
57
+ end
48
58
  end
@@ -1,21 +1,22 @@
1
+ # Mori::SessionsController is responsible for creating and destroying sessions
1
2
  class Mori::SessionsController < Mori::BaseController
2
3
  def new
3
4
  if current_user
4
- redirect_to Mori.configuration.dashboard_path
5
+ redirect_to @config.dashboard_path
5
6
  else
6
- @user = Mori.configuration.user_model.new
7
- flash.now.alert = warden.message if warden.message.present?
7
+ @user = @config.user_model.new
8
+ flash.now.alert = warden.message
8
9
  render :template => 'sessions/new'
9
10
  end
10
11
  end
11
12
 
12
13
  def create
13
14
  warden.authenticate!
14
- redirect_to Mori.configuration.dashboard_path, :notice => 'You have logged in'
15
+ redirect_to @config.dashboard_path, :notice => 'You have logged in'
15
16
  end
16
17
 
17
18
  def destroy
18
19
  warden.logout
19
- redirect_to Mori.configuration.after_logout_path
20
+ redirect_to @config.after_logout_path
20
21
  end
21
22
  end
@@ -1,5 +1,5 @@
1
1
  module MoriHelper
2
- def logout_link(text = 'Log Out')
2
+ def mori_logout_link(text = 'Log Out')
3
3
  link_to text, logout_path, :method => :delete
4
4
  end
5
5
  end
@@ -1,3 +1,4 @@
1
+ # MoriMailer sends Forgot Passwords, User Invitations, and Confirmation Emails
1
2
  class MoriMailer < ActionMailer::Base
2
3
  default :from => Mori.configuration.from_email
3
4
 
@@ -1,7 +1,7 @@
1
1
  <%= form_for @user, :url => accept_invites_path, :method => :put, :id => 'accept_invites_form', :class => 'mori_form' do |f| %>
2
2
  <h3 class="form-title">Accept Invitation</h3>
3
3
  <h4><%= flash[:notice] %></h4>
4
- <%= f.hidden_field :invitation_token %>
4
+ <%= f.hidden_field :token, :value => @user.invitation_token %>
5
5
  <%= f.hidden_field :email %>
6
6
  <div class="form-group">
7
7
  <%= f.label :password %>
@@ -7,7 +7,7 @@
7
7
  </div>
8
8
  <% end %>
9
9
  <%= f.hidden_field :email %>
10
- <%= f.hidden_field :password_reset_token %>
10
+ <%= f.hidden_field :token, :value => @user.password_reset_token %>
11
11
  <div class="form-group">
12
12
  <%= f.label :password, "New Password" %>
13
13
  <%= f.password_field :password, :class => "form-control" %>
@@ -1,4 +1,4 @@
1
- Rails.application.config.middleware.use Warden::Manager do |manager|
1
+ Rails.application.config.middleware.insert_after ActionDispatch::Flash, Warden::Manager do |manager|
2
2
  manager.default_strategies :password
3
3
  manager.failure_app = Mori::SessionsController.action(:new)
4
4
  end
@@ -13,15 +13,18 @@ end
13
13
 
14
14
  Warden::Strategies.add(:password) do
15
15
  def valid?
16
- params['user'].present? and params['user']['email'] and params['user']['password']
16
+ user_params.present? and user_params['email'] and user_params['password']
17
17
  end
18
18
 
19
19
  def authenticate!
20
- user = User.find_by_email(params['user']['email'])
21
- if user and user.authenticate(params['user']['password'])
20
+ user = User.find_by_email(user_params['email'])
21
+ if user and user.authenticate(user_params['password'])
22
22
  success! user
23
23
  else
24
24
  fail! "Invalid login credentials"
25
25
  end
26
26
  end
27
+ def user_params
28
+ params['user']
29
+ end
27
30
  end
@@ -4,6 +4,7 @@ en:
4
4
  password_change_failed: We were unable to reset your password. Please try again
5
5
  password_changed_sucessfully: Your password has been updated
6
6
  password_has_been_reset: Your password has been reset
7
+ invalid_password_reset_token: Password Reset Token is Invalid, please try resetting your password again
7
8
  could_not_invite_user: Could not invite user
8
9
  accepted_invitation_message: You have accepted the invitation, welcome magical user
9
10
  logged_in: You have logged in
@@ -0,0 +1,31 @@
1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2
+
3
+ Mori Next steps:
4
+
5
+ 1. Configure the mailer to create full URLs in emails:
6
+
7
+ # config/environments/{development,test}.rb
8
+ config.action_mailer.default_url_options = { host: 'localhost:3000' }
9
+
10
+ In production it should be your app's domain name.
11
+
12
+ 2. Display session info and flashes. For example, in your application layout:
13
+
14
+ <% if signed_in? %>
15
+ Signed in as: <%= current_user.email %>
16
+ <%= mori_logout_link %>
17
+ <% else %>
18
+ <%= link_to 'Sign in', sign_in_path %>
19
+ <% end %>
20
+
21
+ <div id="flash">
22
+ <% flash.each do |key, value| %>
23
+ <div class="flash <%= key %>"><%= value %></div>
24
+ <% end %>
25
+ </div>
26
+
27
+ 3. Migrate the database:
28
+
29
+ rake db:migrate
30
+
31
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1,23 +1,23 @@
1
1
  class AddMoriToUsers < ActiveRecord::Migration
2
2
  def self.up
3
3
  change_table :users do |t|
4
- <% config[:new_columns].values.each do |column| -%>
5
- <%= column %>
6
- <% end -%>
4
+ <% config[:new_columns].values.each do |column| -%>
5
+ <%= column %>
6
+ <% end -%>
7
7
  end
8
8
 
9
- <% config[:new_indexes].values.each do |index| -%>
10
- <%= index %>
11
- <% end -%>
9
+ <% config[:new_indexes].values.each do |index| -%>
10
+ <%= index %>
11
+ <% end -%>
12
12
 
13
13
  end
14
14
  end
15
15
 
16
16
  def self.down
17
17
  change_table :users do |t|
18
- <% if config[:new_columns].any? -%>
19
- t.remove <%= new_columns.keys.map { |column| ":#{column}" }.join(',') %>
20
- <% end -%>
18
+ <% if config[:new_columns].any? -%>
19
+ t.remove <%= new_columns.keys.map { |column| ":#{column}" }.join(',') %>
20
+ <% end -%>
21
21
  end
22
22
  end
23
23
  end
@@ -1,4 +1,5 @@
1
1
  module Mori
2
+ # Mori Configuration is for setting application wide settings
2
3
  class Configuration
3
4
  attr_accessor \
4
5
  :from_email,
@@ -7,7 +7,7 @@ module Mori
7
7
  end
8
8
 
9
9
  def signed_in?
10
- !current_user.nil?
10
+ current_user.preset?
11
11
  end
12
12
 
13
13
  def current_user
@@ -19,7 +19,8 @@ module Mori
19
19
  end
20
20
 
21
21
  def user_params
22
- params[:user] if params[:user].present?
22
+ user = params[:user]
23
+ user if user.present?
23
24
  end
24
25
  end
25
26
  end
data/lib/mori/engine.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  module Mori
2
+ # Mori::Engine configuration file
2
3
  class Engine < ::Rails::Engine
3
- config.generators do |g|
4
- g.test_framework :rspec, :fixture => false
5
- g.fixture_replacement :factory_girl, :dir => 'spec/factories'
6
- g.assets false
7
- g.helper false
4
+ config.generators do |gen|
5
+ gen.test_framework :rspec, :fixture => false
6
+ gen.fixture_replacement :factory_girl, :dir => 'spec/factories'
7
+ gen.assets false
8
+ gen.helper false
8
9
  end
9
10
 
10
11
  initializer 'mori.filter' do |app|
data/lib/mori/token.rb CHANGED
@@ -1,7 +1,11 @@
1
1
  module Mori
2
+ # Mori::Token is used to generate Password Reset, Invitaiton and Confirmation tokens
2
3
  class Token
3
4
  def self.new
4
- SecureRandom.hex(20).encode('UTF-8')
5
+ SecureRandom.hex(10).encode('UTF-8')
6
+ end
7
+ def self.expiration_date
8
+ Date.today - Mori.configuration.token_expiration.days
5
9
  end
6
10
  end
7
11
  end
data/lib/mori/user.rb CHANGED
@@ -16,38 +16,13 @@ module Mori
16
16
  module ClassMethods
17
17
 
18
18
  def find_by_normalized_email(email)
19
- find_by_email normalize_email(email)
19
+ find_by_email(normalize_email(email))
20
20
  end
21
21
 
22
22
  def normalize_email(string)
23
23
  string.gsub(/\s+/, '').downcase
24
24
  end
25
25
 
26
- def confirm_email(token)
27
- user = find_by_confirmation_token(token)
28
- return false, 'Invalid Confirmation Token' if user.blank?
29
- return false, 'Expired Confirmation Token' if user.confirmation_sent < Date.today - Mori.configuration.token_expiration.days
30
- user.confirmed = true
31
- return true, 'Email Confirmed' if user.save
32
- end
33
-
34
- def accept_invitation(token, password, password_confirmation)
35
- user = find_by_invitation_token(token)
36
- return false, I18n.t('flashes.passwords_dont_match') if password != password_confirmation
37
- return false, 'Expired Invitation Token' if user.invitation_sent < Date.today - Mori.configuration.token_expiration.days
38
- user.password = password
39
- return true, I18n.t('flashes.logged_in') if user.save
40
- end
41
-
42
- def reset_password(token, new_password, confirmation)
43
- user = find_by_password_reset_token token
44
- return false, 'Passwords do not match' if new_password != confirmation
45
- return false, 'Invalid Password Reset Token' unless token == user.password_reset_token
46
- return false, 'Expired Reset Token' if user.password_reset_sent < Date.today - Mori.configuration.token_expiration.days
47
- user.password = new_password
48
- user.save
49
- end
50
-
51
26
  def invite(email)
52
27
  user = create(
53
28
  :email => email,
@@ -61,14 +36,6 @@ module Mori
61
36
  end
62
37
  end
63
38
 
64
- def forgot_password(email)
65
- user = find_by_normalized_email(email)
66
- return false if user.blank?
67
- user.password_reset_token = Token.new
68
- user.password_reset_sent = Date.today
69
- MoriMailer.forgot_password(user)
70
- user.save
71
- end
72
39
  end
73
40
 
74
41
  module Callbacks
@@ -91,16 +58,36 @@ module Mori
91
58
  end
92
59
  end
93
60
 
94
- def change_password(password, new_password, confirm)
95
- return false, I18n.t('flashes.password_change_failed') if ::BCrypt::Password.new(self.password) != password
96
- return false, I18n.t('flashes.passwords_did_not_match') if new_password != confirm
61
+ def accept_invitation(password)
62
+ self.password = password
63
+ self.confirmed = true
64
+ self.save
65
+ end
66
+
67
+ def change_password(new_password)
97
68
  self.password = new_password
98
69
  save
99
70
  end
100
71
 
72
+ def forgot_password
73
+ self.password_reset_token = Token.new
74
+ self.password_reset_sent = Date.today
75
+ MoriMailer.forgot_password(self)
76
+ save
77
+ end
78
+
79
+ def confirm_email
80
+ self.confirmed = true
81
+ self.save
82
+ end
83
+
84
+ def reset_password(new_password)
85
+ self.password = new_password
86
+ self.save
87
+ end
88
+
101
89
  def authenticate(password)
102
- return false if ::BCrypt::Password.new(self.password) != password
103
- true
90
+ ::BCrypt::Password.new(self.password) == password
104
91
  end
105
92
 
106
93
  private
data/lib/mori/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mori
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  <h1> Hello World </h1>
2
2
  <%= flash[:notice] %>
3
- <%= logout_link %>
3
+ <%= mori_logout_link %>
4
4
  <br/>
5
5
  <%= link_to 'Sign In', login_path %>
6
6
  <br/>
Binary file