Add login via Mozilla Persona

openid
Marcin Kulik 11 years ago
parent 769acb6593
commit 8c43aaf081

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

@ -11,6 +11,7 @@
//= require underscore-min
//= require backbone-min
//= require jquery.timeago
//= require persona
$(function() {
$('abbr.timeago').timeago();

@ -0,0 +1,28 @@
$ ->
$('#persona-button').click (event) ->
event.preventDefault()
navigator.id.request { siteName: window.location.hostname }
if window.browserIdUser
$('.session-info .logout').click (event) ->
event.preventDefault()
navigator.id.logout()
navigator.id.watch
loggedInUser: window.browserIdUser
onlogin: (assertion) ->
console.log 'onlogin'
if assertion
form = $(
"<form action='/auth/browser_id/callback'>" +
"<input type='hidden' name='assertion' value='#{assertion}' />"
)
$('body').append form
form.submit()
onlogout: ->
console.log 'onlogout'
window.location = '/logout'

@ -1,17 +1,16 @@
class SessionsController < ApplicationController
before_filter :load_omniauth_auth, :only => :create
def new; end
def create
@user = request.env['asciiio.user']
@user = user_from_omniauth
if @user.persisted? || @user.save
if @user.persisted?
self.current_user = @user
redirect_back_or_to root_url, :notice => "Logged in!"
else
store_sensitive_user_data_in_session
render 'users/new', :status => 422
redirect_to new_user_path
end
end
@ -26,10 +25,6 @@ class SessionsController < ApplicationController
private
def load_omniauth_auth
@auth = request.env["omniauth.auth"]
end
def store_sensitive_user_data_in_session
session[:new_user] = {
:provider => @user.provider,
@ -38,4 +33,27 @@ class SessionsController < ApplicationController
}
end
def user_from_omniauth
omniauth = request.env['omniauth.auth']
find_user(omniauth) || build_user(omniauth)
end
def find_user(omniauth)
query = { :provider => omniauth['provider'], :uid => omniauth['uid'].to_s }
User.where(query).first
end
def build_user(omniauth)
user = User.new
user.provider = omniauth['provider']
user.uid = omniauth['uid']
user.nickname = omniauth['info']['nickname']
user.name = omniauth['info']['name'] unless user.provider == 'browser_id'
user.email = omniauth["info"]["email"]
user.avatar_url = OmniAuthHelper.get_avatar_url(omniauth)
user
end
end

@ -1,8 +1,14 @@
class UsersController < ApplicationController
PER_PAGE = 15
before_filter :ensure_authenticated!, :only => [:edit, :update]
def new
@user = User.new
load_sensitive_user_data_from_session
end
def show
@user = User.find_by_nickname!(params[:nickname]).decorate
@ -22,7 +28,7 @@ class UsersController < ApplicationController
if @user.save
clear_sensitive_session_user_data
self.current_user = @user
redirect_back_or_to root_url, :notice => "Logged in!"
redirect_back_or_to root_url, :notice => "Welcome!"
else
render 'users/new', :status => 422
end
@ -45,10 +51,12 @@ class UsersController < ApplicationController
@user.provider = session[:new_user][:provider]
@user.uid = session[:new_user][:uid]
@user.avatar_url = session[:new_user][:avatar_url]
@user.email = @user.uid if @user.provider == 'browser_id'
end
end
def clear_sensitive_session_user_data
session.delete(:new_user)
end
end

@ -1,4 +1,5 @@
module ApplicationHelper
def page_title
title = "asciinema"
@ -17,6 +18,16 @@ module ApplicationHelper
"/auth/github"
end
def browser_id_user
user = current_user || @user
if user && user.provider == 'browser_id'
"'#{user.uid}'".html_safe
else
'null'
end
end
def markdown(&block)
text = capture(&block)
MKD_RENDERER.render(capture(&block)).html_safe
@ -58,4 +69,5 @@ module ApplicationHelper
asciicast_path(id)
end
end
end

@ -1,36 +0,0 @@
class OmniAuthUserLoader
def initialize(app)
@app = app
end
def call(env)
omniauth = env['omniauth.auth']
if omniauth
env['asciiio.user'] = find_user(omniauth) || build_user(omniauth)
end
@app.call(env)
end
private
def find_user(omniauth)
query = { :provider => omniauth['provider'], :uid => omniauth['uid'].to_s }
User.where(query).first
end
def build_user(omniauth)
user = User.new
user.provider = omniauth['provider']
user.uid = omniauth['uid']
user.nickname = omniauth['info']['nickname']
user.name = omniauth['info']['name']
user.avatar_url = OmniAuthHelper.get_avatar_url(omniauth)
user
end
end

@ -5,12 +5,14 @@ html[lang="en"]
title = page_title
= csrf_meta_tags
= stylesheet_link_tag "application", :media => "all"
= javascript_include_tag "https://login.persona.org/include.js"
= javascript_include_tag "application"
= javascript_include_tag "player"
= favicon_link_tag 'favicon.png'
= render :partial => 'layouts/ga'
script
| window.mainWorkerPath = '#{javascript_path "main_worker"}';
| window.browserIdUser = #{browser_id_user};
body
header
.wrapper

@ -3,7 +3,16 @@
<h1>Log In</h1>
<p>
Log in with your GitHub or Twitter account:
We recommend logging in with your email using <%= link_to "Mozilla Persona", "https://login.persona.org/" %>.
Look <%= link_to "here", "https://developer.mozilla.org/en-US/docs/Persona" %> for more details.
</p>
<ul id="login">
<li><%= link_to image_tag('persona_sign_in_blue.png', :title => "Log in via Persona"), '#', :id => 'persona-button' %></li>
</ul>
<p>
Or just log in with your GitHub or Twitter account:
</p>
<ul id="login">

@ -1,10 +1,9 @@
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, CFG['TWITTER_CONSUMER_KEY'], CFG['TWITTER_CONSUMER_SECRET'], :client_options => { :ssl => { :ca_path => "/etc/ssl/certs" } }
provider :github, CFG['GITHUB_CONSUMER_KEY'], CFG['GITHUB_CONSUMER_SECRET'], :client_options => { :ssl => { :ca_path => "/etc/ssl/certs" } }
provider :browser_id
end
OmniAuth.config.on_failure = Proc.new { |env|
OmniAuth::FailureEndpoint.new(env).redirect_to_failure
}
Rails.application.config.middleware.insert_after OmniAuth::Builder, OmniAuthUserLoader

@ -22,7 +22,7 @@ Asciinema::Application.routes.draw do
get "/connect/:user_token" => "user_tokens#create"
resource :user, :only => [:create, :edit, :update]
resource :user
namespace :api do
resources :asciicasts

@ -1,10 +1,15 @@
class OmniAuthHelper
def self.get_avatar_url(auth)
if auth["provider"] == "twitter"
case auth["provider"]
when "twitter"
auth["info"]["image"]
elsif auth["provider"] == "github"
when "github"
auth["extra"]["raw_info"]["avatar_url"]
when "browser_id"
email = auth["uid"]
hash = Digest::MD5.hexdigest(email.to_s.downcase)
"http://gravatar.com/avatar/#{hash}?s=64"
end
end

@ -1,63 +0,0 @@
require 'spec_helper'
describe OmniAuthUserLoader do
let(:middleware) { OmniAuthUserLoader.new(app) }
let(:app) { double('app', :call => nil) }
describe '#call' do
let(:env) { { :path => '/foo' } }
subject { env['asciiio.user'] }
before do
OmniAuth.config.mock_auth[:twitter] = omniauth
env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
end
context "when there's no omniauth hash" do
let(:omniauth) { nil }
before do
middleware.call(env)
end
it { should be(nil) }
end
context "when the omniauth hash is present" do
let(:omniauth) { {
"provider" => 'twitter',
"uid" => 1234,
"info" => {
"nickname" => 'quux',
"name" => 'Quux'
}
} }
context "user exists" do
let!(:user) { create(:user, :provider => 'twitter', :uid => 1234) }
before do
middleware.call(env)
end
it { should eq(user) }
end
context "user doesn't exist" do
before do
allow(OauthHelper).to receive(:get_avatar_url) { 'http://a.eu/1.jpg' }
middleware.call(env)
end
it { should be_new_record }
its(:provider) { should eq('twitter') }
its(:uid) { should eq(1234) }
its(:nickname) { should eq('quux') }
its(:name) { should eq('Quux') }
its(:avatar_url) { should eq('http://a.eu/1.jpg') }
end
end
end
end
Loading…
Cancel
Save