diff --git a/Gemfile b/Gemfile
index d730ac6e194..459f49de6cd 100644
--- a/Gemfile
+++ b/Gemfile
@@ -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
diff --git a/app/assets/javascripts/discourse/templates/modal/login.js.handlebars b/app/assets/javascripts/discourse/templates/modal/login.js.handlebars
index 79665f45be1..32f55efa98d 100644
--- a/app/assets/javascripts/discourse/templates/modal/login.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/modal/login.js.handlebars
@@ -7,6 +7,9 @@
{{#if Discourse.SiteSettings.enable_facebook_logins}}
{{/if}}
+ {{#if Discourse.SiteSettings.enable_cas_logins}}
+
+ {{/if}}
{{#if Discourse.SiteSettings.enable_twitter_logins}}
{{/if}}
diff --git a/app/assets/javascripts/discourse/views/modal/login_view.js b/app/assets/javascripts/discourse/views/modal/login_view.js
index 8bf21210f47..95414e9efd5 100644
--- a/app/assets/javascripts/discourse/views/modal/login_view.js
+++ b/app/assets/javascripts/discourse/views/modal/login_view.js
@@ -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;
diff --git a/app/assets/stylesheets/components/buttons.css.scss b/app/assets/stylesheets/components/buttons.css.scss
index d65cd88dcbc..ca9e9c2f3b6 100644
--- a/app/assets/stylesheets/components/buttons.css.scss
+++ b/app/assets/stylesheets/components/buttons.css.scss
@@ -156,6 +156,9 @@
content: "f";
}
}
+ &.cas {
+ background: $cas;
+ }
&.twitter {
background: $twitter;
&:before {
diff --git a/app/assets/stylesheets/foundation/variables.scss b/app/assets/stylesheets/foundation/variables.scss
index a6bdf11a978..2f5619b7569 100644
--- a/app/assets/stylesheets/foundation/variables.scss
+++ b/app/assets/stylesheets/foundation/variables.scss
@@ -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;
diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb
index 14cf394a733..4e45f814b2a 100644
--- a/app/controllers/users/omniauth_callbacks_controller.rb
+++ b/app/controllers/users/omniauth_callbacks_controller.rb
@@ -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]
diff --git a/app/models/cas_user_info.rb b/app/models/cas_user_info.rb
new file mode 100644
index 00000000000..633566eb614
--- /dev/null
+++ b/app/models/cas_user_info.rb
@@ -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
diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
index 5a770f0d2e2..1635b3185eb 100644
--- a/app/models/site_setting.rb
+++ b/app/models/site_setting.rb
@@ -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, '')
diff --git a/app/models/user.rb b/app/models/user.rb
index a307ef3efc8..8b62665cbf6 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -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
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index 32e292f03da..18c4a8d1891 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -45,4 +45,7 @@ Rails.application.config.middleware.use OmniAuth::Builder do
provider :browser_id,
:name => 'persona'
+ provider :cas,
+ :host => SiteSetting.cas_hostname
+
end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 64ab63586fe..18eb87c4795 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -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)"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 1d4faa1d0e7..8d07f2d3787 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -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 the Site Settings and update the settings. See this guide to learn more.'
+ 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 the Site Settings and update the settings. See this guide to learn more.'
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 the Site Settings and update the settings. See this guide to learn more.'
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. See the failed jobs in Sidekiq.'
@@ -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"
diff --git a/db/migrate/20130521210140_create_cas_user_infos.rb b/db/migrate/20130521210140_create_cas_user_infos.rb
new file mode 100644
index 00000000000..befadc56aa6
--- /dev/null
+++ b/db/migrate/20130521210140_create_cas_user_infos.rb
@@ -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
diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb
index 4c6984475d1..37eb2959a77 100644
--- a/spec/controllers/omniauth_callbacks_controller_spec.rb
+++ b/spec/controllers/omniauth_callbacks_controller_spec.rb
@@ -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
diff --git a/spec/views/omniauth_callbacks/complete.html.erb_spec.rb b/spec/views/omniauth_callbacks/complete.html.erb_spec.rb
index c29c4e12c22..91f5a5aa72f 100644
--- a/spec/views/omniauth_callbacks/complete.html.erb_spec.rb
+++ b/spec/views/omniauth_callbacks/complete.html.erb_spec.rb
@@ -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})