mori 0.0.1 → 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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +51 -1
- data/Rakefile +1 -0
- data/app/controllers/mori/base_controller.rb +3 -0
- data/app/controllers/mori/invites_controller.rb +37 -0
- data/app/controllers/mori/passwords_controller.rb +59 -0
- data/app/controllers/mori/registrations_controller.rb +32 -7
- data/app/controllers/mori/sessions_controller.rb +10 -6
- data/app/helpers/mori_helper.rb +1 -1
- data/app/mailers/mori_mailer.rb +18 -0
- data/app/views/invites/new.html.erb +1 -0
- data/app/views/invites/show.html.erb +1 -0
- data/app/views/layouts/mori/application.html.erb +7 -1
- data/app/views/layouts/mori/form.html.erb +15 -0
- data/app/views/mori_forms/_accept_invite.html.erb +16 -0
- data/app/views/mori_forms/_change_password.html.erb +22 -0
- data/app/views/mori_forms/_forgot_password.html.erb +14 -0
- data/app/views/mori_forms/_invite_new_user_form.html.erb +14 -0
- data/app/views/mori_forms/_password_reset.html.erb +20 -0
- data/app/views/mori_forms/_registration.html.erb +22 -0
- data/app/views/mori_forms/_sessions.html.erb +18 -0
- data/app/views/mori_mailer/confirm_email.html.erb +4 -0
- data/app/views/mori_mailer/forgot_password.html.erb +7 -0
- data/app/views/mori_mailer/invite_user.html.erb +5 -0
- data/app/views/passwords/change.html.erb +1 -0
- data/app/views/passwords/forgot.html.erb +2 -0
- data/app/views/passwords/reset.html.erb +1 -0
- data/app/views/passwords/send_reset.html.erb +1 -0
- data/app/views/registrations/new.html.erb +2 -0
- data/app/views/sessions/new.html.erb +2 -0
- data/app/views/shared/_links.html.erb +11 -0
- data/config/database.travis.yml +3 -25
- data/config/initializers/warden.rb +5 -5
- data/config/locales/mori.en.yml +20 -16
- data/config/routes.rb +22 -2
- data/db/migrate/20140128055658_create_users.rb +29 -0
- data/lib/assets/javascripts/bootstrap.min.js +6 -0
- data/lib/assets/stylesheets/bootstrap.min.css +7 -0
- data/lib/generators/mori/install/install_generator.rb +130 -0
- data/lib/generators/mori/install/templates/db/migrate/add_mori_to_users.rb +23 -0
- data/{db/migrate/20140128055658_create_mori_users.rb → lib/generators/mori/install/templates/db/migrate/create_users.rb} +6 -9
- data/lib/generators/mori/install/templates/mori.rb +32 -0
- data/lib/generators/mori/install/templates/user.rb +3 -0
- data/lib/generators/mori/views/USAGE +12 -0
- data/lib/generators/mori/views/views_generator.rb +39 -0
- data/lib/mori/configuration.rb +17 -10
- data/lib/mori/controller.rb +25 -0
- data/lib/mori/engine.rb +2 -6
- data/lib/mori/password.rb +21 -0
- data/lib/mori/token.rb +3 -12
- data/lib/mori/user.rb +124 -0
- data/lib/mori/version.rb +1 -1
- data/lib/mori.rb +3 -3
- data/spec/dummy/app/assets/javascripts/application.js +2 -0
- data/spec/dummy/app/controllers/application_controller.rb +1 -0
- data/spec/dummy/app/models/user.rb +4 -0
- data/spec/dummy/app/views/application/index.html.erb +13 -0
- data/spec/dummy/app/views/application/test_login.html.erb +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +2 -2
- data/spec/dummy/config/application.rb +9 -7
- data/spec/dummy/config/database.yml +6 -24
- data/spec/dummy/config/environments/production.rb +2 -2
- data/spec/dummy/config/environments/test.rb +3 -3
- data/spec/dummy/config/initializers/mime_types.rb +2 -2
- data/spec/dummy/config/initializers/mori.rb +12 -1
- data/spec/dummy/config/initializers/secret_token.rb +6 -1
- data/spec/dummy/config/locales/en.yml +1 -1
- data/spec/dummy/config/routes.rb +2 -1
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/{20140209071716_create_users.mori_engine.rb → 20140421045106_create_users.mori_engine.rb} +2 -6
- data/spec/dummy/db/schema.rb +14 -21
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +14442 -21478
- data/spec/dummy/log/test.log +128933 -76950
- data/spec/dummy/public/404.html +1 -1
- data/spec/dummy/public/422.html +1 -1
- data/spec/dummy/public/500.html +1 -1
- data/spec/dummy/tmp/cache/assets/development/sprockets/07db4022ed50ebf1535599a3e2344037 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/09f817f5fe8888d5c59a3b285c3ef605 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/19f899de0e04ccfd931a7a11e36aca13 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1b98ef3337306536c2890a74951d225c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2000a2ad47f8e201455b785beb7b1384 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/22de1150643c428d3f508171d74347a3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3453364cd811fec54cae0a92adc719e4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4462cfec451130aa58d88b3da13913c3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/45753608d28d02693f8f6277074589a1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/56b349da612a4be9d5e6733778ce17e4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5b3ef4ce70e1da7b1afd392754613726 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/770ff8b64985dd08cab8c32a1fa76438 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8e4cef792c949716da8fe3e9ee0cda70 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a6374c002de146da5c25b8cfd375ce6c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b085c718dd9381a5d4036f00b47d1b91 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c207a30f2b33f7df2c5336aed05485a2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cf4d7483cd5aff334d69dd3173f9b953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e2b0bfc208732a6cf47d67c1be32e54f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/07db4022ed50ebf1535599a3e2344037 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/09f817f5fe8888d5c59a3b285c3ef605 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/1143c7a241c19613744d1a2be3ad7cd1 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/19f899de0e04ccfd931a7a11e36aca13 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/1b98ef3337306536c2890a74951d225c +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/39cd89cab4906d24583c876a477cf098 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/4462cfec451130aa58d88b3da13913c3 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/45753608d28d02693f8f6277074589a1 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/56b349da612a4be9d5e6733778ce17e4 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/5b3ef4ce70e1da7b1afd392754613726 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/770ff8b64985dd08cab8c32a1fa76438 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/8e4cef792c949716da8fe3e9ee0cda70 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/9d5b4060cdb29606bd153ef2ca742a22 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/a6374c002de146da5c25b8cfd375ce6c +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/b085c718dd9381a5d4036f00b47d1b91 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/c1fb58de0c271425746c77af9e101750 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/c207a30f2b33f7df2c5336aed05485a2 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/e2b0bfc208732a6cf47d67c1be32e54f +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/factories/mori_users.rb +8 -8
- data/spec/features/invites_spec.rb +64 -0
- data/spec/features/passwords_spec.rb +101 -0
- data/spec/features/registrations_spec.rb +37 -10
- data/spec/features/sessions_spec.rb +24 -28
- data/spec/helpers/mori_helper_spec.rb +3 -12
- data/spec/helpers.rb +10 -0
- data/spec/mailers/mori/mailer_spec.rb +24 -4
- data/spec/models/mori/user_spec.rb +187 -167
- data/spec/spec_helper.rb +17 -6
- metadata +108 -53
- data/app/assets/javascripts/mori/application.js +0 -13
- data/app/assets/stylesheets/mori/application.css +0 -13
- data/app/controllers/mori_controller.rb +0 -8
- data/app/mailers/mori/mailer.rb +0 -17
- data/app/models/mori/user.rb +0 -85
- data/app/views/mori/mailer/confirm_email.html.erb +0 -1
- data/app/views/mori/mailer/invite_user.html.erb +0 -1
- data/app/views/mori/mailer/password_reset_notification.html.erb +0 -1
- data/app/views/mori/registrations/new.slim +0 -9
- data/app/views/mori/sessions/new.slim +0 -8
- data/db/migrate/20140126052000_enable_hstore.rb +0 -9
- data/lib/mori/string.rb +0 -20
- data/spec/dummy/app/views/application/index.slim +0 -2
- data/spec/dummy/db/migrate/20140128055553_enable_hstore.mori.rb +0 -10
- data/spec/dummy/log/user.log +0 -43
- data/spec/dummy/tmp/pids/server.pid +0 -1
- data/spec/mailer_matcher.rb +0 -33
- data/spec/views/mori/registrations/create.html.erb_spec.rb +0 -5
- data/spec/views/mori/registrations/new.html.erb_spec.rb +0 -5
- data/spec/views/mori/sessions/create.html.erb_spec.rb +0 -5
- data/spec/views/mori/sessions/destroy.html.erb_spec.rb +0 -5
- data/spec/views/mori/sessions/new.html.erb_spec.rb +0 -5
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'rails/generators/base'
|
|
2
|
+
|
|
3
|
+
module Mori
|
|
4
|
+
module Generators
|
|
5
|
+
class ViewsGenerator < Rails::Generators::Base
|
|
6
|
+
source_root Mori.root
|
|
7
|
+
|
|
8
|
+
def create_views
|
|
9
|
+
views.each do |view|
|
|
10
|
+
copy_file view
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_locales
|
|
15
|
+
locales.each do |locale|
|
|
16
|
+
copy_file locale
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def views
|
|
23
|
+
files_within_root('.', 'app/views/**/*.*')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def locales
|
|
27
|
+
files_within_root('.', 'config/locales/**/*.*')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def files_within_root(prefix, glob)
|
|
31
|
+
root = "#{self.class.source_root}/#{prefix}"
|
|
32
|
+
|
|
33
|
+
Dir["#{root}/#{glob}"].sort.map do |full_path|
|
|
34
|
+
full_path.sub(root, '.').gsub('/./', '/')
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/mori/configuration.rb
CHANGED
|
@@ -2,24 +2,31 @@ module Mori
|
|
|
2
2
|
class Configuration
|
|
3
3
|
attr_accessor \
|
|
4
4
|
:from_email,
|
|
5
|
-
:
|
|
6
|
-
:account_database,
|
|
5
|
+
:app_name,
|
|
7
6
|
:allow_sign_up,
|
|
8
|
-
:
|
|
9
|
-
:
|
|
10
|
-
:
|
|
7
|
+
:after_sign_up_path,
|
|
8
|
+
:after_logout_path,
|
|
9
|
+
:dashboard_path,
|
|
10
|
+
:user_model,
|
|
11
|
+
:token_expiration
|
|
11
12
|
|
|
12
13
|
def initialize
|
|
13
|
-
@from_email =
|
|
14
|
-
@
|
|
14
|
+
@from_email = 'noreply@example.com'
|
|
15
|
+
@app_name = Rails.application.class.parent_name.humanize
|
|
15
16
|
@allow_sign_up = true
|
|
16
|
-
@
|
|
17
|
-
@
|
|
18
|
-
@
|
|
17
|
+
@after_sign_up_path = '/'
|
|
18
|
+
@after_logout_path = '/'
|
|
19
|
+
@dashboard_path = '/'
|
|
20
|
+
@token_expiration = 14
|
|
19
21
|
end
|
|
22
|
+
|
|
20
23
|
def allow_sign_up?
|
|
21
24
|
allow_sign_up
|
|
22
25
|
end
|
|
26
|
+
|
|
27
|
+
def user_model
|
|
28
|
+
@user_model || ::User
|
|
29
|
+
end
|
|
23
30
|
end
|
|
24
31
|
|
|
25
32
|
def self.configuration
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Mori
|
|
2
|
+
module Controller
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
def authenticate!
|
|
6
|
+
warden.authenticate!
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def signed_in?
|
|
10
|
+
!current_user.nil?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def current_user
|
|
14
|
+
warden.user
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def warden
|
|
18
|
+
env['warden']
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def user_params
|
|
22
|
+
params[:user] if params[:user].present?
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/mori/engine.rb
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
module Mori
|
|
2
2
|
class Engine < ::Rails::Engine
|
|
3
|
-
|
|
4
3
|
config.generators do |g|
|
|
5
|
-
g.test_framework
|
|
4
|
+
g.test_framework :rspec, :fixture => false
|
|
6
5
|
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
|
|
7
6
|
g.assets false
|
|
8
7
|
g.helper false
|
|
9
8
|
end
|
|
10
9
|
|
|
11
10
|
initializer 'mori.filter' do |app|
|
|
12
|
-
app.config.filter_parameters += [:password]
|
|
11
|
+
app.config.filter_parameters += [:password, :new_password, :new_password_confirmation]
|
|
13
12
|
end
|
|
14
13
|
|
|
15
|
-
config.to_prepare do
|
|
16
|
-
ApplicationHelper.send :include, MoriHelper
|
|
17
|
-
end
|
|
18
14
|
end
|
|
19
15
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'bcrypt'
|
|
2
|
+
|
|
3
|
+
module Mori
|
|
4
|
+
module Password
|
|
5
|
+
include BCrypt
|
|
6
|
+
|
|
7
|
+
def encrypt(string)
|
|
8
|
+
::BCrypt::Password.create(string, :cost => cost)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def compare_encrypted(string)
|
|
12
|
+
::BCrypt::Password.new(string)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def cost
|
|
18
|
+
::BCrypt::Engine::DEFAULT_COST
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/mori/token.rb
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
module Mori
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
included do
|
|
6
|
-
generate_token
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
module ClassMethods
|
|
10
|
-
|
|
11
|
-
def generate_token
|
|
12
|
-
SecureRandom.hex(25)
|
|
13
|
-
end
|
|
2
|
+
class Token
|
|
3
|
+
def self.new
|
|
4
|
+
SecureRandom.hex(20).encode('UTF-8')
|
|
14
5
|
end
|
|
15
6
|
end
|
|
16
7
|
end
|
data/lib/mori/user.rb
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require 'email_validator'
|
|
2
|
+
require 'mori/token'
|
|
3
|
+
require 'mori/password'
|
|
4
|
+
|
|
5
|
+
module Mori
|
|
6
|
+
module User
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
include Password
|
|
11
|
+
|
|
12
|
+
include Validations
|
|
13
|
+
include Callbacks
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module ClassMethods
|
|
17
|
+
|
|
18
|
+
def find_by_normalized_email(email)
|
|
19
|
+
find_by_email normalize_email(email)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def normalize_email(string)
|
|
23
|
+
string.gsub(/\s+/, '').downcase
|
|
24
|
+
end
|
|
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
|
+
def invite(email)
|
|
52
|
+
user = create(
|
|
53
|
+
:email => email,
|
|
54
|
+
:invitation_token => Token.new,
|
|
55
|
+
:invitation_sent => Date.today)
|
|
56
|
+
if user.save
|
|
57
|
+
MoriMailer.invite_user(user)
|
|
58
|
+
return true, "An invite has been sent to #{email}"
|
|
59
|
+
else
|
|
60
|
+
return false, I18n.t('flashes.could_not_invite_user')
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
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
|
+
end
|
|
73
|
+
|
|
74
|
+
module Callbacks
|
|
75
|
+
extend ActiveSupport::Concern
|
|
76
|
+
|
|
77
|
+
included do
|
|
78
|
+
before_save :encrypt_password, :if => proc { |user| user.password_changed? }
|
|
79
|
+
before_validation :normalize_email, :if => proc { |user| user.email_changed? }
|
|
80
|
+
before_create :send_email_confirmation, :if => proc { |user| user.password.present? }
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
module Validations
|
|
85
|
+
extend ActiveSupport::Concern
|
|
86
|
+
included do
|
|
87
|
+
validates :email, :email => { :strict_mode => true }, :presence => true, :uniqueness => true
|
|
88
|
+
validates :password, :presence => true, :unless => :invitation_token?
|
|
89
|
+
validates :password_reset_token, :uniqueness => true, :if => :password_reset_token?
|
|
90
|
+
validates :invitation_token, :uniqueness => true, :if => :invitation_token?
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
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
|
|
97
|
+
self.password = new_password
|
|
98
|
+
save
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def authenticate(password)
|
|
102
|
+
return false if ::BCrypt::Password.new(self.password) != password
|
|
103
|
+
true
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def normalize_email
|
|
109
|
+
self.email = self.class.normalize_email(email)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def send_email_confirmation
|
|
113
|
+
self.confirmation_token = SecureRandom.hex(25)
|
|
114
|
+
self.confirmation_sent = Date.today
|
|
115
|
+
MoriMailer.confirm_email(self)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def encrypt_password
|
|
119
|
+
self.password = encrypt(password)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
end
|
data/lib/mori/version.rb
CHANGED
data/lib/mori.rb
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<h1> Hello World </h1>
|
|
2
|
+
<%= flash[:notice] %>
|
|
3
|
+
<%= logout_link %>
|
|
4
|
+
<br/>
|
|
5
|
+
<%= link_to 'Sign In', login_path %>
|
|
6
|
+
<br/>
|
|
7
|
+
<%= link_to 'Sign Up', sign_up_path %>
|
|
8
|
+
<br/>
|
|
9
|
+
<%= link_to 'Reset Password', forgot_passwords_path %>
|
|
10
|
+
<br/>
|
|
11
|
+
<%= link_to 'Invite New User', new_invite_path %>
|
|
12
|
+
<br/>
|
|
13
|
+
<%= link_to 'Change Password', change_passwords_path %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= 'Logged In' if current_user %>
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
4
|
<title>Dummy</title>
|
|
5
|
-
<%= stylesheet_link_tag
|
|
6
|
-
<%= javascript_include_tag
|
|
5
|
+
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
|
|
6
|
+
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
|
|
7
7
|
<%= csrf_meta_tags %>
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
require File.expand_path('../boot', __FILE__)
|
|
2
2
|
|
|
3
3
|
# Pick the frameworks you want:
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
# require
|
|
4
|
+
require 'active_record/railtie'
|
|
5
|
+
require 'action_controller/railtie'
|
|
6
|
+
require 'action_mailer/railtie'
|
|
7
|
+
require 'sprockets/railtie'
|
|
8
|
+
# require 'rails/test_unit/railtie'
|
|
9
9
|
|
|
10
10
|
Bundler.require(*Rails.groups)
|
|
11
|
-
require
|
|
11
|
+
require 'mori'
|
|
12
12
|
|
|
13
13
|
module Dummy
|
|
14
14
|
class Application < Rails::Application
|
|
@@ -17,7 +17,7 @@ module Dummy
|
|
|
17
17
|
# -- all .rb files in that directory are automatically loaded.
|
|
18
18
|
|
|
19
19
|
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
|
20
|
-
# Run
|
|
20
|
+
# Run 'rake -D time' for a list of tasks for finding time zone names. Default is UTC.
|
|
21
21
|
# config.time_zone = 'Central Time (US & Canada)'
|
|
22
22
|
|
|
23
23
|
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
|
@@ -26,6 +26,8 @@ module Dummy
|
|
|
26
26
|
|
|
27
27
|
config.i18n.enforce_available_locales = false
|
|
28
28
|
|
|
29
|
+
config.action_mailer.default_url_options = { host: 'localhost' }
|
|
30
|
+
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
|
|
@@ -1,29 +1,11 @@
|
|
|
1
1
|
development:
|
|
2
|
-
adapter:
|
|
3
|
-
|
|
4
|
-
database: dummy_development
|
|
2
|
+
adapter: sqlite3
|
|
3
|
+
database: db/development.sqlite3
|
|
5
4
|
pool: 5
|
|
6
|
-
|
|
5
|
+
timeout: 5000
|
|
7
6
|
|
|
8
7
|
test:
|
|
9
|
-
adapter:
|
|
10
|
-
|
|
11
|
-
database: dummy_test
|
|
8
|
+
adapter: sqlite3
|
|
9
|
+
database: db/test.sqlite3
|
|
12
10
|
pool: 5
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
production:
|
|
16
|
-
adapter: postgresql
|
|
17
|
-
encoding: unicode
|
|
18
|
-
database: dummy_production
|
|
19
|
-
pool: 5
|
|
20
|
-
username: dummy
|
|
21
|
-
password:
|
|
22
|
-
|
|
23
|
-
user:
|
|
24
|
-
adapter: postgresql
|
|
25
|
-
encoding: unicode
|
|
26
|
-
database: account_database
|
|
27
|
-
pool: 5
|
|
28
|
-
username: AaronMiler
|
|
29
|
-
password:
|
|
11
|
+
timeout: 5000
|
|
@@ -36,7 +36,7 @@ Dummy::Application.configure do
|
|
|
36
36
|
config.assets.version = '1.0'
|
|
37
37
|
|
|
38
38
|
# Specifies the header that your server uses for sending files.
|
|
39
|
-
# config.action_dispatch.x_sendfile_header =
|
|
39
|
+
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for apache
|
|
40
40
|
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
|
|
41
41
|
|
|
42
42
|
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
|
@@ -55,7 +55,7 @@ Dummy::Application.configure do
|
|
|
55
55
|
# config.cache_store = :mem_cache_store
|
|
56
56
|
|
|
57
57
|
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
|
58
|
-
# config.action_controller.asset_host =
|
|
58
|
+
# config.action_controller.asset_host = 'http://assets.example.com'
|
|
59
59
|
|
|
60
60
|
# Precompile additional assets.
|
|
61
61
|
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
|
|
@@ -3,7 +3,7 @@ Dummy::Application.configure do
|
|
|
3
3
|
|
|
4
4
|
# The test environment is used exclusively to run your application's
|
|
5
5
|
# test suite. You never need to work with it otherwise. Remember that
|
|
6
|
-
# your test database is
|
|
6
|
+
# your test database is 'scratch space' for the test suite and is wiped
|
|
7
7
|
# and recreated between test runs. Don't rely on the data there!
|
|
8
8
|
config.cache_classes = true
|
|
9
9
|
|
|
@@ -14,7 +14,7 @@ Dummy::Application.configure do
|
|
|
14
14
|
|
|
15
15
|
# Configure static asset server for tests with Cache-Control for performance.
|
|
16
16
|
config.serve_static_assets = true
|
|
17
|
-
config.static_cache_control =
|
|
17
|
+
config.static_cache_control = 'public, max-age=3600'
|
|
18
18
|
|
|
19
19
|
# Show full error reports and disable caching.
|
|
20
20
|
config.consider_all_requests_local = true
|
|
@@ -42,7 +42,7 @@ Dummy::Application.configure do
|
|
|
42
42
|
:port => '2525',
|
|
43
43
|
:authentication => :plain
|
|
44
44
|
}
|
|
45
|
-
FactoryGirl.definition_file_paths << Pathname.new(
|
|
45
|
+
FactoryGirl.definition_file_paths << Pathname.new('../factories')
|
|
46
46
|
FactoryGirl.definition_file_paths.uniq!
|
|
47
47
|
FactoryGirl.find_definitions
|
|
48
48
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Be sure to restart your server when you modify this file.
|
|
2
2
|
|
|
3
3
|
# Add new mime types for use in respond_to blocks:
|
|
4
|
-
# Mime::Type.register
|
|
5
|
-
# Mime::Type.register_alias
|
|
4
|
+
# Mime::Type.register 'text/richtext', :rtf
|
|
5
|
+
# Mime::Type.register_alias 'text/html', :iphone
|
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
Mori.configure do |config|
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
# Mori Configuration Options
|
|
4
|
+
|
|
5
|
+
config.from_email = 'reply@example.com'
|
|
6
|
+
|
|
7
|
+
# Other Configuration Options
|
|
8
|
+
#
|
|
9
|
+
# config.app_name = "My Application Name"
|
|
10
|
+
# config.allow_sign_up = true/false
|
|
11
|
+
# config.dashboard_path = '/dashboard'
|
|
12
|
+
# config.after_sign_up_path = '/welcome'
|
|
13
|
+
# config.after_logout_path = '/destination_path'
|
|
3
14
|
end
|
|
@@ -9,4 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
# Make sure your secret_key_base is kept private
|
|
11
11
|
# if you're sharing your code publicly.
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
Dummy::Application.config.secret_token = 'SECRET_TOKEN_IS_MIN_30_CHARS_LONG'
|
|
14
|
+
if Rails::VERSION::MAJOR == 4
|
|
15
|
+
Dummy::Application.config.secret_key_base = '04cb504d4532ea6e41d7c885782aad2390c244f9708511affef23f67b0fdf17f78053da54644069112a9185141fe8be62b901ba75362d177d8e6888e704be014'
|
|
16
|
+
end
|
|
17
|
+
|
data/spec/dummy/config/routes.rb
CHANGED
|
Binary file
|
|
@@ -19,16 +19,12 @@ class CreateUsers < ActiveRecord::Migration
|
|
|
19
19
|
t.string :confirmation_token
|
|
20
20
|
t.datetime :confirmation_sent
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
t.
|
|
24
|
-
|
|
25
|
-
# Application specific attributes
|
|
26
|
-
t.hstore :data, :default => {}
|
|
22
|
+
# Using Postgres?
|
|
23
|
+
# t.hstore :data, :default => {}
|
|
27
24
|
|
|
28
25
|
t.timestamps
|
|
29
26
|
|
|
30
27
|
end
|
|
31
28
|
add_index :users, :email
|
|
32
|
-
add_index :users, :group_id
|
|
33
29
|
end
|
|
34
30
|
end
|
data/spec/dummy/db/schema.rb
CHANGED
|
@@ -11,29 +11,22 @@
|
|
|
11
11
|
#
|
|
12
12
|
# It's strongly recommended that you check this file into your version control system.
|
|
13
13
|
|
|
14
|
-
ActiveRecord::Schema.define(version:
|
|
14
|
+
ActiveRecord::Schema.define(version: 20140421045106) do
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
t.string
|
|
22
|
-
t.
|
|
23
|
-
t.
|
|
24
|
-
t.
|
|
25
|
-
t.
|
|
26
|
-
t.datetime
|
|
27
|
-
t.
|
|
28
|
-
t.string "confirmation_token"
|
|
29
|
-
t.datetime "confirmation_sent"
|
|
30
|
-
t.integer "group_id"
|
|
31
|
-
t.hstore "data", default: ""
|
|
32
|
-
t.datetime "created_at"
|
|
33
|
-
t.datetime "updated_at"
|
|
16
|
+
create_table 'users', force: true do |t|
|
|
17
|
+
t.string 'email'
|
|
18
|
+
t.text 'password'
|
|
19
|
+
t.string 'invitation_token'
|
|
20
|
+
t.datetime 'invitation_sent'
|
|
21
|
+
t.string 'password_reset_token'
|
|
22
|
+
t.datetime 'password_reset_sent'
|
|
23
|
+
t.boolean 'confirmed'
|
|
24
|
+
t.string 'confirmation_token'
|
|
25
|
+
t.datetime 'confirmation_sent'
|
|
26
|
+
t.datetime 'created_at'
|
|
27
|
+
t.datetime 'updated_at'
|
|
34
28
|
end
|
|
35
29
|
|
|
36
|
-
add_index
|
|
37
|
-
add_index "users", ["group_id"], name: "index_users_on_group_id", using: :btree
|
|
30
|
+
add_index 'users', ['email'], name: 'index_users_on_email'
|
|
38
31
|
|
|
39
32
|
end
|
|
Binary file
|