How to catch Sinatra::NotFound? - exception

http://rollbar.com is error tracker service.
UPDATE
I found this URL on dashboard - http://52.38.72.163/robots.txt. It seems I need to change nginx config
Robots come to my production site and are causing Sinatra::NotFound.
I tried to fix it like this:
application.rb
class Application < Sinatra::Base
def route_missing
if #app
forward
else
halt 404, 'Not found'
end
end
# also tried this
error Sinatra::NotFound do
'Route not found'
end
end
I still receive mails about this error.
Anyone faced this problem ? Any help will be appreciated.

Did you try the following ?
class App < Sinatra::Base
set :raise_errors, false
set :show_exceptions, false
error do
redirect to('/') # or something else
end

I blocked access by IP on nginx level
nginx/sites-enabled/...conf
server {
// other configurations
if ($host = "52.38.72.163") {
return 404;
}
}

Related

Can you show a flash message conditionally on what happened inside a yield block in an around_action filter?

I think I have an understanding of how an around_action works, basically performing what is before the yield as a before_action and what happens after the yield as an after_action.
I would like to know how to effectively handle errors and feedback given to the user if something wrong happens along the way, since yield runs all the code in the block (in this exampe, the index action of a controller) no matter what.
How can I display flash messages conditionally of wether an error was raised or if a rescue from error was performed or not?
Problem: A flash[:success] is rendered even when a rescue from error is performed (misleading).
controller:
class ReportsController
around_action :wrap_in_transaction, only: %i(index)
rescue_from FileExportError, with: :file_export_error
def index
#tickets = Ticket.all
respond_to do |format|
format.html
format.xlsx do
response.headers["Content-Disposition"] = "attachment; filename=report"
end
end
flash[:success] = "Success"
update_tickets(#tickets) # rolls back if a rescue happens
end
end
private
def wrap_in_transaction
ActiveRecord::Base.transaction do
yield
rescue FileExportError
raise ActiveRecord::Rollback
end
end
def file_export_error
flash[:danger] = t(".file_export_error")
redirect_to reports_path
end
def update_tickets(tickets)
tickets.each do |ticket|
ticket.update(status: "unpaid")
end
end
end
.xls.erb raise error if corrupted data trying to build file:
#tickets.each do |ticket|
if ticket.some_data.nil?
raise FileExportError
end
sheet.add_row [ticket.user.full_name,
ticket.user.phone,
...]
(Disregard my prev answer, I was skimming and misread how you were triggering the rollback.)
Your code does the following:
Loads all tickets
Configures the response format
Sets the flash message to Success
Performs some record updates
At some point after this, an export error might be raised; this triggers the rollback of the DB transaction, but the flash[:success] assignment isn't going to roll back because it's not a DB transaction. Why not try doing a flash[:error] rescue block instead of success? Or maybe moving success after yield in the transaction block might work?

Ruby on Rails IF Statement Verification Check

so I'm new to ruby on rails and I'm having a problem with this if statement, basically what I'm checking for is if the confirmation token in the sql database exists for the email address logging in. If it does kick back a message your email isn't verified. Once you click the link in the email, it deletes the token in the database. Then you can proceed to login. I cant get it working for the life of me. Everything else works but the verification check. Thank you for your help !!!
def authenticate(email, password)
command = AuthenticateUser.call(email, password)
user = User.find_by email:(email)
confirmationtoken =
User.find_by_confirmation_token(params[:confirmation_token].to_s)
if user.present? && confirmationtoken.present?
render json: {error: 'Email not verified' }, status: :unauthorized
elsif command.success?
render json: {
access_token: command.result,
message: 'Login Successful'
}
else
render json: { error: command.errors }, status: :unauthorized
end
end
You can simply check whether the user's confirmation_token attribute is set:
user = User.find_by(email: email)
if user && user.confirmation_token.present?
# ...
elsif command.success?
# ...
else
# ...
end
user.confirmation_token.present? can be shortened to user.confirmation_token?
I think this will help clean up your logic since theres no need to do a user lookup twice. And looking up the user and using the object could cause security concern .. let AuthenticateUser find the user and get success if they're in the system. When you send an email off just build a button in the email with a link to an endpoint that will verify the email and set the confirmation token to nil.
def authenticate(email, password)
command = AuthenticateUser.call(email, password)
has_confirmation_token =
User.find_by_confirmation_token(params[:confirmation_token]).present?
if !has_confirmation_token && !command.success?
render json: {error: 'Email not verified' }, status: :unauthorized
elsif command && command.success?
render json: {
access_token: command.result,
message: 'Login Successful'
}
else
render json: { error: command.errors }, status: :unauthorized
end
end

Adldap2 authentication always returns true - Yii2

I'm working in Yii2 with the Adldap extension found here: https://github.com/Adldap2/Adldap2
I'm running into an issue when I try to authenticate users on my ldap server. I can successfully make a connection and and retrieve user data, but when trying to authenticate if a user's username and password are correct or not, it always returns true, even if the creds are wrong. Below is my code snippet (with the config array not showing of course):
$ad->addProvider($config);
try {
// If a successful connection is made to your server, the provider will be returned.
$provider = $ad->connect();
//User below does return the correct information from the ldap server
$user = $provider->search()->users()->find('quillin');
try{
$provider->auth()->attempt("wrongUsername","wrongPassword");
die("WIN");
}catch( Exception $e ){
die("Exception " . $e);
}
}catch (\Adldap\Auth\BindException $e) {
die( "There was an issue binding / connecting to the server. <br />" . $e);
}
No matter what I put in for the username and password fields, it always returns true and hits the die("WIN"); line. In my composer.json file, i'm using "adldap2/adldap2": "v7.0.*"
I have also tried to bind the user using the following:
try{
$provider->auth()->attempt("wrongUsername","wrongPassword", $bindAsUser = true);
die("WIN");
}catch( Exception $e ){
die("lose :(");
die("Exception " . $e);
}
And that also always returns true;
I figured this out and will explain here in anyone else has the same issue.
1) $provider->auth()->attempt() should be wrapped in an IF, and not a try/catch.
2) The first parameter, $username, is actually looking for the userprincipalname, the docs had made it sound like it was looking instead for a username.
After that, I was able to authenticate the user successfully.

Can't catch my mysql errors

I am using codeigniter for my server side in php.
I set my email field UNIQUE on my Users table.
The problem is that whatever I tried I can't catch the error mysql generated when trying to insert a duplicate email.
What i tried inside my model:
function insert($arr) {
$query= $this->CI->db->insert('user', $arr);
if($query){
return $this->CI->db->insert_id();
} else {
$msg = $this->CI-db->_error_message();
return $msg;
}
}
The issues goes that everything is fine until I get a duplicate and I actually get NOTHING inside the $msg. I know debug is on from the database config file.
If your database config 'db_debug' => TRUE, your code will exit with showing the error message and you will not able to reach this line $msg = $this->CI-db->_error_message();.
So to catch the error message you need to set the.
db_debug' => FALSE
At CI-2 your above code will work.See more at this question
But At CI-3 those function is not available and it will produce php undefined method error. CI-3 has a method display_error. You can check it.
My solution: If you want the errors you can get it using this line
$msg = $this->db->conn_id->error_list;
This will give you the error lists as array.But remember you need to set db_debug' => FALSE

How to make Authlogic sessions work for all subdomains

When a user logs into my site at example.com, I want him to be logged in when he visits something.example.com. How can I accomplish this? (I'm using subdomain-fu if relevant)
Well, you can, just add following lines into /etc/hosts after "127.0.0.1 localhost"
127.0.0.1 localhost.com
127.0.0.1 sub.localhost.com
Then edit your environments/development.rb and add
config.action_controller.session = { :domain => '.localhost.com' }
From now on use http://localhost.com:3000 or the same but with sub-domain to access your app locally.
[update] oops, it was the answer to Horace Loeb
For Rails3 the code above will raise NoMethodError:
undefined method `session=' for ActionController::Base:Class
So, for Rails3 you should not change you environment config but should set your app/config/initializers/session_store.rb to look like:
YourAppName::Application.config.session_store :active_record_store,
{:key => '_your_namespace_session', :domain => '.yourdomain.com'}
Also after changing the initializer you'll need to restart a webserver in order to apply the initializer.
Notice, that users who were logged in before code update won't be able to logout after that because the default logout action which is looking something like:
destroy
current_user_session.destroy
flash[:notice] = "You have been logged out"
redirect_to root_path
end
is not sufficient - it doesn't delete user_credentials cookie set for a non-wildcard domain yourdomain.com by default. So you should add cookies.delete :user_credentials to the destroy action so it will look like this:
destroy
current_user_session.destroy
cookies.delete :user_credentials
flash[:notice] = "You have been logged out"
redirect_to root_path
end
And that's odd but it should be added after destroying user session despite of cookies[:user_credentials].is_nil? == true at this point. Also there is a problem that after a user logouts and then logins having cookies.delete :user_credentials in the destroy action also makes users to be unable to logout and it should be removed. Does anybody have a solution for this?
Update. Finally I came up to this - I added a boolean flag to User model via migration:
class AddReloginedToUsers < ActiveRecord::Migration
def change
add_column :users, :relogined, :boolean, :default => false
end
end
and changed the destroy action this way:
def destroy
current_user_session.destroy
if !current_user.relogined
current_user.relogined = true
current_user.save
cookies.delete(:user_credentials)
end
session = nil
flash[:notice] = "You have been logged out"
redirect_to root_path
end
Now everything works as expected although that's not a very beautiful solution. I'll be glad if anyone provides something smarter.
The fix is to add this to production.rb:
if config.action_controller.session
config.action_controller.session[:domain] = '.your-site.com'
else
config.action_controller.session = { :domain => '.your-site.com' }
end
I still can't get it to work in development with localhost:3000, but whatever