From 523d9a38f25372d39f460701e6d022beb74fdfa8 Mon Sep 17 00:00:00 2001 From: shawn-higgins1 <23224097+shawn-higgins1@users.noreply.github.com> Date: Wed, 10 Jul 2019 11:26:43 -0400 Subject: [PATCH] GRN2-30: Add custom ldap sign in page (#619) * Add custom ldap signin page * Remove old omniauth-ldap gem * Use new bn gems --- Gemfile | 5 +- Gemfile.lock | 23 ++--- app/assets/images/ldap-logo.png | Bin 0 -> 8231 bytes app/assets/stylesheets/main.scss | 11 +++ app/controllers/sessions_controller.rb | 84 +++++++++++++------ app/controllers/users_controller.rb | 4 + app/helpers/application_helper.rb | 8 +- app/views/shared/_header.html.erb | 4 +- app/views/users/ldap_signin.html.erb | 34 ++++++++ config/initializers/omniauth.rb | 41 +-------- config/locales/en.yml | 1 + config/routes.rb | 2 + spec/controllers/sessions_controller_spec.rb | 37 ++++++++ spec/controllers/users_controller_spec.rb | 8 ++ 14 files changed, 180 insertions(+), 82 deletions(-) create mode 100644 app/assets/images/ldap-logo.png create mode 100644 app/views/users/ldap_signin.html.erb diff --git a/Gemfile b/Gemfile index 33b61aca..2e77d0e3 100644 --- a/Gemfile +++ b/Gemfile @@ -45,8 +45,9 @@ gem 'omniauth' gem 'omniauth-twitter' gem 'omniauth-google-oauth2' gem 'omniauth-bn-office365', git: 'https://github.com/blindsidenetworks/omniauth-bn-office365.git', tag: '0.1.0' -gem 'omniauth-ldap' -gem 'omniauth-bn-launcher', git: 'https://github.com/blindsidenetworks/omniauth-bn-launcher.git', tag: '0.1.0' +gem 'omniauth-bn-launcher', git: 'https://github.com/blindsidenetworks/omniauth-bn-launcher.git', tag: '0.1.1' +gem 'bn-ldap-authentication', git: 'https://github.com/blindsidenetworks/bn-ldap-authentication.git' +gem 'net-ldap' # BigBlueButton API wrapper. gem 'bigbluebutton-api-ruby' diff --git a/Gemfile.lock b/Gemfile.lock index 44e22c68..9bc6b0b0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,9 +1,16 @@ +GIT + remote: https://github.com/blindsidenetworks/bn-ldap-authentication.git + revision: 538132e0df70dbe470120f7bc7a93968c522031f + specs: + bn-ldap-authentication (1.0.0) + net-ldap + GIT remote: https://github.com/blindsidenetworks/omniauth-bn-launcher.git - revision: 0d0597bec9aed63b9c9d44e99e16353c5d587d48 - tag: 0.1.0 + revision: 025785046c3d532ed2252ef4762469c8d08d4839 + tag: 0.1.1 specs: - omniauth-bn-launcher (0.1.0) + omniauth-bn-launcher (0.1.1) omniauth (~> 1.3, >= 1.3.2) omniauth-oauth2 (= 1.5.0) @@ -165,11 +172,6 @@ GEM jwt (>= 2.0) omniauth (>= 1.1.1) omniauth-oauth2 (>= 1.5) - omniauth-ldap (1.0.5) - net-ldap (~> 0.12) - omniauth (~> 1.0) - pyu-ruby-sasl (~> 0.0.3.2) - rubyntlm (~> 0.3.4) omniauth-oauth (1.1.0) oauth omniauth (~> 1.0) @@ -187,7 +189,6 @@ GEM popper_js (1.14.5) public_suffix (3.0.3) puma (3.12.1) - pyu-ruby-sasl (0.0.3.3) rack (2.0.7) rack-test (0.6.3) rack (>= 1.0) @@ -256,7 +257,6 @@ GEM ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 1.7) ruby-progressbar (1.10.0) - rubyntlm (0.3.4) safe_yaml (1.0.5) sass (3.7.4) sass-listen (~> 4.0.0) @@ -336,6 +336,7 @@ DEPENDENCIES action-cable-testing bcrypt (~> 3.1.7) bigbluebutton-api-ruby + bn-ldap-authentication! bootstrap (~> 4.3.1) byebug cancancan (~> 2.0) @@ -351,11 +352,11 @@ DEPENDENCIES jquery-rails (~> 4.3.3) listen (~> 3.0.5) mini_racer + net-ldap omniauth omniauth-bn-launcher! omniauth-bn-office365! omniauth-google-oauth2 - omniauth-ldap omniauth-twitter pagy pg (~> 0.18) diff --git a/app/assets/images/ldap-logo.png b/app/assets/images/ldap-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f11320ef02daad6da7ac625cc8eb6ffce6a1a496 GIT binary patch literal 8231 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 literal 0 HcmV?d00001 diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index 42e41209..4271ade6 100755 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -145,6 +145,17 @@ } } +.customBtn-ldap { + @extend .customBtn; + background: #d61515; + + .customBtn-image { + background: #ffffff image-url("ldap-logo.png") no-repeat left top; + background-size: 18px 18px; + padding:10px 10px 10px 10px; + } +} + .signin-button { font-size: 16px; } diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 678ea8a0..f4de6416 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -19,6 +19,7 @@ class SessionsController < ApplicationController include Registrar include Emailer + include LdapAuthenticator skip_before_action :verify_authenticity_token, only: [:omniauth, :fail] @@ -47,8 +48,65 @@ class SessionsController < ApplicationController # GET/POST /auth/:provider/callback def omniauth + @auth = request.env['omniauth.auth'] + + process_signin + end + + # POST /auth/failure + def omniauth_fail + redirect_to root_path, alert: I18n.t(params[:message], default: I18n.t("omniauth_error")) + end + + # GET /auth/ldap + def ldap + ldap_config = {} + ldap_config[:host] = ENV['LDAP_SERVER'] + ldap_config[:port] = ENV['LDAP_PORT'].to_i != 0 ? ENV['LDAP_PORT'].to_i : 389 + ldap_config[:bind_dn] = ENV['LDAP_BIND_DN'] + ldap_config[:password] = ENV['LDAP_PASSWORD'] + ldap_config[:encryption] = if ENV['LDAP_METHOD'] == 'ssl' + 'simple_tls' + elsif ENV['LDAP_METHOD'] == 'tls' + 'start_tls' + end + ldap_config[:base] = ENV['LDAP_BASE'] + ldap_config[:uid] = ENV['LDAP_UID'] + + result = send_ldap_request(params[:session], ldap_config) + + if result + result = result.first + else + return redirect_to(ldap_signin_path, alert: I18n.t("invalid_credentials")) + end + + @auth = parse_auth(result) + + process_signin + end + + private + + def session_params + params.require(:session).permit(:email, :password) + end + + def check_user_exists + provider = @auth['provider'] == "bn_launcher" ? @auth['info']['customer'] : @auth['provider'] + User.exists?(social_uid: @auth['uid'], provider: provider) + end + + # Check if the user already exists, if not then check for invitation + def passes_invite_reqs + return true if @user_exists + + invitation = check_user_invited("", session[:invite_token], @user_domain) + invitation[:present] + end + + def process_signin begin - @auth = request.env['omniauth.auth'] @user_exists = check_user_exists if !@user_exists && @auth['provider'] == "twitter" @@ -89,28 +147,4 @@ class SessionsController < ApplicationController omniauth_fail end end - - # POST /auth/failure - def omniauth_fail - redirect_to root_path, alert: I18n.t(params[:message], default: I18n.t("omniauth_error")) - end - - private - - def session_params - params.require(:session).permit(:email, :password) - end - - def check_user_exists - provider = @auth['provider'] == "bn_launcher" ? @auth['info']['customer'] : @auth['provider'] - User.exists?(social_uid: @auth['uid'], provider: provider) - end - - # Check if the user already exists, if not then check for invitation - def passes_invite_reqs - return true if @user_exists - - invitation = check_user_invited("", session[:invite_token], @user_domain) - invitation[:present] - end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 3883a584..dd89d633 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -68,6 +68,10 @@ class UsersController < ApplicationController end end + # GET /ldap_signin + def ldap_signin + end + # GET /signup def new return redirect_to root_path unless Rails.configuration.allow_user_signup diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 248ebbf8..eb3ebf65 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -33,7 +33,7 @@ module ApplicationHelper # Determines which providers can show a login button in the login modal. def iconset_providers - providers = configured_providers & [:google, :twitter, :microsoft_office365] + providers = configured_providers & [:google, :twitter, :microsoft_office365, :ldap] providers.delete(:twitter) if session[:old_twitter_user_id] @@ -42,7 +42,11 @@ module ApplicationHelper # Generates the login URL for a specific provider. def omniauth_login_url(provider) - "#{Rails.configuration.relative_url_root}/auth/#{provider}" + if provider == :ldap + ldap_signin_path + else + "#{Rails.configuration.relative_url_root}/auth/#{provider}" + end end # Determine if Greenlight is configured to allow user signups. diff --git a/app/views/shared/_header.html.erb b/app/views/shared/_header.html.erb index a11211df..1228e2b4 100755 --- a/app/views/shared/_header.html.erb +++ b/app/views/shared/_header.html.erb @@ -72,9 +72,7 @@ <% else %> <% allow_greenlight_accounts = allow_greenlight_accounts? %> - <% if Rails.configuration.omniauth_ldap %> - <%= link_to t("login"), omniauth_login_url(:ldap), :class => "btn btn-outline-primary mx-2 sign-in-button" %> - <% elsif allow_greenlight_accounts %> + <% if allow_greenlight_accounts %> <%= link_to t("login"), signin_path, :class => "btn btn-outline-primary mx-2 sign-in-button" %> <% elsif Rails.configuration.loadbalanced_configuration %> <%= link_to t("login"), omniauth_login_url(:bn_launcher), :class => "btn btn-outline-primary mx-2 sign-in-button" %> diff --git a/app/views/users/ldap_signin.html.erb b/app/views/users/ldap_signin.html.erb new file mode 100644 index 00000000..3d7c301c --- /dev/null +++ b/app/views/users/ldap_signin.html.erb @@ -0,0 +1,34 @@ +
+
+
+
+
+

<%= t("login_title") %>

+
+
+ <%= form_for(:session, url: ldap_callback_path) do |f| %> +
+
+ + + + <%= f.text_field :username, class: "form-control", placeholder: t("administrator.users.table.username"), value: "" %> +
+
+
+
+ + + + <%= f.password_field :password, class: "form-control", placeholder: t("password"), value: "" %> +
+
+
+ <%= f.submit t("login"), class: "btn btn-primary btn-block signin-button" %> +
+ <% end %> +
+
+
+
+
\ No newline at end of file diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index d601fb3f..b046590a 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -15,9 +15,6 @@ Rails.application.config.omniauth_google = ENV['GOOGLE_OAUTH2_ID'].present? && E Rails.application.config.omniauth_office365 = ENV['OFFICE365_KEY'].present? && ENV['OFFICE365_SECRET'].present? -# If LDAP is enabled, override and disable allow_user_signup. -Rails.application.config.allow_user_signup = false if Rails.application.config.omniauth_ldap - SETUP_PROC = lambda do |env| SessionsController.helpers.omniauth_options env end @@ -29,19 +26,9 @@ Rails.application.config.middleware.use OmniAuth::Builder do client_secret: ENV['CLIENT_SECRET'], client_options: { site: ENV['BN_LAUNCHER_URI'] || ENV['BN_LAUNCHER_REDIRECT_URI'] }, setup: SETUP_PROC - elsif Rails.configuration.omniauth_ldap - Rails.application.config.providers << :ldap - - provider :ldap, - host: ENV['LDAP_SERVER'], - port: ENV['LDAP_PORT'] || '389', - method: ENV['LDAP_METHOD'].blank? ? :plain : ENV['LDAP_METHOD'].to_sym, - allow_username_or_email_login: true, - uid: ENV['LDAP_UID'], - base: ENV['LDAP_BASE'], - bind_dn: ENV['LDAP_BIND_DN'], - password: ENV['LDAP_PASSWORD'] else + Rails.application.config.providers << :ldap if Rails.configuration.omniauth_ldap + if Rails.configuration.omniauth_twitter Rails.application.config.providers << :twitter @@ -69,27 +56,3 @@ end OmniAuth.config.on_failure = proc { |env| OmniAuth::FailureEndpoint.new(env).redirect_to_failure } - -# Work around beacuse callback_url option causes -# omniauth.auth to be nil in the authhash when -# authenticating with LDAP. -module OmniAuthLDAPExt - def request_phase - rel_root = ENV['RELATIVE_URL_ROOT'].present? ? ENV['RELATIVE_URL_ROOT'] : '/b' - - @callback_path = nil - path = options[:callback_path] - options[:callback_path] = "#{rel_root if Rails.env == 'production'}/auth/ldap/callback" - form = super - options[:callback_path] = path - form - end -end - -module OmniAuth - module Strategies - class LDAP - prepend OmniAuthLDAPExt - end - end -end diff --git a/config/locales/en.yml b/config/locales/en.yml index f821a047..fe338331 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -302,6 +302,7 @@ en: google: Google office365: Office 365 twitter: Twitter + ldap: LDAP recaptcha: errors: recaptcha_unreachable: Oops, we failed to validate your reCAPTCHA response. Please try again. diff --git a/config/routes.rb b/config/routes.rb index a99d62cb..e0429db7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -29,6 +29,7 @@ Rails.application.routes.draw do get '/signin', to: 'users#signin', as: :signin get '/signup', to: 'users#new', as: :signup post '/signup', to: 'users#create', as: :create_user + get '/ldap_signin', to: 'users#ldap_signin', as: :ldap_signin # Redirect to terms page match '/terms', to: 'users#terms', via: [:get, :post] @@ -88,6 +89,7 @@ Rails.application.routes.draw do # Handles Omniauth authentication. match '/auth/:provider/callback', to: 'sessions#omniauth', via: [:get, :post], as: :omniauth_session get '/auth/failure', to: 'sessions#omniauth_fail' + post '/auth/ldap', to: 'sessions#ldap', as: :ldap_callback # Room resources. resources :rooms, only: [:create, :show, :destroy], param: :room_uid, path: '/' diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 3ea499c5..d8f2bbc3 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -336,4 +336,41 @@ describe SessionsController, type: :controller do expect(response).to redirect_to(root_path) end end + + describe "POST #ldap" do + it "should create and login a user with a ldap login" do + entry = Net::LDAP::Entry.new("cn=Test User,ou=people,dc=planetexpress,dc=com") + entry[:cn] = "Test User" + entry[:givenName] = "Test" + entry[:sn] = "User" + entry[:mail] = "test@example.com" + allow_any_instance_of(Net::LDAP).to receive(:bind_as).and_return([entry]) + + post :ldap, params: { + session: { + user: "test", + password: 'password', + }, + } + + u = User.last + expect(u.provider).to eql("ldap") + expect(u.email).to eql("test@example.com") + expect(@request.session[:user_id]).to eql(u.id) + end + + it "should redirect to signin on invalid credentials" do + allow_any_instance_of(Net::LDAP).to receive(:bind_as).and_return(false) + + post :ldap, params: { + session: { + user: "test", + password: 'passwor', + }, + } + + expect(response).to redirect_to(ldap_signin_path) + expect(flash[:alert]).to eq(I18n.t("invalid_credentials")) + end + end end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 5622dcb1..42bc6103 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -387,4 +387,12 @@ describe UsersController, type: :controller do expect(response).to redirect_to(root_path) end end + + context 'GET #ldap_signin' do + it "should render the ldap signin page" do + get :ldap_signin + + expect(response).to render_template(:ldap_signin) + end + end end