LDAP connection and modified Devise

This commit is contained in:
Matt Fu 2012-02-22 14:43:24 +08:00
parent 9cd3cbc478
commit 678f1eabef
22 changed files with 245 additions and 17 deletions

View File

@ -5,6 +5,7 @@ gem 'bson_ext'
gem 'carrierwave' gem 'carrierwave'
gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid' gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid'
gem 'devise' gem 'devise'
gem "net-ldap", "~> 0.3.1"
gem 'exception_notification' # Send error trace gem 'exception_notification' # Send error trace
gem 'execjs' gem 'execjs'
gem 'jquery-rails' gem 'jquery-rails'
@ -21,6 +22,8 @@ gem 'sinatra'
gem 'sprockets' gem 'sprockets'
gem 'tinymce-rails' gem 'tinymce-rails'
# Gems used only for assets and not required # Gems used only for assets and not required
# in production environments by default. # in production environments by default.
group :assets do group :assets do

View File

@ -95,6 +95,7 @@ GEM
mongo (~> 1.3) mongo (~> 1.3)
tzinfo (~> 0.3.22) tzinfo (~> 0.3.22)
multi_json (1.0.4) multi_json (1.0.4)
net-ldap (0.3.1)
orm_adapter (0.0.6) orm_adapter (0.0.6)
polyglot (0.3.3) polyglot (0.3.3)
rack (1.3.6) rack (1.3.6)
@ -216,6 +217,7 @@ DEPENDENCIES
kaminari kaminari
mini_magick mini_magick
mongoid mongoid
net-ldap (~> 0.3.1)
radius radius
rails (>= 3.1.0, < 3.2.0) rails (>= 3.1.0, < 3.2.0)
rake rake

View File

@ -0,0 +1,37 @@
class SessionsController < Devise::SessionsController
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
include Devise::Controllers::InternalHelpers
# POST /resource/sign_in
def create
login_password = params[:user][:password]
login_uid = params[:user][:nccu_ldap_uid]
result = false
ldap = Net::LDAP.new
ldap.port = '8001'
ldap.host = '127.0.0.1'
ldap_filter = "(uid=#{login_uid})"
ldap_base = 'ou=People,dc=nccu,dc=edu,dc=tw'
ldap.authenticate("cn=uccn,ou=profile,dc=nccu,dc=edu,dc=tw","nccu2ucc")
if ldap.bind
result = ldap.bind_as(:base => ldap_base,:filter => ldap_filter,:password=> login_password)
if result
resource = User.find_or_initialize_by( nccu_ldap_uid: login_uid )
# resource = env['warden'].authenticate!(:check_nccu_ldap)
# resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
set_flash_message(:notice, :signed_in) if is_navigational_format?
resource_name = resource._type.downcase
sign_in(resource_name, resource)
respond_with resource, :location => redirect_location(resource_name, resource)
else
flash[:notice] = t('devise.failure.ldap_invalid')
render :action => "new"
end
else
flash[:notice] = t('devise.failure.ldap_connection_failed')
render :action => "new"
end
end
end

View File

@ -9,6 +9,7 @@ class User
field :admin, :type => Boolean, :default => true field :admin, :type => Boolean, :default => true
field :active_role field :active_role
field :nccu_ldap_uid
has_many :attribute_values, :autosave => true, :dependent => :destroy has_many :attribute_values, :autosave => true, :dependent => :destroy
has_many :app_auths,as: :privilege_apps,:inverse_of => :privilege_lists has_many :app_auths,as: :privilege_apps,:inverse_of => :privilege_lists

View File

@ -0,0 +1,12 @@
<h2>Resend confirmation instructions</h2>
<%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.submit "Resend confirmation instructions" %></div>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,5 @@
<p>Welcome <%= @resource.email %>!</p>
<p>You can confirm your account through the link below:</p>
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>

View File

@ -0,0 +1,8 @@
<p>Hello <%= @resource.email %>!</p>
<p>Someone has requested a link to change your password, and you can do this through the link below.</p>
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %></p>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>

View File

@ -0,0 +1,7 @@
<p>Hello <%= @resource.email %>!</p>
<p>Your account has been locked due to an excessive amount of unsuccessful sign in attempts.</p>
<p>Click the link below to unlock your account:</p>
<p><%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %></p>

View File

@ -0,0 +1,16 @@
<h2>Change your password</h2>
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<%= f.hidden_field :reset_password_token %>
<div><%= f.label :password, "New password" %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Change my password" %></div>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,12 @@
<h2>Forgot your password?</h2>
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.submit "Send me reset password instructions" %></div>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,25 @@
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %></div>
<div><%= f.submit "Update" %></div>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
<%= link_to "Back", :back %>

View File

@ -0,0 +1,18 @@
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,17 @@
<h2>Sign in</h2>
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
<div><%= f.label :nccu_ldap_uid %><br />
<%= f.text_field :nccu_ldap_uid %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<% if devise_mapping.rememberable? -%>
<div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
<% end -%>
<div><%= f.submit "Sign in" %></div>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -0,0 +1,25 @@
<%- if controller_name != 'sessions' %>
<%= link_to "Sign in", new_session_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
<% end -%>
<% end -%>

View File

@ -0,0 +1,12 @@
<h2>Resend unlock instructions</h2>
<%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.submit "Resend unlock instructions" %></div>
<% end %>
<%= render :partial => "devise/shared/links" %>

View File

@ -19,7 +19,7 @@ module PrototypeR4
# Add directories for plugins # Add directories for plugins
config.paths["vendor/plugins"] += %W(#{config.root}/vendor/built_in_modules) config.paths["vendor/plugins"] += %W(#{config.root}/vendor/built_in_modules)
config.paths["vendor/plugins"] += %W(#{config.root}/vendor/downloaded_modules) config.paths["vendor/plugins"] += %W(#{config.root}/vendor/downloaded_modules)
config.paths.app.views << "app/views/devise"
# Settings in config/environments/* take precedence over those specified here. # Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers # Application configuration should go into files in config/initializers

View File

@ -24,21 +24,21 @@ PrototypeR4::Application.configure do
config.action_dispatch.best_standards_support = :builtin config.action_dispatch.best_standards_support = :builtin
config.middleware.use ExceptionNotifier, # config.middleware.use ExceptionNotifier,
:email_prefix => "[R4_error]", # :email_prefix => "[R4_error]",
:sender_address => %{"notifier" <redmine@rulingcom.com>}, # :sender_address => %{"notifier" <redmine@rulingcom.com>},
:exception_recipients => %w{chris@rulingcom.com} # :exception_recipients => %w{chris@rulingcom.com}
#
config.action_mailer.delivery_method = :smtp # config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { # config.action_mailer.smtp_settings = {
:tls => true, # :tls => true,
:enable_starttls_auto => true, # :enable_starttls_auto => true,
:address => "smtp.gmail.com", # :address => "smtp.gmail.com",
:port => '587', # :port => '587',
:domain => "smtp.gmail.com", # :domain => "smtp.gmail.com",
:authentication => "plain", # :authentication => "plain",
:user_name => "redmine@rulingcom.com", # :user_name => "redmine@rulingcom.com",
:password => "rulingredmine" } # :password => "rulingredmine" }
end end

View File

@ -21,6 +21,8 @@ Devise.setup do |config|
# parameters are used only when authenticating and not when retrieving from # parameters are used only when authenticating and not when retrieving from
# session. If you need permissions, you should implement that in a before filter. # session. If you need permissions, you should implement that in a before filter.
# config.authentication_keys = [ :email ] # config.authentication_keys = [ :email ]
config.authentication_keys = [ :nccu_ldap_uid ]
# Tell if authentication through request.params is enabled. True by default. # Tell if authentication through request.params is enabled. True by default.
# config.params_authenticatable = true # config.params_authenticatable = true
@ -139,4 +141,7 @@ Devise.setup do |config|
# end # end
# manager.default_strategies(:scope => :user).unshift :twitter_oauth # manager.default_strategies(:scope => :user).unshift :twitter_oauth
# end # end
config.warden do |manager|
manager.default_strategies.unshift :check_nccu_ldap
end
end end

View File

@ -0,0 +1,19 @@
# Warden::Strategies.add(:check_nccu_ldap) do
# def valid?
# # code here to check whether to try and authenticate using this strategy;
# params['nccu_ldap_uid'] && params['password']
# end
# def authenticate!
# debugger
# user = User.first(conditions:{ nccu_ldap_uid: "901001" })
# if user
# success! user
# else
# success! User.create
#
# # fail!(message)
# # User.create
# end
# end
#
# end

View File

@ -9,6 +9,8 @@ en:
failure: failure:
unauthenticated: 'You need to sign in or sign up before continuing.' unauthenticated: 'You need to sign in or sign up before continuing.'
unconfirmed: 'You have to confirm your account before continuing.' unconfirmed: 'You have to confirm your account before continuing.'
ldap_invalid: 'Your LDAP account is invalid'
ldap_connection_failed: 'LDAP connection failed'
locked: 'Your account is locked.' locked: 'Your account is locked.'
invalid: 'Invalid email or password.' invalid: 'Invalid email or password.'
invalid_token: 'Invalid authentication token.' invalid_token: 'Invalid authentication token.'

View File

@ -9,6 +9,8 @@ zh_tw:
failure: failure:
unauthenticated: '您需要先註冊、登入後才能繼續。' unauthenticated: '您需要先註冊、登入後才能繼續。'
unconfirmed: '您的帳號需需要經過確認後,才能繼續。' unconfirmed: '您的帳號需需要經過確認後,才能繼續。'
ldap_invalid: '您的LDAP帳號錯誤'
ldap_connection_failed: '與LDAP之間連線異常'
locked: '您的帳號已被鎖定。' locked: '您的帳號已被鎖定。'
invalid: 'Email 或密碼是無效的。' invalid: 'Email 或密碼是無效的。'
invalid_token: '無效的認證代碼。' invalid_token: '無效的認證代碼。'

View File

@ -1,6 +1,6 @@
PrototypeR4::Application.routes.draw do PrototypeR4::Application.routes.draw do
devise_for :users devise_for :users,:controllers => {:sessions => 'sessions'}
# routes for sinatra app # routes for sinatra app
match '/site/set_registered', :to => CentralServerExchangeApp match '/site/set_registered', :to => CentralServerExchangeApp