add twitter oauth linking

This commit is contained in:
Carl Chenet 2017-05-23 10:41:09 +02:00
parent b4f0f57df9
commit c9b5ec10e3
5 changed files with 96 additions and 1 deletions

View File

@ -171,7 +171,7 @@ class SettingsController < ApplicationController
def github_callback
if !session[:github_state].present? || !params[:code].present? ||
(params[:state].to_s != session[:github_state].to_s)
flash[:error] = "No OAuth state"
flash[:error] = "Invalid OAuth state"
return redirect_to "/settings"
end
@ -199,6 +199,45 @@ class SettingsController < ApplicationController
return redirect_to "/settings"
end
def twitter_auth
session[:twitter_state] = SecureRandom.hex
return redirect_to Twitter.oauth_auth_url(session[:twitter_state])
end
def twitter_callback
if !session[:twitter_state].present? ||
(params[:state].to_s != session[:twitter_state].to_s)
flash[:error] = "Invalid OAuth state"
return redirect_to "/settings"
end
session.delete(:twitter_state)
tok, sec, username = Twitter.token_secret_and_user_from_token_and_verifier(
params[:oauth_token], params[:oauth_verifier])
if tok.present? && username.present?
@user.twitter_oauth_token = tok
@user.twitter_oauth_token_secret = sec
@user.twitter_username = username
@user.save!
flash[:success] = "Your account has been linked to Twitter user @" <<
"#{username}."
else
return twitter_disconnect
end
return redirect_to "/settings"
end
def twitter_disconnect
@user.twitter_oauth_token = nil
@user.twitter_username = nil
@user.twitter_oauth_token_secret = nil
@user.save!
flash[:success] = "Your Twitter association has been removed."
return redirect_to "/settings"
end
private
def user_params

View File

@ -48,6 +48,9 @@ class User < ActiveRecord::Base
s.string :totp_secret
s.string :github_oauth_token
s.string :github_username
s.string :twitter_oauth_token
s.string :twitter_oauth_token_secret
s.string :twitter_username
end
validates :email, :format => { :with => /\A[^@ ]+@[^@ ]+\.[^@ ]+\Z/ },
@ -121,6 +124,10 @@ class User < ActiveRecord::Base
h[:github_username] = self.github_username
end
if self.twitter_username.present?
h[:twitter_username] = self.twitter_username
end
h
end

View File

@ -246,6 +246,21 @@
</div>
<% end %>
<% if Twitter.enabled? %>
<div class="boxline">
<%= label_tag :twitter_username, "Twitter:", :class => "required" %>
<% if @edit_user.twitter_username.present? %>
Linked to
<strong><a href="https://twitter.com/<%= h(@edit_user.twitter_username)
%>">@<%= h(@edit_user.twitter_username) %></a></strong>
(<%= link_to "Disconnect", "/settings/twitter_disconnect",
:method => :post %>)
<% else %>
<a href="/settings/twitter_auth">Connect</a>
<% end %>
</div>
<% end %>
<br>
<br>

View File

@ -121,6 +121,9 @@ Lobsters::Application.routes.draw do
get "/settings/github_auth" => "settings#github_auth"
get "/settings/github_callback" => "settings#github_callback"
post "/settings/github_disconnect" => "settings#github_disconnect"
get "/settings/twitter_auth" => "settings#twitter_auth"
get "/settings/twitter_callback" => "settings#twitter_callback"
post "/settings/twitter_disconnect" => "settings#twitter_disconnect"
get "/filters" => "filters#index"
post "/filters" => "filters#update"

View File

@ -4,6 +4,9 @@ class Twitter
# these need to be overridden in config/initializers/production.rb
@@CONSUMER_KEY = nil
@@CONSUMER_SECRET = nil
# these are set for the account used to post updates in
# script/post_to_twitter (needs read/write access)
@@AUTH_TOKEN = nil
@@AUTH_SECRET = nil
@ -12,6 +15,10 @@ class Twitter
# https://t.co/eyW1U2HLtP
TCO_LEN = 23
def self.enabled?
self.CONSUMER_KEY.present?
end
def self.oauth_consumer
OAuth::Consumer.new(self.CONSUMER_KEY, self.CONSUMER_SECRET,
{ :site => "https://api.twitter.com" })
@ -47,4 +54,28 @@ class Twitter
end
end
end
def self.token_secret_and_user_from_token_and_verifier(tok, verifier)
rt = OAuth::RequestToken.from_hash(self.oauth_consumer,
{ :oauth_token => tok })
at = rt.get_access_token({ :oauth_verifier => verifier })
res = at.get("/1.1/account/verify_credentials.json")
js = JSON.parse(res.body)
if !js["screen_name"].present?
return nil
end
[ at.token, at.secret, js["screen_name"] ]
end
def self.oauth_request_token(state)
self.oauth_consumer.get_request_token(:oauth_callback =>
Rails.application.root_url + "settings/twitter_callback?state=#{state}")
end
def self.oauth_auth_url(state)
self.oauth_request_token(state).authorize_url
end
end