Using Ruby Webrick HTTPAuth with LDAP - ruby-on-rails

The app I am writing has the ability to have a login popup appear and it authenticates against a hard coded username/password constant pair. I would like to authenticate against our central LDAP server. the we dont have a base however we do have a bind_dn string of "cn=USERFOO,ou=it,o=corporate". The variables user/pass are passed in through the basic login box.
I am trying to do this through ActiveLdap however I dont mind using any other library as long as I can validate the credentials through a single sign on against our LDAP server using the HTTPAuth since is written completely in Webrick Ruby. Below is a sample of the function I am calling.
Does anyone have any idea how to do this?
Thanks in advance.
def authenticate_ldap(req,res)
authlabel = "LDAP Authentication"
HTTPAuth.basic_auth(req, res, authlabel) { |user, pass|
ActiveLdap::Base.setup_connection(
:host => 'ldap.internalserver.com',
:port => 389,
:bind_dn => "cn=#{user},ou=it,o=corporate",
:password_block => Proc.new { pass },
)
}
return
end

I figured out a solution. The person who manages our LDAP server provided the incorrect ldap connection string, but even with that it still didn't work.
The solution I discovered that did indeed make a connection with very basic validation is something to this effect for anyone else interested in a very simple ldap authentication popup in pure Ruby.
def authenticate(req,res)
authlabel = 'LDAP Authentication'
HTTPAuth.basic_auth(req, res, authlabel) { |user, pass|
if pass.to_s != ''
ldap = Net::LDAP.new
ldap.host = "ldap.serverfoo.com"
ldap.port = 389
result = ldap.bind_as(
:base => "t=basetreefoo",
:filter => "uid=#{user}",
:password => pass
)
if result
ldap = Net::LDAP.new :host => "ldap.serverfoo.com",
:port => "389",
:auth => {
:method => :simple,
:username => "",
:password => ""
}
group_name = Net::LDAP::Filter.eq("cn", "#{user}")
group_type = Net::LDAP::Filter.eq("groupmembership", "cn=infra,ou=IT,o=Corporate")
filter = group_name & group_type
treebase = "t=basetreefoo"
ldap.search(:base => treebase, :filter => filter) do |entry|
if entry.dn.to_s != ""
puts 'success'
return
end
end
end
end
puts 'fail'
}
end

Related

Dot missing(on domain name) of password reset email link send by SendGrid

I am using SendGrid mailer on Ruby and Rails framework. In password reset email template we are sending a password reset link which looks like the following format (https://subdomain.domainname.com/password_reset/token/?some_other_params). Most of the time the password reset link is emailed to recipient in correct format but for some customer it is not sending the proper link. The issue we noticed is "the dot is missing between (subdomain and domainname) or (domainname and com) randomly and the resulting password reset link to customer looks like (https://subdomaindomainname.com/password_reset/token/?some_other_params) which is a wrong link. This issue is happening only on production and occur very random.
I verified our variable which have domain name in our source code and verified the code which is generating the url and also thoroughly tested this and their is no issue on our source code. On google i see this question. I did't understand how to programatically solve this on SendGrid email client.
mailer.rb
class Mailer < ActionMailer::Base
sendgrid_category Rails.env
default_url_options[:host] = APP_URL
end
config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.sendgrid.net",
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => "subdomain.domainname.com",
:port => 587,
:authentication => "plain",
:enable_starttls_auto => true
}
APP_URL = "subdomain.domainname.com"
mailer_helper.rb
def link_to_with_ga(*args)
args[1] = append_ga args[1], 'html'
link_to *args
end
def append_ga(link, utm_content)
link << "#{link.include?('?') ? '&' : '?' }#{#ga_tag}&utm_content=#{utm_content}"
end
_reset_password_view.rb
<%= link_to_with_ga(t("users.reset_password"), reset_password_url(:token => #token, :locale=>#user_locale,:protocol => ( Rails.env.eql?('development') ? 'http' : 'https' )),:id => 'reset_link') %>
Please help me in solve this issue.
Thank you

Listing all OU's in LDAP with Rails

I am trying to list all Organizational Units (OU) from my LDAP directory. I am using the "devise_ldap_authenticatable" gem to authenticate my users. The LDAP sign in works fine. I am trying to get all the OU's now.
I'm new to LDAP, please let me know if my search query is wrong here.
ldap = Net::LDAP.new
ldap.host = "192.168.0.100"
ldap.port = 389
ldap.auth "cn=admin,dc=company,dc=com", "password"
treebase = "dc=company,dc=com"
filter = Net::LDAP::Filter.eq( "objectClass=organizationalUnit","company.com" )
attrs = ["*"]
ldap.search( :base => treebase, :filter => filter, :attributes => attrs, :return_result => false ) do |entry|
puts entry
end
When I ran this, I got nothing returned. I have two OU's in my LDAP, DevOps and Development. There are 5 test users in each.
I'm not sure if this is the right way to do it, but it got me what I wanted and I'm happy with that.
I just removed the filter and retrieved the ou from the entry directly.
ldap.search( :base => treebase, :attributes => attrs, :return_result => false ) do |entry|
puts entry["ou"]
end

401 unauthorized error in oauth with Jira 2L0 in Rails using oauth-plugin

I'm trying to hook up an OAuth consumer using 2-legged authentication. I have two questions:
1) is it possible to use Oauth with a custom REST plugin (as opposed to the built-in API)
2) as a test of the built-in REST API, I'm trying the following, and receiving:
<Net::HTTPUnauthorized 401 Unauthorized readbody=true>
{"errorMessages":["You do not have the permission to see the specified issue","Login Required"],"errors":{}}
Here is the test method:
jira_url = "http://localhost:2990/jira"
consumer_key = "hardcoded-consumer"
consumer_secret = OpenSSL::PKey::RSA.new(IO.read(File.dirname(__FILE__) + "/../rsakey.pem"))
#consumer ||= OAuth::Consumer.new(consumer_key, consumer_secret, {
:site => 'http://localhost:2990',
:context_path => '/jira',
:signature_method => 'RSA-SHA1',
:auth_type => :oauth,
:scheme => :header,
:oauth_callback => false,
:ssl_verify_mode => OpenSSL::SSL::VERIFY_PEER,
:use_ssl => true,
:http_method => :post,
:request_token_path => jira_url + '/plugins/servlet/oauth/request-token',
:access_token_path => jira_url + '/plugins/servlet/oauth/access-token',
:authorize_path => jira_url + '/plugins/servlet/oauth/authorize'
})
testurl = jira_url + "/rest/api/latest/issue/SPI-1"
puts "1 #################################### first method"
req = #consumer.create_signed_request(:get, testurl, nil)
res = Net::HTTP.start('localhost', '2990') { |http| http.request(req) }
puts res.inspect
puts res.body
puts "2 #################################### second method"
#acc_tok = OAuth::AccessToken.new #consumer
resp = #acc_tok.get(testurl)
puts #acc_tok.inspect
puts resp.inspect
puts resp.body
Both methods output the same error.
Can anyone tell me what I'm doing wrong?
Answer 1. OAuth is an authorization framework and REST is a stateless, client-server, cacheable communications protocol. So yes you can use OAuth for authentication with your custom REST plugin.
Answer 2. You could try without SSL or use :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE if it works, than problem is in your SSL connection. Alternatively you may try basic authentication:
{
:username => "*Your JIRA username*",
:password => "*Your JIRA password*",
:site => 'http://localhost:2990/',
:context_path => 'jira',
:auth_type => :basic,
:use_ssl => true,
:signature_method => 'RSA-SHA1',
:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE
}
I found this gem very useful.

Rails LDAP login using net/ldap

I am trying to get LDAP authentication to work under Rails.
I have chosen net/ldap since it's a native Ruby LDAP library.
I have tried all possible stuff, specially examples from http://net-ldap.rubyforge.org/classes/Net/LDAP.html but still unable to get it work.
Any ideas?
The best solution I managed to reach is a Model with the following:
require 'net/ldap'
class User < ActiveRecord::Base
def after_initialize
#config = YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
end
def ldap_auth(user, pass)
ldap = initialize_ldap_con
result = ldap.bind_as(
:base => #config['base_dn'],
:filter => "(#{#config['attributes']['id']}=#{user})",
:password => pass
)
if result
# fetch user DN
get_user_dn user
sync_ldap_with_db user
end
nil
end
private
def initialize_ldap_con
options = { :host => #config['host'],
:port => #config['port'],
:encryption => (#config['tls'] ? :simple_tls : nil),
:auth => {
:method => :simple,
:username => #config['ldap_user'],
:password => #config['ldap_password']
}
}
Net::LDAP.new options
end
def get_user_dn(user)
ldap = initialize_ldap_con
login_filter = Net::LDAP::Filter.eq #config['attributes']['id'], "#{user}"
object_filter = Net::LDAP::Filter.eq "objectClass", "*"
ldap.search :base => #config['base_dn'],
:filter => object_filter & login_filter,
:attributes => ['dn', #config['attributes']['first_name'], #config['attributes']['last_name'], #config['attributes']['mail']] do |entry|
logger.debug "DN: #{entry.dn}"
entry.each do |attr, values|
values.each do |value|
logger.debug "#{attr} = #{value}"
end
end
end
end
end
I work on a Devise plugin for Rails 3 that uses LDAP for authentication, you can look at the source to get some ideas, it currently uses net-ldap 0.1.1:
http://github.com/cschiewek/devise_ldap_authenticatable
The actual connecting and authenticating to the LDAP sever is done at:
http://github.com/cschiewek/devise_ldap_authenticatable/blob/master/lib/devise_ldap_authenticatable/ldap_adapter.rb
Lastly, you can look at the sample LDAP server config and Rails 3 app I use to run the tests against:
App: http://github.com/cschiewek/devise_ldap_authenticatable/tree/master/test/rails_app/
Server: http://github.com/cschiewek/devise_ldap_authenticatable/tree/master/test/ldap/

How to send emails from ruby using a gmail account, for example?

I'm kind of new at ruby on rails, and I've read many tutorials about this, but I still can't figure out what's wrong.
I already set up the environment.rb with the following lines at the bottom:
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.default_content_type = "text/html"
ActionMailer::Base.smtp_settings = {
:address => 'smtp.gmail.com',
:port => 25,
:domain => 'gmail.com',
:authentication => :login,
:user_name => 'myname#gmail.com',
:password => 'mypassword'
}
Then, I've got some code that came with the baseApp I'm using, and it does the following:
UserMailer.deliver_forgot_password(self)
Where self is the user object, that contains the email, login, etc.
That method(which belongs to the UserMailer class) has the following code:
def forgot_password(user)
setup_email(user)
#subject += "Forgotten password instructions"
#{user.password_reset_code}
#body[:url] = "http://#{Setting.get(:site_url)}/users/reset_password/#"
end
protected
def setup_email(user)
#recipients = "#{user.email}"
#from = "#{Setting.get(:support_name)} <#{Setting.get(:support_email)}>"
#subject = "[#{Setting.get(:site_name)}] "
#sent_on = Time.now
#body[:user] = user
# Get Settings
[:site_name, :company_name, :support_email, :support_name].each do |id|
#body[id] = Setting.get(id)
end
end
Well, the emails are fine, I've already checked them doing raise inspect, but it's not sending...and it doesn't throw me an exception either.
Now I'm getting Errno::ECONNREFUSED error when trying to send an email. What's wrong now?
Thanks,
Brian
Gmail port should be 587 or 465.
and add
:tls => true,
Do you have the ActionMailerTLS Gem installed ?
The new way of doing this as of rails 2.3.2 is
:enable_starttls_auto => true
No need for additional plugins.
On my Mac, I had to turn on postfix to get emails to send. Maybe you don't have a similar mail program turned on capable of sending emails. What that is for Windows 7, I do not know.

Resources