Ruby script not running when Process.daemon is added - ruby-on-rails

I have the following simple script, which checks an email account and if there is new mail it forwards the email and sends an SMS. This happens as expected when the script is run without Process.daemon. When it is added, and email is received at the email account, nothing happens (nothing is forwarded and no SMS is sent) and there are no error messages in the console. Any suggestions?
#!/usr/bin/env ruby
require "bundler/setup"
require "mailman"
require "twilio-ruby"
Mailman.config.pop3 = {
:username => 'address#gmail.com',
:password => 'password',
:server => 'pop.gmail.com',
:port => 995,
:ssl => true
}
Mailman.config.poll_interval = 60
Mailman::Application.run do
default do
begin
Ticket.receive_mail(message)
MailForwarder.forwarded_email(message).deliver
#account_sid = 'xxxxxxxxxxx'
#auth_token = 'xxxxxxxxxx'
#client = Twilio::REST::Client.new(#account_sid, #auth_token)
#account = #client.account
#sms = #account.sms.messages.create(
:from => '+1111111111',
:to => '+122222222',
:body => message.subject
)
puts #sms
puts "#{message.subject}"
rescue Exception => e
Mailman.logger.error "Exception occurred whle receiving message:\n#{message}"
Mailman.logger.error [e, *e.backtrace].join("\n")
end
end
Process.daemon
end

I believe you need to set up your script as a daemon before you start up the mailman application. I did a bit of testing, and it worked fine if I called Process.daemon before calling the Mailman::Application.run but it didn't work if I put it where you had it.
So I had it as:
....
Mailman.config.poll_interval = 15
Process.daemon
Mailman::Application.run do
default do
end
end

Related

Why ldap bind is failing on server?

I'm authenticating against LDAP server in my rails application,
the code below is working locally but not on the server.
On the server it throws Net::LDAP::BindingInformationInvalidError (Invalid binding information) when trying to login in the app but works through the console
I'm pretty new to Ruby and can't figure out the proper way to debug it... I know the LDAP configuration is right because i can authenticate and bind from the console or on my local development environment.. I tried to pass :verbose => true to the LDAP constructor but without effect...
require 'net/ldap'
require 'devise/strategies/authenticatable'
module Devise
module Strategies
class LdapAuthenticatable < Authenticatable
def authenticate!
if params[:user]
ldap = Net::LDAP.new :host => 'XX.XX.XX.XX',
:port => 636,
:connect_timeout => 5,
:base => 'CN=Configuration,DC=internal,DC=XX,DC=XX',
:encryption => {
:method => :simple_tls
},
:auth => {
:method => :simple,
:username => ENV['LDAP_USER'],
:password => ENV['LDAP_PASSWORD']
}
result = ldap.bind_as(:base => "OU=Users,OU=XX,DC=XX,DC=XX,DC=XX",
:filter => "(userPrincipalName=#{email})",
:password => password,
)
if result
user = User.find_by(email: email)
success!(user)
else
return fail(:invalid_login)
end
end
end
def email
params[:user][:email]
end
def password
params[:user][:password]
end
end
end
end
Warden::Strategies.add(:ldap_authenticatable, Devise::Strategies::LdapAuthenticatable)
SOLVED
turned out it was the ENV variables that were not read.
Maybe that account is not authorized? Sounds like the problem is in the binding configuration: base => "OU=Users,OU=XX,DC=XX,DC=XX,DC=XX"
More information from other users who encountered this error:
https://gitlab.com/gitlab-org/gitlab-ce/issues/21937
LDAP groups authentication fails: Invalid Binding Information

Rails scheduled SMS sender

I want send an SMS each 5 minutes to my users. At the moment, my application sends an SMS during the creation of an account.
# users_controller.rb
def create
#user = User.new(user_params)
if #user.save
#user.send_activation_email
#user.send_daily_sms
flash[:info] = "Veuillez contrôler votre boîte mail pour activer votre compte."
redirect_to root_url
else
render 'new'
end
end
# user.rb
def send_daily_sms
# put your own credentials here
account_sid = '**********************'
auth_token = '**********************'
# set up a client to talk to the Twilio REST API
#client = Twilio::REST::Client.new account_sid, auth_token
#client.account.messages.create({
:from => '**********',
:to => '***********',
:body => 'Salut',
})
end
I already have scheduled mails working in my project by doing this :
# schedule.rb
every :day, :at => '12pm' do
rake "email_sender_daily"
end
# My task
task :email_sender_daily => :environment do |_, args|
User.find_each do |user|
UserMailer.daily_mail(user).deliver_now if user.daily == true
end
end
# My UserMailer
def daily_mail(user)
#user = user
mail to: user.email, subject: "Mail journalier"
end
I'm showing you this because, with the UserMailer, I know how to access it from an other file. Here, I'd like to do the exactly the same for SMS, but how can I access the method that is in my Model ? If not, where can I put this method to be able to access it from my rake task ?
Twilio developer evangelist here.
It looks to me like you have all the parts you need. If send_daily_sms is a method in your User class then all you require is a rake task like so:
task :sms_sender_daily => :environment do |_, args|
User.find_each do |user|
user.send_daily_sms if user.daily == true
end
end
And then your schedule.rb would look like:
every :day, :at => '12pm' do
rake "email_sender_daily"
rake "sms_sender_daily"
end
I would warn that sending sms messages to all your users via one method that calls the API over and over again is somewhat fragile. If one message fails to send because of a timeout or some other error then the task will throw an error and not be able to complete sending all the messages.
I'd suggest sending both emails and sms messages by workers using a background queue, like Rails's ActiveJob. If you are on the latest Rails 4.2 then you can use a gem called Textris that works much like ActionMailer and then you could define a UserTexter class like this:
class UserTexter < Textris::Base
default :from => YOUR_NUMBER
def daily_sms(user)
#user = user
text :to => #user.phone_number
end
end
Then your tasks could look like this:
task :email_sender_daily => :environment do |_, args|
User.find_each do |user|
UserMailer.daily_mail(user).deliver_later if user.daily == true
end
end
task :sms_sender_daily => :environment do |_, args|
User.find_each do |user|
UserTexter.daily_sms(user).deliver_later if user.daily == true
end
end
Check out the Textris documentation for more on how to use the gem.
Let me know if this helps at all!

Ruby websocket client for websocket-rails gem

I am developing a rails webpage which need to use websocket functionality to communicate with an external ruby client. In order to do this, I am using the websocket-rails gem in the rails server, definning the client_connected client_disconnected event and a specific action to received the messages from the client (new_message).
On the client side I have tried to use different ruby gems like faye-websocket-ruby and websocket-client-simple but I always obtain errors when I try to send a message. On the server I can't find the way to process these messages. Both gems has a send method with only accepts a string (not being able to specify the name of the event)
The code that I have been using is the following:
Server side
app/controllers/chat_controller.rb
class ChatController < WebsocketRails::BaseController
def new_message
puts ')'*40
end
def client_connected
puts '-'*40
end
def client_disconnected
puts '&'*40
end
end
config/events.rb
WebsocketRails::EventMap.describe do
subscribe :client_connected, :to => ChatController, :with_method => :client_connected
subscribe :message, :to => ChatController, :with_method => :new_message
subscribe :client_disconnected, :to => ChatController, :with_method => :client_disconnected
end
config/initializers/websocket_rails.rb
WebsocketRails.setup do |config|
config.log_path = "#{Rails.root}/log/websocket_rails.log"
config.log_internal_events = true
config.synchronize = false
end
Client side
websocket-client-simple
require 'rubygems'
require 'websocket-client-simple'
ws = WebSocket::Client::Simple.connect 'ws://localhost:3000/websocket'
ws.on :message do |msg|
puts msg.data
end
ws.on :new_message do
hash = { channel: 'example' }
ws.send hash
end
ws.on :close do |e|
p e
exit 1
end
ws.on :error do |e|
p e
end
hash = { channel: 'Example', message: 'Example' }
ws.send 'new_message', hash
loop do
ws.send STDIN.gets.strip
end
faye-websocket
require 'faye/websocket'
require 'eventmachine'
EM.run {
ws = Faye::WebSocket::Client.new('ws://localhost:3000/websocket')
ws.on :open do |event|
p [:open]
end
ws.on :message do |event|
p [:message, event.data]
end
ws.on :close do |event|
p [:close, event.code, event.reason]
ws = nil
end
ws.send( 'Example Text' )
}
Thanks in advance. Regards.
PD: Let me know if you need more code.
Finally I have found the solution. The problem was that the message needs to be constructed with a certain format in order to be understood by websocket-rails.
Example: ws.send( '["new_message",{"data":"Example message"}]' )
where new_message is the event which websocket-rails is listening to.

sendmail: recipients with -t option not supported on Linux 3.2.12-gentoo

I am working on an application in ruby on rails where an email is generated when user clicks con forgot password after giving his username. the new password is sent to him via an email.
I have Linux 3.2.12-gentoo vps where my application deployed. the code for sending email is under the following.
Notifier.rb
def send_password ( email, user )
#password = user.UserPassword
mail :to => "#{email}",
:subject => "Your new TrackerPal password."
end
development.rb
require 'tlsmail'
#Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.smtp_settings = {
:address => "mail.securealert.com",
:port => 25,
:domain => "mail.securealert.com",
:authentication => :login,
:user_name => "",
:password => ""
}
The code gets executed and I could see an email template being generated for new password along with a message i.e.
sendmail: recipients with -t option not supported
The same code is on another linux debian system which works absolutely fine and I received email from there.

Rails authentication with LDAP and local database

I am trying to rewrite an older app that was created with PHP/MySQL.
The authentication system used has a users table in the database that stores username, email etc... but NOT passwords.
Whenever the user logs in it first checks the database to see if the user exists if not then returns a login error. If the user exists in the local database then it tries to bind to the active directory using the username/password combination entered by the user and creates a session if successful.
What is the best way to accomplish this using Rails?
Ruby's Net::LDAP library is pretty good.
Here's a simplified version of what I've been using for years:
# sessions_controller.rb
def create
user = User.find_by_login(params[:login])
if user && Ldap.authenticate(params[:login], params[:password])
self.current_user = user
Rails.logger.info "Logged in #{user.name}"
flash[:notice] = "Successfully Logged In!"
redirect_back_or_default root_url
else
flash[:alert] = "Invalid User credentials"
render :new
end
end
# lib/ldap.rb
# Ldap.authenticate('user','password')
# Returns true if validated
# Returns false if invalidated
# Returns nil if LDAP unavailable
require 'net/ldap'
class Ldap
def self.config
# this is actually loaded from a yaml config file
{
:domain => 'YOURDOMAIN',
:host => '10.10.10.100'
}
end
def self.authenticate(login, password)
conn = Net::LDAP.new(
:host => config[:host],
:port => 636,
:base => "dc=#{config[:domain]}, dc=local",
:encryption => :simple_tls,
:auth => {
:username => "#{login}##{config[:domain]}.local",
:password => password,
:method => :simple
}
)
Timeout::timeout(15) do
return conn.bind ? true : false
end
rescue Net::LDAP::LdapError => e
notify_ldap_admin(config[:host],'Error',e)
nil
rescue Timeout::Error => e
notify_ldap_admin(config[:host],'Timeout',e)
nil
end
def self.notify_ldap_admin(host,error_type,error)
msg = "LDAP #{error_type} on #{host}"
RAILS_DEFAULT_LOGGER.debug(msg)
DeveloperMailer.deliver_ldap_failure_msg(msg,error)
end
end
Check out the devise and devise_ldap_authenticatable libraries.

Resources