auther 4.1.0 → 5.0.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +70 -43
  5. data/app/assets/stylesheets/auther/application.scss +3 -1
  6. data/app/assets/stylesheets/auther/auther.scss +98 -9
  7. data/app/controllers/auther/base_controller.rb +26 -21
  8. data/app/controllers/auther/session_controller.rb +10 -7
  9. data/app/models/auther/account.rb +2 -1
  10. data/app/presenters/auther/account.rb +10 -0
  11. data/app/views/auther/session/new.html.slim +19 -37
  12. data/app/views/layouts/auther/auth.html.slim +0 -2
  13. data/bin/rails +4 -7
  14. data/lib/auther/authenticator.rb +14 -18
  15. data/lib/auther/cipher.rb +2 -3
  16. data/lib/auther/engine.rb +3 -22
  17. data/lib/auther/gatekeeper.rb +18 -15
  18. data/lib/auther/identity.rb +3 -2
  19. data/lib/auther/keymaster.rb +5 -4
  20. data/lib/auther/null_logger.rb +6 -6
  21. data/lib/auther/settings.rb +14 -7
  22. data/lib/auther/tasks/rspec.rake +6 -0
  23. data/lib/auther/tasks/rubocop.rake +6 -0
  24. data/lib/generators/auther/install/install_generator.rb +1 -0
  25. data/vendor/assets/stylesheets/bitters/_base.scss +10 -0
  26. data/vendor/assets/stylesheets/bitters/_buttons.scss +35 -0
  27. data/vendor/assets/stylesheets/bitters/_forms.scss +90 -0
  28. data/vendor/assets/stylesheets/bitters/_grid-settings.scss +14 -0
  29. data/vendor/assets/stylesheets/bitters/_typography.scss +49 -0
  30. data/vendor/assets/stylesheets/bitters/_variables.scss +42 -0
  31. metadata +53 -20
  32. metadata.gz.sig +0 -0
  33. data/app/assets/javascripts/auther/application.js +0 -5
  34. data/app/assets/stylesheets/auther/foundation_and_overrides.scss +0 -1191
  35. data/app/helpers/auther/foundation_helper.rb +0 -9
@@ -2,6 +2,7 @@ require "active_model"
2
2
 
3
3
  module Auther
4
4
  module Presenter
5
+ # Adapter for presenting an account within a view.
5
6
  class Account
6
7
  include ActiveModel::Validations
7
8
 
@@ -14,6 +15,15 @@ module Auther
14
15
  @login = options[:login]
15
16
  @password = options[:password]
16
17
  end
18
+
19
+ def error? key
20
+ errors.key? key
21
+ end
22
+
23
+ def error_message key
24
+ return "" unless error?(key)
25
+ "#{key.capitalize} #{errors.messages[key].first}"
26
+ end
17
27
  end
18
28
  end
19
29
  end
@@ -1,43 +1,25 @@
1
1
  - content_for(:title) { @title }
2
2
 
3
- - error_keys = @account_presenter.errors.keys
4
- - login_error = error_keys.include?(:login)
5
- - password_error = error_keys.include?(:password)
6
- - name_error = error_keys.include?(:name)
3
+ .auther-page
4
+ .auther-content
5
+ h1.auther-title = "Authorization"
7
6
 
8
- .authorization
9
- = form_for @account_presenter, as: :account, url: "/auther/session" do |form|
10
- .small-12
11
- .row
12
- h1.authorization-label = @label
7
+ = form_for @account, as: :account, url: "/auther/session", html: {class: "auther-credentials"} do |form|
8
+ div class=%(auther-form-section #{"auther-error" if @account.error?(:login)})
9
+ = form.label :login, "Login:", class: "auther-form-label"
10
+ .auther-form-group
11
+ = form.text_field :login, class: "auther-form-input"
12
+ small.auther-error-message = @account.error_message(:login)
13
13
 
14
- .row
15
- .small-8
16
- .row
17
- = content_tag :div, class: render_foundation_error(login_error, classes: %w(small-6 columns))
18
- = form.label :login, "Login:", class: "inline right"
19
- = content_tag :div, class: render_foundation_error(login_error, classes: %w(small-6 columns))
20
- = form.text_field :login
21
- = content_tag(:small, @account_presenter.errors.full_messages.first, class: "error") if login_error
22
- .row
23
- .small-8
24
- .row
25
- = content_tag :div, class: render_foundation_error(password_error, classes: %w(small-6 columns))
26
- = form.label :password, "Password:", class: "inline right"
27
- = content_tag :div, class: render_foundation_error(password_error, classes: %w(small-6 columns))
28
- = form.password_field :password
29
- = content_tag(:small, @account_presenter.errors.full_messages.first, class: "error") if password_error
14
+ div class=%(auther-form-section #{"auther-error" if @account.error?(:password)})
15
+ = form.label :password, "Password:", class: "auther-form-label"
16
+ .auther-form-group
17
+ = form.password_field :password, class: "auther-form-input"
18
+ small.auther-error-message = @account.error_message(:password)
30
19
 
31
- .row
32
- .small-8
33
- .row
34
- .small-6.columns
35
- = form.label :name, "Account:", class: "inline right"
36
- .small-6.columns
37
- = form.select :name, @account_options
20
+ .auther-form-section
21
+ = form.label :name, "Account:", class: "auther-form-select-label"
22
+ .auther-form-group
23
+ = form.select :name, @account_options, {}, class: "auther-form-select"
38
24
 
39
- .row
40
- .small-8
41
- .row
42
- .small-6.right
43
- = form.submit "Login", class: "button round expand"
25
+ = form.submit "Login", class: "auther-button"
@@ -6,8 +6,6 @@ html lang="en"
6
6
  title = yield :title
7
7
 
8
8
  = stylesheet_link_tag "auther/application", media: "all"
9
- = javascript_include_tag :modernizr
10
9
  = csrf_meta_tags
11
10
  body
12
11
  = yield
13
- = javascript_include_tag "auther/application"
data/bin/rails CHANGED
@@ -1,8 +1,5 @@
1
- #!/usr/bin/env ruby
2
- # This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
1
+ ENGINE_ROOT = File.expand_path("../..", __FILE__)
2
+ ENGINE_PATH = File.expand_path("../../lib/auther/engine", __FILE__)
3
3
 
4
- ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
- ENGINE_PATH = File.expand_path('../../lib/auther/engine', __FILE__)
6
-
7
- require 'rails/all'
8
- require 'rails/engine/commands'
4
+ require "rails/all"
5
+ require "rails/engine/commands"
@@ -1,9 +1,7 @@
1
1
  module Auther
2
+ # Manages account authentication.
2
3
  class Authenticator
3
-
4
- attr_reader :logger
5
-
6
- def initialize secret, account_model, account_presenter, logger = Auther::NullLogger.new(STDOUT)
4
+ def initialize secret, account_model, account_presenter, logger: Auther::NullLogger.new(STDOUT)
7
5
  @cipher = Auther::Cipher.new secret
8
6
  @account_model = account_model
9
7
  @account_presenter = account_presenter
@@ -12,15 +10,15 @@ module Auther
12
10
 
13
11
  def authenticated?
14
12
  account_model.valid? &&
15
- account_presenter.valid? &&
16
- authentic_name? &&
17
- authentic_login? &&
18
- authentic_password?
13
+ account_presenter.valid? &&
14
+ authentic_name? &&
15
+ authentic_login? &&
16
+ authentic_password?
19
17
  end
20
18
 
21
19
  private
22
20
 
23
- attr_reader :cipher, :account_model, :account_presenter
21
+ attr_reader :cipher, :account_model, :account_presenter, :logger
24
22
 
25
23
  def log_info message
26
24
  id = "[#{Auther::Keymaster.namespace}]"
@@ -28,17 +26,15 @@ module Auther
28
26
  end
29
27
 
30
28
  def authentic? encrypted_value, value, error_name
31
- begin
32
- if cipher.decrypt(encrypted_value) == value
33
- true
34
- else
35
- account_presenter.errors.add error_name, "is invalid"
36
- false
37
- end
38
- rescue ActiveSupport::MessageVerifier::InvalidSignature => error
39
- log_info %(Authentication failed! Invalid credential(s) for "#{account_model.name}" account.)
29
+ if cipher.decrypt(encrypted_value) == value
30
+ true
31
+ else
32
+ account_presenter.errors.add error_name, "is invalid"
40
33
  false
41
34
  end
35
+ rescue ActiveSupport::MessageVerifier::InvalidSignature
36
+ log_info %(Authentication failed! Invalid credential(s) for "#{account_model.name}" account.)
37
+ false
42
38
  end
43
39
 
44
40
  def authentic_name?
@@ -1,4 +1,5 @@
1
1
  module Auther
2
+ # Manages encryption/decryption.
2
3
  class Cipher
3
4
  def initialize secret
4
5
  @encryptor = ActiveSupport::MessageEncryptor.new secret
@@ -14,8 +15,6 @@ module Auther
14
15
 
15
16
  private
16
17
 
17
- def encryptor
18
- @encryptor
19
- end
18
+ attr_reader :encryptor
20
19
  end
21
20
  end
@@ -1,11 +1,11 @@
1
1
  module Auther
2
+ # The main engine.
2
3
  class Engine < ::Rails::Engine
3
4
  isolate_namespace Auther
4
5
 
5
- # Set defaults. Can be overwritten in app config.
6
6
  config.auther_settings = {}
7
+ config.action_view.field_error_proc = proc { |html_tag, _| html_tag.html_safe }
7
8
 
8
- # Autoload presenters
9
9
  config.to_prepare do
10
10
  Dir.glob(Engine.root + "app/presenters/**/*.rb").each do |presenter|
11
11
  require_dependency presenter
@@ -13,23 +13,8 @@ module Auther
13
13
  end
14
14
 
15
15
  initializer "auther.initialize" do |app|
16
- asset_paths = app.config.assets.paths
17
-
18
- # Add jQuery assets.
19
- add_asset_paths asset_paths, "jquery-rails", "javascripts"
20
-
21
- # Add Modernizr assets.
22
- add_asset_paths asset_paths, "modernizr-rails", "javascripts"
23
-
24
- # Add Zurb Foundation assets.
25
- add_asset_paths asset_paths, "foundation-rails", "javascripts"
26
- add_asset_paths asset_paths, "foundation-rails", "stylesheets"
27
-
28
- # Configure log filter parameters.
16
+ app.config.app_middleware.use Gatekeeper, app.config.auther_settings
29
17
  app.config.filter_parameters += [:login, :password]
30
-
31
- # Initialize Gatekeeper middleware.
32
- app.config.app_middleware.use Auther::Gatekeeper, app.config.auther_settings
33
18
  end
34
19
 
35
20
  private
@@ -37,9 +22,5 @@ module Auther
37
22
  def full_gem_path name
38
23
  Gem.loaded_specs[name].full_gem_path
39
24
  end
40
-
41
- def add_asset_paths paths, name, directory
42
- paths << "#{full_gem_path name}/vendor/assets/#{directory}"
43
- end
44
25
  end
45
26
  end
@@ -1,4 +1,5 @@
1
1
  module Auther
2
+ # Rack middleware that guards access to sensitive routes.
2
3
  class Gatekeeper
3
4
  attr_reader :application, :environment, :settings
4
5
 
@@ -70,7 +71,7 @@ module Auther
70
71
  end
71
72
 
72
73
  def clean_paths paths
73
- paths.map { |path| path.chomp '/' }
74
+ paths.map { |path| path.chomp "/" }
74
75
  end
75
76
 
76
77
  def blacklisted_paths
@@ -82,23 +83,25 @@ module Auther
82
83
  blacklisted_paths.select { |blacklisted_path| path.include? blacklisted_path }
83
84
  end
84
85
 
85
- def authenticated? account
86
+ def account_authenticated? account
86
87
  keymaster = Auther::Keymaster.new account.fetch(:name)
87
88
  cipher = Auther::Cipher.new settings.secret
88
89
 
89
- begin
90
- session_login = cipher.decrypt session[keymaster.login_key]
91
- session_password = cipher.decrypt session[keymaster.password_key]
92
- account_login = cipher.decrypt account.fetch(:encrypted_login)
93
- account_password = cipher.decrypt account.fetch(:encrypted_password)
94
-
95
- authenticated = session_login == account_login && session_password == account_password
96
- log_authentication authenticated, account.fetch(:name)
97
- authenticated
98
- rescue ActiveSupport::MessageVerifier::InvalidSignature => error
99
- log_info %(Authentication failed! Invalid credential(s) for "#{account.fetch :name}" account.)
100
- false
101
- end
90
+ session_login = cipher.decrypt session[keymaster.login_key]
91
+ session_password = cipher.decrypt session[keymaster.password_key]
92
+ account_login = cipher.decrypt account.fetch(:encrypted_login)
93
+ account_password = cipher.decrypt account.fetch(:encrypted_password)
94
+
95
+ session_login == account_login && session_password == account_password
96
+ end
97
+
98
+ def authenticated? account
99
+ authenticated = account_authenticated? account
100
+ log_authentication authenticated, account.fetch(:name)
101
+ authenticated
102
+ rescue ActiveSupport::MessageVerifier::InvalidSignature
103
+ log_info %(Authentication failed! Invalid credential(s) for "#{account.fetch :name}" account.)
104
+ false
102
105
  end
103
106
 
104
107
  def account_authorized? account, path
@@ -1,4 +1,5 @@
1
1
  module Auther
2
+ # Gem identity information.
2
3
  module Identity
3
4
  def self.name
4
5
  "auther"
@@ -9,11 +10,11 @@ module Auther
9
10
  end
10
11
 
11
12
  def self.version
12
- "4.1.0"
13
+ "5.0.0"
13
14
  end
14
15
 
15
16
  def self.label_version
16
- [label, version].join " "
17
+ "#{label} #{version}"
17
18
  end
18
19
  end
19
20
  end
@@ -1,4 +1,5 @@
1
1
  module Auther
2
+ # Provides access to setting keys.
2
3
  class Keymaster
3
4
  attr_reader :account_name
4
5
 
@@ -7,13 +8,13 @@ module Auther
7
8
  end
8
9
 
9
10
  def self.redirect_url_key options = {}
10
- [namespace, "redirect", "url"] * options.fetch(:delimiter, '_')
11
+ [namespace, "redirect", "url"] * options.fetch(:delimiter, "_")
11
12
  end
12
13
 
13
14
  def self.get_account_name session = {}
14
15
  matching_keys = session.keys.select { |key| key.to_s =~ /auther.+login/ }
15
- key = matching_keys.first || ''
16
- key.gsub("#{namespace}_", '').gsub "_login", ''
16
+ key = matching_keys.first || ""
17
+ key.gsub("#{namespace}_", "").gsub "_login", ""
17
18
  end
18
19
 
19
20
  def self.get_account_login session = {}
@@ -36,7 +37,7 @@ module Auther
36
37
  private
37
38
 
38
39
  def build_key key_name, options = {}
39
- [self.class.namespace, account_name, key_name].compact * options.fetch(:delimiter, '_')
40
+ [self.class.namespace, account_name, key_name].compact * options.fetch(:delimiter, "_")
40
41
  end
41
42
  end
42
43
  end
@@ -1,22 +1,22 @@
1
1
  module Auther
2
2
  # The default logger which purposefully does nothing at all.
3
3
  class NullLogger
4
- def initialize(*)
4
+ def initialize _
5
5
  end
6
6
 
7
- def info(*)
7
+ def info _
8
8
  end
9
9
 
10
- def warn(*)
10
+ def warn _
11
11
  end
12
12
 
13
- def error(*)
13
+ def error _
14
14
  end
15
15
 
16
- def fatal(*)
16
+ def fatal _
17
17
  end
18
18
 
19
- def debug(*)
19
+ def debug _
20
20
  end
21
21
  end
22
22
  end
@@ -1,14 +1,21 @@
1
1
  module Auther
2
+ # Represents Auther settings.
2
3
  class Settings
3
4
  attr_reader :title, :label, :secret, :accounts, :auth_url, :logger
4
5
 
5
- def initialize options = {}
6
- @title = options.fetch :title, "Authorization"
7
- @label = options.fetch :title, "Authorization"
8
- @secret = options.fetch :secret, nil
9
- @accounts = options.fetch :accounts, []
10
- @auth_url = options.fetch :auth_url, "/login"
11
- @logger = options.fetch :logger, Auther::NullLogger.new(STDOUT)
6
+ def initialize title: "Authorization",
7
+ label: "Authorization",
8
+ secret: "",
9
+ accounts: [],
10
+ auth_url: "/login",
11
+ logger: Auther::NullLogger.new(STDOUT)
12
+
13
+ @title = title
14
+ @label = label
15
+ @secret = secret
16
+ @accounts = accounts
17
+ @auth_url = auth_url
18
+ @logger = logger
12
19
  end
13
20
 
14
21
  def find_account name
@@ -0,0 +1,6 @@
1
+ begin
2
+ require "rspec/core/rake_task"
3
+ RSpec::Core::RakeTask.new(:spec)
4
+ rescue LoadError => error
5
+ puts error.message
6
+ end
@@ -0,0 +1,6 @@
1
+ begin
2
+ require "rubocop/rake_task"
3
+ RuboCop::RakeTask.new
4
+ rescue LoadError => error
5
+ puts error.message
6
+ end
@@ -1,4 +1,5 @@
1
1
  module Auther
2
+ # Install generator for adding Auther support to existing application.
2
3
  class InstallGenerator < ::Rails::Generators::Base
3
4
  source_root File.join(File.dirname(__FILE__), "..", "templates")
4
5
 
@@ -0,0 +1,10 @@
1
+ // Bitters 1.1.0
2
+ // http://bitters.bourbon.io
3
+ // Copyright 2013-2015 thoughtbot, inc.
4
+ // MIT License
5
+
6
+ @import "variables";
7
+ @import "grid-settings";
8
+ @import "buttons";
9
+ @import "forms";
10
+ @import "typography";
@@ -0,0 +1,35 @@
1
+ #{$all-buttons} {
2
+ appearance: none;
3
+ background-color: $action-color;
4
+ border: 0;
5
+ border-radius: $base-border-radius;
6
+ color: #fff;
7
+ cursor: pointer;
8
+ display: inline-block;
9
+ font-family: $base-font-family;
10
+ font-size: $base-font-size;
11
+ -webkit-font-smoothing: antialiased;
12
+ font-weight: 600;
13
+ line-height: 1;
14
+ padding: $small-spacing $base-spacing;
15
+ text-decoration: none;
16
+ transition: background-color $base-duration $base-timing;
17
+ user-select: none;
18
+ vertical-align: middle;
19
+ white-space: nowrap;
20
+
21
+ &:hover,
22
+ &:focus {
23
+ background-color: shade($action-color, 20%);
24
+ color: #fff;
25
+ }
26
+
27
+ &:disabled {
28
+ cursor: not-allowed;
29
+ opacity: 0.5;
30
+
31
+ &:hover {
32
+ background-color: $action-color;
33
+ }
34
+ }
35
+ }