Permalink
Browse files

Added ability to login to root domain. A token is created then the us…

…er is signed out of the root domain and redirected to their subdomain. The token is validated and the user is signed in to the subdomain. Cleaned up helpers, routes, readme and views to account for new login methods.
  • Loading branch information...
1 parent 65d8a86 commit 8b2a441bf63e7e6cbef01ff649d9fd83c855d422 @salex salex committed Oct 26, 2010
View
@@ -14,7 +14,11 @@ Routes and associations were modified:
<pre>
devise_for :users
- resources :users, :only => [:index, :show]
+ resources :users, :only => [:index, :show] do
+ member do
+ get :valid
+ end
+ end
resources :subdomains, :only => [:index, :show]
constraints(SubdomainRoute) do
match '/' => 'sites#index'
@@ -29,7 +33,6 @@ User and subdomains are no longer nested, but associated.
<pre><code>
class Subdomain < ActiveRecord::Base
has_many :users
- has_friendly_id :name, :use_slug => true, :strip_non_ascii => true
validates_uniqueness_of :name, :case_sensitive => false
validates_presence_of :name
end
@@ -38,19 +41,40 @@ User and subdomains are no longer nested, but associated.
belongs_to :subdomain
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
- validates_presence_of :name, :subdomain_name
+ validates_presence_of :name
+ validates_presence_of :subdomain_name, :on => :create # used to create a subdomain
validates_uniqueness_of :email, :case_sensitive => false
- attr_accessible :name, :subdomain_name, :email, :password, :password_confirmation, :remember_me
- #has_friendly_id :subdomain_name, :use_slug => true, :strip_non_ascii => true
+ attr_accessor :subdomain_name # used to create a subdomain
+ attr_accessible :name, :subdomain_name, :email, :password, :password_confirmation, :loginable_token
before_create :create_subdomain
+ after_create :update_subdomain_owner
+
+ def self.valid?(params)
+ token_user = self.where(:loginable_token => params[:id]).first
+ if token_user
+ token_user.loginable_token = nil
+ token_user.save
+ end
+ return token_user
+ end
private
def create_subdomain
+ # get or create a subdomain on creating a new user
self.subdomain = Subdomain.find_by_name(self.subdomain_name)
- self.subdomain ||= Subdomain.create!(:name => self.subdomain_name, :user_id => self.id)
+ self.subdomain ||= Subdomain.create!(:name => self.subdomain_name)
end
-
+
+ def update_subdomain_owner
+ # set owner of subdomain to user that created it
+ subdomain = self.subdomain
+ if subdomain && subdomain.user_id.nil?
+ subdomain.user_id = self.id
+ subdomain.save
+ end
+ end
+
end
@@ -65,16 +89,17 @@ The model names were not changed, but take on different roles. List of other cha
* Subdomain still has user_id and indicates who created the subdomain (assume subdomain admin)
* A helper method "current_subdomain" was added to controllers/application.rb to check if subdomain exists
* Another helper method "check_my_domain(subdomain)" will check a passed subdomain against the current domain. Subdomain is kind of the root table, all major tables should be belong to subdomain and this check is there to prevent url modification (edit member not belonging to your domain). It will redirect to an "opps" action in the site controller.
-* Sign-in has been removed if no subdomain exists. If you modifiy the url and sign_in without a subdomain. It will log you in, but then immediately log you out and redirect to the subdomain sign_in form. I can't seem to get the flash notice to work in this area.
-** I've made a few attempts to sign-in at the root level and redirect to the subdomain and create a session there, but failed! If anyone has any ideas on how to do this with devise, you are more than welcome to give it a try.
-** Send sign-in parameters to subdomain with a CURL post ofter sign-out of root domain?
+* <del>Sign-in has been removed if no subdomain exists. If you modifiy the url and sign_in without a subdomain. It will log you in, but then immediately log you out and redirect to the subdomain sign_in form. I can't seem to get the flash notice to work in this area.</del>
+* If you sign-in to the root domain.
+** A token is saved in the users record. You are signed_out of the root domain and redirected a user/valid action in the subdomin.
+** The valid action will check the token and if found, will clear the toke and sign-in the user to the subdomain.
* If you register without a subdomain, it will be created when the user is created. If it exists, you are added as a user of that subdomain (TODO this should be fixed to reject adding user from sign_up without subdomain, if it exists)
* If you register in a subdomain, you are added as a the users of that subdomain.
P.S. I am not a novice at Rails, but don't consider myself experienced.
-Installation (I think!)
+Installation
* git clone
* bundle install
@@ -21,4 +21,28 @@ def check_my_subdomain(subdomain)
end
end
+
+ def after_sign_in_path_for(resource_or_scope)
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
+ subdomain_name = current_user.subdomain.name
+ if current_subdomain.nil?
+ # logout of root domain and login by token to subdomain
+ token = Devise.friendly_token
+ current_user.loginable_token = token
+ current_user.save
+ sign_out(current_user)
+ flash[:notice] = nil
+ home_path = valid_user_url(token, :subdomain => subdomain_name)
+ return home_path
+ else
+ if subdomain_name != current_subdomain.name
+ # user not part of current_subdomain
+ sign_out(current_user)
+ flash[:notice] = nil
+ flash[:alert] = "Sorry, invalid user or password for subdomain"
+ end
+ end
+ super
+ end
+
end
@@ -1,10 +1,5 @@
class HomeController < ApplicationController
def index
- if current_user
- subdomain = current_user.subdomain.name
- sign_out(current_user)
- redirect_to new_user_session_url( :subdomain => subdomain), :notice => "Please sign-in to your subdomain account"
- end
end
end
@@ -10,5 +10,15 @@ def show
check_my_subdomain(@user.subdomain.name)
end
end
-
+
+ def valid
+ token_user = User.valid?(params)
+ if token_user
+ sign_in(:user, token_user)
+ flash[:notice] = "You have been logged in"
+ else
+ flash[:alert] = "Login could not be validated"
+ end
+ redirect_to :root
+ end
end
@@ -1,6 +1,5 @@
module UrlHelper
def with_subdomain(subdomain)
- puts "Now is the time " + subdomain.inspect
subdomain = (subdomain || "")
subdomain += "." unless subdomain.empty?
View
@@ -1,6 +1,5 @@
class Subdomain < ActiveRecord::Base
has_many :users
- has_friendly_id :name, :use_slug => true, :strip_non_ascii => true
validates_uniqueness_of :name, :case_sensitive => false
validates_presence_of :name
end
View
@@ -2,16 +2,45 @@ class User < ActiveRecord::Base
belongs_to :subdomain
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
- validates_presence_of :name, :subdomain_name
+ validates_presence_of :name
+ validates_presence_of :subdomain_name, :on => :create # used to create a subdomain
validates_uniqueness_of :email, :case_sensitive => false
- attr_accessor :subdomain_name
- attr_accessible :name, :subdomain_name, :email, :password, :password_confirmation, :remember_me
- # has_friendly_id :subdomain_name, :use_slug => true, :strip_non_ascii => true
+ attr_accessor :subdomain_name # used to create a subdomain
+ attr_accessible :name, :subdomain_name, :email, :password, :password_confirmation, :loginable_token
before_create :create_subdomain
+ after_create :update_subdomain_owner
+
+ def self.valid?(params)
+ token_user = self.where(:loginable_token => params[:id]).first
+ if token_user
+ token_user.loginable_token = nil
+ token_user.save
+ end
+ return token_user
+ end
private
+
def create_subdomain
+ # get or create a subdomain on creating a new user
self.subdomain = Subdomain.find_by_name(self.subdomain_name)
- self.subdomain ||= Subdomain.create!(:name => self.subdomain_name, :user_id => self.id)
+ self.subdomain ||= Subdomain.create!(:name => self.subdomain_name)
+ end
+
+ def update_subdomain_owner
+ # set owner of subdomain to user that created it
+ subdomain = self.subdomain
+ if subdomain && subdomain.user_id.nil?
+ subdomain.user_id = self.id
+ subdomain.save
+ end
end
+
end
+
+
+ # def self.find_for_authentication(conditions={})
+ # #conditions[:active] = true
+ # logger.info conditions.inspect
+ # super
+ # end
@@ -2,13 +2,7 @@
<li>
<%= link_to('Logout', destroy_user_session_path) %>
</li>
-<% else
- if !current_subdomain.nil?%>
- <li>
- <%= link_to('Login', new_user_session_path) %>
- </li>
- <% end
-end %>
+<% end %>
<% if !current_subdomain.nil?%>
<li>
User:
@@ -6,4 +6,7 @@
<li>
<%= link_to('Sign up', new_user_registration_path) %>
</li>
+ <li>
+ <%= link_to('Login', new_user_session_path) %>
+ </li>
<% end %>
@@ -4,9 +4,9 @@
<%= devise_error_messages! %>
<% if current_subdomain %>
- <%= f.hidden_field :subdomain_name, :value => current_subdomain.name %>
+ <%= f.hidden_field :subdomain_name, :value => current_subdomain.name %>
<% else%>
- <p><%= f.label :subdomain %>
+ <p><%= f.label :subdomain %>
<br /><%= f.text_field :subdomain_name%></p>
<% end %>
@@ -1,2 +1,3 @@
<h1>Rails3-Subdomain-Devise</h1>
-<p><%= link_to "View List of Users", users_path %></p>
+<p><%= link_to "View List of all Users", users_path %></p>
+<p><%= link_to "View List of subdomains", subdomains_path %></p>
View
@@ -1,6 +1,10 @@
Rails3SubdomainDevise::Application.routes.draw do
devise_for :users
- resources :users, :only => [:index, :show]
+ resources :users, :only => [:index, :show] do
+ member do
+ get :valid
+ end
+ end
resources :subdomains, :only => [:index, :show]
constraints(SubdomainRoute) do
match '/' => 'sites#index'
View
@@ -10,19 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20100930104337) do
-
- create_table "slugs", :force => true do |t|
- t.string "name"
- t.integer "sluggable_id"
- t.integer "sequence", :default => 1, :null => false
- t.string "sluggable_type", :limit => 40
- t.string "scope"
- t.datetime "created_at"
- end
-
- add_index "slugs", ["name", "sluggable_type", "sequence", "scope"], :name => "index_slugs_on_n_s_s_and_s", :unique => true
- add_index "slugs", ["sluggable_id"], :name => "index_slugs_on_sluggable_id"
+ActiveRecord::Schema.define(:version => 20101024200552) do
create_table "subdomains", :force => true do |t|
t.string "name"
@@ -46,15 +34,15 @@
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "name"
- t.string "loginable_type", :limit => 40
- t.integer "loginable_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "subdomain_id"
+ t.string "loginable_token"
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
add_index "users", ["subdomain_id"], :name => "index_users_on_subdomain_id"
-
+ add_index "users", ["loginable_token"], :name => "index_users_on_loginable_token"
+
end
View
@@ -6,16 +6,13 @@
# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
# Mayor.create(:name => 'Daley', :city => cities.first)
puts 'SETTING UP EXAMPLE USERS'
-user1 = User.create! :name => 'Foo First User', :subdomain_name => "foo", :email => 'user@test.com', :password => 'please', :password_confirmation => 'please'
+user1 = User.create! :name => 'Foo First User', :subdomain_name => "foo", :email => 'user1@test.com', :password => 'please', :password_confirmation => 'please'
puts 'New user created: ' << user1.name
-user2 = User.create! :name => 'Other User', :subdomain_name => "bar", :email => 'otheruser@test.com', :password => 'please', :password_confirmation => 'please'
+user2 = User.create! :name => 'Bar First User', :subdomain_name => "bar", :email => 'user2@test.com', :password => 'please', :password_confirmation => 'please'
puts 'New user created: ' << user2.name
-# subdomains creation removed because they are created automaticaly by user signup left only the display
-puts 'SETTING UP EXAMPLE SUBDOMAINS'
-# subdomain1 = Subdomain.create! :name => 'foo', :user_id => user1.id
-puts 'Created subdomain: ' << user1.subdomain.name
-# subdomain2 = Subdomain.create! :name => 'bar', :user_id => user2.id
-puts 'Created subdomain: ' << user2.subdomain.name
+user3 = User.create! :name => 'Foo Second User', :subdomain_name => "foo", :email => 'user3@test.com', :password => 'please', :password_confirmation => 'please'
+puts 'New user created: ' << user3.name
+user4 = User.create! :name => 'Bar Second User', :subdomain_name => "bar", :email => 'user4@test.com', :password => 'please', :password_confirmation => 'please'
+puts 'New user created: ' << user4.name
-user3 = User.create! :name => 'Foo Second User', :subdomain_name => "foo", :email => 'user2@test.com', :password => 'please', :password_confirmation => 'please'
-user3 = User.create! :name => 'Foo Third User', :subdomain_name => "foo", :email => 'user3@test.com', :password => 'please', :password_confirmation => 'please'
+# subdomains creation removed because they are created automaticaly by user signup left only the display

0 comments on commit 8b2a441

Please sign in to comment.