auther 4.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }