Added Github authentication option, disabled by default with enable options in settings.
This commit is contained in:
parent
b50e0536c7
commit
b45f872c04
1
Gemfile
1
Gemfile
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}}
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -162,6 +162,12 @@
|
||||||
content: "Y";
|
content: "Y";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.github {
|
||||||
|
background: $github;
|
||||||
|
&:before {
|
||||||
|
content: "g";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button Sizes
|
// Button Sizes
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
class GithubUserInfo < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
end
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
|
@ -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');
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue