Class: AuthenticationGenerator

Inherits:
Rails::Generators::NamedBase
  • Object
show all
Defined in:
lib/generators/authentication/authentication_generator.rb

Instance Method Summary collapse

Instance Method Details

#create_controllersObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/generators/authentication/authentication_generator.rb', line 15

def create_controllers
  generate "base_controller", class_name
  template "controllers/sessions_controller.rb.erb", 
           "app/controllers/#{plural_file_name}/sessions_controller.rb"
  template "controllers/password_resets_controller.rb.erb", 
          "app/controllers/#{plural_file_name}/password_resets_controller.rb"

  if options[:two_factor]             
    template "controllers/tfa_sessions_controller.rb.erb", 
             "app/controllers/#{plural_file_name}/tfa_sessions_controller.rb"
            
    template "controllers/tfas_controller.rb.erb", 
             "app/controllers/#{plural_file_name}/tfas_controller.rb"
  end
end

#create_factoriesObject



166
167
168
169
170
# File 'lib/generators/authentication/authentication_generator.rb', line 166

def create_factories
  generate "factory_bot:model", "otp_credential"
  generate "factory_bot:model", "password_reset_token"
  generate "factory_bot:model", "#{singular_name}_session email:email password:password"    
end

#create_form_objectsObject



80
81
82
83
84
85
# File 'lib/generators/authentication/authentication_generator.rb', line 80

def create_form_objects
  template "models/session.rb.erb", "app/models/#{singular_name}_session.rb" 
  if options[:two_factor]
    copy_file "models/tfa_session.rb", "app/models/tfa_session.rb"
  end   
end

#create_mailerObject



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/generators/authentication/authentication_generator.rb', line 51

def create_mailer
  generate "mailer", "#{class_name}Mailer"
  inject_into_class "app/mailers/#{singular_name}_mailer.rb", "#{class_name}Mailer", <<~RUBY

  def password_reset_link(#{singular_name})
    @#{singular_name} = #{singular_name}
    mail(to: #{singular_name}.email, subject: "Reset your password")
  end
  
  RUBY
  template "views/mailers/password_reset_link.html.slim.erb",
           "app/views/#{singular_name}_mailer/password_reset_link.html.slim"
end

#create_migrationsObject



103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/generators/authentication/authentication_generator.rb', line 103

def create_migrations
  generate "migration", "create_password_reset_tokens secret:token "\
                                                      "expires_at:datetime:index "\
                                                      "resetable:references{polymorphic}"
  if options[:two_factor]
    generate "migration", "create_otp_credentials \
                            created_at:datetime \
                            last_used_at:datetime \
                            secret:string{32} \
                            authable:references{polymorphic} \
                            recovery_codes:json"
  end    
end

#create_modelsObject



65
66
67
68
69
70
# File 'lib/generators/authentication/authentication_generator.rb', line 65

def create_models
  copy_file "models/password_reset_token.rb", "app/models/password_reset_token.rb"
  if options[:two_factor]
    template "models/otp_credential.rb.erb", "app/models/otp_credential.rb"
  end    
end

#create_routesObject



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/generators/authentication/authentication_generator.rb', line 183

def create_routes
  route <<~RUBY
  namespace :#{plural_name} do
  
    resource :session, only: [:new, :create, :destroy]
  
    #{"resource :tfa_session, only: [:new, :create]" if options[:two_factor]}
  
    resource :tfa, only: [:create, :show, :destroy]
      
    resources :password_resets, only: [:new, :create, :edit, :update], param: :token
  
  end
  RUBY
end

#create_specsObject



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/generators/authentication/authentication_generator.rb', line 137

def create_specs
  return if options[:skip_tests]
  
  copy_file "spec/support/factory_bot.rb", "spec/support/factory_bot.rb"
  
  template "spec/system/authentication_spec.rb.erb", 
           "spec/system/#{plural_name}/authentication_spec.rb" 

  template "spec/system/password_resets_spec.rb.erb", 
           "spec/system/#{plural_name}/password_resets_spec.rb" 
           
  template "spec/models/session_spec.rb.erb", 
          "spec/models/#{singular_name}_session_spec.rb" 
  
  copy_file "spec/models/password_reset_token_spec.rb", 
            "spec/models/password_reset_token_spec.rb"
  
  if options[:two_factor]
    copy_file "spec/support/authentication_helpers.rb", 
              "spec/support/authentication_helpers.rb"
    template "spec/models/tfa_session_spec.rb.erb", "spec/models/tfa_session_spec.rb"
    copy_file "spec/models/otp_credential_spec.rb", 
              "spec/models/otp_credential_spec.rb"      
    template "spec/system/tfa_authentication_spec.rb.erb", 
             "spec/system/#{plural_name}/tfa_authentication_spec.rb" 
    
  end
end

#create_view_templatesObject



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/generators/authentication/authentication_generator.rb', line 117

def create_view_templates
  return if options[:skip_views]
  template "views/sessions/new.html.slim.erb", 
           "app/views/#{plural_name}/sessions/new.html.slim"    

  template "views/password_resets/new.html.slim.erb", 
           "app/views/#{plural_name}/password_resets/new.html.slim"    

  template "views/password_resets/edit.html.slim.erb", 
           "app/views/#{plural_name}/password_resets/edit.html.slim"    
           
  if options[:two_factor]
    template "views/tfa_sessions/new.html.slim.erb", 
             "app/views/#{plural_name}/tfa_sessions/new.html.slim"      
    template "views/tfas/show.html.slim.erb", 
             "app/views/#{plural_name}/tfas/show.html.slim"      
             
  end
end

#ensure_concernsObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/generators/authentication/authentication_generator.rb', line 87

def ensure_concerns
  template "controllers/concerns/authentication.rb.erb", 
           "app/controllers/concerns/authentication.rb"
  copy_file "models/concerns/authenticateable.rb", 
            "app/models/concerns/authenticateable.rb"    
  copy_file "models/concerns/password_resetable.rb", 
            "app/models/concerns/password_resetable.rb"    

  if options[:two_factor]
    copy_file "controllers/concerns/two_factor_authentication.rb", 
              "app/controllers/concerns/two_factor_authentication.rb"    
    
    copy_file "models/concerns/otpable.rb", "app/models/concerns/otpable.rb"    
  end
end

#ensure_gemsObject



172
173
174
175
176
177
178
179
180
181
# File 'lib/generators/authentication/authentication_generator.rb', line 172

def ensure_gems
  gem "validates_email_format_of", version: "~> 1.6"
  gem "slim-rails"
  gem "factory_bot_rails"
  gem "faker"
  if options[:two_factor]
    gem "rotp", version: "~> 5.1.0"
    gem "rqrcode", require: false
  end
end

#ensure_helpersObject



39
40
41
42
43
# File 'lib/generators/authentication/authentication_generator.rb', line 39

def ensure_helpers
  if options[:two_factor]
    copy_file "helpers/otp_credentials_helper.rb", "app/helpers/otp_credentials_helper.rb"
  end
end

#ensure_jsObject



45
46
47
48
49
# File 'lib/generators/authentication/authentication_generator.rb', line 45

def ensure_js
  if options[:two_factor] && options[:js]
    copy_file "javascript/tfa_forms.js", "app/javascript/packs/tfa_forms.js"
  end
end

#extend_controllersObject



31
32
33
34
35
36
37
# File 'lib/generators/authentication/authentication_generator.rb', line 31

def extend_controllers
  inject_into_class "app/controllers/#{plural_name}/base_controller.rb", 
                    "#{plural_class_name}::BaseController", 
                    "  authenticate_model :#{singular_name}, tfa: #{options[:two_factor]}\n"
  include_module_in_controller("#{plural_name}/base_controller", "Authentication")
  
end

#extend_modelsObject



72
73
74
75
76
77
78
# File 'lib/generators/authentication/authentication_generator.rb', line 72

def extend_models
  include_module_in_model(class_name, "Authenticateable")
  include_module_in_model(class_name, "PasswordResetable")    
  if options[:two_factor]
    include_module_in_model(class_name, "Otpable")
  end
end