Skip to content

Commit

Permalink
Divlian/Google OAuth
Browse files Browse the repository at this point in the history
Added google oauth sign in flow and seeded database with sample staff/participant
  • Loading branch information
julianrkung authored and adowski committed Oct 14, 2019
1 parent 238f998 commit d085494
Show file tree
Hide file tree
Showing 40 changed files with 939 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

# Ignore master key for decrypting credentials and more.
/config/master.key
/config/secrets.yml

/public/packs
/public/packs-test
Expand Down
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.6'

# Allows for google-sign in authentication
gem 'omniauth-google-oauth2'

# Allows for all other user authentication
gem 'devise'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.0'
# Use postgresql as the database for Active Record
Expand Down
40 changes: 39 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,38 @@ GEM
tzinfo (~> 1.1)
zeitwerk (~> 2.1, >= 2.1.8)
ast (2.4.0)
bcrypt (3.1.13)
bindex (0.8.1)
bootsnap (1.4.5)
msgpack (~> 1.0)
builder (3.2.3)
byebug (11.0.1)
concurrent-ruby (1.1.5)
crass (1.0.4)
devise (4.7.1)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
erubi (1.9.0)
faraday (0.17.0)
multipart-post (>= 1.2, < 3)
ffi (1.11.1)
globalid (0.4.2)
activesupport (>= 4.2.0)
hashie (3.6.0)
i18n (1.6.0)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.3)
jbuilder (2.9.1)
activesupport (>= 4.2.0)
jwt (2.2.1)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
loofah (2.2.3)
loofah (2.3.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
Expand All @@ -90,9 +101,29 @@ GEM
mini_portile2 (2.4.0)
minitest (5.12.0)
msgpack (1.3.1)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.1.1)
nio4r (2.5.2)
nokogiri (1.10.4)
mini_portile2 (~> 2.4.0)
oauth2 (1.4.2)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
omniauth (1.9.0)
hashie (>= 3.4.6, < 3.7.0)
rack (>= 1.6.2, < 3)
omniauth-google-oauth2 (0.8.0)
jwt (>= 2.0)
omniauth (>= 1.1.1)
omniauth-oauth2 (>= 1.6)
omniauth-oauth2 (1.6.0)
oauth2 (~> 1.1)
omniauth (~> 1.9)
orm_adapter (0.5.0)
parallel (1.17.0)
parser (2.6.5.0)
ast (~> 2.4.0)
Expand Down Expand Up @@ -134,6 +165,9 @@ GEM
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
responders (3.0.0)
actionpack (>= 5.0)
railties (>= 5.0)
rubocop (0.75.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
Expand Down Expand Up @@ -174,6 +208,8 @@ GEM
tzinfo (1.2.5)
thread_safe (~> 0.1)
unicode-display_width (1.6.0)
warden (1.2.8)
rack (>= 2.0.6)
web-console (4.0.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
Expand All @@ -194,8 +230,10 @@ PLATFORMS
DEPENDENCIES
bootsnap (>= 1.4.2)
byebug
devise
jbuilder (~> 2.7)
listen (>= 3.0.5, < 3.2)
omniauth-google-oauth2
pg (>= 0.18, < 2.0)
puma (~> 3.11)
rails (~> 6.0.0)
Expand Down
3 changes: 3 additions & 0 deletions app/assets/stylesheets/omniuser.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Place all the styles related to the omniuser controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
1 change: 1 addition & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
class ApplicationController < ActionController::Base
devise_group :omniuser, contains: [:participant, :staff]
end
14 changes: 14 additions & 0 deletions app/controllers/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Omniuser::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def google_oauth2
@omniuser = Omniuser.from_omniauth(request.env['omniauth.auth'])

if @omniuser and @omniuser.persisted?
flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google'
sign_in_and_redirect @omniuser, event: :authentication
else
# Removing extra as it can overflow some session stores
session['devise.google_data'] = request.env['omniauth.auth'].except(:extra).except(:id_token)
redirect_to new_omniuser_session_path
end
end
end
4 changes: 4 additions & 0 deletions app/controllers/omniuser_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class OmniuserController < ApplicationController
def get
end
end
2 changes: 2 additions & 0 deletions app/helpers/omniuser_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module OmniuserHelper
end
29 changes: 29 additions & 0 deletions app/models/omniuser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# omniuser is the parent user type of staff and participants
# it allows for google authentication with both user types, staff and participant
# it has a type column which allows us to identify if the user is a staff member or participant
# staffs and participants inherit from omniusers

class Omniuser < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:omniauthable, omniauth_providers: [:google_oauth2]

has_one :participant
has_one :staff

def self.from_omniauth(access_token)
data = access_token.info
omniuser = Omniuser.where(email: data['email']).first

unless omniuser
omniuser = Omniuser.create(
name: data['name'],
email: data['email'],
password: Devise.friendly_token[0,20]
)
end
omniuser
end


end
19 changes: 13 additions & 6 deletions app/models/participant.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
class Participant < ApplicationRecord
has_many :casenotes
has_many :paperworks
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable

has_one :personal_questionnaire
has_one :professional_questionnaire

enum status: {r0: 0, r1: 1, r2: 2, studio: 3}
# uncomment if devise needs to be here
# devise :database_authenticatable, :registerable,
# :recoverable, :rememberable, :validatable
belongs_to :omniuser
has_many :casenotes
has_many :paperworks

has_one :personal_questionnaire
has_one :professional_questionnaire

enum status: {r0: 0, r1: 1, r2: 2, studio: 3}
end
4 changes: 4 additions & 0 deletions app/models/staff.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
class Staff < ApplicationRecord
# uncomment if devise needs to be here
# devise :database_authenticatable, :registerable,
# :recoverable, :rememberable, :validatable
belongs_to :omniuser
has_many :casenotes
has_many :paperworks
end
16 changes: 16 additions & 0 deletions app/views/devise/confirmations/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h2>Resend confirmation instructions</h2>

<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
</div>

<div class="actions">
<%= f.submit "Resend confirmation instructions" %>
</div>
<% end %>

<%= render "devise/shared/links" %>
5 changes: 5 additions & 0 deletions app/views/devise/mailer/confirmation_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<p>Welcome <%= @email %>!</p>

<p>You can confirm your account email through the link below:</p>

<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
7 changes: 7 additions & 0 deletions app/views/devise/mailer/email_changed.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<p>Hello <%= @email %>!</p>

<% if @resource.try(:unconfirmed_email?) %>
<p>We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.</p>
<% else %>
<p>We're contacting you to notify you that your email has been changed to <%= @resource.email %>.</p>
<% end %>
3 changes: 3 additions & 0 deletions app/views/devise/mailer/password_change.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>Hello <%= @resource.email %>!</p>

<p>We're contacting you to notify you that your password has been changed.</p>
8 changes: 8 additions & 0 deletions app/views/devise/mailer/reset_password_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<p>Hello <%= @resource.email %>!</p>

<p>Someone has requested a link to change your password. You can do this through the link below.</p>

<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>

<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
7 changes: 7 additions & 0 deletions app/views/devise/mailer/unlock_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<p>Hello <%= @resource.email %>!</p>

<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>

<p>Click the link below to unlock your account:</p>

<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
25 changes: 25 additions & 0 deletions app/views/devise/passwords/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<h2>Change your password</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<%= f.hidden_field :reset_password_token %>

<div class="field">
<%= f.label :password, "New password" %><br />
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em><br />
<% end %>
<%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
</div>

<div class="field">
<%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>

<div class="actions">
<%= f.submit "Change my password" %>
</div>
<% end %>

<%= render "devise/shared/links" %>
16 changes: 16 additions & 0 deletions app/views/devise/passwords/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h2>Forgot your password?</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>

<div class="actions">
<%= f.submit "Send me reset password instructions" %>
</div>
<% end %>

<%= render "devise/shared/links" %>
43 changes: 43 additions & 0 deletions app/views/devise/registrations/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>

<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>

<div class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "new-password" %>
<% if @minimum_password_length %>
<br />
<em><%= @minimum_password_length %> characters minimum</em>
<% end %>
</div>

<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>

<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "current-password" %>
</div>

<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>

<h3>Cancel my account</h3>

<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>

<%= link_to "Back", :back %>
29 changes: 29 additions & 0 deletions app/views/devise/registrations/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>

<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "new-password" %>
</div>

<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>

<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>

<%= render "devise/shared/links" %>
Loading

0 comments on commit d085494

Please sign in to comment.