add cas support with a few tests

This commit is contained in:
Erik Ordway 2013-05-23 13:40:50 -07:00
parent 0f296cd42b
commit 1575ce7b10
15 changed files with 145 additions and 2 deletions

View File

@ -45,6 +45,7 @@ gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'omniauth-github'
gem 'omniauth-browserid', git: 'https://github.com/callahad/omniauth-browserid.git', branch: 'observer_api'
gem 'omniauth-cas'
gem 'oj'
gem 'pg'
# we had pain with the 3.2.13 upgrade so monkey patch the security fix

View File

@ -7,6 +7,9 @@
{{#if Discourse.SiteSettings.enable_facebook_logins}}
<button class="btn btn-social facebook" title="{{i18n login.facebook.title}}" {{action "facebookLogin" target="view"}}>{{i18n login.facebook.title}}</button>
{{/if}}
{{#if Discourse.SiteSettings.enable_cas_logins}}
<button class="btn btn-social cas" title="{{i18n login.cas.title}}" {{action "casLogin" target="view"}}>{{i18n login.cas.title}}</button>
{{/if}}
{{#if Discourse.SiteSettings.enable_twitter_logins}}
<button class="btn btn-social twitter" title="{{i18n login.twitter.title}}" {{action "twitterLogin" target="view"}}>{{i18n login.twitter.title}}</button>
{{/if}}

View File

@ -31,6 +31,7 @@ Discourse.LoginView = Discourse.ModalBodyView.extend({
hasAtLeastOneLoginButton: function() {
return Discourse.SiteSettings.enable_google_logins ||
Discourse.SiteSettings.enable_facebook_logins ||
Discourse.SiteSettings.enable_cas_logins ||
Discourse.SiteSettings.enable_twitter_logins ||
Discourse.SiteSettings.enable_yahoo_logins ||
Discourse.SiteSettings.enable_github_logins ||
@ -102,6 +103,14 @@ Discourse.LoginView = Discourse.ModalBodyView.extend({
return window.open(Discourse.getURL("/auth/facebook"), "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top);
},
casLogin: function() {
var left, top;
this.set('authenticate', 'cas');
left = this.get('lastX') - 400;
top = this.get('lastY') - 200;
return window.open("/auth/cas", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top);
},
openidLogin: function(provider) {
var left = this.get('lastX') - 400;
var top = this.get('lastY') - 200;

View File

@ -156,6 +156,9 @@
content: "f";
}
}
&.cas {
background: $cas;
}
&.twitter {
background: $twitter;
&:before {

View File

@ -121,6 +121,7 @@ $black: #000 !default;
$white: #fff !default;
$google: #5b76f7 !default;
$facebook: #3b5998 !default;
$cas: #70BA61 !default;
$twitter: #00bced !default;
$yahoo: #810293 !default;
$github: #6d6d6d !default;

View File

@ -7,7 +7,7 @@ class Users::OmniauthCallbacksController < ApplicationController
layout false
def self.types
@types ||= Enum.new(:facebook, :twitter, :google, :yahoo, :github, :persona)
@types ||= Enum.new(:facebook, :twitter, :google, :yahoo, :github, :persona, :cas)
end
# need to be able to call this
@ -142,6 +142,58 @@ class Users::OmniauthCallbacksController < ApplicationController
end
def create_or_sign_on_user_using_cas(auth_token)
logger.error "authtoken #{auth_token}"
email = "#{auth_token[:extra][:user]}@evergreen.edu"
username = auth_token[:extra][:user]
name = auth_token["uid"]
cas_user_id = auth_token["uid"]
session[:authentication] = {
cas: {
cas_user_id: cas_user_id ,
username: username
},
email: email,
email_valid: true
}
user_info = CasUserInfo.where(:cas_user_id => cas_user_id ).first
@data = {
username: username,
name: name,
email: email,
auth_provider: "CAS",
email_valid: true
}
if user_info
user = user_info.user
if user
unless user.active
user.active = true
user.save
end
log_on_user(user)
@data[:authenticated] = true
end
else
user = User.where(email: email).first
if user
CasUserInfo.create!(session[:authentication][:cas].merge(user_id: user.id))
unless user.active
user.active = true
user.save
end
log_on_user(user)
@data[:authenticated] = true
end
end
end
def create_or_sign_on_user_using_openid(auth_token)
data = auth_token[:info]

View File

@ -0,0 +1,5 @@
class CasUserInfo < ActiveRecord::Base
attr_accessible :email, :cas_user_id, :first_name, :gender, :last_name, :name, :user_id, :username, :link
belongs_to :user
end

View File

@ -140,6 +140,11 @@ class SiteSetting < ActiveRecord::Base
setting(:facebook_app_id, '')
setting(:facebook_app_secret, '')
client_setting(:enable_cas_logins, false)
setting(:cas_url, '')
setting(:cas_hostname, '')
setting(:cas_domainname, '')
client_setting(:enable_github_logins, false)
setting(:github_client_id, '')
setting(:github_client_secret, '')

View File

@ -27,6 +27,7 @@ class User < ActiveRecord::Base
has_one :twitter_user_info, dependent: :destroy
has_one :github_user_info, dependent: :destroy
has_one :cas_user_info, dependent: :destroy
belongs_to :approved_by, class_name: 'User'
has_many :group_users

View File

@ -45,4 +45,7 @@ Rails.application.config.middleware.use OmniAuth::Builder do
provider :browser_id,
:name => 'persona'
provider :cas,
:host => SiteSetting.cas_hostname
end

View File

@ -316,6 +316,9 @@ en:
facebook:
title: "with Facebook"
message: "Authenticating with Facebook (make sure pop up blockers are not enabled)"
cas:
title: "Log In with CAS"
message: "Authenticating with CAS (make sure pop up blockers are not enabled)"
yahoo:
title: "with Yahoo"
message: "Authenticating with Yahoo (make sure pop up blockers are not enabled)"

View File

@ -376,6 +376,7 @@ en:
queue_size_warning: 'The number of queued jobs is %{queue_size}, which is high. This could indicate a problem with the Sidekiq process(es), or you may need to add more Sidekiq workers.'
memory_warning: 'Your server is running with less than 1 GB of total memory. At least 1 GB of memory is recommended.'
facebook_config_warning: 'The server is configured to allow signup and log in with Facebook (enable_facebook_logins), but the app id and app secret values are not set. Go to <a href="/admin/site_settings">the Site Settings</a> and update the settings. <a href="https://github.com/discourse/discourse/wiki/The-Discourse-Admin-Quick-Start-Guide#enable-facebook-logins" target="_blank">See this guide to learn more</a>.'
cas_config_warning: 'The server is configured to allow signup and log in with CAS (enable_facebook_logins), but the hostname and domain name values are not set.'
twitter_config_warning: 'The server is configured to allow signup and log in with Twitter (enable_twitter_logins), but the key and secret values are not set. Go to <a href="/admin/site_settings">the Site Settings</a> and update the settings. <a href="https://github.com/discourse/discourse/wiki/The-Discourse-Admin-Quick-Start-Guide#enable-twitter-logins" target="_blank">See this guide to learn more</a>.'
github_config_warning: 'The server is configured to allow signup and log in with GitHub (enable_github_logins), but the client id and secret values are not set. Go to <a href="/admin/site_settings">the Site Settings</a> and update the settings. <a href="https://github.com/discourse/discourse/wiki/The-Discourse-Admin-Quick-Start-Guide" target="_blank">See this guide to learn more</a>.'
failing_emails_warning: 'There are %{num_failed_jobs} email jobs that failed. Check your config/environments/production.rb file and ensure that the config.action_mailer settings are correct. <a href="/sidekiq/retries" target="_blank">See the failed jobs in Sidekiq</a>.'
@ -503,6 +504,11 @@ en:
facebook_app_id: "App id for Facebook authentication, registered at https://developers.facebook.com/apps"
facebook_app_secret: "App secret for Facebook authentication, registered at https://developers.facebook.com/apps"
enable_cas_logins: "Enable CAS authentication"
cas_url: "Url for cas server"
cas_hostname: "Hostname for cas server"
cas_domainname: "Domain name generated email addresses for cas server"
enable_github_logins: "Enable Github authentication, requires github_client_id and github_client_secret"
github_client_id: "Client id for Github authentication, registered at https://github.com/settings/applications"
github_client_secret: "Client secret for Github authentication, registered at https://github.com/settings/applications"

View File

@ -0,0 +1,19 @@
class CreateCasUserInfos < ActiveRecord::Migration
def change
create_table :cas_user_infos do |t|
t.integer :user_id, null: false
t.string :cas_user_id, null: false
t.string :username, null: false
t.string :first_name
t.string :last_name
t.string :email
t.string :gender
t.string :name
t.string :link
t.timestamps
end
add_index :cas_user_infos, :user_id, unique: true
add_index :cas_user_infos, :cas_user_id, unique: true
end
end

View File

@ -3,7 +3,7 @@ require 'spec_helper'
describe Users::OmniauthCallbacksController do
let(:auth) { {info: {email: 'eviltrout@made.up.email', name: 'Robin Ward', uid: 123456789}, "extra" => {"raw_info" => {} } } }
let(:cas_auth) {{ uid: "caluser2", extra: {user: "caluser2"} } }
describe 'invalid provider' do
it "fails" do
@ -54,6 +54,26 @@ describe Users::OmniauthCallbacksController do
end
describe 'cas' do
before do
request.env["omniauth.auth"] = cas_auth
end
it "fails when cas logins are disabled" do
SiteSetting.stubs(:enable_cas_logins?).returns(false)
get :complete, provider: 'cas'
response.should_not be_success
end
it "succeeds when cas logins are enabled" do
SiteSetting.stubs(:enable_cas_logins?).returns(true)
get :complete, provider: 'cas'
response.should be_success
end
end
describe 'open id handler' do

View File

@ -13,6 +13,18 @@ describe "users/omniauth_callbacks/complete.html.erb" do
rendered_data["awaiting_activation"].should eq(true)
end
it "renders cas data " do
assign(:data, {username: "username", :auth_provider=> "CAS", :awaiting_activation=>true})
render
rendered_data = JSON.parse(rendered.match(/window.opener.Discourse.authenticationComplete\((.*)\)/)[1])
rendered_data["username"].should eq("username")
rendered_data["auth_provider"].should eq("CAS")
rendered_data["awaiting_activation"].should eq(true)
end
it "renders twitter data " do
assign(:data, {username: "username", :auth_provider=>"Twitter", :awaiting_activation=>true})