tachiban 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3fbe2ce6b5eb049f1a610456e1071a346881c14df1222f9963f9821fb02681b9
4
- data.tar.gz: 8e085cd08268eef3597869b00bc42361e08baac42f8de346d92e559e81a8466b
3
+ metadata.gz: 6a4772cbc2387fbc462f6fd7f0bb3e1738521e1ede9a4d8b02e6cda05ab9ffc1
4
+ data.tar.gz: 16069ee6e897992462ce538ec514fdeef1c2798014f573265e293e15603f8b42
5
5
  SHA512:
6
- metadata.gz: d6c945ffabc49f82f57782db4bb145c3eab6a1a719ae84219f95bf6a7d25a2022b564ace70c1fca45eab965c28db136fb669ef095bf52c4b4eaeb1e58d5b96cc
7
- data.tar.gz: a498df67c718b21dee1ebbe0d1bba26002b9c11734a1fda51f3c6a9bfded7721f467377f0a0a7ade8677df15187420752ccb1f83616072120f2a6b67806a9fcb
6
+ metadata.gz: d8d446ac3dd3f8762154859b8a32369d2e92a8eeb570a05bffdb8bc9674ed1676d288c8e71a1666887beda650e91db0c98becf306db4f097ff9ff00f1defac60
7
+ data.tar.gz: 4745b414ecf91bb84564b54febbab5febcd1c40d0e0df454140286b454b9af5938546a91da8f3f17ae7612a598eeada823f5e8616d8fc8377a90383089c36db6
data/README.md CHANGED
@@ -10,11 +10,7 @@ offers the following functionalities (with methods listed below
10
10
  - Authentication
11
11
  - Session handling
12
12
  - Password reset
13
- - Authorization
14
-
15
- The Tachiban logic (apart from the Authorization) and code were extracted from a Hanami based web app using
16
- Hanami::Model and was also used in a Camping based web app using Active Record.
17
-
13
+ - Authorization has been moved to [Rokku](https://github.com/sebastjan-hribar/rokku)
18
14
 
19
15
  ## Installation
20
16
 
@@ -48,22 +44,16 @@ end
48
44
  Prior to logging in or authenticating the user, retrieve the entity from the
49
45
  database and assign it to the instance variable of `@user`.
50
46
 
51
- The password reset methods require the user entity to have the following attributes:
52
- **token** and **password_reset_sent_at (set as `Time.now`)**. The token can be used to compose
53
- the password reset url and to later retrieve the correct user from
54
- the database when the user visits the password reset url.
55
-
56
- The **password_reset_sent_at** can be used to check the reset link validity.
47
+ In addition to that, the user entity must have the following attributes:
57
48
 
58
- The only prerequisite for the authorization is the attribute of **role** for the user entity.
49
+ * **token** (used to compose the password reset url and get the user from the database)
50
+ * **password_reset_sent_at** (set as `Time.now` to check the reset link validity)
51
+ * **hashed_pass** (to hold the generated hashed password)
59
52
 
60
53
 
61
54
  ### Usage
62
55
 
63
56
  #### Signup
64
- The entity for which authentication is used must have the
65
- attribute `hashed_pass` to hold the generated hashed password.
66
-
67
57
  To create a user with a hashed password use the `hashed_password(password)`
68
58
  method for the password and store it as the user's attribute `hashed_pass`.
69
59
 
@@ -81,14 +71,14 @@ def call(params)
81
71
  end
82
72
  ```
83
73
 
84
- #### Login
74
+ #### Authentication and login
85
75
  To authenticate a user use the `authenticated?(input_password)` method and log
86
76
  them in with the `login` method. Authentication is successful if the user exists and passwords match.
87
77
 
88
- The user is logged in by setting the user object as the `session[:current_user]`.
78
+ The user is logged in by setting the user object ID as the `session[:current_user]`.
89
79
  After the user is logged in the session start time is defined as
90
- `session[:session_start_time] = Time.now`. A flash message is also
91
- assigned as `flash[:success_notice] = flash_message`.
80
+ `session[:session_start_time] = Time.now`. A default flash message is also
81
+ assigned as 'You have been successfully logged in.'.
92
82
 
93
83
  The `session[:session_start_time]` is then used by the `session_expired?`
94
84
  method to determine whether the session has expired or not.
@@ -101,11 +91,9 @@ email = params[:entity_session][:email]
101
91
  password = params[:entity_session][:password]
102
92
 
103
93
  @user = EntityRepository.new.find_by_email(email)
104
- login("You have been successfully logged in.") if authenticated?(password)
94
+ login if authenticated?(password)
105
95
  ```
106
96
 
107
-
108
- #### Authentication
109
97
  To check whether the user is logged in use the `check_for_logged_in_user` method.
110
98
  If the user is not logged in the `logout` method takes over.
111
99
 
@@ -116,10 +104,10 @@ expired and then restarts the session start time if the session
116
104
  is still valid or proceeds with the following if the session
117
105
  has expired:
118
106
 
119
- - setting the `session[:current_user]` to `nil`
120
- - a flash message is set: `flash[:failed_notice] = "Your session has expired"`
107
+ - setting the `session[:current_user]` to `nil`,
108
+ - a flash message is set: `flash[:failed_notice] = "Your session has expired"`,
121
109
  - redirects to the `routes.root_path` which can be overwritten by assigning
122
- a different url to @redirect_url
110
+ a different url to @redirect_url.
123
111
 
124
112
 
125
113
  The `session_expired?` method compares the session start time
@@ -132,7 +120,7 @@ by default, but can be overwritten) with the current time.
132
120
  if session_expired?
133
121
  @redirect_url ||= routes.root_path
134
122
  session[:current_user] = nil
135
- flash[:failed_notice] = "Your session has expired"
123
+ flash[:failed_notice] = "Your session has expired."
136
124
  redirect_to @redirect_url
137
125
  else
138
126
  restart_session_counter
@@ -189,37 +177,26 @@ password_reset_url_valid?(link_validity)
189
177
  ```
190
178
 
191
179
 
192
- #### Authorization
193
- Authorization support was setup as inspired by [this blog post](http://billpatrianakos.me/blog/2013/10/22/authorize-users-based-on-roles-and-permissions-without-a-gem/).
194
-
195
- Authorization features support the generation of policy files for each controller where authorized roles are specified for each action.
196
-
197
- ```ruby
198
- tachiban -n mightyPoster -p post
199
- ```
200
- The above CLI command will generate a policy file for the application mightyPoster (not the project) and the controller post. The file will be generated as `myProject/lib/mightyPoster/policies/PostPolicy.rb`
201
-
202
- Each application would have its own `app/policies` folders.
180
+ ### ToDo
203
181
 
204
- **The command must be run in the project root folder.**
182
+ - Add full Hanami app for testing purposes.
205
183
 
206
- Once the file is generated the authorized roles variables in the initialize block for required actions need to be uncommneted and supplied with specific roles.
184
+ ### Changelog
207
185
 
208
- Then we can check if a user is authorized:
186
+ #### 0.7.0
209
187
 
210
- ```ruby
211
- authorized?(controller, role, action)
212
- ```
188
+ Authorization was moved to a separate gem [Rokku](https://github.com/sebastjan-hribar/rokku).
189
+ Readme update.
213
190
 
191
+ Method: `Tachiban::login`
192
+ <br>Change:
193
+ Default flash message and redirect url provided.
214
194
 
215
- ### ToDo
216
195
 
217
- - Add support for level based authorizations. [x]
218
- - Add generators for adding authorization rules to existing policies.
219
- - Add generators for entities with required attributes.
196
+ #### 0.6.1
220
197
 
198
+ Dependency change for **rake** to ">= 12.3.3".
221
199
 
222
- ### Changelog
223
200
 
224
201
  #### 0.6.0
225
202
 
@@ -231,10 +208,6 @@ Method: `Tachiban::logout`
231
208
  <br>Change:
232
209
  Added `session.clear` to remove any other values upon logout.
233
210
 
234
- #### 0.6.1
235
-
236
- Dependency change for **rake** to ">= 12.3.3".
237
-
238
211
 
239
212
 
240
213
  ## Development
data/bin/tachiban CHANGED
@@ -1,2 +1 @@
1
1
  #!/usr/bin/env ruby
2
- require_relative "../lib/tachiban/commands/commands.rb"
data/lib/tachiban.rb CHANGED
@@ -5,7 +5,6 @@ require 'hanami/action/session'
5
5
 
6
6
  module Hanami
7
7
  module Tachiban
8
-
9
8
  private
10
9
 
11
10
  # ### Signup ###
@@ -19,7 +18,6 @@ private
19
18
  BCrypt::Password.create(password)
20
19
  end
21
20
 
22
-
23
21
  # ### Login ###
24
22
 
25
23
  # The authenticated? method returns true if the the following criteria
@@ -31,7 +29,6 @@ private
31
29
  @user && BCrypt::Password.new(@user.hashed_pass) == input_pass
32
30
  end
33
31
 
34
-
35
32
  # The login method can be used in combination with the authenticated? method to
36
33
  # log the user in if the authenticated? method returns true. The user is
37
34
  # logged in by setting the user object id as the session[:current_user].
@@ -39,28 +36,34 @@ private
39
36
  # by the session_expired? method to determine whether the session has
40
37
  # expired or not.
41
38
 
39
+ # There are two defualt values set: one for flash message and
40
+ # the other for redirect url. Both can be overwritten by assigning
41
+ # new values for @flash_message and @login_redirect_url.
42
+
42
43
  # Example:
43
44
  # login if authenticated?(input_pass)
44
45
 
45
- def login(flash_message)
46
+ def login
46
47
  session[:current_user] = @user.id
47
48
  session[:session_start_time] = Time.now
48
- flash[:success_notice] = flash_message
49
+ @flash_message ||= 'You have been successfully logged in.'
50
+ flash[:success_notice] = @flash_message
51
+ @login_redirect_url ||= routes.root_path
52
+ redirect_to @login_redirect_url
49
53
  end
50
54
 
51
-
52
55
  # The logout method sets the current user in the session to nil
53
- # and performs a redirect to the @redirect_to which is set to
54
- # routes.root_path and can be overwritten as needed with a specific url.
56
+ # and performs a redirect to the redirect_url which is set to
57
+ # /login, but can be overwritten as needed with a specific url
58
+ # by setting a new value for @logout_redirect_url.
55
59
 
56
60
  def logout
57
61
  session[:current_user] = nil
58
62
  session.clear
59
- @redirect_url ||= routes.root_path
60
- redirect_to @redirect_url
63
+ @logout_redirect_url ||= '/login'
64
+ redirect_to @logout_redirect_url
61
65
  end
62
66
 
63
-
64
67
  # ### Authentication ###
65
68
 
66
69
  # The check_for_logged_in_user method can be used to check for each
@@ -68,10 +71,9 @@ private
68
71
  # the logout method takes over.
69
72
 
70
73
  def check_for_logged_in_user
71
- logout unless session[:current_user]
74
+ logout unless session[:current_user]
72
75
  end
73
76
 
74
-
75
77
  # ### Session handling ###
76
78
 
77
79
  # Session handling includes methods session_expired?,
@@ -88,7 +90,6 @@ private
88
90
  end
89
91
  end
90
92
 
91
-
92
93
  # The restart_session_counter method resets the session start time to
93
94
  # Time.now. It's used in the handle session method.
94
95
 
@@ -96,7 +97,6 @@ private
96
97
  session[:session_start_time] = Time.now
97
98
  end
98
99
 
99
-
100
100
  # The handle_session method is used to handle the incoming requests
101
101
  # based on the the session expiration. If the session has expired the
102
102
  # session user is set to nil, a flash message of "Your session has expired"
@@ -110,16 +110,14 @@ private
110
110
  if session_expired?
111
111
  @redirect_url ||= routes.root_path
112
112
  session[:current_user] = nil
113
- flash[:failed_notice] = "Your session has expired"
113
+ flash[:failed_notice] = 'Your session has expired.'
114
114
  redirect_to @redirect_url
115
115
  else
116
116
  restart_session_counter
117
117
  end
118
118
  end
119
119
 
120
-
121
120
  # ### Password reset ###
122
-
123
121
  def token
124
122
  SecureRandom.urlsafe_base64
125
123
  end
@@ -137,20 +135,6 @@ private
137
135
  def password_reset_url_valid?(link_validity)
138
136
  Time.now > @user.password_reset_sent_at + link_validity
139
137
  end
140
-
141
-
142
- # ### Authorization ###
143
- # The authorized? method checks if the specified user has the required role
144
- # and permission to access the action. It returns true or false and
145
- # provides the basis for further actions in either case.
146
- #
147
- # Example: redirect_to "/" unless authorized?
148
-
149
- def authorized?(controller, role, action)
150
- Object.const_get(controller.downcase.capitalize + "Policy").new(role).send("#{action.downcase}?")
151
- end
152
-
153
-
154
138
  end
155
139
  end
156
140
 
@@ -1,3 +1,3 @@
1
1
  module Tachiban
2
- VERSION = "0.6.1"
2
+ VERSION = "0.7.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tachiban
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastjan Hribar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-02 00:00:00.000000000 Z
11
+ date: 2021-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -191,8 +191,6 @@ files:
191
191
  - bin/setup
192
192
  - bin/tachiban
193
193
  - lib/tachiban.rb
194
- - lib/tachiban/commands/commands.rb
195
- - lib/tachiban/policy_generator/policy_generator.rb
196
194
  - lib/tachiban/version.rb
197
195
  - tachiban.gemspec
198
196
  homepage: https://github.com/sebastjan-hribar/tachiban
@@ -1,45 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optparse'
3
- require_relative "../policy_generator/policy_generator.rb"
4
-
5
-
6
- options = {}
7
- optparse = OptionParser.new do |opts|
8
- opts.banner = "\nHanami authorization policy generator
9
- Usage: tachiban -n myapp -p user
10
- Flags:
11
- \n"
12
-
13
- opts.on("-n", "--app_name APP", "Specify the application name for the policy") do |app_name|
14
- options[:app_name] = app_name
15
- end
16
-
17
- opts.on("-p", "--policy POLICY", "Specify the policy name") do |policy|
18
- options[:policy] = policy
19
- end
20
-
21
- opts.on("-h", "--help", "Displays help") do
22
- puts opts
23
- exit
24
- end
25
-
26
- end
27
-
28
-
29
- begin
30
- optparse.parse!
31
- puts "Add flag -h or --help to see usage instructions." if options.empty?
32
- mandatory = [:app_name, :policy]
33
- missing = mandatory.select{ |arg| options[arg].nil? }
34
- unless missing.empty?
35
- raise OptionParser::MissingArgument.new(missing.join(', '))
36
- end
37
-
38
- rescue OptionParser::InvalidOption, OptionParser::MissingArgument
39
- puts $!.to_s
40
- puts optparse
41
- exit
42
- end
43
-
44
- puts "Performing task with options: #{options.inspect}"
45
- generate_policy("#{options[:app_name]}", "#{options[:policy]}") if options[:policy]
@@ -1,58 +0,0 @@
1
- require 'fileutils'
2
-
3
- # The generate_policy method creates the policy file for specified
4
- # application and controller. By default all actions to check against
5
- # are commented out.
6
- # Uncomment the needed actions and define appropriate user role.
7
-
8
- def generate_policy(app_name, controller_name)
9
- app_name = app_name
10
- controller = controller_name.downcase.capitalize
11
- policy_txt = <<-TXT
12
- class #{controller}Policy
13
- def initialize(role)
14
- @user_role = role
15
-
16
- # Uncomment the required roles and add the
17
- # appropriate user role to the @authorized_roles* array.
18
-
19
- # @authorized_roles_for_new = []
20
- # @authorized_roles_for_create = []
21
- # @authorized_roles_for_show = []
22
- # @authorized_roles_for_index = []
23
- # @authorized_roles_for_edit = []
24
- # @authorized_roles_for_update = []
25
- # @authorized_roles_for_destroy = []
26
- end
27
-
28
- def new?
29
- @authorized_roles_for_new.include? @user_role
30
- end
31
- def create?
32
- @authorized_roles_for_create.include? @user_role
33
- end
34
- def show?
35
- @authorized_roles_for_show.include? @user_role
36
- end
37
- def index?
38
- @authorized_roles_for_index.include? @user_role
39
- end
40
- def edit?
41
- @authorized_roles_for_edit.include? @user_role
42
- end
43
- def update?
44
- @authorized_roles_for_update.include? @user_role
45
- end
46
- def destroy?
47
- @authorized_roles_for_destroy.include? @user_role
48
- end
49
- end
50
- TXT
51
-
52
-
53
- FileUtils.mkdir_p "lib/#{app_name}/policies" unless File.directory?("lib/#{app_name}/policies")
54
- unless File.file?("lib/#{app_name}/policies/#{controller}Policy.rb")
55
- File.open("lib/#{app_name}/policies/#{controller}Policy.rb", 'w') { |file| file.write(policy_txt) }
56
- end
57
- puts("Generated policy: lib/#{app_name}/policies/#{controller}Policy.rb") if File.file?("lib/#{app_name}/policies/#{controller}Policy.rb")
58
- end