Merge pull request #225 from joshua-arts/ldap

Add support for LDAP authentication.
This commit is contained in:
Joshua Arts 2018-07-23 15:34:42 -04:00 committed by GitHub
commit 12a448aa24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 117 additions and 58 deletions

View File

@ -47,6 +47,7 @@ gem 'bcrypt', '~> 3.1.7'
gem 'omniauth'
gem 'omniauth-twitter'
gem 'omniauth-google-oauth2'
gem 'omniauth-ldap'
gem 'omniauth-bn-launcher', '~> 0.1.0'
# BigBlueButton API wrapper.

View File

@ -111,6 +111,7 @@ GEM
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
net-ldap (0.16.1)
nio4r (2.3.1)
nokogiri (1.8.3)
mini_portile2 (~> 2.3.0)
@ -131,6 +132,11 @@ GEM
jwt (>= 1.5)
omniauth (>= 1.1.1)
omniauth-oauth2 (>= 1.5)
omniauth-ldap (2.0.0)
net-ldap (~> 0.16)
omniauth (~> 1.8.1)
pyu-ruby-sasl (~> 0.0.3.3)
rubyntlm (~> 0.6.2)
omniauth-oauth (1.1.0)
oauth
omniauth (~> 1.0)
@ -147,6 +153,7 @@ GEM
popper_js (1.12.9)
powerpack (0.1.2)
puma (3.11.4)
pyu-ruby-sasl (0.0.3.3)
rack (2.0.5)
rack-test (0.6.3)
rack (>= 1.0)
@ -210,6 +217,7 @@ GEM
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.9.0)
rubyntlm (0.6.2)
sass (3.5.6)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
@ -282,6 +290,7 @@ DEPENDENCIES
omniauth
omniauth-bn-launcher (~> 0.1.0)
omniauth-google-oauth2
omniauth-ldap
omniauth-twitter
pg (~> 0.18)
puma (~> 3.0)

View File

@ -1,6 +1,8 @@
# frozen_string_literal: true
class SessionsController < ApplicationController
skip_before_action :verify_authenticity_token, only: [:omniauth, :fail]
# GET /users/logout
def destroy
logout
@ -13,7 +15,7 @@ class SessionsController < ApplicationController
if user.try(:authenticate, session_params[:password])
login(user)
else
redirect_to root_path, notice: I18n.t("login_failed")
redirect_to root_path, notice: I18n.t("invalid_credentials")
end
end
@ -23,12 +25,12 @@ class SessionsController < ApplicationController
login(user)
rescue => e
logger.error "Error authenticating via omniauth: #{e}"
redirect_to root_path
omniauth_fail
end
# POST /auth/failure
def fail
redirect_to root_path
def omniauth_fail
redirect_to root_path, notice: I18n.t(params[:message], default: I18n.t("omniauth_error"))
end
private

View File

@ -10,6 +10,11 @@ module ApplicationHelper
end
end
# Determines which providers can show a login button in the login modal.
def iconset_providers
configured_providers & [:google, :twitter]
end
# Generates the login URL for a specific provider.
def omniauth_login_url(provider)
"#{Rails.configuration.relative_url_root}/auth/#{provider}"

View File

@ -25,10 +25,10 @@ class User < ApplicationRecord
# Provider is the customer name if in loadbalanced config mode
provider = auth['provider'] == "bn_launcher" ? auth['info']['customer'] : auth['provider']
find_or_initialize_by(social_uid: auth['uid'], provider: provider).tap do |u|
u.name = send("#{auth['provider']}_name", auth) unless u.name
u.username = send("#{auth['provider']}_username", auth) unless u.username
u.email = send("#{auth['provider']}_email", auth)
u.image = send("#{auth['provider']}_image", auth)
u.name = auth_name(auth) unless u.name
u.username = auth_username(auth) unless u.username
u.email = auth_email(auth)
u.image = auth_image(auth)
u.save!
end
end
@ -36,52 +36,32 @@ class User < ApplicationRecord
private
# Provider attributes.
def twitter_name(auth)
def auth_name(auth)
auth['info']['name']
end
def twitter_username(auth)
auth['info']['nickname']
def auth_username(auth)
case auth['provider']
when :google
auth['info']['email'].split('@').first
when :bn_launcher
auth['info']['username']
else
auth['info']['nickname']
end
end
def twitter_email(auth)
def auth_email(auth)
auth['info']['email']
end
def twitter_image(auth)
auth['info']['image'].gsub("http", "https").gsub("_normal", "")
end
def google_name(auth)
auth['info']['name']
end
def google_username(auth)
auth['info']['email'].split('@').first
end
def google_email(auth)
auth['info']['email']
end
def google_image(auth)
auth['info']['image']
end
def bn_launcher_name(auth)
auth['info']['name']
end
def bn_launcher_username(auth)
auth['info']['username']
end
def bn_launcher_email(auth)
auth['info']['email']
end
def bn_launcher_image(auth)
auth['info']['image']
def auth_image(auth)
case auth['provider']
when :twitter
auth['info']['image'].gsub("http", "https").gsub("_normal", "")
else
auth['info']['image']
end
end
end

View File

@ -30,7 +30,7 @@
<i class="dropdown-icon fas fa-cog"></i> <%= t("header.dropdown.settings") %>
<% end %>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="http://docs.bigbluebutton.org/install/greenlight.html" target="_blank">
<a class="dropdown-item" href="http://docs.bigbluebutton.org/install/greenlight-v2.html" target="_blank">
<i class="dropdown-icon far fa-question-circle"></i> <%= t("header.dropdown.help") %>
</a>
<%= link_to logout_path, class: "dropdown-item" do %>
@ -39,9 +39,11 @@
</div>
</div>
<% else %>
<% if Rails.configuration.omniauth_bn_launcher && !current_user %>
<%= link_to t("login"), "#{Rails.configuration.relative_url_root}/auth/bn_launcher", :class => "btn btn-pill btn-outline-primary mx-2" %>
<% else %>
<% if Rails.configuration.omniauth_bn_launcher %>
<%= link_to t("login"), omniauth_login_url(:bn_launcher), :class => "btn btn-pill btn-outline-primary mx-2" %>
<% elsif Rails.configuration.omniauth_ldap %>
<%= link_to t("login"), omniauth_login_url(:ldap), :class => "btn btn-pill btn-outline-primary mx-2" %>
<% else %>
<%= link_to t("login"), "#loginModal", :class => "btn btn-pill btn-outline-primary mx-2", "data-toggle": "modal" %>
<% end %>

View File

@ -7,8 +7,8 @@
<h3><%= t("login") %></h3>
</div>
<% unless configured_providers.length.zero? %>
<% configured_providers.each do |provider| %>
<% unless iconset_providers.length.zero? %>
<% iconset_providers.each do |provider| %>
<%= link_to omniauth_login_url(provider), class: "btn btn-pill btn-#{provider} btn-block" do %>
<i class="fab fa-<%= provider %>"></i>&ensp;<%= t("modal.login.with", provider: provider.capitalize) %>
<% end %>

View File

@ -1,11 +1,14 @@
# frozen_string_literal: true
# List of supported Omniauth providers.
Rails.application.config.providers = [:google, :twitter]
Rails.application.config.providers = [:google, :twitter, :ldap]
# Set which providers are configured.
Rails.application.config.omniauth_google = ENV['GOOGLE_OAUTH2_ID'].present? && ENV['GOOGLE_OAUTH2_SECRET'].present?
Rails.application.config.omniauth_twitter = ENV['TWITTER_ID'].present? && ENV['TWITTER_SECRET'].present?
Rails.application.config.omniauth_ldap = ENV['LDAP_SERVER'].present? && ENV['LDAP_UID'].present? &&
ENV['LDAP_BASE'].present? && ENV['LDAP_BIND_DN'].present? &&
ENV['LDAP_PASSWORD'].present?
Rails.application.config.omniauth_bn_launcher = Rails.configuration.loadbalanced_configuration
SETUP_PROC = lambda do |env|
@ -16,9 +19,9 @@ end
Rails.application.config.middleware.use OmniAuth::Builder do
if Rails.configuration.omniauth_bn_launcher
provider :bn_launcher, client_id: ENV['CLIENT_ID'],
client_secret: ENV['CLIENT_SECRET'],
client_options: { site: ENV['BN_LAUNCHER_REDIRECT_URI'] },
setup: SETUP_PROC
client_secret: ENV['CLIENT_SECRET'],
client_options: { site: ENV['BN_LAUNCHER_REDIRECT_URI'] },
setup: SETUP_PROC
end
provider :twitter, ENV['TWITTER_ID'], ENV['TWITTER_SECRET']
@ -28,4 +31,43 @@ Rails.application.config.middleware.use OmniAuth::Builder do
access_type: 'online',
name: 'google',
hd: ENV['GOOGLE_OAUTH2_HD'].blank? ? nil : ENV['GOOGLE_OAUTH2_HD']
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']
end
# Redirect back to login in development mode.
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

View File

@ -43,6 +43,7 @@ en:
settings: Settings
signout: Sign out
info_update_success: Information successfully updated.
invalid_credentials: Login failed due to invalid credentials. Are you sure you entered them correctly?
invite_message: "To invite someone to the meeting, send them this link:"
landing:
about: A simple front end for your BigBlueButton Open Source Web Conferencing Server.
@ -50,8 +51,8 @@ en:
video: Watch a tutorial on using Greenlight
upgrade: Show me how to upgrade to 2.0!
version: We've released a new version of Greenlight, but your database isn't compatible.
ldap_error: Unable to connect to the LDAP server. Please check your LDAP configuration in the env file and ensure your server is running.
login: Login
login_failed: Login failed due to invalid credentials. Are you sure you typed them correctly?
modal:
create_room:
auto_join: Automatically join me into the room.
@ -67,6 +68,7 @@ en:
login:
or: or
with: Login with %{provider}
omniauth_error: An error occured while authenticating with omniauth. Please try again or contact an administrator!
password: Password
recording:
email: Email Recording

View File

@ -26,7 +26,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#fail'
get '/auth/failure', to: 'sessions#omniauth_fail'
# Room resources.
resources :rooms, only: [:create, :show, :destroy], param: :room_uid, path: '/'

View File

@ -38,6 +38,22 @@ GOOGLE_OAUTH2_HD=
TWITTER_ID=
TWITTER_SECRET=
# LDAP Login Provider (optional)
#
# You can enable LDAP authentication by providing values for the variables below.
# Configuring LDAP authentication will take precedence over all other providers.
# For information about setting up LDAP, see:
#
# http://docs.bigbluebutton.org/install/greenlight-v2.html#ldap-auth
#
LDAP_SERVER=
LDAP_PORT=
LDAP_METHOD=
LDAP_UID=
LDAP_BASE=
LDAP_BIND_DN=
LDAP_PASSWORD=
# Set this to true if you want GreenLight to support user signup and login without
# Omniauth. For more information, see:
#