auther 1.3.0 → 1.4.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
- checksums.yaml.gz.sig +2 -1
- data.tar.gz.sig +0 -0
- data/README.md +22 -25
- data/app/controllers/auther/base_controller.rb +7 -2
- data/app/models/auther/account.rb +2 -1
- data/app/views/auther/session/new.html.slim +2 -2
- data/lib/auther/engine.rb +16 -7
- data/lib/auther/gatekeeper.rb +33 -25
- data/lib/auther/version.rb +1 -1
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65a58c9e0dbe816215f33e5daa86064c83a06185
|
4
|
+
data.tar.gz: 276515d8c4cf3b4fcc96e6dd548400f362270d03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f85b9b1dd51400d5a52aa18f006e9c06bc8a5f5c91e1757bda195c323e6df33e8b9709b6d3fbd0586a94466154b2e1be388960b9741ed765251b76262ace07ef
|
7
|
+
data.tar.gz: 4e8e0a69cb00fa91133f3c074517643c9affa4c6970edcc65609ec6d4e48e9540ab2055ea208640f8c54f0bfb2c4c4f0616a3e86087c2eb8c3f037301fe47814
|
checksums.yaml.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
�{k=��&53����Ђǃ��5�q^�<����}XyJ���#�F���:6��}��a�l���%i A��r�4�Kqs�
|
2
|
+
�}��9s
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -59,37 +59,34 @@ Edit your routes.rb as follows:
|
|
59
59
|
get "/login", to: "auther/session#new"
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
paths: ["/admin"]
|
75
|
-
],
|
76
|
-
secret: "vuKrwD9XWoYuv@s99?tR(9VqryiL,KV{W7wFnejUa4QcVBP+D{2rD4JfuD(mXgA=$tNK4Pfn#NeGs3o3TZ3CqNc^Qb",
|
77
|
-
auth_url: "/login",
|
78
|
-
logger: ActiveSupport::Logger.new("log/#{Rails.env}.log")
|
79
|
-
}
|
80
|
-
|
81
|
-
end
|
82
|
-
end
|
62
|
+
Add a config/initializers/auther.rb to your application with the following content:
|
63
|
+
|
64
|
+
Rails.application.config.auther_settings = {
|
65
|
+
secret: "vuKrwD9XWoYuv@s99?tR(9VqryiL,KV{W7wFnejUa4QcVBP+D{2rD4JfuD(mXgA=$tNK4Pfn#NeGs3o3TZ3CqNc^Qb",
|
66
|
+
accounts: [
|
67
|
+
name: "admin",
|
68
|
+
login: "N3JzR213WlBISDZsMjJQNkRXbEVmYVczbVdnMHRYVHRud29lOWRCekp6ST0tLWpFMkROekUvWDBkOHZ4ZngxZHV6clE9PQ==--cd863c39991fa4bb9a35de918aa16da54514e331",
|
69
|
+
password: "cHhFSStjRm9KbEYwK3ZJVlF2MmpTTWVVZU5acEdlejZsZEhjWFJoQWxKND0tLTE3cmpXZVBQdW5VUW1jK0ZSSDdLUnc9PQ==--f51171174fa77055540420f205e0dd9d499cfeb6",
|
70
|
+
paths: ["/admin"]
|
71
|
+
],
|
72
|
+
auth_url: "/login"
|
73
|
+
}
|
83
74
|
|
84
75
|
The purpose of each setting is as follows:
|
85
76
|
|
86
77
|
* *title* - Optional. The HTML page title (as rendered within a browser tab). Default: "Authorization".
|
87
78
|
* *label* - Optional. The page label (what would appear above the form). Default: "Authorization".
|
79
|
+
* *secret* - Required. The secret passphrase used to encrypt/decrypt account credentials.
|
88
80
|
* *accounts* - Required. The array of accounts with different or similar access to the application.
|
81
|
+
* *name* - Required. The account name. The name that uniquely identifies each account.
|
89
82
|
* *login* - Required. The encrypted account login. For example, the above decrypts to: *test@test.com*.
|
90
83
|
* *password* - Required. The encrypted account password. For example, the above decrypts to: *password*.
|
91
84
|
* *paths* - Required. The array of blacklisted paths for which only this account has access to.
|
92
|
-
* *
|
85
|
+
* *success_url* - Optional. The URL to redirect to upon successful authorization. Success redirection works
|
86
|
+
as follows (in the order defined):
|
87
|
+
0. The blacklisted path (if requested prior to authorization but now authorized).
|
88
|
+
0. The success URL (if defined and the blacklisted path wasn't requested).
|
89
|
+
0. The root path (if none of the above).
|
93
90
|
* *auth_url* - Required. The URL to redirect to when enforcing authentication to a blacklisted path.
|
94
91
|
* *logger* - Optional. The logger used to log path/account authorization messages. Default: Auther::NullLogger.
|
95
92
|
|
@@ -138,7 +135,7 @@ you add a controller to your app that inherits from the Auther::BaseController.
|
|
138
135
|
|
139
136
|
# Example Path: app/controllers/session_controller.rb
|
140
137
|
class SessionController < Auther::BaseController
|
141
|
-
layout "
|
138
|
+
layout "example"
|
142
139
|
end
|
143
140
|
|
144
141
|
This allows complete customization of session controller behavior to serve any special business needs. See the
|
@@ -146,7 +143,7 @@ Auther::BaseController for additional details or the Auther::SessionController f
|
|
146
143
|
|
147
144
|
## Routes
|
148
145
|
|
149
|
-
As mentioned in the setup above, the routes can
|
146
|
+
As mentioned in the setup above, the routes can be customized as follows:
|
150
147
|
|
151
148
|
Rails.application.routes.draw do
|
152
149
|
mount Auther::Engine => "/auther"
|
@@ -156,7 +153,7 @@ As mentioned in the setup above, the routes can also be customized. Example:
|
|
156
153
|
|
157
154
|
## Logging
|
158
155
|
|
159
|
-
As mentioned in the setup above, the logger can be customized
|
156
|
+
As mentioned in the setup above, the logger can be customized as follows:
|
160
157
|
|
161
158
|
Auther::NullLogger.new # This is the default logger (which is no logging at all).
|
162
159
|
ActiveSupport::Logger.new("log/#{Rails.env}.log") # Can be used to log to the environment log.
|
@@ -11,7 +11,7 @@ module Auther
|
|
11
11
|
def create
|
12
12
|
if account.valid?
|
13
13
|
store_credentials
|
14
|
-
redirect_to
|
14
|
+
redirect_to redirect_url
|
15
15
|
else
|
16
16
|
remove_credentials account.name
|
17
17
|
render template: new_template_path
|
@@ -46,7 +46,8 @@ module Auther
|
|
46
46
|
secure_login: account_settings.fetch(:login),
|
47
47
|
password: account_params.fetch(:password),
|
48
48
|
secure_password: account_settings.fetch(:password),
|
49
|
-
secret: settings.fetch(:secret)
|
49
|
+
secret: settings.fetch(:secret),
|
50
|
+
success_url: account_settings.fetch(:success_url, nil)
|
50
51
|
end
|
51
52
|
|
52
53
|
def name_options
|
@@ -60,6 +61,10 @@ module Auther
|
|
60
61
|
raise NotImplementedError, "The method, #new_template_path, is not implemented."
|
61
62
|
end
|
62
63
|
|
64
|
+
def redirect_url
|
65
|
+
session["auther_redirect_url"] || account.success_url || '/'
|
66
|
+
end
|
67
|
+
|
63
68
|
def find_account name
|
64
69
|
settings.fetch(:accounts).select { |account| account.fetch(:name) == name }.first
|
65
70
|
end
|
@@ -2,7 +2,7 @@ module Auther
|
|
2
2
|
class Account
|
3
3
|
include ActiveModel::Validations
|
4
4
|
|
5
|
-
attr_accessor :name, :login, :secure_login, :password, :secure_password, :paths
|
5
|
+
attr_accessor :name, :login, :secure_login, :password, :secure_password, :paths, :success_url
|
6
6
|
|
7
7
|
validates :name, presence: true
|
8
8
|
validates :paths, presence: {unless: lambda { |account| account.paths.is_a? Array }, message: "must be an array"}
|
@@ -15,6 +15,7 @@ module Auther
|
|
15
15
|
@secure_password = options.fetch :secure_password, nil
|
16
16
|
@paths = options.fetch :paths, []
|
17
17
|
@secret = options.fetch :secret, nil
|
18
|
+
@success_url = options.fetch :success_url, nil
|
18
19
|
end
|
19
20
|
|
20
21
|
def valid?
|
@@ -18,7 +18,7 @@
|
|
18
18
|
= form.label :login, "Login:", class: "inline right"
|
19
19
|
= content_tag :div, class: render_foundation_error(login_error, classes: %w(small-6 columns))
|
20
20
|
= form.text_field :login
|
21
|
-
= content_tag(:small, @account.errors.full_messages.first) if login_error
|
21
|
+
= content_tag(:small, @account.errors.full_messages.first, class: "error") if login_error
|
22
22
|
.row
|
23
23
|
.small-8
|
24
24
|
.row
|
@@ -26,7 +26,7 @@
|
|
26
26
|
= form.label :password, "Password:", class: "inline right"
|
27
27
|
= content_tag :div, class: render_foundation_error(password_error, classes: %w(small-6 columns))
|
28
28
|
= form.password_field :password
|
29
|
-
= content_tag(:small, @account.errors.full_messages.first) if password_error
|
29
|
+
= content_tag(:small, @account.errors.full_messages.first, class: "error") if password_error
|
30
30
|
|
31
31
|
.row
|
32
32
|
.small-8
|
data/lib/auther/engine.rb
CHANGED
@@ -6,18 +6,17 @@ module Auther
|
|
6
6
|
config.auther_settings = {}
|
7
7
|
|
8
8
|
initializer "auther.initialize" do |app|
|
9
|
+
asset_paths = app.config.assets.paths
|
10
|
+
|
9
11
|
# Add jQuery assets.
|
10
|
-
|
11
|
-
app.config.assets.paths << "#{jquery_gem_path}/vendor/assets/javascripts"
|
12
|
+
add_asset_paths asset_paths, "jquery-rails", "javascripts"
|
12
13
|
|
13
14
|
# Add Modernizr assets.
|
14
|
-
|
15
|
-
app.config.assets.paths << "#{modernizr_gem_path}/vendor/assets/javascripts"
|
15
|
+
add_asset_paths asset_paths, "modernizr-rails", "javascripts"
|
16
16
|
|
17
17
|
# Add Zurb Foundation assets.
|
18
|
-
|
19
|
-
|
20
|
-
app.config.assets.paths << "#{foundation_gem_path}/vendor/assets/javascripts"
|
18
|
+
add_asset_paths asset_paths, "foundation-rails", "javascripts"
|
19
|
+
add_asset_paths asset_paths, "foundation-rails", "stylesheets"
|
21
20
|
|
22
21
|
# Configure log filter parameters.
|
23
22
|
app.config.filter_parameters += [:login, :password]
|
@@ -25,5 +24,15 @@ module Auther
|
|
25
24
|
# Initialize Gatekeeper middleware.
|
26
25
|
app.config.app_middleware.use Auther::Gatekeeper, app.config.auther_settings
|
27
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def full_gem_path name
|
31
|
+
Gem.loaded_specs[name].full_gem_path
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_asset_paths paths, name, directory
|
35
|
+
paths << "#{full_gem_path name}/vendor/assets/#{directory}"
|
36
|
+
end
|
28
37
|
end
|
29
38
|
end
|
data/lib/auther/gatekeeper.rb
CHANGED
@@ -36,17 +36,35 @@ module Auther
|
|
36
36
|
Rack::Response.new body, status, headers
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
39
|
+
def log_info message
|
40
40
|
id = "[#{Auther::Keymaster.namespace}]"
|
41
41
|
logger.info [id, message].join(": ")
|
42
42
|
end
|
43
43
|
|
44
|
+
def log_authentication authenticated, account_name
|
45
|
+
if authenticated
|
46
|
+
log_info %(Authentication passed. Account: "#{account_name}".)
|
47
|
+
else
|
48
|
+
log_info %(Authentication failed! Account: "#{account_name}".)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def log_authorization authorized, account_name, blacklist, request_path
|
53
|
+
details = %(Account: "#{account_name}". Blacklist: #{blacklist}. Request Path: "#{request_path}".)
|
54
|
+
|
55
|
+
if authorized
|
56
|
+
log_info %(Authorization failed! #{details})
|
57
|
+
else
|
58
|
+
log_info %(Authorization passed. #{details})
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
44
62
|
def find_account
|
45
63
|
session["auther_init"] = true # Force session to initialize.
|
46
64
|
account_name = Auther::Keymaster.get_account_name session
|
47
65
|
account = settings.fetch(:accounts).detect { |account| account.fetch(:name) == account_name }
|
48
66
|
|
49
|
-
account ?
|
67
|
+
account ? log_info("Account found.") : log_info("Account unknown.")
|
50
68
|
account
|
51
69
|
end
|
52
70
|
|
@@ -64,19 +82,6 @@ module Auther
|
|
64
82
|
paths.select { |blacklisted_path| path.include? blacklisted_path }
|
65
83
|
end
|
66
84
|
|
67
|
-
def blacklisted_account? account, path
|
68
|
-
paths = clean_paths account.fetch(:paths)
|
69
|
-
blacklisted = paths.include? path
|
70
|
-
|
71
|
-
if blacklisted
|
72
|
-
info %(Authorization failed! Requested path "#{request.path}" blacklisted by "#{account.fetch :name}" account blacklist: #{paths}.)
|
73
|
-
else
|
74
|
-
info %(Authorization passed. Requested path "#{request.path}" allowed for "#{account.fetch :name}" account blacklist: #{paths}.)
|
75
|
-
end
|
76
|
-
|
77
|
-
blacklisted
|
78
|
-
end
|
79
|
-
|
80
85
|
def authenticated? account
|
81
86
|
keymaster = Auther::Keymaster.new account.fetch(:name)
|
82
87
|
cipher = Auther::Cipher.new settings.fetch(:secret)
|
@@ -86,29 +91,32 @@ module Auther
|
|
86
91
|
session_password = cipher.decrypt session[keymaster.password_key]
|
87
92
|
account_login = cipher.decrypt account.fetch(:login)
|
88
93
|
account_password = cipher.decrypt account.fetch(:password)
|
89
|
-
authenticated = session_login == account_login && session_password == account_password
|
90
|
-
|
91
|
-
if authenticated
|
92
|
-
info %(Authentication passed for "#{account.fetch :name}" account.)
|
93
|
-
else
|
94
|
-
info %(Authentication failed for "#{account.fetch :name}" account!)
|
95
|
-
end
|
96
94
|
|
95
|
+
authenticated = session_login == account_login && session_password == account_password
|
96
|
+
log_authentication authenticated, account.fetch(:name)
|
97
97
|
authenticated
|
98
98
|
rescue ActiveSupport::MessageVerifier::InvalidSignature => error
|
99
|
-
|
99
|
+
log_info %(Authentication failed! Invalid credential(s) for "#{account.fetch :name}" account.)
|
100
100
|
false
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
+
def account_authorized? account, path
|
105
|
+
paths = clean_paths account.fetch(:paths)
|
106
|
+
|
107
|
+
authorized = paths.include? path
|
108
|
+
log_authorization authorized, account.fetch(:name), paths, request.path
|
109
|
+
authorized
|
110
|
+
end
|
111
|
+
|
104
112
|
def authorized? path
|
105
113
|
accounts = settings.fetch :accounts
|
106
114
|
all_blacklisted_paths = blacklisted_paths settings.fetch(:accounts)
|
107
115
|
|
108
116
|
if blacklisted_matched_paths(accounts, path).any?
|
109
|
-
|
117
|
+
log_info %(Requested path "#{request.path}" found in blacklisted paths: #{all_blacklisted_paths}.)
|
110
118
|
account = find_account
|
111
|
-
account && authenticated?(account) && !
|
119
|
+
account && authenticated?(account) && !account_authorized?(account, path)
|
112
120
|
else
|
113
121
|
true
|
114
122
|
end
|
data/lib/auther/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: auther
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brooke Kuhlmann
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
SJpzzzZ8gO6BKn4fhd+ENNQ333Qy3nuNk07TVIaNnlgeHhowUDuD9T7Z8Lka0pt3
|
31
31
|
4PteiTppsf0SSVAM9zSO5IuFngXMRwWgvjOfXE70f43RDuUVTCSyylc=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2014-05-
|
33
|
+
date: 2014-05-29 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: pry-byebug
|
metadata.gz.sig
CHANGED
Binary file
|