Commit 405e1bec
Changed files (13)
app
helpers
models
views
authentications
devise
sessions
registrations
config
public
stylesheets
test
functional
unit
helpers
app/controllers/authentications_controller.rb
@@ -8,10 +8,27 @@ class AuthenticationsController < ApplicationController
# POST /authentications
# POST /authentications.xml
def create
- auth = request.env["omniauth.auth"]
- current_user.authentications.find_or_create_by_provider_and_uid(auth['provider'], auth['uid'])
- flash[:notice] = "Authentication successful."
- redirect_to authentications_url
+ omniauth = request.env["omniauth.auth"]
+ authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
+ if authentication
+ flash[:notice] = "Signed in successfully."
+ sign_in_and_redirect(:user, authentication.user)
+ elsif current_user
+ current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid'])
+ flash[:notice] = "Authentication successful."
+ redirect_to authentications_url
+ else
+ user = User.new
+ user.apply_omniauth(omniauth)
+ if user.save
+ flash[:notice] = "Signed in successfully."
+ sign_in_and_redirect(:user, user)
+ else
+ session[:omniauth] = omniauth.except('extra')
+ redirect_to new_user_registration_url
+ end
+ end
+
end
# DELETE /authentications/1
app/controllers/registrations_controller.rb
@@ -0,0 +1,17 @@
+class RegistrationsController < Devise::RegistrationsController
+ def create
+ super
+ session[:omniauth] = nil unless @user.new_record?
+ end
+
+ private
+
+ def build_resource(*args)
+ super
+ if session[:omniauth]
+ @user.apply_omniauth(session[:omniauth])
+ @user.valid?
+ end
+ end
+end
+
app/helpers/registrations_helper.rb
@@ -0,0 +1,2 @@
+module RegistrationsHelper
+end
app/models/authentication.rb
@@ -1,3 +1,11 @@
class Authentication < ActiveRecord::Base
belongs_to :user
+
+ def provider_name
+ if provider == 'open_id'
+ "OpenID"
+ else
+ provider.titleize
+ end
+ end
end
app/models/user.rb
@@ -8,4 +8,13 @@ class User < ActiveRecord::Base
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
+
+ def apply_omniauth(omniauth)
+ self.email = omniauth['user_info']['email'] if email.blank?
+ authentications.build(:provider => omniauth['provider'], :uid => omniauth['uid'])
+ end
+
+ def password_required?
+ (authentications.empty? || !password.blank?) && super
+ end
end
app/views/authentications/index.html.erb
@@ -6,7 +6,7 @@
<% for authentication in @authentications %>
<div class="authentication">
<%= image_tag "#{authentication.provider}_32.png", :size => "32x32" %>
- <div class="provider"><%= authentication.provider.titleize %></div>
+ <div class="provider"><%= authentication.provider_name %></div>
<div class="uid"><%= authentication.uid %></div>
<%= link_to "X", authentication, :confirm => 'Are you sure you want to remove this authentication option?', :method => :delete, :class => "remove" %>
</div>
app/views/devise/sessions/new.html.erb
@@ -1,3 +1,4 @@
+
<h2>Sign in</h2>
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
@@ -13,5 +14,25 @@
<p><%= f.submit "Sign in" %></p>
<% end %>
+<%= render :partial => "devise/shared/links" %>
+
+<p>or</p>
+<h2>Sign in through one of these services</h2>
+<a href="/auth/twitter" class="auth_provider">
+ <%= image_tag "twitter_64.png", :size => "64x64", :alt => "Twitter" %>
+ Twitter
+</a>
+<a href="/auth/facebook" class="auth_provider">
+ <%= image_tag "facebook_64.png", :size => "64x64", :alt => "Facebook" %>
+ Facebook
+</a>
+<a href="/auth/google_apps" class="auth_provider">
+ <%= image_tag "google_64.png", :size => "64x64", :alt => "Google" %>
+ Google
+</a>
+<a href="/auth/open_id" class="auth_provider">
+ <%= image_tag "openid_64.png", :size => "64x64", :alt => "OpenID" %>
+ OpenID
+</a>
+<div class="clear"></div>
-<%= render :partial => "devise/shared/links" %>
\ No newline at end of file
app/views/registrations/edit.html.erb
@@ -0,0 +1,25 @@
+<h2>Edit <%= resource_name.to_s.humanize %></h2>
+
+<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
+ <%= devise_error_messages! %>
+
+ <p><%= f.label :email %><br />
+ <%= f.email_field :email %></p>
+
+ <p><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
+ <%= f.password_field :password %></p>
+
+ <p><%= f.label :password_confirmation %><br />
+ <%= f.password_field :password_confirmation %></p>
+
+ <p><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
+ <%= f.password_field :current_password %></p>
+
+ <p><%= f.submit "Update" %></p>
+<% end %>
+
+<h3>Cancel my account</h3>
+
+<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
+
+<%= link_to "Back", :back %>
app/views/registrations/new.html.erb
@@ -0,0 +1,39 @@
+<h2>Sign up</h2>
+
+<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
+ <%= devise_error_messages! %>
+
+ <p><%= f.label :email %><br />
+ <%= f.email_field :email %></p>
+
+<% if @user.password_required? %>
+ <p><%= f.label :password %><br />
+ <%= f.password_field :password %></p>
+
+ <p><%= f.label :password_confirmation %><br />
+ <%= f.password_field :password_confirmation %></p>
+<% end %>
+
+ <p><%= f.submit "Sign up" %></p>
+<% end %>
+
+<%= render :partial => "devise/shared/links" %>
+<p>or</p>
+<h2>Sign up through one of these services</h2>
+<a href="/auth/twitter" class="auth_provider">
+ <%= image_tag "twitter_64.png", :size => "64x64", :alt => "Twitter" %>
+ Twitter
+</a>
+<a href="/auth/facebook" class="auth_provider">
+ <%= image_tag "facebook_64.png", :size => "64x64", :alt => "Facebook" %>
+ Facebook
+</a>
+<a href="/auth/google_apps" class="auth_provider">
+ <%= image_tag "google_64.png", :size => "64x64", :alt => "Google" %>
+ Google
+</a>
+<a href="/auth/open_id" class="auth_provider">
+ <%= image_tag "openid_64.png", :size => "64x64", :alt => "OpenID" %>
+ OpenID
+</a>
+<div class="clear"></div>
config/routes.rb
@@ -1,11 +1,13 @@
Cake::Application.routes.draw do
+ match '/auth/:provider/callback' => 'authentications#create'
+ devise_for :users, :controllers => {:registrations => 'registrations'}
resources :authentications
-
get "dashboard/index"
-
get "home/index"
-
- devise_for :users
+ authenticate :user do
+ root :to => "home#index"
+ end
+ root :to => "devise:sessions#new"
# The priority is based upon order of creation:
# first created -> highest priority.
@@ -57,10 +59,6 @@ Cake::Application.routes.draw do
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
#root :to => "home#index"
- authenticate :user do
- root :to => "home#index"
- end
- root :to => "devise:sessions#new"
# See how all your routes lay out with "rake routes"
@@ -68,5 +66,4 @@ Cake::Application.routes.draw do
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id(.:format)))'
#
- match '/auth/:provider/callback' => 'authentications#create'
end
public/stylesheets/scaffold.css
@@ -54,3 +54,24 @@ div.field, div.actions {
font-size: 12px;
list-style: square;
}
+.auth_provider img {
+ display: block;
+}
+
+.auth_provider {
+ float: left;
+ text-decoration: none;
+ margin-right: 20px;
+ text-align: center;
+ margin-bottom: 10px;
+}
+.clear {
+ clear: both;
+ height: 0;
+ overflow: hidden;
+}
+.width100{width: 100%;}
+.width50{width: 50%;}
+.floatLeft{float:left;}
+.floatRight{float:right;}
+
test/functional/registrations_controller_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class RegistrationsControllerTest < ActionController::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
test/unit/helpers/registrations_helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class RegistrationsHelperTest < ActionView::TestCase
+end