aerogel-users 1.4.3

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.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +16 -0
  6. data/Rakefile +1 -0
  7. data/aerogel-users.gemspec +30 -0
  8. data/app/helpers/access_control.rb +32 -0
  9. data/app/helpers/auth.rb +58 -0
  10. data/app/helpers/auth_login_providers.rb +18 -0
  11. data/app/mailers/user.rb +43 -0
  12. data/app/routes/access_control.rb +15 -0
  13. data/app/routes/auth.rb +53 -0
  14. data/app/routes/user.rb +192 -0
  15. data/assets/README.md +1 -0
  16. data/assets/javascripts/.gitkeep +0 -0
  17. data/assets/stylesheets/.gitkeep +0 -0
  18. data/config/auth.conf +43 -0
  19. data/config/development/.keep +0 -0
  20. data/config/production/.keep +0 -0
  21. data/db/model/access.rb +67 -0
  22. data/db/model/authentication.rb +54 -0
  23. data/db/model/role.rb +17 -0
  24. data/db/model/user.rb +223 -0
  25. data/db/model/user_email.rb +24 -0
  26. data/db/model/user_registration_form.rb +23 -0
  27. data/db/model/user_request_account_activation_form.rb +30 -0
  28. data/db/model/user_request_email_confirmation_form.rb +40 -0
  29. data/db/model/user_request_password_reset_form.rb +37 -0
  30. data/db/model/user_reset_password_form.rb +41 -0
  31. data/db/seed/01_user_role.seed +8 -0
  32. data/db/seed/02_access_user.seed +25 -0
  33. data/db/seed/development/.keep +0 -0
  34. data/db/seed/development/test-user.seed +77 -0
  35. data/db/seed/production/.keep +0 -0
  36. data/lib/aerogel/users.rb +22 -0
  37. data/lib/aerogel/users/auth.rb +67 -0
  38. data/lib/aerogel/users/omniauth-failure_endpoint_ex.rb +21 -0
  39. data/lib/aerogel/users/omniauth-password.rb +63 -0
  40. data/lib/aerogel/users/secure_password.rb +55 -0
  41. data/lib/aerogel/users/version.rb +5 -0
  42. data/locales/actions/en.yml +18 -0
  43. data/locales/actions/ru.yml +17 -0
  44. data/locales/auth/en.yml +22 -0
  45. data/locales/auth/ru.yml +22 -0
  46. data/locales/mailers/en.yml +69 -0
  47. data/locales/mailers/ru.yml +73 -0
  48. data/locales/models/en.yml +65 -0
  49. data/locales/models/ru.yml +64 -0
  50. data/locales/views/en.yml +122 -0
  51. data/locales/views/ru.yml +126 -0
  52. data/public/README.md +1 -0
  53. data/rake/README.md +3 -0
  54. data/views/mailers/user/account_activation.html.erb +3 -0
  55. data/views/mailers/user/account_activation.text.erb +3 -0
  56. data/views/mailers/user/email_confirmation.html.erb +3 -0
  57. data/views/mailers/user/email_confirmation.text.erb +3 -0
  58. data/views/mailers/user/password_reset.html.erb +3 -0
  59. data/views/mailers/user/password_reset.text.erb +3 -0
  60. data/views/user/activate_account.html.erb +3 -0
  61. data/views/user/activate_account_failure.html.erb +3 -0
  62. data/views/user/confirm_email.html.erb +3 -0
  63. data/views/user/confirm_email_failure.html.erb +3 -0
  64. data/views/user/edit.html.erb +6 -0
  65. data/views/user/index.html.erb +19 -0
  66. data/views/user/login.html.erb +3 -0
  67. data/views/user/login/_form.html.erb +28 -0
  68. data/views/user/login/_provider.html.erb +5 -0
  69. data/views/user/logout.html.erb +3 -0
  70. data/views/user/register.html.erb +10 -0
  71. data/views/user/register_success.html.erb +3 -0
  72. data/views/user/request_account_activation.html.erb +9 -0
  73. data/views/user/request_account_activation_success.html.erb +3 -0
  74. data/views/user/request_email_confirmation.html.erb +8 -0
  75. data/views/user/request_email_confirmation_success.html.erb +3 -0
  76. data/views/user/request_password_reset.html.erb +8 -0
  77. data/views/user/request_password_reset_success.html.erb +3 -0
  78. data/views/user/reset_password.html.erb +9 -0
  79. data/views/user/reset_password_success.html.erb +3 -0
  80. metadata +234 -0
@@ -0,0 +1,30 @@
1
+ class UserRequestAccountActivationForm
2
+
3
+ include Model::NonPersistent
4
+
5
+ field :email, type: String
6
+
7
+ validates_presence_of :email
8
+ validates_format_of :email, with: /@/, message: :invalid_format
9
+
10
+ # validates uniqueness of provider & uid (email) among all users
11
+ validate do |record|
12
+ user = User.where( 'emails.email' => record.email ).first
13
+ unless user
14
+ record.errors.add :email, :not_registered
15
+ return
16
+ end
17
+ if user.activated?( record.email )
18
+ record.errors.add :base, :account_already_activated
19
+ return
20
+ end
21
+ end
22
+
23
+ # Returns UserEmail object, corresponding to this email address
24
+ #
25
+ def user
26
+ user = User.where( 'emails.email' => email ).first
27
+ end
28
+
29
+
30
+ end # class UserRequestAccountActivationForm
@@ -0,0 +1,40 @@
1
+ class UserRequestEmailConfirmationForm
2
+
3
+ include Model::NonPersistent
4
+
5
+ field :email, type: String
6
+
7
+ validates_presence_of :email
8
+ validates_format_of :email, with: /@/, message: :invalid_format
9
+
10
+ # validates uniqueness of provider & uid (email) among all users
11
+ validate do |record|
12
+ user = User.where( 'emails.email' => record.email ).first
13
+ unless user
14
+ record.errors.add :email, :not_registered
15
+ return
16
+ end
17
+ user_email = user.emails.where( email: record.email ).first
18
+ unless user_email
19
+ record.errors.add :email, :invalid
20
+ return
21
+ end
22
+ if user_email.confirmed
23
+ record.errors.add :email, :already_confirmed
24
+ end
25
+ end
26
+
27
+ # Returns User object, corresponding to this email address
28
+ #
29
+ def user
30
+ User.where( 'emails.email' => email ).first
31
+ end
32
+
33
+ # Returns UserEmail object, corresponding to this email address
34
+ #
35
+ def user_email
36
+ user.emails.where( email: email ).first
37
+ end
38
+
39
+
40
+ end # class UserRequestEmailConfirmationForm
@@ -0,0 +1,37 @@
1
+ class UserRequestPasswordResetForm
2
+
3
+ include Model::NonPersistent
4
+
5
+ field :email, type: String
6
+
7
+ validates_presence_of :email
8
+ validates_format_of :email, with: /@/, message: :invalid_format
9
+
10
+ # validates uniqueness of provider & uid (email) among all users
11
+ validate do |record|
12
+ user = User.where( 'emails.email' => record.email ).first
13
+ unless user
14
+ record.errors.add :email, :not_registered
15
+ return
16
+ end
17
+ authentication = user.authentications.where( provider: :password, uid: record.email ).first
18
+ unless authentication
19
+ record.errors.add :email, :password_login_not_allowed
20
+ return
21
+ end
22
+ end
23
+
24
+ # Returns User object, corresponding to this email address
25
+ #
26
+ def user
27
+ User.where( 'emails.email' => email ).first
28
+ end
29
+
30
+ # Returns UserEmail object, corresponding to this email address
31
+ #
32
+ def authentication
33
+ user.authentications.where( provider: :password, uid: email ).first
34
+ end
35
+
36
+
37
+ end # class UserRequestPasswordResetForm
@@ -0,0 +1,41 @@
1
+ class UserResetPasswordForm
2
+
3
+ include Model::NonPersistent
4
+ include Aerogel::Db::SecurePassword
5
+
6
+ field :email, type: String
7
+ field :password_reset_token, type: String
8
+
9
+ use_secure_password
10
+
11
+ validates_presence_of :email, :password_reset_token
12
+ validates_format_of :email, with: /@/, message: :invalid_format
13
+
14
+ # validates uniqueness of provider & uid (email) among all users
15
+ validate do |record|
16
+ user = User.where( 'emails.email' => record.email ).first
17
+ unless user
18
+ record.errors.add :email, :not_registered
19
+ return
20
+ end
21
+ authentication = user.authentications.where( provider: :password, uid: record.email ).first
22
+ unless authentication
23
+ record.errors.add :email, :password_login_not_allowed
24
+ return
25
+ end
26
+ end
27
+
28
+ # Returns User object, corresponding to this email address
29
+ #
30
+ def user
31
+ User.where( 'emails.email' => email ).first
32
+ end
33
+
34
+ # Returns UserEmail object, corresponding to this email address
35
+ #
36
+ def authentication
37
+ user.authentications.where( provider: :password, uid: email ).first
38
+ end
39
+
40
+
41
+ end # class UserRequestPasswordResetForm
@@ -0,0 +1,8 @@
1
+ model Role
2
+
3
+ find_by [:slug]
4
+
5
+ seeds [
6
+ { slug: :user, name: "Registered user" }
7
+ ]
8
+
@@ -0,0 +1,25 @@
1
+ # A .seed file is a .conf file which stores
2
+ # database seed data and rules.
3
+ #
4
+
5
+ # Model class to use
6
+ #
7
+ # ! required
8
+ model Access
9
+
10
+ # Attribute name or a list of attribute names to be used as key(s)
11
+ # when finding objects
12
+ #
13
+ # Usage:
14
+ # find_by :name
15
+ # or
16
+ # find_by [:first_name, :last_name]
17
+ #
18
+ # ! required
19
+ find_by [:path, :role]
20
+
21
+ seeds [
22
+ { path: '/user', access: :R, role: :user },
23
+ { path: '/user/edit', access: :RW, role: :user }
24
+ ]
25
+
File without changes
@@ -0,0 +1,77 @@
1
+ model User
2
+
3
+ # Attribute name or a list of attribute names to be used as key(s)
4
+ # when finding objects
5
+ #
6
+ # Usage:
7
+ # find_by :name
8
+ # or
9
+ # find_by [:first_name, :last_name]
10
+ #
11
+ # ! required
12
+ find_by :full_name
13
+
14
+ # Values of attributes listed here will be set even
15
+ # if they exist already in the matching database object.
16
+ #
17
+ # Other attributes in the seed data will be treated as a default value,
18
+ # i.e. they will only be set if the matching database object does not exist
19
+ # or its corresponding attribute is not set.
20
+ #
21
+ # Usage:
22
+ # force :value
23
+ # or:
24
+ # force [:value, :description]
25
+ #
26
+ # default is: no fields are forced
27
+
28
+ #force :value
29
+
30
+ seeds [
31
+ {
32
+ full_name: 'test',
33
+ roles: [:user],
34
+ emails:[{
35
+ email: 'test@test',
36
+ confirmed: true
37
+ }],
38
+ authentications:[{
39
+ provider: :password,
40
+ uid: 'test@test',
41
+ email_id: 'test@test',
42
+ password: 'test',
43
+ password_confirmation: 'test'
44
+ }]
45
+ },
46
+ {
47
+ full_name: 'test1',
48
+ roles: [:user],
49
+ emails:[{
50
+ email: 'test1@test',
51
+ confirmed: true
52
+ }],
53
+ authentications:[{
54
+ provider: :password,
55
+ uid: 'test1@test',
56
+ email_id: 'test1@test',
57
+ password: 'test',
58
+ password_confirmation: 'test'
59
+ }]
60
+ },
61
+ {
62
+ full_name: 'test2',
63
+ roles: [:user],
64
+ emails:[{
65
+ email: 'test2@test',
66
+ confirmed: true
67
+ }],
68
+ authentications:[{
69
+ provider: :password,
70
+ uid: 'test2@test',
71
+ email_id: 'test2@test',
72
+ password: 'test',
73
+ password_confirmation: 'test'
74
+ }]
75
+ }
76
+ ]
77
+
File without changes
@@ -0,0 +1,22 @@
1
+ require 'omniauth'
2
+ require 'aerogel/core'
3
+ require 'aerogel/mailer'
4
+ require "aerogel/users/version"
5
+ require "aerogel/users/auth"
6
+ require "aerogel/users/omniauth-password"
7
+ require "aerogel/users/omniauth-failure_endpoint_ex"
8
+ require "aerogel/users/secure_password"
9
+
10
+ module Aerogel
11
+ module Users
12
+ # Your code goes here...
13
+ end
14
+
15
+ # Finally, register module's root folder
16
+ register_path File.join( File.dirname(__FILE__), '..', '..' )
17
+
18
+ on_load do |app|
19
+ Aerogel::Auth.load_middleware( app )
20
+ end
21
+ end
22
+
@@ -0,0 +1,67 @@
1
+ module Aerogel
2
+ module Auth
3
+
4
+ # known providers
5
+ # PROVIDERS = {
6
+ # password: { name: "Password", gem: nil },
7
+ # github: { name: "GitHub", gem: 'omniauth-github' },
8
+ # facebook: { name: "Facebook", gem: 'omniauth-facebook' },
9
+ # twitter: { name: "Twitter", gem: 'omniauth-twitter' },
10
+ # linkedin: { name: "LinkedIn", gem: 'omniauth-linkedin-oauth2' },
11
+ # vkontakte: { name: "Vkontakte", gem: 'omniauth-vkontakte' }
12
+ # }
13
+ #
14
+ PROVIDERS = nil
15
+
16
+ # Returns hash of registered omniauth providers.
17
+ #
18
+ def self.providers
19
+ return @providers unless @providers.nil?
20
+ @providers = Aerogel.config.auth.providers.to_hash
21
+ end
22
+
23
+ # Returns list of enabled omniauth providers as symbols.
24
+ #
25
+ # Example:
26
+ # Aerogel::Auth.enabled_providers # => [:password, :github, :twitter]
27
+ #
28
+ def self.enabled_providers
29
+ return @enabled_providers unless @enabled_providers.nil?
30
+ @enabled_providers = []
31
+ providers.each do |provider, opts|
32
+ # always enable :password
33
+ next unless provider == :password || Aerogel.config.auth.send( :"#{provider}?" )
34
+ @enabled_providers << provider
35
+ end
36
+ @enabled_providers
37
+ end
38
+
39
+ # Loads gems for enabled providers.
40
+ #
41
+ def self.load_provider_gems
42
+ enabled_providers.each do |provider_key|
43
+ gem_name = providers[provider_key][:gem_name]
44
+ # puts "** requiring #{provider_key}: #{gem_name}"
45
+ require gem_name if gem_name
46
+ end
47
+ end
48
+
49
+ # Loads OmniAuth middleware with enabled providers.
50
+ #
51
+ def self.load_middleware( app )
52
+ load_provider_gems
53
+ app.use OmniAuth::Builder do
54
+ # puts "** configuring OmniAuth"
55
+ provider :password, model: User
56
+ Aerogel::Auth.enabled_providers.each do |provider_key|
57
+ next if provider_key == :password
58
+ provider_config = app.config.auth.send(provider_key)
59
+ provider provider_key, provider_config.api_key!, provider_config.api_secret!
60
+ # puts "** configuring #{provider_key}: #{provider_config.api_key!}"
61
+ end
62
+ on_failure {|env| OmniAuth::FailureEndpointEx.new(env).redirect_to_failure }
63
+ end
64
+ end
65
+
66
+ end # module Auth
67
+ end # module Aerogel
@@ -0,0 +1,21 @@
1
+ # Alternative FailureEndpoint for OmniAuth,
2
+ # which preserves all parameters passed to provider/callback
3
+ #
4
+ module OmniAuth
5
+ class FailureEndpointEx < FailureEndpoint
6
+
7
+ def redirect_to_failure
8
+ message_key = env['omniauth.error.type']
9
+ new_path = "#{env['SCRIPT_NAME']}#{OmniAuth.config.path_prefix}/failure?message=#{message_key}#{origin_query_param}#{strategy_name_query_param}#{extra_query_param}"
10
+ Rack::Response.new(["302 Moved"], 302, 'Location' => new_path).finish
11
+ end
12
+
13
+ # Returns extra query params passed to callback.
14
+ #
15
+ def extra_query_param
16
+ return "" unless env['omniauth.params']
17
+ env['omniauth.params'].map{|k,v| "&#{k}=#{Rack::Utils.escape(v)}"}.join
18
+ end
19
+
20
+ end # class FailureEndpointEx < FailureEndpoint
21
+ end # module OmniAuth
@@ -0,0 +1,63 @@
1
+ require 'omniauth'
2
+
3
+ module OmniAuth
4
+ module Strategies
5
+ class Password
6
+ include OmniAuth::Strategy
7
+
8
+ PROVIDER_NAME = :password
9
+
10
+ option :username_field, :email
11
+ option :password_field, :password
12
+ option :uid_field, :email
13
+ if defined? User
14
+ option :model, User
15
+ else
16
+ option :model, nil
17
+ end
18
+ option :authenticate_method, :authenticate
19
+
20
+ option :on_authenticate, ->(params) {
21
+ options.model.send( options.authenticate_method, PROVIDER_NAME, params )
22
+ }
23
+
24
+
25
+ # def request_phase
26
+ # form = OmniAuth::Form.new(:title => "User Info", :url => callback_path)
27
+ # [ options.username_field, options.password_field ].each do |field|
28
+ # form.text_field field.to_s.capitalize.gsub("_", " "), field.to_s
29
+ # end
30
+ # form.button "Sign In"
31
+ # form.to_response
32
+ # end
33
+
34
+ def callback_phase
35
+ request.params['uid'] = uid
36
+ request.env['omniauth.origin'] ||= request.params['origin']
37
+ request.env['omniauth.params'] = request.params
38
+ unless instance_exec( request.params, &options.on_authenticate )
39
+ return fail!(:invalid_credentials)
40
+ end
41
+ super
42
+ end
43
+
44
+ uid do
45
+ if options.uid_field.is_a? Proc
46
+ options.uid_field.call( request.params )
47
+ else
48
+ request.params[options.uid_field.to_s]
49
+ end
50
+ end
51
+
52
+ info do
53
+ hash = {}
54
+ [ options.username_field, options.password_field ].each do |field|
55
+ hash[field] = request.params[field.to_s]
56
+ end
57
+ hash
58
+ end
59
+
60
+
61
+ end # class Password
62
+ end # module Strategies
63
+ end # module OmniAuth