Added Github authentication option, disabled by default with enable options in settings.

This commit is contained in:
nverba 2013-02-26 04:28:32 +00:00 committed by nverba
parent b50e0536c7
commit b45f872c04
18 changed files with 170 additions and 1 deletions

View File

@ -35,6 +35,7 @@ gem "omniauth-openid"
gem "openid-redis-store" gem "openid-redis-store"
gem "omniauth-facebook" gem "omniauth-facebook"
gem "omniauth-twitter" gem "omniauth-twitter"
gem "omniauth-github"
gem 'oj' gem 'oj'
gem 'pbkdf2' gem 'pbkdf2'
gem 'pg' gem 'pg'

View File

@ -279,6 +279,9 @@ GEM
rack rack
omniauth-facebook (1.4.1) omniauth-facebook (1.4.1)
omniauth-oauth2 (~> 1.1.0) omniauth-oauth2 (~> 1.1.0)
omniauth-github (1.1.0)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.1)
omniauth-oauth (1.0.1) omniauth-oauth (1.0.1)
oauth oauth
omniauth (~> 1.0) omniauth (~> 1.0)
@ -489,6 +492,7 @@ DEPENDENCIES
oj oj
omniauth omniauth
omniauth-facebook omniauth-facebook
omniauth-github
omniauth-openid omniauth-openid
omniauth-twitter omniauth-twitter
openid-redis-store openid-redis-store

View File

@ -5,6 +5,9 @@
<br> <br>
<button class="btn btn-social twitter" title="{{i18n login.twitter.title}}" {{action "twitterLogin" target="view"}}>{{i18n login.twitter.title}}</button> <button class="btn btn-social twitter" title="{{i18n login.twitter.title}}" {{action "twitterLogin" target="view"}}>{{i18n login.twitter.title}}</button>
<button class="btn btn-social yahoo" title="{{i18n login.yahoo.title}}" {{action openidLogin "yahoo" target="view"}}>{{i18n login.yahoo.title}}</button> <button class="btn btn-social yahoo" title="{{i18n login.yahoo.title}}" {{action openidLogin "yahoo" target="view"}}>{{i18n login.yahoo.title}}</button>
{{#if Discourse.SiteSettings.enable_github_logins}}
<button class="btn btn-social github" title="{{i18n login.github.title}}" {{action "githubLogin" target="view"}}>{{i18n login.github.title}}</button>
{{/if}}
</div> </div>
<h3 style="text-align:center; margin-bottom:10px;"> <h3 style="text-align:center; margin-bottom:10px;">
{{i18n login.or}} {{i18n login.or}}

View File

@ -101,6 +101,14 @@ Discourse.LoginView = Discourse.ModalBodyView.extend({
} }
}, },
githubLogin: function() {
var left, top;
this.set('authenticate', 'github');
left = this.get('lastX') - 400;
top = this.get('lastY') - 200;
return window.open("/auth/github", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top);
},
authenticationComplete: function(options) { authenticationComplete: function(options) {
if (options.awaiting_approval) { if (options.awaiting_approval) {
this.flash(Em.String.i18n('login.awaiting_approval'), 'success'); this.flash(Em.String.i18n('login.awaiting_approval'), 'success');

View File

@ -162,6 +162,12 @@
content: "Y"; content: "Y";
} }
} }
&.github {
background: $github;
&:before {
content: "g";
}
}
} }
// Button Sizes // Button Sizes

View File

@ -123,6 +123,7 @@ $google: #5b76f7 !default;
$facebook: #3b5998 !default; $facebook: #3b5998 !default;
$twitter: #00bced !default; $twitter: #00bced !default;
$yahoo: #810293 !default; $yahoo: #810293 !default;
$github: #6d6d6d !default;
// Layout dimensions // Layout dimensions

View File

@ -19,6 +19,8 @@ class Users::OmniauthCallbacksController < ApplicationController
create_or_sign_on_user_using_twitter(auth_token) create_or_sign_on_user_using_twitter(auth_token)
when "google", "yahoo" when "google", "yahoo"
create_or_sign_on_user_using_openid(auth_token) create_or_sign_on_user_using_openid(auth_token)
when "github"
create_or_sign_on_user_using_github(auth_token)
end end
end end
@ -169,4 +171,35 @@ class Users::OmniauthCallbacksController < ApplicationController
end end
end end
def create_or_sign_on_user_using_github(auth_token)
data = auth_token[:info]
screen_name = data["nickname"]
github_user_id = auth_token["uid"]
session[:authentication] = {
github_user_id: github_user_id,
github_screen_name: screen_name
}
user_info = GithubUserInfo.where(:github_user_id => github_user_id).first
@data = {
username: screen_name,
auth_provider: "Github"
}
if user_info
if user_info.user.active
log_on_user(user_info.user)
@data[:authenticated] = true
else
@data[:awaiting_activation] = true
# send another email ?
end
else
@data[:name] = screen_name
end
end
end end

View File

@ -177,6 +177,10 @@ class UsersController < ApplicationController
if auth[:facebook].present? and FacebookUserInfo.find_by_facebook_user_id(auth[:facebook][:facebook_user_id]).nil? if auth[:facebook].present? and FacebookUserInfo.find_by_facebook_user_id(auth[:facebook][:facebook_user_id]).nil?
FacebookUserInfo.create!(auth[:facebook].merge(user_id: user.id)) FacebookUserInfo.create!(auth[:facebook].merge(user_id: user.id))
end end
if auth[:github_user_id] && auth[:github_screen_name] && GithubUserInfo.find_by_github_user_id(auth[:github_user_id]).nil?
GithubUserInfo.create(:user_id => user.id, :screen_name => auth[:github_screen_name], :github_user_id => auth[:github_user_id])
end
end end

View File

@ -0,0 +1,3 @@
class GithubUserInfo < ActiveRecord::Base
belongs_to :user
end

View File

@ -113,6 +113,10 @@ class SiteSetting < ActiveRecord::Base
setting(:facebook_app_id, '') setting(:facebook_app_id, '')
setting(:facebook_app_secret, '') setting(:facebook_app_secret, '')
client_setting(:enable_github_logins, false)
setting(:github_client_id, '')
setting(:github_client_secret, '')
setting(:enforce_global_nicknames, true) setting(:enforce_global_nicknames, true)
setting(:discourse_org_access_key, '') setting(:discourse_org_access_key, '')
setting(:enable_s3_uploads, false) setting(:enable_s3_uploads, false)

View File

@ -21,6 +21,7 @@ class User < ActiveRecord::Base
has_many :user_visits has_many :user_visits
has_many :invites has_many :invites
has_one :twitter_user_info has_one :twitter_user_info
has_one :github_user_info
belongs_to :approved_by, class_name: 'User' belongs_to :approved_by, class_name: 'User'
validates_presence_of :username validates_presence_of :username

View File

@ -27,4 +27,8 @@ Rails.application.config.middleware.use OmniAuth::Builder do
SiteSetting.twitter_consumer_key, SiteSetting.twitter_consumer_key,
SiteSetting.twitter_consumer_secret SiteSetting.twitter_consumer_secret
provider :github,
SiteSetting.github_client_id,
SiteSetting.github_client_secret
end end

View File

@ -248,6 +248,9 @@ en:
yahoo: yahoo:
title: "Log In with Yahoo" title: "Log In with Yahoo"
message: "Authenticating with Yahoo (make sure pop up blockers are not enabled)" message: "Authenticating with Yahoo (make sure pop up blockers are not enabled)"
github:
title: "Log In with Github"
message: "Authenticating with Github (make sure pop up blockers are not enabled)"
composer: composer:
saving_draft_tip: "saving" saving_draft_tip: "saving"

View File

@ -310,6 +310,10 @@ en:
facebook_app_id: "App id for Facebook authentication, registered at https://developers.facebook.com/apps" 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" facebook_app_secret: "App secret for Facebook authentication, registered at https://developers.facebook.com/apps"
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"
allow_import: "Allow import, which can replace ALL site data; leave false unless you plan to do imports" allow_import: "Allow import, which can replace ALL site data; leave false unless you plan to do imports"
active_user_rate_limit_secs: "How frequently we update the 'last_seen_at' field, in seconds" active_user_rate_limit_secs: "How frequently we update the 'last_seen_at' field, in seconds"

View File

@ -0,0 +1,13 @@
class AddGithubUserInfo < ActiveRecord::Migration
def change
create_table :github_user_infos do |t|
t.integer :user_id, :null => false
t.string :screen_name, :null => false
t.integer :github_user_id, :null => false
t.timestamps
end
add_index :github_user_infos, [:github_user_id], :unique => true
add_index :github_user_infos, [:user_id], :unique => true
end
end

View File

@ -308,6 +308,39 @@ CREATE SEQUENCE facebook_user_infos_id_seq
ALTER SEQUENCE facebook_user_infos_id_seq OWNED BY facebook_user_infos.id; ALTER SEQUENCE facebook_user_infos_id_seq OWNED BY facebook_user_infos.id;
--
-- Name: github_user_infos; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE github_user_infos (
id integer NOT NULL,
user_id integer NOT NULL,
screen_name character varying(255) NOT NULL,
github_user_id integer NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
--
-- Name: github_user_infos_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE github_user_infos_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: github_user_infos_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE github_user_infos_id_seq OWNED BY github_user_infos.id;
-- --
-- Name: incoming_links; Type: TABLE; Schema: public; Owner: -; Tablespace: -- Name: incoming_links; Type: TABLE; Schema: public; Owner: -; Tablespace:
-- --
@ -1310,6 +1343,13 @@ ALTER TABLE ONLY email_tokens ALTER COLUMN id SET DEFAULT nextval('email_tokens_
ALTER TABLE ONLY facebook_user_infos ALTER COLUMN id SET DEFAULT nextval('facebook_user_infos_id_seq'::regclass); ALTER TABLE ONLY facebook_user_infos ALTER COLUMN id SET DEFAULT nextval('facebook_user_infos_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY github_user_infos ALTER COLUMN id SET DEFAULT nextval('github_user_infos_id_seq'::regclass);
-- --
-- Name: id; Type: DEFAULT; Schema: public; Owner: - -- Name: id; Type: DEFAULT; Schema: public; Owner: -
-- --
@ -1560,6 +1600,14 @@ ALTER TABLE ONLY topics
ADD CONSTRAINT forum_threads_pkey PRIMARY KEY (id); ADD CONSTRAINT forum_threads_pkey PRIMARY KEY (id);
--
-- Name: github_user_infos_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY github_user_infos
ADD CONSTRAINT github_user_infos_pkey PRIMARY KEY (id);
-- --
-- Name: incoming_links_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- Name: incoming_links_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
-- --
@ -1888,6 +1936,20 @@ CREATE UNIQUE INDEX index_forum_thread_users_on_forum_thread_id_and_user_id ON t
CREATE INDEX index_forum_threads_on_bumped_at ON topics USING btree (bumped_at DESC); CREATE INDEX index_forum_threads_on_bumped_at ON topics USING btree (bumped_at DESC);
--
-- Name: index_github_user_infos_on_github_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE UNIQUE INDEX index_github_user_infos_on_github_user_id ON github_user_infos USING btree (github_user_id);
--
-- Name: index_github_user_infos_on_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE UNIQUE INDEX index_github_user_infos_on_user_id ON github_user_infos USING btree (user_id);
-- --
-- Name: index_invites_on_email_and_invited_by_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- Name: index_invites_on_email_and_invited_by_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
-- --
@ -2539,4 +2601,6 @@ INSERT INTO schema_migrations (version) VALUES ('20130213021450');
INSERT INTO schema_migrations (version) VALUES ('20130213203300'); INSERT INTO schema_migrations (version) VALUES ('20130213203300');
INSERT INTO schema_migrations (version) VALUES ('20130221215017'); INSERT INTO schema_migrations (version) VALUES ('20130221215017');
INSERT INTO schema_migrations (version) VALUES ('20130226015336');

View File

@ -27,6 +27,7 @@ The following Ruby Gems are used in Discourse:
* [omniauth-openid](https://github.com/intridea/omniauth-openid) * [omniauth-openid](https://github.com/intridea/omniauth-openid)
* [omniauth-facebook](https://github.com/mkdynamic/omniauth-facebook) * [omniauth-facebook](https://github.com/mkdynamic/omniauth-facebook)
* [omniauth-twitter](https://github.com/arunagw/omniauth-twitter) * [omniauth-twitter](https://github.com/arunagw/omniauth-twitter)
* [omniauth-github](https://github.com/intridea/omniauth-github)
* [has_ip_address](https://rubygems.org/gems/has_ip_address) * [has_ip_address](https://rubygems.org/gems/has_ip_address)
* [vestal_versions](https://rubygems.org/gems/vestal_versions) * [vestal_versions](https://rubygems.org/gems/vestal_versions)
* [uglifier](https://rubygems.org/gems/uglifier) * [uglifier](https://rubygems.org/gems/uglifier)

View File

@ -37,6 +37,18 @@ describe "users/omniauth_callbacks/complete.html.erb" do
rendered_data["auth_provider"].should eq("OpenId") rendered_data["auth_provider"].should eq("OpenId")
rendered_data["awaiting_activation"].should eq(true) rendered_data["awaiting_activation"].should eq(true)
end end
it "renders github data " do
assign(:data, {:username =>"username", :auth_provider=>"Github", :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("Github")
rendered_data["awaiting_activation"].should eq(true)
end
end end