RubyOnRails 7 redirection protection - ruby-on-rails

I want to redirect out of the application like this:
def create
#customer = Customer.new(customer_params)
#customer.save
redirect_to "https://www.shoptet.cz/", allow_other_host: true
end
ROR 7 have integrated redirect protection so I am using, allow_other_host: true as they say in the documentation and it's not working anyway, no error executed just nothing happed...
here is Server log:
Started POST "/customers" for 89.24.40.97 at 2022-08-20 21:38:41 +0200
Cannot render console from 89.24.40.97! Allowed networks: 127.0.0.0/127.255.255.255, ::1
Processing by CustomersController#create as TURBO_STREAM
Parameters: {"authenticity_token"=>"[FILTERED]", "customer"=>{"name"=>"jirkanovakneda#seznam.cz", "heslo"=>"hahshjsueb28"}, "commit"=>"Přihlášení"}
TRANSACTION (0.1ms) begin transaction
↳ app/controllers/customers_controller.rb:25:in `create'
Customer Create (0.6ms) INSERT INTO "customers" ("name", "heslo", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "jirkanovakneda#seznam.cz"], ["heslo", "hahshjsueb28"], ["created_at", "2022-08-20 19:38:41.917978"], ["updated_at", "2022-08-20 19:38:41.917978"]]
↳ app/controllers/customers_controller.rb:25:in `create'
TRANSACTION (12.0ms) commit transaction
↳ app/controllers/customers_controller.rb:25:in `create'
Redirected to https://www.shoptet.cz/
Completed 302 Found in 22ms (ActiveRecord: 12.8ms | Allocations: 2081)
Thanks for the help.

Thanks for help, problem fixed by disabling turbo on the button:
data: {turbo: false}

Related

ActiveStorage::DiskController#update throws 422 when uploading image through ActiveStorage::DirectUploadsController

I've been banging my head against this wall trying to figure out what's going on and would appreciate the help of someone with more experience.
Here's what's going on,
I'm trying to use the ActiveStorage::DirectUploadsController to upload an image. Here's what my custom controller looks like:
class DirectUploadsController < ActiveStorage::DirectUploadsController
# Should only allow null_session in API context, so request is JSON format
protect_from_forgery with: :null_session, if: proc { |c| c.request.format == 'application/json' }
before_action :authenticate_request
private
def authenticate_request
user = AuthorizeApiRequest.call(request.headers).result
render json: { error: 'Not Authorized' }, status: 401 unless user
end
end
However, when hitting the endpoint with a jpeg, I get the following:
Started POST "/direct_uploads" for ::1 at 2020-04-17 17:42:40 -0400
Processing by DirectUploadsController#create as JSON
Parameters: {"blob"=>{"filename"=>"image_picker_1249334B-5119-4F5E-91FB-99D55063495C-37712-0000F8C231364FA5.jpg", "content_type"=>"image/jpeg", "byte_size"=>1476387, "checksum"=>"33cpsUeaiJpTT+o6MkZlAQ=="}, "direct_upload"=>{"blob"=>{"filename"=>"image_picker_1249334B-5119-4F5E-91FB-99D55063495C-37712-0000F8C231364FA5.jpg", "content_type"=>"image/jpeg", "byte_size"=>1476387, "checksum"=>"33cpsUeaiJpTT+o6MkZlAQ=="}}}
Can't verify CSRF token authenticity.
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/commands/authorize_api_request.rb:19:in `user'
(0.1ms) begin transaction
ActiveStorage::Blob Create (1.5ms) INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "byte_size", "checksum", "created_at") VALUES (?, ?, ?, ?, ?, ?) [["key", "2qcdc5dzs615rkxf5xgptki4l5pe"], ["filename", "image_picker_1249334B-5119-4F5E-91FB-99D55063495C-37712-0000F8C231364FA5.jpg"], ["content_type", "image/jpeg"], ["byte_size", 1476387], ["checksum", "33cpsUeaiJpTT+o6MkZlAQ=="], ["created_at", "2020-04-17 21:42:41.075445"]]
(10.2ms) commit transaction
Disk Storage (4.8ms) Generated URL for file at key: 2qcdc5dzs615rkxf5xgptki4l5pe (http://localhost:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhNbkZqWkdNMVpIcHpOakUxY210NFpqVjRaM0IwYTJrMGJEVndaUVk2QmtWVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWRG9UWTI5dWRHVnVkRjlzWlc1bmRHaHBBeU9IRmpvTlkyaGxZMnR6ZFcxSkloMHpNMk53YzFWbFlXbEtjRlJVSzI4MlRXdGFiRUZSUFQwR093WlUiLCJleHAiOiIyMDIwLTA0LTE3VDIxOjQ3OjQxLjExMVoiLCJwdXIiOiJibG9iX3Rva2VuIn19--b2c1b25a821e7ef4b150012ad33d28e5bb6752e8)
Completed 200 OK in 439ms (Views: 1.9ms | ActiveRecord: 14.4ms | Allocations: 20173)
Started PUT "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhNbkZqWkdNMVpIcHpOakUxY210NFpqVjRaM0IwYTJrMGJEVndaUVk2QmtWVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWRG9UWTI5dWRHVnVkRjlzWlc1bmRHaHBBeU9IRmpvTlkyaGxZMnR6ZFcxSkloMHpNMk53YzFWbFlXbEtjRlJVSzI4MlRXdGFiRUZSUFQwR093WlUiLCJleHAiOiIyMDIwLTA0LTE3VDIxOjQ3OjQxLjExMVoiLCJwdXIiOiJibG9iX3Rva2VuIn19--b2c1b25a821e7ef4b150012ad33d28e5bb6752e8" for ::1 at 2020-04-17 17:42:41 -0400
Processing by ActiveStorage::DiskController#update as HTML
Parameters: {"encoded_token"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhNbkZqWkdNMVpIcHpOakUxY210NFpqVjRaM0IwYTJrMGJEVndaUVk2QmtWVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWRG9UWTI5dWRHVnVkRjlzWlc1bmRHaHBBeU9IRmpvTlkyaGxZMnR6ZFcxSkloMHpNMk53YzFWbFlXbEtjRlJVSzI4MlRXdGFiRUZSUFQwR093WlUiLCJleHAiOiIyMDIwLTA0LTE3VDIxOjQ3OjQxLjExMVoiLCJwdXIiOiJibG9iX3Rva2VuIn19--b2c1b25a821e7ef4b150012ad33d28e5bb6752e8"}
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 218)
It looks like the first request succeeds, then an internal call is made from within the ActiveStorage gem that fails. I've done some digging, and the only similar issue I could find is here: https://github.com/rails/rails/issues/34058
It seems this check fails, causing the 422: https://github.com/rails/rails/blob/bfea0af4ba7d717d6a065b4370e3ccfd8869dde6/activestorage/app/controllers/active_storage/disk_controller.rb#L22-L26
After debugging, it seems this check is failing: token[:content_length] == request.content_length, because token[:content_length] is correct but request.content_length is 0.
I'm not really sure where to look next, I think I found the source of the request but content_length is set correctly from what I can tell. Any idea what's going on?
I'm making the request from a Flutter frontend using this package: https://pub.dev/packages/active_storage/. I'd love to test the API directly using Postman but I can't seem to find any info on the request format.
In case you still have this issue, I forked the active_storage library, to set a Content-Length header as the file is being streamed to Rails. Fork is available here: https://github.com/leesus/dart-active-storage

How to submit ajax form in Rails 6 with Webpack? Getting ActionController::InvalidAuthenticityToken error

all!
I am following along with the video on GoRails on how to make a chat application using action cable. In the video, I believe Rails 5 is being used, however, I wanted to try it out with Rails 6.
Everything was going great so far. Installed Bootstrap and jQuery and properly configured my environments.js file. It was awesome. Then I get to the part right before we add action cable, and we make the chatroom form remote: true.
I cannot figure out why my form is trying to still submit as HTML instead of JS. On top of that, I am getting an ActionController::InvalidAuthenticityToken error.
Here's how I have my form set up:
<%= simple_form_for [#chatroom, Message.new], remote: true, html: { id: 'message-input' } do |f| %>
<%= f.input :body, label: false, input_html: { rows: 1, autofocus: true } %>
<% end %>
When I submit, I get this error in my rails server:
Started POST "/chatrooms/1/messages" for ::1 at 2019-10-16 21:02:01 -0500
Processing by MessagesController#create as HTML
Parameters: {"message"=>{"body"=>"test3"}, "chatroom_id"=>"1"}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 968)
ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:
Started POST "/__better_errors/cf3c4e5c6fa2d1b1/variables" for ::1 at 2019-10-16 21:02:01 -0500
Not sure what to do. I've googled and came across this but I'm not sure if it's entirely applicable: Using Rails-UJS in JS modules (Rails 6 with webpacker)
Any help would be greatly appreciated!
So, it turns out I had to use form_with instead of form_for in order to get it to process as JS. I guess form_for is slowing being deprecated?
My form now looks like this:
<%= form_with(model: [#chatroom, Message.new]) do |f| %>
<%= f.text_field :body %>
<% end %>
and the output is what I was expecting with out having to submit the CSRF token with JS or skipping the before action in the controller.
Started POST "/chatrooms/1/messages" for ::1 at 2019-10-18 20:15:14 -0500
Processing by MessagesController#create as JS
Parameters: {"authenticity_token"=>"xPBQ+4LOS5aMa7PQ3HEGXAMX6wIIEfQ0Izy/xUqUtleK4mB18IYxC4mOcIoiS5M+FGm6J/WEYMdbM4IVPojScw==", "message"=>{"body"=>"test 5"}, "chatroom_id"=>"1"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Chatroom Load (0.3ms) SELECT "chatrooms".* FROM "chatrooms" WHERE "chatrooms"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/controllers/messages_controller.rb:19:in `set_chatroom'
(0.1ms) BEGIN
↳ app/controllers/messages_controller.rb:12:in `create'
Message Create (0.7ms) INSERT INTO "messages" ("chatroom_id", "user_id", "body", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["chatroom_id", 1], ["user_id", 1], ["body", "test 5"], ["created_at", "2019-10-19 01:15:14.619853"], ["updated_at", "2019-10-19 01:15:14.619853"]]
↳ app/controllers/messages_controller.rb:12:in `create'
(5.6ms) COMMIT
↳ app/controllers/messages_controller.rb:12:in `create'
Redirected to http://localhost:3000/chatrooms/1
Completed 200 OK in 17ms (ActiveRecord: 7.6ms | Allocations: 4690)
When requesting POST requests rails does authenticity_token check.
In your request from javascript, you'll need to add a header: 'X-CSRF-Token': csrfToken.
You can get csrfToken with the following JS:
const csrfToken = document.querySelector('[name="csrf-token"]').getAttribute('content');
Another solution is to disable verify_authenticity_token, you can add this to your application_controller.rb to disable it or you can add it to controller specific:
skip_before_action :verify_authenticity_token

Rails / Devise (Devise token auth) Redirect upon unlocking account

I'm currently trying to find a way to change my redirection url upon unlocking an account. Currently when an account is locked the user is getting a email to unlock is account but then the te user get redirect on a default url. Since my rails project is an api it would be nice to redirect to my front-end
Started GET "/api/auth/unlock?unlock_token=YvR4nNssxhB9h8hvDAse" for
127.0.0.1 at 2017-12-04 15:28:08 -0500
Processing by Devise::UnlocksController#show as JSON
Parameters: {"unlock_token"=>"YvR4nNssxhB9h8hvDAse"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE
"users"."unlock_token" = $1 ORDER BY "users"."id" ASC LIMIT $2
[["unlock_token",
"6f3c4d7aa5254e143f89cd7f187e22ce56b11e6abe1f5eb252e34d86ac101908"],
["LIMIT", 1]]
(0.1ms) BEGIN
SQL (0.7ms) UPDATE "users" SET "locked_at" = $1, "failed_attempts" = $2,
"unlock_token" = $3, "updated_at" = $4 WHERE "users"."id" = $5
[["locked_at", nil], ["failed_attempts", 0], ["unlock_token", nil],
["updated_at", "2017-12-04 20:28:08.783744"], ["id", 1]]
(3.4ms) COMMIT
Redirected to http://localhost:3000/api/auth/sign_in
Completed 302 Found in 17ms (ActiveRecord: 5.0ms)
Started GET "/api/auth/sign_in" for 127.0.0.1 at 2017-12-04 15:28:08
-0500
Processing by DeviseTokenAuth::SessionsController#new as JSON
[active_model_serializers] Rendered ActiveModel::Serializer::Null with
Hash (0.14ms)
Completed 405 Method Not Allowed in 2ms (Views: 0.9ms | ActiveRecord:
0.0ms)
Started GET "/api/auth/sign_in" for 127.0.0.1 at 2017-12-04 15:31:26
-0500
Processing by DeviseTokenAuth::SessionsController#new as JSON
[active_model_serializers] Rendered ActiveModel::Serializer::Null with
Hash (0.11ms)
Completed 405 Method Not Allowed in 1ms (Views: 0.7ms | ActiveRecord:
0.0ms)
To do any customization with Devise, one must override the default controllers by creating a new controller and inheriting from it in your case that would be Devise::UnlocksController
For example:
CustomUnlocksController < Devise::UnlocksController
https://github.com/plataformatec/devise/blob/master/app/controllers/devise/unlocks_controller.rb
Override after_unlock_path_for to the path which you are going to redirect after.

Record not unique error in rails , while i'm using Devise

Completed 200 OK in 43ms (Views: 26.5ms | ActiveRecord: 0.5ms)
Started POST "/members" for 127.0.0.1 at 2017-06-08 10:43:18 -0400
Processing by RegistrationController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"i1xfaMmmX6HttiUo5Xwbx35gOCKKyAo+DMAecqcOUT/cw14di/WTlZ1KrZsdiJuIhN7tjxfVXZDvSDOpGzmK5A==", "member"=>{"username"=>"asdf", "email"=>"ash#ash.in", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "contact"=>{"mobile"=>"5", "address"=>"lkdjsk"}, "commit"=>"Submit"}
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "members" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2017-06-08 14:43:18.965179"], ["updated_at", "2017-06-08 14:43:18.965179"]]
(0.1ms) rollback transaction
Completed 500 Internal Server Error in 4ms (ActiveRecord: 0.6ms)
**ActiveRecord::RecordNotUnique (SQLite3::ConstraintException: UNIQUE constraint failed: members.email: INSERT INTO "members" ("created_at", "updated_at") VALUES (?, ?)):**
app/controllers/registration_controller.rb:22:in `create'

Why do I get a 500 error (undefined method 'to_model' on save of duplicated Ruby on Rails Model

I'm new to rails and still fuzzy on some things but here goes.
I am sending json post request to /microposts/10/duplicate.json to duplicate a micropost.
The route goes to microposts#duplicate
The Controller action is:
def duplicate
micropost = current_user.microposts.find(params[:id])
new_micropost = micropost.dup
respond_with new_micropost.save
end
The server logs for the request is:
Started POST "/microposts/15/duplicate.json" for 180.181.247.76 at 2015-09-06 11:00:38 +0000
Processing by MicropostsController#duplicate as JSON
Parameters: {"_json"=>15, "id"=>"15", "micropost"=>{}}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
Micropost Load (0.3ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? AND "microposts"."id" = ? ORDER BY "microposts"."created_at" DESC LIMIT 1 [["user_id", 2], ["id", 15]]
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "microposts" ("content", "user_id", "title", "link", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["content", "RLCPYIIG"], ["user_id", 2], ["title", "herp"], ["link", "snerp"], ["created_at", "2015-09-06 11:00:38.576553"], ["updated_at", "2015-09-06 11:00:38.576553"]]
(11.7ms) commit transaction
Completed 500 Internal Server Error in 28ms (ActiveRecord: 12.8ms)
NoMethodError (undefined method `to_model' for true:TrueClass):
app/controllers/microposts_controller.rb:23:in `duplicate'
So the micropost is saved but I don't know why I get the 500 error.
Also, should I be using .require and .permit here? The only thing in params from the front end should be the id.
Any help would be appreciated.
I was recently getting a similar error when using respond_with.
Turned out I was just missing the corresponding view for my action when requesting a HTML response.
Unfortunately the error was rather cryptic with..
undefined method `to_model' for #<Array:0x007fc7c59ada50> Did you mean? to_xml
TLDR: Check you have a corresponding view.
Hope this helps someone.
Figured it out. I should be using PUT not POST here.

Resources