From 678f1eabef9ac20b4728163b8c1cbccc65afb7c2 Mon Sep 17 00:00:00 2001 From: Matt Fu Date: Wed, 22 Feb 2012 14:43:24 +0800 Subject: [PATCH] LDAP connection and modified Devise --- Gemfile | 3 ++ Gemfile.lock | 2 + app/controllers/sessions_controller.rb | 37 +++++++++++++++++++ app/models/user/user.rb | 1 + app/views/devise/confirmations/new.html.erb | 12 ++++++ .../mailer/confirmation_instructions.html.erb | 5 +++ .../reset_password_instructions.html.erb | 8 ++++ .../mailer/unlock_instructions.html.erb | 7 ++++ app/views/devise/passwords/edit.html.erb | 16 ++++++++ app/views/devise/passwords/new.html.erb | 12 ++++++ app/views/devise/registrations/edit.html.erb | 25 +++++++++++++ app/views/devise/registrations/new.html.erb | 18 +++++++++ app/views/devise/sessions/new.html.erb | 17 +++++++++ app/views/devise/shared/_links.erb | 25 +++++++++++++ app/views/devise/unlocks/new.html.erb | 12 ++++++ config/application.rb | 2 +- config/environments/development.rb | 30 +++++++-------- config/initializers/devise.rb | 5 +++ config/initializers/rulingcom_ldap.rb | 19 ++++++++++ config/locales/devise.en.yml | 2 + config/locales/devise.zh_tw.yml | 2 + config/routes.rb | 2 +- 22 files changed, 245 insertions(+), 17 deletions(-) create mode 100644 app/controllers/sessions_controller.rb create mode 100644 app/views/devise/confirmations/new.html.erb create mode 100644 app/views/devise/mailer/confirmation_instructions.html.erb create mode 100644 app/views/devise/mailer/reset_password_instructions.html.erb create mode 100644 app/views/devise/mailer/unlock_instructions.html.erb create mode 100644 app/views/devise/passwords/edit.html.erb create mode 100644 app/views/devise/passwords/new.html.erb create mode 100644 app/views/devise/registrations/edit.html.erb create mode 100644 app/views/devise/registrations/new.html.erb create mode 100644 app/views/devise/sessions/new.html.erb create mode 100644 app/views/devise/shared/_links.erb create mode 100644 app/views/devise/unlocks/new.html.erb create mode 100644 config/initializers/rulingcom_ldap.rb diff --git a/Gemfile b/Gemfile index e7f88e3f4..94d29f4fa 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,7 @@ gem 'bson_ext' gem 'carrierwave' gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid' gem 'devise' +gem "net-ldap", "~> 0.3.1" gem 'exception_notification' # Send error trace gem 'execjs' gem 'jquery-rails' @@ -21,6 +22,8 @@ gem 'sinatra' gem 'sprockets' gem 'tinymce-rails' + + # Gems used only for assets and not required # in production environments by default. group :assets do diff --git a/Gemfile.lock b/Gemfile.lock index 92db033df..1abf066f1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -95,6 +95,7 @@ GEM mongo (~> 1.3) tzinfo (~> 0.3.22) multi_json (1.0.4) + net-ldap (0.3.1) orm_adapter (0.0.6) polyglot (0.3.3) rack (1.3.6) @@ -216,6 +217,7 @@ DEPENDENCIES kaminari mini_magick mongoid + net-ldap (~> 0.3.1) radius rails (>= 3.1.0, < 3.2.0) rake diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 000000000..3e31ca4e7 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -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 \ No newline at end of file diff --git a/app/models/user/user.rb b/app/models/user/user.rb index 13d282bb4..6796b47eb 100644 --- a/app/models/user/user.rb +++ b/app/models/user/user.rb @@ -9,6 +9,7 @@ class User field :admin, :type => Boolean, :default => true field :active_role + field :nccu_ldap_uid has_many :attribute_values, :autosave => true, :dependent => :destroy has_many :app_auths,as: :privilege_apps,:inverse_of => :privilege_lists diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb new file mode 100644 index 000000000..b7ae403ca --- /dev/null +++ b/app/views/devise/confirmations/new.html.erb @@ -0,0 +1,12 @@ +

Resend confirmation instructions

+ +<%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %> + <%= devise_error_messages! %> + +
<%= f.label :email %>
+ <%= f.email_field :email %>
+ +
<%= f.submit "Resend confirmation instructions" %>
+<% end %> + +<%= render :partial => "devise/shared/links" %> \ No newline at end of file diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb new file mode 100644 index 000000000..a6ea8ca17 --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.html.erb @@ -0,0 +1,5 @@ +

Welcome <%= @resource.email %>!

+ +

You can confirm your account through the link below:

+ +

<%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %>

diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb new file mode 100644 index 000000000..ae9e888ab --- /dev/null +++ b/app/views/devise/mailer/reset_password_instructions.html.erb @@ -0,0 +1,8 @@ +

Hello <%= @resource.email %>!

+ +

Someone has requested a link to change your password, and you can do this through the link below.

+ +

<%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %>

+ +

If you didn't request this, please ignore this email.

+

Your password won't change until you access the link above and create a new one.

diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb new file mode 100644 index 000000000..2263c2195 --- /dev/null +++ b/app/views/devise/mailer/unlock_instructions.html.erb @@ -0,0 +1,7 @@ +

Hello <%= @resource.email %>!

+ +

Your account has been locked due to an excessive amount of unsuccessful sign in attempts.

+ +

Click the link below to unlock your account:

+ +

<%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %>

diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb new file mode 100644 index 000000000..e75c93710 --- /dev/null +++ b/app/views/devise/passwords/edit.html.erb @@ -0,0 +1,16 @@ +

Change your password

+ +<%= 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 %> + +
<%= f.label :password, "New password" %>
+ <%= f.password_field :password %>
+ +
<%= f.label :password_confirmation, "Confirm new password" %>
+ <%= f.password_field :password_confirmation %>
+ +
<%= f.submit "Change my password" %>
+<% end %> + +<%= render :partial => "devise/shared/links" %> \ No newline at end of file diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb new file mode 100644 index 000000000..6c21e9fda --- /dev/null +++ b/app/views/devise/passwords/new.html.erb @@ -0,0 +1,12 @@ +

Forgot your password?

+ +<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %> + <%= devise_error_messages! %> + +
<%= f.label :email %>
+ <%= f.email_field :email %>
+ +
<%= f.submit "Send me reset password instructions" %>
+<% end %> + +<%= render :partial => "devise/shared/links" %> \ No newline at end of file diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb new file mode 100644 index 000000000..ff3805090 --- /dev/null +++ b/app/views/devise/registrations/edit.html.erb @@ -0,0 +1,25 @@ +

Edit <%= resource_name.to_s.humanize %>

+ +<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %> + <%= devise_error_messages! %> + +
<%= f.label :email %>
+ <%= f.email_field :email %>
+ +
<%= f.label :password %> (leave blank if you don't want to change it)
+ <%= f.password_field :password %>
+ +
<%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation %>
+ +
<%= f.label :current_password %> (we need your current password to confirm your changes)
+ <%= f.password_field :current_password %>
+ +
<%= f.submit "Update" %>
+<% end %> + +

Cancel my account

+ +

Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.

+ +<%= link_to "Back", :back %> diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb new file mode 100644 index 000000000..d15e275ad --- /dev/null +++ b/app/views/devise/registrations/new.html.erb @@ -0,0 +1,18 @@ +

Sign up

+ +<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %> + <%= devise_error_messages! %> + +
<%= f.label :email %>
+ <%= f.email_field :email %>
+ +
<%= f.label :password %>
+ <%= f.password_field :password %>
+ +
<%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation %>
+ +
<%= f.submit "Sign up" %>
+<% end %> + +<%= render :partial => "devise/shared/links" %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb new file mode 100644 index 000000000..93d15237a --- /dev/null +++ b/app/views/devise/sessions/new.html.erb @@ -0,0 +1,17 @@ +

Sign in

+ +<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %> +
<%= f.label :nccu_ldap_uid %>
+ <%= f.text_field :nccu_ldap_uid %>
+ +
<%= f.label :password %>
+ <%= f.password_field :password %>
+ + <% if devise_mapping.rememberable? -%> +
<%= f.check_box :remember_me %> <%= f.label :remember_me %>
+ <% end -%> + +
<%= f.submit "Sign in" %>
+<% end %> + +<%= render :partial => "devise/shared/links" %> \ No newline at end of file diff --git a/app/views/devise/shared/_links.erb b/app/views/devise/shared/_links.erb new file mode 100644 index 000000000..eab783a4c --- /dev/null +++ b/app/views/devise/shared/_links.erb @@ -0,0 +1,25 @@ +<%- if controller_name != 'sessions' %> + <%= link_to "Sign in", new_session_path(resource_name) %>
+<% end -%> + +<%- if devise_mapping.registerable? && controller_name != 'registrations' %> + <%= link_to "Sign up", new_registration_path(resource_name) %>
+<% end -%> + +<%- if devise_mapping.recoverable? && controller_name != 'passwords' %> + <%= link_to "Forgot your password?", new_password_path(resource_name) %>
+<% end -%> + +<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> + <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
+<% 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) %>
+<% 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) %>
+ <% end -%> +<% end -%> \ No newline at end of file diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb new file mode 100644 index 000000000..c6cdcfe51 --- /dev/null +++ b/app/views/devise/unlocks/new.html.erb @@ -0,0 +1,12 @@ +

Resend unlock instructions

+ +<%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %> + <%= devise_error_messages! %> + +
<%= f.label :email %>
+ <%= f.email_field :email %>
+ +
<%= f.submit "Resend unlock instructions" %>
+<% end %> + +<%= render :partial => "devise/shared/links" %> \ No newline at end of file diff --git a/config/application.rb b/config/application.rb index 3a7fb91f4..74e0c3994 100644 --- a/config/application.rb +++ b/config/application.rb @@ -19,7 +19,7 @@ module PrototypeR4 # Add directories for plugins config.paths["vendor/plugins"] += %W(#{config.root}/vendor/built_in_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. # Application configuration should go into files in config/initializers diff --git a/config/environments/development.rb b/config/environments/development.rb index d1b671e55..549fc11e6 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -24,21 +24,21 @@ PrototypeR4::Application.configure do config.action_dispatch.best_standards_support = :builtin - config.middleware.use ExceptionNotifier, - :email_prefix => "[R4_error]", - :sender_address => %{"notifier" }, - :exception_recipients => %w{chris@rulingcom.com} - - config.action_mailer.delivery_method = :smtp - config.action_mailer.smtp_settings = { - :tls => true, - :enable_starttls_auto => true, - :address => "smtp.gmail.com", - :port => '587', - :domain => "smtp.gmail.com", - :authentication => "plain", - :user_name => "redmine@rulingcom.com", - :password => "rulingredmine" } + # config.middleware.use ExceptionNotifier, + # :email_prefix => "[R4_error]", + # :sender_address => %{"notifier" }, + # :exception_recipients => %w{chris@rulingcom.com} + # + # config.action_mailer.delivery_method = :smtp + # config.action_mailer.smtp_settings = { + # :tls => true, + # :enable_starttls_auto => true, + # :address => "smtp.gmail.com", + # :port => '587', + # :domain => "smtp.gmail.com", + # :authentication => "plain", + # :user_name => "redmine@rulingcom.com", + # :password => "rulingredmine" } end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 03480dbe1..6e608309d 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -21,6 +21,8 @@ Devise.setup do |config| # parameters are used only when authenticating and not when retrieving from # session. If you need permissions, you should implement that in a before filter. # config.authentication_keys = [ :email ] + config.authentication_keys = [ :nccu_ldap_uid ] + # Tell if authentication through request.params is enabled. True by default. # config.params_authenticatable = true @@ -139,4 +141,7 @@ Devise.setup do |config| # end # manager.default_strategies(:scope => :user).unshift :twitter_oauth # end + config.warden do |manager| + manager.default_strategies.unshift :check_nccu_ldap + end end diff --git a/config/initializers/rulingcom_ldap.rb b/config/initializers/rulingcom_ldap.rb new file mode 100644 index 000000000..28625797c --- /dev/null +++ b/config/initializers/rulingcom_ldap.rb @@ -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 \ No newline at end of file diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index 5e4e43321..8d06c609e 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -9,6 +9,8 @@ en: failure: unauthenticated: 'You need to sign in or sign up 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.' invalid: 'Invalid email or password.' invalid_token: 'Invalid authentication token.' diff --git a/config/locales/devise.zh_tw.yml b/config/locales/devise.zh_tw.yml index bd5c4a432..d36054d54 100644 --- a/config/locales/devise.zh_tw.yml +++ b/config/locales/devise.zh_tw.yml @@ -9,6 +9,8 @@ zh_tw: failure: unauthenticated: '您需要先註冊、登入後才能繼續。' unconfirmed: '您的帳號需需要經過確認後,才能繼續。' + ldap_invalid: '您的LDAP帳號錯誤' + ldap_connection_failed: '與LDAP之間連線異常' locked: '您的帳號已被鎖定。' invalid: 'Email 或密碼是無效的。' invalid_token: '無效的認證代碼。' diff --git a/config/routes.rb b/config/routes.rb index cd3921f00..24dd9e95b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,6 @@ PrototypeR4::Application.routes.draw do - devise_for :users + devise_for :users,:controllers => {:sessions => 'sessions'} # routes for sinatra app match '/site/set_registered', :to => CentralServerExchangeApp