gridauth 0.1.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 +7 -0
- data/CHANGELOG.md +6 -0
- data/MIT-LICENSE +20 -0
- data/README.md +261 -0
- data/Rakefile +6 -0
- data/app/controllers/gridauth/application_controller.rb +27 -0
- data/app/controllers/gridauth/challenges_controller.rb +63 -0
- data/app/controllers/gridauth/grid_cards_controller.rb +85 -0
- data/app/helpers/gridauth/grid_helper.rb +18 -0
- data/app/models/gridauth/application_record.rb +5 -0
- data/app/models/gridauth/grid_card.rb +154 -0
- data/app/views/gridauth/challenges/new.html.erb +20 -0
- data/app/views/gridauth/grid_cards/print.html.erb +32 -0
- data/app/views/gridauth/grid_cards/show.html.erb +89 -0
- data/app/views/gridauth/shared/_challenge_fields.html.erb +18 -0
- data/app/views/gridauth/shared/_grid.html.erb +22 -0
- data/app/views/gridauth/shared/_styles.html.erb +18 -0
- data/config/locales/en.yml +61 -0
- data/lib/generators/gridauth/install/install_generator.rb +86 -0
- data/lib/generators/gridauth/install/templates/create_gridauth_grid_cards.rb.tt +26 -0
- data/lib/generators/gridauth/install/templates/initializer.rb.tt +44 -0
- data/lib/generators/gridauth/views/views_generator.rb +14 -0
- data/lib/gridauth/authentication.rb +76 -0
- data/lib/gridauth/configuration.rb +89 -0
- data/lib/gridauth/engine.rb +14 -0
- data/lib/gridauth/grid.rb +63 -0
- data/lib/gridauth/model.rb +48 -0
- data/lib/gridauth/routing.rb +29 -0
- data/lib/gridauth/version.rb +3 -0
- data/lib/gridauth.rb +41 -0
- data/lib/tasks/gridauth_tasks.rake +20 -0
- metadata +86 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Gridauth
|
|
2
|
+
# Adds the `has_grid_card` macro to Active Record models.
|
|
3
|
+
#
|
|
4
|
+
# class User < ApplicationRecord
|
|
5
|
+
# has_secure_password
|
|
6
|
+
# has_many :sessions, dependent: :destroy
|
|
7
|
+
# has_grid_card
|
|
8
|
+
# end
|
|
9
|
+
module Model
|
|
10
|
+
def has_grid_card
|
|
11
|
+
has_many :grid_cards, class_name: "Gridauth::GridCard", foreign_key: :user_id,
|
|
12
|
+
inverse_of: :user, dependent: :delete_all
|
|
13
|
+
|
|
14
|
+
include InstanceMethods
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module InstanceMethods
|
|
18
|
+
# The card currently used to sign in, if any.
|
|
19
|
+
def grid_card
|
|
20
|
+
grid_cards.active.order(activated_at: :desc).first
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# A card that has been issued but not yet confirmed by the user.
|
|
24
|
+
def pending_grid_card
|
|
25
|
+
grid_cards.pending.order(created_at: :desc).first
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def grid_card_enabled?
|
|
29
|
+
grid_cards.active.exists?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Issues a new pending card (replacing any other pending card) and
|
|
33
|
+
# returns `[card, grid]`, where `grid` is the only copy of the plaintext.
|
|
34
|
+
# The current card, if any, keeps working until the new one is activated.
|
|
35
|
+
def issue_grid_card!
|
|
36
|
+
Gridauth::GridCard.issue_for!(self)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Revokes every card, e.g. when an administrator resets a lost card.
|
|
40
|
+
def revoke_grid_cards!
|
|
41
|
+
transaction do
|
|
42
|
+
grid_cards.pending.delete_all
|
|
43
|
+
grid_cards.active.find_each(&:revoke!)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Gridauth
|
|
2
|
+
# Draws the grid card routes into the application's route set, so the
|
|
3
|
+
# engine's pages render inside the app's layout with all of its route
|
|
4
|
+
# helpers available.
|
|
5
|
+
#
|
|
6
|
+
# Rails.application.routes.draw do
|
|
7
|
+
# resource :session
|
|
8
|
+
# gridauth_routes
|
|
9
|
+
# end
|
|
10
|
+
#
|
|
11
|
+
# Route helpers: new_gridauth_challenge_path, gridauth_challenge_path,
|
|
12
|
+
# gridauth_grid_card_path, print_gridauth_grid_card_path,
|
|
13
|
+
# activate_gridauth_grid_card_path and discard_gridauth_grid_card_path.
|
|
14
|
+
module Routing
|
|
15
|
+
def gridauth_routes(path: "gridauth")
|
|
16
|
+
scope path, module: "gridauth", as: "gridauth" do
|
|
17
|
+
resource :challenge, only: %i[ new create destroy ]
|
|
18
|
+
|
|
19
|
+
resource :grid_card, path: "card", only: %i[ show create destroy ] do
|
|
20
|
+
get :print
|
|
21
|
+
post :activate
|
|
22
|
+
delete :discard
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
ActionDispatch::Routing::Mapper.include Gridauth::Routing
|
data/lib/gridauth.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require "gridauth/version"
|
|
2
|
+
require "gridauth/configuration"
|
|
3
|
+
require "gridauth/grid"
|
|
4
|
+
require "gridauth/model"
|
|
5
|
+
require "gridauth/routing"
|
|
6
|
+
require "gridauth/authentication"
|
|
7
|
+
require "gridauth/engine"
|
|
8
|
+
|
|
9
|
+
# Grid card two-factor authentication for applications using the Rails 8
|
|
10
|
+
# authentication generator.
|
|
11
|
+
module Gridauth
|
|
12
|
+
# Rails session key holding a login that passed the password check but has
|
|
13
|
+
# not yet answered the grid card challenge.
|
|
14
|
+
PENDING_LOGIN_KEY = :gridauth_pending_login
|
|
15
|
+
|
|
16
|
+
# Rails session key holding the plaintext of a freshly issued card so it can
|
|
17
|
+
# be displayed and printed until the user activates it.
|
|
18
|
+
NEW_CARD_KEY = :gridauth_new_card
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def table_name_prefix
|
|
22
|
+
"gridauth_"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def config
|
|
26
|
+
@config ||= Configuration.new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def configure
|
|
30
|
+
yield config
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def reset_config!
|
|
34
|
+
@config = Configuration.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def user_class
|
|
38
|
+
config.user_class.to_s.constantize
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
namespace :gridauth do
|
|
2
|
+
desc "Revoke all grid cards for a user (e.g. a lost card): bin/rails \"gridauth:revoke[user@example.com]\""
|
|
3
|
+
task :revoke, [ :user ] => :environment do |_task, args|
|
|
4
|
+
abort "Usage: bin/rails \"gridauth:revoke[<user id or #{Gridauth.config.user_label_attribute}>]\"" if args[:user].blank?
|
|
5
|
+
|
|
6
|
+
users = Gridauth.user_class
|
|
7
|
+
user = users.find_by(id: args[:user]) || users.find_by(Gridauth.config.user_label_attribute => args[:user])
|
|
8
|
+
abort "No user found for #{args[:user].inspect}" unless user
|
|
9
|
+
|
|
10
|
+
user.revoke_grid_cards!
|
|
11
|
+
puts "Revoked grid cards for #{args[:user]}. They can sign in with their password and set up a new card."
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
desc "List active grid cards that are due for rotation"
|
|
15
|
+
task due: :environment do
|
|
16
|
+
Gridauth::GridCard.active.includes(:user).find_each do |card|
|
|
17
|
+
puts "#{card.serial}\tuser #{card.user_id}\tactivated #{card.activated_at.to_date}\tuses #{card.use_count}" if card.rotation_due?
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: gridauth
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- jcallahan
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rails
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '8.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '8.0'
|
|
26
|
+
description: 'Adds a grid card (a printed table of random characters) as a second
|
|
27
|
+
factor to Rails 8+ apps using `bin/rails generate authentication`: per-user cards,
|
|
28
|
+
card rotation, and a challenge step after the password sign-in.'
|
|
29
|
+
email:
|
|
30
|
+
- jcallahan@acm.org
|
|
31
|
+
executables: []
|
|
32
|
+
extensions: []
|
|
33
|
+
extra_rdoc_files: []
|
|
34
|
+
files:
|
|
35
|
+
- CHANGELOG.md
|
|
36
|
+
- MIT-LICENSE
|
|
37
|
+
- README.md
|
|
38
|
+
- Rakefile
|
|
39
|
+
- app/controllers/gridauth/application_controller.rb
|
|
40
|
+
- app/controllers/gridauth/challenges_controller.rb
|
|
41
|
+
- app/controllers/gridauth/grid_cards_controller.rb
|
|
42
|
+
- app/helpers/gridauth/grid_helper.rb
|
|
43
|
+
- app/models/gridauth/application_record.rb
|
|
44
|
+
- app/models/gridauth/grid_card.rb
|
|
45
|
+
- app/views/gridauth/challenges/new.html.erb
|
|
46
|
+
- app/views/gridauth/grid_cards/print.html.erb
|
|
47
|
+
- app/views/gridauth/grid_cards/show.html.erb
|
|
48
|
+
- app/views/gridauth/shared/_challenge_fields.html.erb
|
|
49
|
+
- app/views/gridauth/shared/_grid.html.erb
|
|
50
|
+
- app/views/gridauth/shared/_styles.html.erb
|
|
51
|
+
- config/locales/en.yml
|
|
52
|
+
- lib/generators/gridauth/install/install_generator.rb
|
|
53
|
+
- lib/generators/gridauth/install/templates/create_gridauth_grid_cards.rb.tt
|
|
54
|
+
- lib/generators/gridauth/install/templates/initializer.rb.tt
|
|
55
|
+
- lib/generators/gridauth/views/views_generator.rb
|
|
56
|
+
- lib/gridauth.rb
|
|
57
|
+
- lib/gridauth/authentication.rb
|
|
58
|
+
- lib/gridauth/configuration.rb
|
|
59
|
+
- lib/gridauth/engine.rb
|
|
60
|
+
- lib/gridauth/grid.rb
|
|
61
|
+
- lib/gridauth/model.rb
|
|
62
|
+
- lib/gridauth/routing.rb
|
|
63
|
+
- lib/gridauth/version.rb
|
|
64
|
+
- lib/tasks/gridauth_tasks.rake
|
|
65
|
+
homepage: https://github.com/johncallahan/gridauth
|
|
66
|
+
licenses:
|
|
67
|
+
- MIT
|
|
68
|
+
metadata: {}
|
|
69
|
+
rdoc_options: []
|
|
70
|
+
require_paths:
|
|
71
|
+
- lib
|
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '3.2'
|
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
requirements: []
|
|
83
|
+
rubygems_version: 3.6.9
|
|
84
|
+
specification_version: 4
|
|
85
|
+
summary: Grid card two-factor authentication for Rails 8 built-in authentication.
|
|
86
|
+
test_files: []
|