Skip to content

Commit

Permalink
Fixes issue hotsh#423. When a user signs up with twitter, set author.…
Browse files Browse the repository at this point in the history
…username from the name that they choose/confirm

Otherwise they'll get the "No route matches" error when they go to their profile since user_xrd_path can't be created without a username.
  • Loading branch information
carols10cents committed Dec 9, 2011
1 parent 26c24d7 commit cd35d14
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 37 deletions.
20 changes: 10 additions & 10 deletions app/controllers/auth_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ class AuthController < ApplicationController
def auth
auth = request.env['omniauth.auth']

# If an authorization is not present then that request is assumed to be for a
# new account. If a request comes from a user that is logged in, it is assumed
# to originate from the edit profile page and the request is to add a linked
# account. If the request does not come from a user it is assumed to be a new
# user and the auth information is collected to provision a new account. The
# If an authorization is not present then that request is assumed to be for
# a new account. If a request comes from a user that is logged in, it is
# assumed to originate from the edit profile page and the request is to add
# a linked account. If the request does not come from a user it is assumed
# to be a new user and the auth information is collected to provision a new
# account.
unless @auth = Authorization.find_from_hash(auth)
if logged_in?
Authorization.create_from_hash(auth, root_url, current_user)
Authorization.create_from_hash!(auth, root_url, current_user)
redirect_to "/users/#{current_user.username}/edit" and return
else

Expand All @@ -35,10 +36,9 @@ def auth
session[:oauth_secret] = auth['credentials']['secret']

# The username is checked to ensure it is unique, if it is not,
# the user is redirected to /users/new to change
# their registration information. If the username is unique
# the user is sent to the confirmation page where they will confirm
# their username and enter an email address.
# the user is informed that they need to change it.
# Everyone is redirected to /users/new to confirm that they'd like
# to have their username.
if User.first :username => auth['user_info']['nickname']
flash[:error] = "Sorry, someone else has that username. Please pick another."
end
Expand Down
22 changes: 4 additions & 18 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,31 +71,17 @@ def update
end

def new
params[:username] = session[:nickname]
@user = User.new
end

def create
# this is really stupid.
auth = {}
auth['uid'] = session[:uid]
auth['provider'] = session[:provider]
auth['user_info'] = {}
auth['user_info']['name'] = session[:name]
auth['user_info']['nickname'] = session[:nickname]
auth['user_info']['urls'] = {}
auth['user_info']['urls']['Website'] = session[:website]
auth['user_info']['description'] = session[:description]
auth['user_info']['image'] = session[:image]
auth['user_info']['email'] = session[:email]
auth['credentials'] = {}
auth['credentials']['token'] = session[:oauth_token]
auth['credentials']['secret'] = session[:oauth_secret]

params[:author] = Author.create_from_hash! auth, root_url
params[:author] = Author.create_from_session!(session, params, root_url)

@user = User.new params

if @user.save
Authorization.create_from_hash(auth, root_url, @user)
Authorization.create_from_session!(session, @user)

flash[:notice] = "Thanks! You're all signed up with #{@user.username} for your username."
session[:user_id] = @user.id
Expand Down
11 changes: 11 additions & 0 deletions app/models/author.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ def self.create_from_hash!(hash, domain)
)
end

def self.create_from_session!(session, params, domain)
create!(
:name => session[:name],
:username => params[:username],
:website => session[:website],
:bio => session[:description],
:image => session[:image],
:domain => domain
)
end

# Reset the public key lease, which will be called when the public key is
# retrieved from a trusted source.
def reset_key_lease
Expand Down
32 changes: 26 additions & 6 deletions app/models/authorization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,48 @@ def self.find_from_hash(hash)
first provider: provider, uid: uid
end

def self.create_from_session!(session, user)
# Create a new authorization with the provided details
create!(
user: user,
uid: session[:uid],
provider: session[:provider],
nickname: session[:nickname],
oauth_token: session[:oauth_token],
oauth_secret: session[:oauth_secret]
)
end

# Creates an authorization from a sucessful omniauth authentication response
def self.create_from_hash(hash, base_uri, user = nil)
def self.create_from_hash!(hash, base_uri, user = nil)

# If there isn't a user, create a user and author.
if user.nil?
domain = base_uri[/\:\/\/(.*?)\//, 1]

author = Author.create_from_hash!(hsh, domain)
user = User.create(:author => author,
:username => author.username
)
user = User.create(
:author => author,
:username => author.username
)
end

# Grab the user information from the hash
uid, provider, nickname = hash['uid'], hash['provider'], hash['user_info']['nickname']

# Grab teh credentials, including token and secret, from the hash
# Grab the credentials, including token and secret, from the hash
credentials = hash['credentials']
token, secret = credentials['token'], credentials['secret']

# Create a new authorization with the provided details
create! user: user, uid: uid, provider: provider, nickname: nickname, oauth_token: token, oauth_secret: secret
create!(
user: user,
uid: uid,
provider: provider,
nickname: nickname,
oauth_token: token,
oauth_secret: secret
)
end

timestamps!
Expand Down
2 changes: 1 addition & 1 deletion app/views/users/new.haml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- content_for :title do
Pick a new username
Pick a username

- content_for :top do
= render :partial => "users/errors", :locals => {:user => @user}
Expand Down
36 changes: 35 additions & 1 deletion test/acceptance/auth_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ def log_in_new_email_user

# TODO: Add one for logging in with twitter
it "signs up with twitter" do
omni_mock("twitter_user", {:uid => 78654, :token => "1111", :secret => "2222"})
omni_mock("twitter_user", {
:uid => 78654,
:token => "1111",
:secret => "2222"
})
visit '/auth/twitter'

assert_match /\/users\/new/, page.current_url
Expand All @@ -76,6 +80,36 @@ def log_in_new_email_user
assert_equal "2222", auth.oauth_secret
end

it "has your username already" do
omni_mock("my_name_is_jonas", {
:uid => 78654,
:token => "1111",
:secret => "2222"
})
visit '/auth/twitter'

assert has_field?("username", :with => "my_name_is_jonas")
end

it "sets the author's username for the user_xrd_path (issue #423)" do
omni_mock("weezer", {
:uid => 78654,
:token => "1111",
:secret => "2222"
})
visit '/auth/twitter'

click_button "Finish Signup"
u = User.first(:username => "weezer")

within "#sidebar" do
assert has_content?(u.username)
click_link "@#{u.username}"
end

assert has_no_content?("No route matches")
end

it "notifies the user of invalid credentials" do
omni_error_mock(:invalid_credentials, :provider => :twitter)

Expand Down
2 changes: 1 addition & 1 deletion test/models/authorization_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

it "can be created from a hash" do
auth = auth_response(@u.username)
a = Authorization.create_from_hash(auth, "/", @u)
a = Authorization.create_from_hash!(auth, "/", @u)

assert_equal auth["uid"], a.uid
assert_equal auth["provider"], a.provider
Expand Down

0 comments on commit cd35d14

Please sign in to comment.