Skip to content

Commit c461d69

Browse files
committed
Merge pull request #86 from em77/implement_omniauth-github
Implement omniauth-github
2 parents f294a36 + e065748 commit c461d69

22 files changed

+277
-15
lines changed

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ gem 'carrierwave'
1212
gem 'cloudinary'
1313

1414
# Assets
15-
gem "devise"
15+
gem 'devise'
16+
gem 'omniauth-github'
1617
gem 'autoprefixer-rails', '~> 6.1.0'
1718
gem 'bootstrap-sass', '~> 3.3.6'
1819
gem 'font-awesome-sass'

Gemfile.lock

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ GEM
122122
railties (>= 3.0.0)
123123
faker (1.5.0)
124124
i18n (~> 0.5)
125+
faraday (0.9.2)
126+
multipart-post (>= 1.2, < 3)
125127
ffi (1.9.10)
126128
font-awesome-sass (4.4.0)
127129
sass (>= 3.2)
@@ -153,6 +155,7 @@ GEM
153155
guard-rubocop (1.2.0)
154156
guard (~> 2.0)
155157
rubocop (~> 0.20)
158+
hashie (3.4.3)
156159
http-cookie (1.0.2)
157160
domain_name (~> 0.5)
158161
i18n (0.7.0)
@@ -165,6 +168,7 @@ GEM
165168
railties (>= 4.2.0)
166169
thor (>= 0.14, < 2.0)
167170
json (1.8.3)
171+
jwt (1.5.2)
168172
kaminari (0.16.3)
169173
actionpack (>= 3.0.0)
170174
activesupport (>= 3.0.0)
@@ -183,6 +187,9 @@ GEM
183187
minitest (5.8.3)
184188
momentjs-rails (2.10.6)
185189
railties (>= 3.1)
190+
multi_json (1.11.2)
191+
multi_xml (0.5.5)
192+
multipart-post (2.0.0)
186193
neat (1.7.2)
187194
bourbon (>= 4.0)
188195
sass (>= 3.3)
@@ -195,6 +202,21 @@ GEM
195202
notiffany (0.0.8)
196203
nenv (~> 0.1)
197204
shellany (~> 0.0)
205+
oauth2 (1.0.0)
206+
faraday (>= 0.8, < 0.10)
207+
jwt (~> 1.0)
208+
multi_json (~> 1.3)
209+
multi_xml (~> 0.5)
210+
rack (~> 1.2)
211+
omniauth (1.2.2)
212+
hashie (>= 1.2, < 4)
213+
rack (~> 1.0)
214+
omniauth-github (1.1.2)
215+
omniauth (~> 1.0)
216+
omniauth-oauth2 (~> 1.1)
217+
omniauth-oauth2 (1.4.0)
218+
oauth2 (~> 1.0)
219+
omniauth (~> 1.2)
198220
orm_adapter (0.5.0)
199221
parser (2.2.3.0)
200222
ast (>= 1.1, < 3.0)
@@ -359,6 +381,7 @@ DEPENDENCIES
359381
guard-rubocop
360382
jquery-rails
361383
newrelic_rpm
384+
omniauth-github
362385
pg
363386
pry
364387
rails (~> 4.2.2)

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,31 @@ Once successfully completed, this setup script will:
8888
- create and setup your database
8989
- cleanup logs and temporary files
9090

91+
__Set environment variables__
92+
93+
Omniauth is used to allow users to log in to the site using GitHub accounts. To
94+
use the GitHub API, you must set environment variables for the GitHub 'key' and
95+
'secret.'
96+
97+
You can first obtain this key/secret [through your GitHub account](https://github.com/settings/applications/new).
98+
99+
Now you need to set the environment variables on your server. The procedure will
100+
depend on your system.
101+
102+
On Unix-based systems using the bash shell, add the following to your `~/.bashrc`
103+
file, replacing the inside of the quotes with your key/secret:
104+
105+
```
106+
export GITHUB_KEY="your_key"
107+
export GITHUB_SECRET="your_secret"
108+
```
109+
110+
If using Heroku, you can set the environment variables like this:
111+
112+
```
113+
heroku config:add GITHUB_KEY=your_key GITHUB_SECRET=your_secret --app Montreal.rb
114+
```
115+
91116
#### Start your Web Server
92117

93118
You should be ready to start your webserver using:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
2+
def github
3+
@user = User.from_omniauth(request.env["omniauth.auth"])
4+
5+
if @user.persisted?
6+
sign_in_and_redirect @user, event: :authentication
7+
set_flash_message(:notice, :success, kind: "GitHub")
8+
else
9+
session["devise.github_data"] = request.env["omniauth.auth"]
10+
redirect_to new_user_registration_url
11+
end
12+
end
13+
end

app/models/user.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,26 @@
1616
# created_at :datetime
1717
# updated_at :datetime
1818
#
19-
2019
class User < ActiveRecord::Base
2120
# Include default devise modules. Others available are:
2221
# :confirmable, :lockable, :timeoutable and :omniauthable
2322
devise :database_authenticatable, :registerable,
24-
:recoverable, :rememberable, :trackable, :validatable
23+
:recoverable, :rememberable, :trackable, :validatable,
24+
:omniauthable, omniauth_providers: [:github]
25+
26+
def self.from_omniauth(auth)
27+
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
28+
user.email = auth.info.email
29+
user.password = Devise.friendly_token[0, 20]
30+
end
31+
end
32+
33+
def self.new_with_session(params, session)
34+
super.tap do |user|
35+
if data = session["devise.github_data"] &&
36+
session["devise.github_data"]["extra"]["raw_info"]
37+
user.email = data["email"] if user.email.blank?
38+
end
39+
end
40+
end
2541
end

app/views/devise/.DS_Store

6 KB
Binary file not shown.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h2>Resend confirmation instructions</h2>
2+
3+
<%= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
4+
<%= f.error_notification %>
5+
<%= f.full_error :confirmation_token %>
6+
7+
<div class="form-inputs">
8+
<%= f.input :email, required: true, autofocus: true %>
9+
</div>
10+
11+
<div class="form-actions">
12+
<%= f.button :submit, "Resend confirmation instructions" %>
13+
</div>
14+
<% end %>
15+
16+
<%= render "devise/shared/links" %>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<p>Welcome <%= @email %>!</p>
2+
3+
<p>You can confirm your account email through the link below:</p>
4+
5+
<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<p>Hello <%= @resource.email %>!</p>
2+
3+
<p>Someone has requested a link to change your password. You can do this through the link below.</p>
4+
5+
<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>
6+
7+
<p>If you didn't request this, please ignore this email.</p>
8+
<p>Your password won't change until you access the link above and create a new one.</p>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<p>Hello <%= @resource.email %>!</p>
2+
3+
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
4+
5+
<p>Click the link below to unlock your account:</p>
6+
7+
<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<h2>Change your password</h2>
2+
3+
<%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
4+
<%= f.error_notification %>
5+
6+
<%= f.input :reset_password_token, as: :hidden %>
7+
<%= f.full_error :reset_password_token %>
8+
9+
<div class="form-inputs">
10+
<%= f.input :password, label: "New password", required: true, autofocus: true, hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length) %>
11+
<%= f.input :password_confirmation, label: "Confirm your new password", required: true %>
12+
</div>
13+
14+
<div class="form-actions">
15+
<%= f.button :submit, "Change my password" %>
16+
</div>
17+
<% end %>
18+
19+
<%= render "devise/shared/links" %>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<h2>Forgot your password?</h2>
2+
3+
<%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
4+
<%= f.error_notification %>
5+
6+
<div class="form-inputs">
7+
<%= f.input :email, required: true, autofocus: true %>
8+
</div>
9+
10+
<div class="form-actions">
11+
<%= f.button :submit, "Send me reset password instructions" %>
12+
</div>
13+
<% end %>
14+
15+
<%= render "devise/shared/links" %>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<h2>Edit <%= resource_name.to_s.humanize %></h2>
2+
3+
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
4+
<%= f.error_notification %>
5+
6+
<div class="form-inputs">
7+
<%= f.input :email, required: true, autofocus: true %>
8+
9+
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
10+
<p>Currently waiting confirmation for: <%= resource.unconfirmed_email %></p>
11+
<% end %>
12+
13+
<%= f.input :password, autocomplete: "off", hint: "leave it blank if you don't want to change it", required: false %>
14+
<%= f.input :password_confirmation, required: false %>
15+
<%= f.input :current_password, hint: "we need your current password to confirm your changes", required: true %>
16+
</div>
17+
18+
<div class="form-actions">
19+
<%= f.button :submit, "Update" %>
20+
</div>
21+
<% end %>
22+
23+
<h3>Cancel my account</h3>
24+
25+
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
26+
27+
<%= link_to "Back", :back %>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<h2>Sign up</h2>
2+
3+
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
4+
<%= f.error_notification %>
5+
6+
<div class="form-inputs">
7+
<%= f.input :email, required: true, autofocus: true %>
8+
<%= f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length) %>
9+
<%= f.input :password_confirmation, required: true %>
10+
</div>
11+
12+
<div class="form-actions">
13+
<%= f.button :submit, "Sign up" %>
14+
</div>
15+
<% end %>
16+
17+
<%= render "devise/shared/links" %>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<h2>Log in</h2>
2+
3+
<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
4+
<div class="form-inputs">
5+
<%= f.input :email, required: false, autofocus: true %>
6+
<%= f.input :password, required: false %>
7+
<%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
8+
</div>
9+
10+
<div class="form-actions">
11+
<%= f.button :submit, "Log in" %>
12+
</div>
13+
<% end %>
14+
15+
<%= render "devise/shared/links" %>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<%- if controller_name != 'sessions' %>
2+
<%= link_to "Log in", new_session_path(resource_name) %><br />
3+
<% end -%>
4+
5+
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
6+
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
7+
<% end -%>
8+
9+
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
10+
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
11+
<% end -%>
12+
13+
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
14+
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
15+
<% end -%>
16+
17+
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
18+
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
19+
<% end -%>
20+
21+
<%- if devise_mapping.omniauthable? %>
22+
<%- resource_class.omniauth_providers.each do |provider| %>
23+
<%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
24+
<% end -%>
25+
<% end -%>

app/views/devise/unlocks/new.html.erb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h2>Resend unlock instructions</h2>
2+
3+
<%= simple_form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
4+
<%= f.error_notification %>
5+
<%= f.full_error :unlock_token %>
6+
7+
<div class="form-inputs">
8+
<%= f.input :email, required: true, autofocus: true %>
9+
</div>
10+
11+
<div class="form-actions">
12+
<%= f.button :submit, "Resend unlock instructions" %>
13+
</div>
14+
<% end %>
15+
16+
<%= render "devise/shared/links" %>

config/initializers/devise.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@
234234
# up on your models and hooks.
235235
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
236236

237+
config.omniauth :github, ENV["GITHUB_KEY"], ENV["GITHUB_SECRET"],
238+
scope: "user:email"
239+
237240
# ==> Warden configuration
238241
# If you want to use other strategies, that are not supported by Devise, or
239242
# change the failure app, you can configure them inside the config.warden block.

config/routes.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
root controller: DashboardManifest::ROOT_DASHBOARD, action: :index
99
end
1010

11-
devise_for :users
11+
devise_for :users,
12+
controllers: { omniauth_callbacks: "users/omniauth_callbacks" }
1213

1314
resources :events, only: [:index, :show]
1415
resources :news_items, only: [:index, :show]
@@ -17,4 +18,3 @@
1718

1819
root 'home#index'
1920
end
20-
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class AddOmniauthToUsers < ActiveRecord::Migration
2+
def change
3+
add_column :users, :provider, :string
4+
add_index :users, :provider
5+
add_column :users, :uid, :string
6+
add_index :users, :uid
7+
end
8+
end

0 commit comments

Comments
 (0)