Class: DoorCode::RestrictedAccess
- Inherits:
-
Object
- Object
- DoorCode::RestrictedAccess
- Defined in:
- lib/door_code/restricted_access.rb
Constant Summary collapse
- MIN_LENGTH =
3- MAX_LENGTH =
6- DEFAULT_CODE =
'12345'
Instance Method Summary collapse
-
#build_rack_objects ⇒ Object
Creates instances of Rack::Request and Rack::Response.
-
#call(env) ⇒ Object
Where the magic happens…
-
#confirm! ⇒ Object
Set a cookie for the correct value (server value may change) Also set up Success message.
-
#confirmed? ⇒ Boolean
Is there a valid code for the area set in the cookie.
-
#cookie_name ⇒ Object
Name of the cookie.
-
#cookied_code ⇒ Object
Returns the value of the saved cookie.
-
#initialize(app, options = {}) ⇒ RestrictedAccess
constructor
A new instance of RestrictedAccess.
-
#parse_code(code) ⇒ Object
Checks that the code provided is valid, returning nil if not.
-
#parse_codes(codes) ⇒ Object
Filters the supplied codes to ensure they are valid, and sets the DEFAULT_CODE if no valid codes are detected.
-
#request ⇒ Object
Rack::Request wrapper around @env.
-
#response ⇒ Object
Rack::Response object with which to respond with.
-
#salt ⇒ Object
Returns the salt or creates one.
-
#supplied_code ⇒ Object
Encrypted code supplied from user.
-
#unconfirm! ⇒ Object
Delete and invalid cookies Also set up Failure message.
-
#valid_code?(code) ⇒ Boolean
Is the supplied code valid for the current area.
-
#validate_code! ⇒ Object
Check if the supplied code is valid; Either sets a confirming cookie and Success message or delete any door code cookie and set Failure message.
Constructor Details
#initialize(app, options = {}) ⇒ RestrictedAccess
Returns a new instance of RestrictedAccess.
25 26 27 28 29 30 |
# File 'lib/door_code/restricted_access.rb', line 25 def initialize app, ={} @app = app # The code or codes can be supplied as either a single string or an array using either # the ":code" or ":codes" key. ":codes" trumps ":code" if both are supplied @codes = [:codes] ? parse_codes([:codes]) : parse_codes([:code]) end |
Instance Method Details
#build_rack_objects ⇒ Object
Creates instances of Rack::Request and Rack::Response
124 125 126 127 |
# File 'lib/door_code/restricted_access.rb', line 124 def build_rack_objects @request = Rack::Request.new(@env) @response = Rack::Response.new end |
#call(env) ⇒ Object
Where the magic happens…
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/door_code/restricted_access.rb', line 130 def call(env) @env = env build_rack_objects return @app.call(env) if confirmed? p 'DoorCode: Unauthorized personnel detected' if request.post? response['Content-Type'] = 'text/javascript' if request.xhr? validate_code! # Validate the user's code and set a cookie if valid else # Set request status to Unauthorized #response.status = 401 index = ::File.read(::File.dirname(__FILE__) + '/index.html') response.write index end # Render response return response.finish end |
#confirm! ⇒ Object
Set a cookie for the correct value (server value may change) Also set up Success message
111 112 113 114 |
# File 'lib/door_code/restricted_access.rb', line 111 def confirm! request.xhr? ? response.write('success') : response.redirect('/') response.(, { :value => supplied_code, :path => "/", :expire_after => (24*60*60) }) end |
#confirmed? ⇒ Boolean
Is there a valid code for the area set in the cookie
105 106 107 |
# File 'lib/door_code/restricted_access.rb', line 105 def confirmed? && valid_code?() end |
#cookie_name ⇒ Object
Name of the cookie
67 68 69 |
# File 'lib/door_code/restricted_access.rb', line 67 def 'door_code' end |
#cookied_code ⇒ Object
Returns the value of the saved cookie
72 73 74 |
# File 'lib/door_code/restricted_access.rb', line 72 def request.[] end |
#parse_code(code) ⇒ Object
Checks that the code provided is valid, returning nil if not
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/door_code/restricted_access.rb', line 46 def parse_code(code) parsed_code = code.to_s.gsub(/\D/, '') if parsed_code == code && (code.length < MIN_LENGTH || code.length > MAX_LENGTH) # Means the supplied code contains only digits, which is good # Just need to check that the code length is valid parsed_code = nil p "DoorCode: invalid PIN code detected" elsif parsed_code != code # Means the supplied code contained non-digits, so revert to default parsed_code = nil p "DoorCode: invalid PIN code detected" end parsed_code end |
#parse_codes(codes) ⇒ Object
Filters the supplied codes to ensure they are valid, and sets the DEFAULT_CODE if no valid codes are detected
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/door_code/restricted_access.rb', line 34 def parse_codes(codes) parsed_codes = codes.respond_to?(:any?) ? codes.map { |c| parse_code(c) } : [parse_code(codes)] # If there are any valid codes supplied which are unique and valid, # strip the default code out in order to circumvent a security hole if parsed_codes.compact.uniq.empty? parsed_codes << DEFAULT_CODE p "DoorCode: no valid codes detected - activating default code" end parsed_codes.compact.uniq.map { |c| Digest::SHA1.hexdigest("--#{salt}--#{c}--") } end |
#request ⇒ Object
Rack::Request wrapper around @env
78 79 80 |
# File 'lib/door_code/restricted_access.rb', line 78 def request @request ||= Rack::Request.new(@env) end |
#response ⇒ Object
Rack::Response object with which to respond with
83 84 85 |
# File 'lib/door_code/restricted_access.rb', line 83 def response @response ||= Rack::Response.new end |
#salt ⇒ Object
Returns the salt or creates one
62 63 64 |
# File 'lib/door_code/restricted_access.rb', line 62 def salt @salt ||= DoorCode.salt end |
#supplied_code ⇒ Object
Encrypted code supplied from user
88 89 90 |
# File 'lib/door_code/restricted_access.rb', line 88 def supplied_code Digest::SHA1.hexdigest("--#{salt}--#{request.params['code']}--") end |
#unconfirm! ⇒ Object
Delete and invalid cookies Also set up Failure message
118 119 120 121 |
# File 'lib/door_code/restricted_access.rb', line 118 def unconfirm! request.xhr? ? response.write('failure') : response.redirect('/') response.(supplied_code) end |
#valid_code?(code) ⇒ Boolean
Is the supplied code valid for the current area
93 94 95 |
# File 'lib/door_code/restricted_access.rb', line 93 def valid_code?(code) @codes.include?(code) end |
#validate_code! ⇒ Object
Check if the supplied code is valid; Either sets a confirming cookie and Success message or delete any door code cookie and set Failure message
100 101 102 |
# File 'lib/door_code/restricted_access.rb', line 100 def validate_code! valid_code?(supplied_code) ? confirm! : unconfirm! end |