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 ⇒ 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_origins` character-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`, or
+Booth::Request+). -
‘scope` - The controller scope identifier (Symbol).
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/booth/request.rb', line 15 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:
“‘ruby 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.
45 46 47 |
# File 'lib/booth/request.rb', line 45 def scope @scope end |
Instance Method Details
#agent ⇒ Object
68 69 70 |
# File 'lib/booth/request.rb', line 68 def agent ::Booth::Requests::Agent.call(request:) end |
#authentication ⇒ Object
80 81 82 |
# File 'lib/booth/request.rb', line 80 def authentication ::Booth::Requests::Authentication.new(scope:, warden: request.env['warden']) end |
#host ⇒ Object
49 50 51 |
# File 'lib/booth/request.rb', line 49 def host ::Booth::Syntaxes::Domain.call(request.host).valid_domain end |
#ip ⇒ Object
72 73 74 |
# File 'lib/booth/request.rb', line 72 def ip ::Booth::Requests::Ip.call(request:) end |
#location ⇒ Object
76 77 78 |
# File 'lib/booth/request.rb', line 76 def location ::Booth::Core::Geolocation.lookup(ip) end |
#must_be_delete! ⇒ Object
134 135 136 |
# File 'lib/booth/request.rb', line 134 def must_be_delete! request.delete? || raise(::Booth::Errors::MustBeDelete) end |
#must_be_get! ⇒ Object
122 123 124 |
# File 'lib/booth/request.rb', line 122 def must_be_get! request.get? || raise(::Booth::Errors::MustBeGet) end |
#must_be_html! ⇒ Object
114 115 116 |
# File 'lib/booth/request.rb', line 114 def must_be_html! request.format.html? || raise(::Booth::Errors::MustBeHtml) end |
#must_be_json! ⇒ Object
118 119 120 |
# File 'lib/booth/request.rb', line 118 def must_be_json! request.format.json? || raise(::Booth::Errors::MustBeJson) end |
#must_be_logged_in! ⇒ Object
107 108 109 110 111 112 |
# File 'lib/booth/request.rb', line 107 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
130 131 132 |
# File 'lib/booth/request.rb', line 130 def must_be_patch! request.patch? || raise(::Booth::Errors::MustBePatch) end |
#must_be_post! ⇒ Object
126 127 128 |
# File 'lib/booth/request.rb', line 126 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 `example.com` (no port) when the port is the scheme default. The browser sends `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.
58 59 60 61 62 63 64 65 66 |
# File 'lib/booth/request.rb', line 58 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
96 97 98 99 100 101 |
# File 'lib/booth/request.rb', line 96 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
103 104 105 |
# File 'lib/booth/request.rb', line 103 def return_path ::Booth::Requests::ReturnPath.call(params:) end |
#session(namespace:) ⇒ Object
84 85 86 |
# File 'lib/booth/request.rb', line 84 def session(namespace:) ::Booth::Requests::Session.new(scope:, namespace:, session: request.session) end |