keycard 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -2
- data/keycard.gemspec +0 -1
- data/lib/keycard/direct_request.rb +19 -0
- data/lib/keycard/institution_finder.rb +1 -1
- data/lib/keycard/proxied_request.rb +24 -0
- data/lib/keycard/railtie.rb +8 -3
- data/lib/keycard/request_attributes.rb +28 -5
- data/lib/keycard/version.rb +1 -1
- data/lib/keycard.rb +8 -0
- metadata +4 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ba441d104509e55f853e1003f6dd2d8c39f362e5e93ee619b0dd9378f8c13b8
|
4
|
+
data.tar.gz: 0d503c7e8c4682348e2c6d1ba9d9d0425fdf61429a278882368bad5cb19c4823
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 578ff3eb3e114a3060b0236f6c471fabf45e947b1f2184828f68206eab35071bfa182482cfbab4e9a1750a48e2e127d1aa4e4feda050a11e53c1937ad0778837
|
7
|
+
data.tar.gz: a268b75e7207d0de7626b8f675567eddce0c070158343e2f55d424c6868c06837bfcd03c0be68a3ff8b1edc42aa5798df7d3b59cbadb5b00bea1173a0e855e6d
|
data/README.md
CHANGED
@@ -37,9 +37,44 @@ And then execute:
|
|
37
37
|
|
38
38
|
$ bundle
|
39
39
|
|
40
|
-
|
40
|
+
## Configuration
|
41
41
|
|
42
|
-
|
42
|
+
There are two aspects of Keycard that are configurable: the database for IP
|
43
|
+
ranges as they map to institutions (IP blocks map to networks, and networks are
|
44
|
+
associated with institutions), and the access mode (whether your application is
|
45
|
+
served directly or behind a reverse proxy). These will be unified eventually,
|
46
|
+
but for now, they are configured separately.
|
47
|
+
|
48
|
+
## For the Database
|
49
|
+
|
50
|
+
For the database, there is a Railtie that, when running in a Rails app,
|
51
|
+
attempts to use the same connection information as ActiveRecord. If you are
|
52
|
+
running in this configuration, you will need to run a `rake db:migrate` to
|
53
|
+
create the Keycard tables and add them to your `db/schema.rb`. From there forward,
|
54
|
+
running `db:setup` or `db:schema:load` will create these tables for you. There is
|
55
|
+
a `keycard:migrate` Rake task if you want to run it separately, but it hooks into
|
56
|
+
the Rails `db:migrate` by default for convenience.
|
57
|
+
|
58
|
+
If you need to customize the database configuration, which will be typical for
|
59
|
+
at least the production environment, the easiest way is to define an
|
60
|
+
initializer. In a multi-application environment, the database may be read-only,
|
61
|
+
which will require the `Keycard::DB.config` to have its `readonly` property set
|
62
|
+
to `true`. You can also set either the `Keycard::DB.config.opts` to the options
|
63
|
+
to pass to the Sequel connection or set `Keycard::DB.config.url` to use a
|
64
|
+
connction string. The latter is equivalent to setting the `KEYCARD_DATABASE_URL`
|
65
|
+
environment variable.
|
66
|
+
|
67
|
+
## For the Access Mode
|
68
|
+
|
69
|
+
To extract the username and client IP from each request, Keycard must be
|
70
|
+
configured for an "access mode". This can be set in an initializer, under the
|
71
|
+
`Keycard.config.access` property, and should be either `:direct` if clients
|
72
|
+
will make HTTP requests directly to the Ruby webserver, or `:proxy` if a
|
73
|
+
reverse proxy will be used.
|
74
|
+
|
75
|
+
Under the hood, these modes amount to using either `REMOTE_USER` and
|
76
|
+
`REMOTE_ADDR` in the environment set by the Ruby webserver for direct mode or
|
77
|
+
the `X-Forwarded-User` and `X-Forwarded-For` headers set by a reverse proxy.
|
43
78
|
|
44
79
|
## License
|
45
80
|
|
data/keycard.gemspec
CHANGED
@@ -25,7 +25,6 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
26
|
spec.require_paths = ["lib"]
|
27
27
|
|
28
|
-
spec.add_dependency "mysql2"
|
29
28
|
spec.add_dependency "sequel"
|
30
29
|
|
31
30
|
spec.add_development_dependency "bundler", "~> 1.16"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Keycard
|
4
|
+
# This request wrapper should be used when the application will serve HTTP
|
5
|
+
# requests directly or through a proxy that sets up the usual environment.
|
6
|
+
class DirectRequest < SimpleDelegator
|
7
|
+
def self.for(request)
|
8
|
+
new(request)
|
9
|
+
end
|
10
|
+
|
11
|
+
def username
|
12
|
+
env['REMOTE_USER'] || ''
|
13
|
+
end
|
14
|
+
|
15
|
+
def client_ip
|
16
|
+
(env['REMOTE_ADDR'] || '').split(',').first || ''
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Keycard
|
4
|
+
# This request wrapper should be used when the application will be served
|
5
|
+
# behind a reverse proxy. It relies on the trusted relationship with the
|
6
|
+
# proxy to use HTTP headers for forwarded values.
|
7
|
+
#
|
8
|
+
# The typical headers forwarded are X-Forwarded-User and X-Forwarded-For,
|
9
|
+
# which, somewhat confusingly, are transposed into HTTP_X_REMOTE_USER and
|
10
|
+
# HTTP_X_FORWARDED_FOR once the Rack request is assembled.
|
11
|
+
class ProxiedRequest < SimpleDelegator
|
12
|
+
def self.for(request)
|
13
|
+
new(request)
|
14
|
+
end
|
15
|
+
|
16
|
+
def username
|
17
|
+
env['HTTP_X_REMOTE_USER'] || ''
|
18
|
+
end
|
19
|
+
|
20
|
+
def client_ip
|
21
|
+
(env['HTTP_X_FORWARDED_FOR'] || '').split(',').first || ''
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/keycard/railtie.rb
CHANGED
@@ -66,9 +66,14 @@ module Keycard
|
|
66
66
|
initializer "keycard.before_initializers", before: :load_config_initializers do
|
67
67
|
config = Keycard::DB.config
|
68
68
|
unless config.url
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
case Rails.env
|
70
|
+
when "development"
|
71
|
+
config[:opts] = { adapter: 'sqlite', database: "db/keycard_development.sqlite3" }
|
72
|
+
when "test"
|
73
|
+
config[:opts] = { adapter: 'sqlite' }
|
74
|
+
else
|
75
|
+
raise "Keycard::DB.config must be configured"
|
76
|
+
end
|
72
77
|
end
|
73
78
|
|
74
79
|
Railtie.before_blocks.each do |block|
|
@@ -5,9 +5,10 @@ module Keycard
|
|
5
5
|
# complete set of things that determine the user's #identity), given a Rack
|
6
6
|
# request.
|
7
7
|
class RequestAttributes
|
8
|
-
def initialize(request, finder: InstitutionFinder.new)
|
9
|
-
@
|
10
|
-
@
|
8
|
+
def initialize(request, finder: InstitutionFinder.new, request_factory: default_factory)
|
9
|
+
@request = request
|
10
|
+
@finder = finder
|
11
|
+
@request_factory = request_factory
|
11
12
|
end
|
12
13
|
|
13
14
|
def [](attr)
|
@@ -15,12 +16,34 @@ module Keycard
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def all
|
18
|
-
finder.attributes_for(request)
|
19
|
+
user_attributes.merge(finder.attributes_for(request))
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
22
23
|
|
24
|
+
def user_attributes
|
25
|
+
{ username: request.username }
|
26
|
+
end
|
27
|
+
|
28
|
+
def request
|
29
|
+
request_factory.for(@request)
|
30
|
+
end
|
31
|
+
|
32
|
+
def default_factory
|
33
|
+
access = Keycard.config.access.to_sym
|
34
|
+
case access
|
35
|
+
when :direct
|
36
|
+
DirectRequest
|
37
|
+
when :proxy
|
38
|
+
ProxiedRequest
|
39
|
+
else
|
40
|
+
# TODO: Warn about this once to the appropriate log; probably in a config check, not here.
|
41
|
+
# puts "Keycard does not recognize the '#{access}' access mode, using 'direct'."
|
42
|
+
DirectRequest
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
23
46
|
attr_reader :finder
|
24
|
-
attr_reader :
|
47
|
+
attr_reader :request_factory
|
25
48
|
end
|
26
49
|
end
|
data/lib/keycard/version.rb
CHANGED
data/lib/keycard.rb
CHANGED
@@ -2,12 +2,20 @@
|
|
2
2
|
|
3
3
|
require "keycard/version"
|
4
4
|
require "sequel"
|
5
|
+
require "ostruct"
|
5
6
|
|
6
7
|
# All of the Keycard components are contained within this top-level module.
|
7
8
|
module Keycard
|
9
|
+
def self.config
|
10
|
+
@config ||= OpenStruct.new(
|
11
|
+
access: :direct
|
12
|
+
)
|
13
|
+
end
|
8
14
|
end
|
9
15
|
|
10
16
|
require "keycard/db"
|
11
17
|
require "keycard/railtie" if defined?(Rails)
|
12
18
|
require "keycard/request_attributes"
|
13
19
|
require "keycard/institution_finder"
|
20
|
+
require "keycard/direct_request"
|
21
|
+
require "keycard/proxied_request"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keycard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noah Botimer
|
@@ -9,22 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-06-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: mysql2
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - ">="
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '0'
|
21
|
-
type: :runtime
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - ">="
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: '0'
|
28
14
|
- !ruby/object:Gem::Dependency
|
29
15
|
name: sequel
|
30
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -202,7 +188,9 @@ files:
|
|
202
188
|
- keycard.gemspec
|
203
189
|
- lib/keycard.rb
|
204
190
|
- lib/keycard/db.rb
|
191
|
+
- lib/keycard/direct_request.rb
|
205
192
|
- lib/keycard/institution_finder.rb
|
193
|
+
- lib/keycard/proxied_request.rb
|
206
194
|
- lib/keycard/railtie.rb
|
207
195
|
- lib/keycard/request_attributes.rb
|
208
196
|
- lib/keycard/version.rb
|