simple_sessions 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b38fcd3f010748f185cbd8d9b3bea565bb63971695fc82548fcb81d91b3a195d
4
- data.tar.gz: 5371ee45a9238fe3b4eebcf62c235cb33fec431ece6d0d06675a4f062ec3db86
3
+ metadata.gz: 382d49fae876965f7d63c5b0b3192d6a52c11a70a9ea7735aaf7044f0fc4a2ab
4
+ data.tar.gz: 8e38e3e1693a089e5bd73602f67df65edeea1e3d8455de46d293cd9889192de5
5
5
  SHA512:
6
- metadata.gz: 75610e77fc4c16566a5b8d82d851d2f25900398893f5d97c40bb93b5711e10f245d13c5cbd906969f6bd90d5738fb39b2d29a82724b180a7ca2af700465fb08e
7
- data.tar.gz: 31b51733d782bbee799f6371a6f8fdd6c26941e32313a7d147832e257b3175947b9ed2c8f06487c277fc037dc5abbdddb5a771fcccb5ee0ca05fbbc1eb2aeebe
6
+ metadata.gz: 72e50c3696623cfd8bcf6016095ea6522b619577be5033bcd844b27e35d4d98ead575ace6ad73c0f53e5ed4b63cd18db068651ab1d019117d8ce613a8a782e79
7
+ data.tar.gz: 7ccf9a3d46099da813c7d2a7cdc684f77772b16539358d27440362ff1f5e25a9b11b253eb9b4def8090e40ed440a9491c1d3ad6e075d97f12854203e5619247b
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2020 lucasmazo32
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # Simple sessions
2
+
3
+ To use the gem type `gem 'simple_sessions', '~> 0.2.0'` in your Gemfile.
4
+
5
+ The objective of this gem is to make your life easier when creating sessions. Creating sessions (especially the ones with permanent secure cookies) can be difficult or can take up some time for the programmer; therefore, I hope this will make your life easier.
6
+
7
+ # Version 0.2.0
8
+
9
+ After running `bundle update` and `bundle` you should be able to run:
10
+
11
+ > `rails g simple NAME` *or* `rails g advanced NAME`
12
+
13
+ ## How does it work?
14
+
15
+ It will automatically generate the view, controller, helper, test (for this version there are no automatic tests!), routes in your config/routes.rb and add the SessionsHelper to your ApplicationController.
16
+
17
+ For this program, 'NAME' means the name of the database. Taking into consideration that the database should be singular (like User), you should write the name in singular. It doesn't matter if you write it in capital letters or downcase, the program will automatically recognize it. What it doesn't understand is the plural version of the word.
18
+
19
+ *e.g:*
20
+
21
+ > `rails g advanced user` *correct*
22
+
23
+ > `rails g advanced users` *wrong!*
24
+
25
+ You can always run `rails destroy advanced NAME` or `rails destroy simple NAME`, but remember that if you had a mistake writing the name, you probably are going to get an error (although most of the times you can ignore them).
26
+
27
+ I strongly recommend creating the user's database before running this command, because it will generate a migration to add the column **remember_digest** to your user's schema.
28
+
29
+ ## Which one to pick
30
+ Simple sessions are an easy way of making your sessions. Those only include a cookie with an encrypted user_id which will expire after the browser is closed. This is an easy way of testing your apps in your localhost without expending time in creating the functions necessary for creating sessions.
31
+
32
+ Advanced sessions also include cookies that expire in 20 years (Thus, permanent). They cover more functions and is more secure (User's id is saved encrypted in a cookie, and for the remember_digest, I use BCrypt hash security and a urlsafe_base64 for generating the tokens that will go in the remember column.
33
+
34
+ ## Files generated and recommendations
35
+
36
+ - `custom.scss`: This file imports the bootstrap configuration, which will be used to automatically style de buttons and form fields.
37
+ - `new.html.erb`: View containing the form for logging in users.
38
+ - `sessions_controller_test.rb`: File in which you can generate your tests for the session.
39
+ - `sessions_controller.rb`: File in which the logic of finding the right user lives. This file doesn't change too much between *simple* and *advanced*.
40
+ - `sessions_helper.rb`: All the logic involving the sessions live here. The cookies and session information lives in here.
41
+ - `migration file (ONLY FOR ADVANCED)`: It will create a migration to add the column **remember_digest** to the database for your users.
42
+
43
+ ### new.html.erb
44
+ ```
45
+ <%= form_for(:session, url: login_path) do |f| %>
46
+
47
+ <%= f.label :username %>
48
+ <%= f.text_field :username, class: 'form-control' %>
49
+
50
+ <%= f.label :password %>
51
+ <%= f.password_field :password, class: 'form-control' %>
52
+
53
+ <%= f.submit 'Sign up!', class: 'btn btn-primary' %>
54
+ <% end %>
55
+ ```
56
+
57
+ ### sessions_controller.rb
58
+ ```
59
+ class SessionsController < ApplicationController
60
+ def new; end
61
+
62
+ def create
63
+ user = User.find_by(username: params[:session][:username].downcase)
64
+ if user&.authenticate(params[:session][:password])
65
+ create_session user
66
+ redirect_to user
67
+ else
68
+ flash.now[:danger] = 'Invalid username/password combination'
69
+ render 'new'
70
+ end
71
+ end
72
+
73
+ def destroy
74
+ log_out
75
+ redirect_to root_path
76
+ end
77
+ end
78
+ ```
79
+
80
+ ### sessions_helper.rb (simple)
81
+ ```
82
+ module SessionsHelper
83
+ def log_in(user)
84
+ session[:user_id] = user.id
85
+ end
86
+
87
+ def current_user
88
+ @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
89
+ end
90
+
91
+ def logged_in?
92
+ !current_user.nil?
93
+ end
94
+
95
+ def log_out
96
+ @current_user = nil
97
+ session[:user_id] = nil
98
+ end
99
+
100
+ def correct_user
101
+ redirect_to root_path unless current_user == User.find(params[:id])
102
+ end
103
+
104
+ def login_if_not_logged
105
+ redirect_to login_path unless logged_in?
106
+ end
107
+ end
108
+ ```
109
+
110
+ ### sessions_helper.rb (advanced)
111
+ ```
112
+ module SessionsHelper
113
+ def log_in(user)
114
+ session[:user_id] = user.id
115
+ end
116
+
117
+ def remember(user)
118
+ cookies.permanent.signed[:user_id] = user.id
119
+ token = SecureRandom.urlsafe_base64
120
+ cookies.permanent[:remember_token] = token
121
+ user.remember_digest = Digest::SHA2.hexdigest token
122
+ end
123
+
124
+ def create_session(user)
125
+ log_in(user)
126
+ remember(user)
127
+ end
128
+
129
+ def current_user
130
+ if session[:user_id]
131
+ @current_user ||= User.find_by(id: session[:user_id])
132
+ elsif cookies.signed[:id]
133
+ user = User.find_by(id: cookies.signed[:id])
134
+ cond1 = Digest::SHA2.hexdigest(cookies[:remember_token]) ==
135
+ user.remember_digest
136
+ if user & cond1
137
+ @current_user ||= user
138
+ session[:user_id] = user.id
139
+ end
140
+ end
141
+ end
142
+
143
+ def logged_in?
144
+ !current_user.nil?
145
+ end
146
+
147
+ def log_out
148
+ @current_user = nil
149
+ session[:user_id] = nil
150
+ cookies.delete :remember_token
151
+ cookies.delete :id
152
+ end
153
+
154
+ def correct_user
155
+ redirect_to root_path unless current_user == User.find(params[:id])
156
+ end
157
+
158
+ def login_if_not_logged
159
+ redirect_to login_path unless logged_in?
160
+ end
161
+ end
162
+ ```
163
+
164
+ ### time_add_remember_digest_to_NAME.rb
165
+ ```
166
+ class AddRememberDigestToName < ActiveRecord::Migration[X.0]
167
+ def change
168
+ add_column :names, :remember_digest, :string
169
+ end
170
+ end
171
+ ```
172
+
173
+ # Recommendations
174
+ Use rails 5.0.0 or newer versions.
175
+
176
+ # Conclusion
177
+
178
+ Note that the only thing that changes between the controllers is the use of create_session instead of a simple log_in, otherwise is the same thing. The way of how the session's functions are organized allows you to spend less time worrying about the code you write, but in how your application will work. I hope you enjoy it!
179
+
180
+ # Author
181
+ Lucas Mazo: [Github](https://github.com/lucasmazo32)
182
+
183
+ # Built with:
184
+ - Ruby ~> 2.6.5
185
+ - VSCode
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AdvancedGenerator < Rails::Generators::NamedBase
4
+ source_root File.expand_path('templates', __dir__)
5
+
6
+ # Adds the helper, view, controller, test, routes and includes the
7
+ # SessionHelper in the ApplicationController
8
+ def create_advanced_file
9
+ copy_file 'new.html.erb', 'app/views/sessions/new.html.erb'
10
+ copy_file 'sessions_controller_test.rb', 'test/controllers/sessions_controller_test.rb'
11
+ create_file 'app/helpers/sessions_helper.rb', <<-FILE
12
+ module SessionsHelper
13
+ def log_in(user)
14
+ session[:user_id] = user.id
15
+ end
16
+
17
+ def remember(user)
18
+ cookies.permanent.signed[:id] = user.id
19
+ token = SecureRandom.urlsafe_base64
20
+ cookies.permanent[:remember_token] = token
21
+ user.remember(token)
22
+ end
23
+
24
+ def create_session(user)
25
+ log_in(user)
26
+ remember(user)
27
+ end
28
+
29
+ def current_user
30
+ if session[:user_id]
31
+ @current_user ||= #{file_name.capitalize}.find_by(id: session[:user_id])
32
+ elsif cookies.signed[:id]
33
+ user = #{file_name.capitalize}.find_by(id: cookies.signed[:id])
34
+ cond1 = user.authenticated?(cookies[:remember_token])
35
+ if user && cond1
36
+ @current_user ||= user
37
+ session[:user_id] = user.id
38
+ end
39
+ end
40
+ end
41
+
42
+ def logged_in?
43
+ !current_user.nil?
44
+ end
45
+
46
+ def log_out
47
+ @current_user = nil
48
+ session[:user_id] = nil
49
+ cookies.delete :remember_token
50
+ cookies.delete :id
51
+ end
52
+
53
+ def correct_user
54
+ redirect_to root_path unless current_user == #{file_name.capitalize}.find(params[:id])
55
+ end
56
+
57
+ def login_if_not_logged
58
+ redirect_to login_path unless logged_in?
59
+ end
60
+ end
61
+ FILE
62
+ create_file 'app/controllers/sessions_controller.rb', <<-FILE
63
+ class SessionsController < ApplicationController
64
+ def new; end
65
+
66
+ def create
67
+ user = #{file_name.capitalize}.find_by(username: params[:session][:username].downcase)
68
+ if user&.authenticate(params[:session][:password])
69
+ create_session user
70
+ redirect_to user
71
+ else
72
+ flash.now[:danger] = 'Invalid username/password combination'
73
+ render 'new'
74
+ end
75
+ end
76
+
77
+ def destroy
78
+ log_out
79
+ redirect_to root_path
80
+ end
81
+ end
82
+ FILE
83
+ copy_file 'custom.scss', 'app/assets/stylesheets/custom.scss'
84
+ end
85
+
86
+ def file_changes
87
+ route "get '/login', to: 'sessions#new'"
88
+ route "post '/login', to: 'sessions#create'"
89
+ route "delete '/logout', to: 'sessions#destroy'"
90
+ inject_into_file 'app/controllers/application_controller.rb', after: "class ApplicationController < ActionController::Base\n" do <<-'RUBY'
91
+ protect_from_forgery with: :exception
92
+ include SessionsHelper
93
+ RUBY
94
+ end
95
+ inject_into_file "app/models/#{file_name.downcase}.rb", after: "class #{file_name.capitalize} < ApplicationRecord\n" do <<-'RUBY'
96
+ attr_accessor :remember_token
97
+ ############
98
+ # Paste this two functions after your validations and before private (If you have it)
99
+ def remember(token)
100
+ self.remember_token = token
101
+ update_attribute(:remember_digest, BCrypt::Password.create(remember_token))
102
+ end
103
+
104
+ def authenticated?(remember_token)
105
+ BCrypt::Password.new(remember_digest).is_password?(remember_token)
106
+ end
107
+ ############
108
+ RUBY
109
+ end
110
+ end
111
+
112
+ def migration
113
+ generate 'migration', "add_remember_digest_to_#{file_name.downcase}s remember_digest:string"
114
+ end
115
+ end
@@ -0,0 +1 @@
1
+ @import 'bootstrap';
@@ -0,0 +1,16 @@
1
+ <div class="row">
2
+ <div class="col"></div>
3
+ <div class="col-4">
4
+ <%= form_for(:session, url: login_path) do |f| %>
5
+
6
+ <%= f.label :username %>
7
+ <%= f.text_field :username, class: 'form-control' %>
8
+
9
+ <%= f.label :password %>
10
+ <%= f.password_field :password, class: 'form-control' %>
11
+
12
+ <%= f.submit 'Sign up!', class: 'btn btn-primary' %>
13
+ <% end %>
14
+ </div>
15
+ <div class="col"></div>
16
+ </div>
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class SessionsControllerTest < ActionDispatch::IntegrationTest
4
+ # test "the truth" do
5
+ # assert true
6
+ # end
7
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SimpleGenerator < Rails::Generators::NamedBase
4
+ source_root File.expand_path('templates', __dir__)
5
+
6
+ # Adds the helper, view, controller, test, routes and includes the
7
+ # SessionHelper in the ApplicationController
8
+ def simple
9
+ copy_file 'new.html.erb', 'app/views/sessions/new.html.erb'
10
+ copy_file 'sessions_controller_test.rb', 'test/controllers/sessions_controller_test.rb'
11
+ copy_file 'custom.scss', 'app/assets/stylesheets/custom.scss'
12
+ create_file 'app/helpers/sessions_helper.rb', <<-FILE
13
+ module SessionsHelper
14
+ def log_in(user)
15
+ session[:user_id] = user.id
16
+ end
17
+
18
+ def current_user
19
+ @current_user ||= #{file_name.capitalize}.find_by(id: session[:user_id]) if session[:user_id]
20
+ end
21
+
22
+ def logged_in?
23
+ !current_user.nil?
24
+ end
25
+
26
+ def log_out
27
+ @current_user = nil
28
+ session[:user_id] = nil
29
+ end
30
+
31
+ def correct_user
32
+ redirect_to root_path unless current_user == #{file_name.capitalize}.find(params[:id])
33
+ end
34
+
35
+ def login_if_not_logged
36
+ redirect_to login_path unless logged_in?
37
+ end
38
+ end
39
+ FILE
40
+ create_file 'app/controllers/sessions_controller.rb', <<-FILE
41
+ class SessionsController < ApplicationController
42
+ def new; end
43
+
44
+ def create
45
+ user = User.find_by(username: params[:session][:username].downcase)
46
+ if user&.authenticate(params[:session][:password])
47
+ log_in user
48
+ redirect_to user
49
+ else
50
+ flash.now[:danger] = 'Invalid username/password combination'
51
+ render 'new'
52
+ end
53
+ end
54
+
55
+ def destroy
56
+ log_out
57
+ redirect_to root_path
58
+ end
59
+ end
60
+ FILE
61
+ route "get '/login', to: 'sessions#new'"
62
+ route "post '/login', to: 'sessions#create'"
63
+ route "delete '/logout', to: 'sessions#destroy'"
64
+ inject_into_file 'app/controllers/application_controller.rb', after: "class ApplicationController < ActionController::Base\n" do <<-'RUBY'
65
+ protect_from_forgery with: :exception
66
+ include SessionsHelper
67
+ RUBY
68
+ end
69
+ end
70
+ end
@@ -0,0 +1 @@
1
+ @import 'bootstrap';
@@ -0,0 +1,16 @@
1
+ <div class="row">
2
+ <div class="col"></div>
3
+ <div class="col-4">
4
+ <%= form_for(:session, url: login_path) do |f| %>
5
+
6
+ <%= f.label :username %>
7
+ <%= f.text_field :username, class: 'form-control' %>
8
+
9
+ <%= f.label :password %>
10
+ <%= f.password_field :password, class: 'form-control' %>
11
+
12
+ <%= f.submit 'Sign up!', class: 'btn btn-primary' %>
13
+ <% end %>
14
+ </div>
15
+ <div class="col"></div>
16
+ </div>
@@ -0,0 +1,19 @@
1
+ class SessionsController < ApplicationController
2
+ def new; end
3
+
4
+ def create
5
+ user = User.find_by(username: params[:session][:username].downcase)
6
+ if user&.authenticate(params[:session][:password])
7
+ log_in user
8
+ redirect_to user
9
+ else
10
+ flash.now[:danger] = 'Invalid username/password combination'
11
+ render 'new'
12
+ end
13
+ end
14
+
15
+ def destroy
16
+ log_out
17
+ redirect_to root_path
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class SessionsControllerTest < ActionDispatch::IntegrationTest
4
+ # test "the truth" do
5
+ # assert true
6
+ # end
7
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleSessions
2
+ VERSION = '0.2.0'
3
+ end
@@ -27,10 +27,10 @@ module Advanced
27
27
  end
28
28
 
29
29
  def remember(user)
30
- cookies.permanent.signed[:user_id] = user.id
30
+ cookies.permanent.signed[:id] = user.id
31
31
  token = SecureRandom.urlsafe_base64
32
32
  cookies.permanent[:remember_token] = token
33
- user.remember_digest = Digest::SHA2.hexdigest token
33
+ user.remember(token)
34
34
  end
35
35
 
36
36
  def create_session(user)
@@ -43,9 +43,8 @@ module Advanced
43
43
  @current_user ||= User.find_by(id: session[:user_id])
44
44
  elsif cookies.signed[:id]
45
45
  user = User.find_by(id: cookies.signed[:id])
46
- cond1 = Digest::SHA2.hexdigest(cookies[:remember_token]) ==
47
- user.remember_digest
48
- if user & cond1
46
+ cond1 = user.authenticated?(cookies[:remember_token])
47
+ if user && cond1
49
48
  @current_user ||= user
50
49
  session[:user_id] = user.id
51
50
  end
@@ -63,45 +62,3 @@ module Advanced
63
62
  cookies.delete :id
64
63
  end
65
64
  end
66
-
67
- # This is the module to create simple sessions in the controller//This does not work
68
- module SimpleController
69
- def new; end
70
-
71
- def create
72
- user = User.find_by(username: params[:session][:username].downcase)
73
- if user&.authenticate(params[:session][:password])
74
- log_in user
75
- redirect_to user
76
- else
77
- flash.now[:danger] = 'Invalid username/password combination'
78
- render 'new'
79
- end
80
- end
81
-
82
- def destroy
83
- log_out
84
- redirect_to root_path
85
- end
86
- end
87
-
88
- # This is the module to create simple sessions in the controller//This does not work
89
- module AdvancedController
90
- def new; end
91
-
92
- def create
93
- user = User.find_by(username: params[:session][:username].downcase)
94
- if user&.authenticate(params[:session][:password])
95
- create_session user
96
- redirect_to user
97
- else
98
- flash.now[:danger] = 'Invalid username/password combination'
99
- render 'new'
100
- end
101
- end
102
-
103
- def destroy
104
- log_out
105
- redirect_to root_path
106
- end
107
- end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_sessions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Mazo
@@ -19,8 +19,20 @@ executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
+ - MIT-LICENSE
23
+ - README.md
24
+ - lib/generators/advanced/advanced_generator.rb
25
+ - lib/generators/advanced/templates/custom.scss
26
+ - lib/generators/advanced/templates/new.html.erb
27
+ - lib/generators/advanced/templates/sessions_controller_test.rb
28
+ - lib/generators/simple/simple_generator.rb
29
+ - lib/generators/simple/templates/custom.scss
30
+ - lib/generators/simple/templates/new.html.erb
31
+ - lib/generators/simple/templates/sessions_controller.rb
32
+ - lib/generators/simple/templates/sessions_controller_test.rb
22
33
  - lib/simple_sessions.rb
23
- homepage: https://rubygems.org/gems/simple_sessions
34
+ - lib/simple_sessions/version.rb
35
+ homepage: https://github.com/lucasmazo32/simple-sessions
24
36
  licenses:
25
37
  - MIT
26
38
  metadata: {}