Class: Booth::Request
Overview
Convenience wrapper for Rack::Request.
Instance Attribute Summary collapse
-
#scope ⇒ Object
readonly
A Controller that logs the user in, needs to know in which scope to login to.
Instance Method Summary collapse
- #agent ⇒ Object
- #authentication(scope: self.scope) ⇒ Object
- #host ⇒ Object
-
#initialize(request:, scope:) ⇒ Request
constructor
Initializes a new Booth::Request instance.
- #ip ⇒ Object
- #location ⇒ Object
- #must_be_delete! ⇒ Object
- #must_be_get! ⇒ Object
- #must_be_html! ⇒ Object
- #must_be_json! ⇒ Object
- #must_be_logged_in! ⇒ Object
- #must_be_patch! ⇒ Object
- #must_be_post! ⇒ Object
-
#origin ⇒ Object
The webauthn gem compares the browser's origin against
allowed_originscharacter-by-character. - #params ⇒ Object
- #return_path ⇒ Object
- #session(namespace:) ⇒ Object
- #storage ⇒ Object
- #sudo ⇒ Object
Constructor Details
#initialize(request:, scope:) ⇒ Request
Initializes a new Booth::Request instance.
Parameters:
-
:request- The request object (ActionDispatch::Request,Rack::Request, orBooth::Request). -
scope- The controller scope identifier (Symbol).
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/booth/request.rb', line 16 def initialize(request:, scope:) # Sometimes we pass the request instance from one `Calls` object to another. # In that case, unwrap the underlying request and take that as basis. # if request.is_a?(::Booth::Request) # return request if request.scope == scope # #request = request.send(:request) # end # The underlying `request` is an `ActionDispatch::Request` or a `Rack::Request`. # For consistency, we always convert to the more rich interface provided by Rails. request = ActionDispatch::Request.new(request.env) if request.is_a?(::Rack::Request) @request = request @scope = ::Booth::Syntaxes::Scope.call(scope).normalized_scope end |
Instance Attribute Details
#scope ⇒ Object (readonly)
A Controller that logs the user in, needs to know in which scope to login to.
The scope is an authoritative way for the Rails developer to specify a dedicated area.
For example:
Booth::Userland.new_login(scope: :admin, ...)
Booth::Userland.new_login(scope: :guest, ...)
The implementation could then check if a user is already logged in in that
scope, while ignoring other scopes.
For convenience, we store the authoritative controller scope here, in the request wrapper.
46 47 48 |
# File 'lib/booth/request.rb', line 46 def scope @scope end |
Instance Method Details
#agent ⇒ Object
69 70 71 |
# File 'lib/booth/request.rb', line 69 def agent ::Booth::Requests::Agent.call(request:) end |
#authentication(scope: self.scope) ⇒ Object
81 82 83 |
# File 'lib/booth/request.rb', line 81 def authentication(scope: self.scope) ::Booth::Requests::Authentication.new(scope:, warden: request.env['warden']) end |
#host ⇒ Object
50 51 52 |
# File 'lib/booth/request.rb', line 50 def host ::Booth::Syntaxes::Domain.call(request.host).valid_domain end |
#ip ⇒ Object
73 74 75 |
# File 'lib/booth/request.rb', line 73 def ip ::Booth::Requests::Ip.call(request:) end |
#location ⇒ Object
77 78 79 |
# File 'lib/booth/request.rb', line 77 def location ::Booth::Core::Geolocation.lookup(ip) end |
#must_be_delete! ⇒ Object
135 136 137 |
# File 'lib/booth/request.rb', line 135 def must_be_delete! request.delete? || raise(::Booth::Errors::MustBeDelete) end |
#must_be_get! ⇒ Object
123 124 125 |
# File 'lib/booth/request.rb', line 123 def must_be_get! request.get? || raise(::Booth::Errors::MustBeGet) end |
#must_be_html! ⇒ Object
115 116 117 |
# File 'lib/booth/request.rb', line 115 def must_be_html! request.format.html? || raise(::Booth::Errors::MustBeHtml) end |
#must_be_json! ⇒ Object
119 120 121 |
# File 'lib/booth/request.rb', line 119 def must_be_json! request.format.json? || raise(::Booth::Errors::MustBeJson) end |
#must_be_logged_in! ⇒ Object
108 109 110 111 112 113 |
# File 'lib/booth/request.rb', line 108 def must_be_logged_in! return if authentication.logged_in? log { "Expected someone to be logged in in scope #{scope.inspect}" } raise ::Booth::Errors::NotAuthenticated end |
#must_be_patch! ⇒ Object
131 132 133 |
# File 'lib/booth/request.rb', line 131 def must_be_patch! request.patch? || raise(::Booth::Errors::MustBePatch) end |
#must_be_post! ⇒ Object
127 128 129 |
# File 'lib/booth/request.rb', line 127 def must_be_post! request.post? || raise(::Booth::Errors::MustBePost) end |
#origin ⇒ Object
The webauthn gem compares the browser's origin against allowed_origins character-by-character.
Hardcoding "http://#{host}:#{port}" caused WebAuthn::OriginVerificationError in production.
The browser sends https://example.com (no port) when the port is the scheme default.
The browser sends http://localhost:3000 (with port) when the port is not the scheme default.
This method builds the origin string to match exactly what the browser sends.
59 60 61 62 63 64 65 66 67 |
# File 'lib/booth/request.rb', line 59 def origin standard_port = request.scheme == 'https' ? 443 : 80 if port == standard_port "#{request.scheme}://#{host}" else "#{request.scheme}://#{host}:#{port}" end end |
#params ⇒ Object
97 98 99 100 101 102 |
# File 'lib/booth/request.rb', line 97 def params # Huh, I thought the following line was needed: # return request.param if request.params.is_a?(::ActionController::Parameters) @params ||= ::ActionController::Parameters.new(request.params) end |
#return_path ⇒ Object
104 105 106 |
# File 'lib/booth/request.rb', line 104 def return_path ::Booth::Requests::ReturnPath.call(params:) end |
#session(namespace:) ⇒ Object
85 86 87 |
# File 'lib/booth/request.rb', line 85 def session(namespace:) ::Booth::Requests::Session.new(scope:, namespace:, session: request.session) end |