Permalink
Browse files

First version mostly working and documented

  • Loading branch information...
1 parent dde7ca8 commit 841fbf105f33e32adc60d6e2c0723908a7035b3f @cjheath committed Aug 5, 2011
Showing with 372 additions and 42 deletions.
  1. +77 −12 README.rdoc
  2. +47 −0 css/auth.css
  3. +91 −30 lib/sinatra/omniauth.rb
  4. +12 −0 models/authentication.rb
  5. +12 −0 models/user.rb
  6. +71 −0 omniauth.yml
  7. +62 −0 views/auth.haml
View
@@ -1,8 +1,12 @@
= sinatra_omniauth
-A Sinatra extension that provides pure OmniAuth authentication to your application (with DataMapper)
+Sinatra OmniAuth provides a Sinatra extension for adding pure OmniAuth authentication
+to your Sinatra application. "Pure" here means that you don't even need a username
+on the system, let alone a password; you just sign in using one of your existing
+social media accounts.
-Not even nearly ready for production yet; don't waste your time.
+SinatraOmniAuth uses DataMapper and Haml, though you can write your own templates too.
+SinatraOmniAuth uses the wonderful icon set from <https://github.com/intridea/authbuttons>
== Description
@@ -12,17 +16,78 @@ Copyright (c) 2011 Clifford Heath
This article demonstrates how to set up a multi-provider authentication in Rails using the fabulous Omniauth gem. Users can add multiple providers to their account and views for sign-in, sign-up and management of linked accounts are provided. The full source code is available on Github as a basis for your own projects.
-This gem, sinatra_omniauth, provides a partial clone of the Omniauth_pure functionality, but as a Sinatra extension using DataMapper.
+This gem, sinatra_omniauth, provides a partial clone of the Omniauth_pure functionality, but as a Sinatra extension using DataMapper and various other goodies.
== Using sinatra_omniauth
-To use sinatra_omniauth in your Sinatra application, you need to:
-* Add this gem to your Gemfile
-* Define your own User model so this gem won't use its own limited version
-* Decide whether to define your own Authorizations model likewise (you don't have to do this)
-* Configure all API keys in the settings of your Sinatra app (info below)
-* Ensure you have sessions enabled
-* Register Sinatra::Omniauth in your application.
+In your Gemfile, add:
+
+ gem 'sinatra_omniauth'
+
+In the root directory of your app (same dir as config.ru), add your API keys to "omniauth.yml"
+
+In your application:
+
+ require 'sinatra/omniauth'
+
+ set :omniauth, YAML.load_file(File.dirname(__FILE__)+"/omniauth.yml")
+
+ register SinatraOmniAuth
+
+Models:
+ Copy user.rb and authentication.rb from the models directory, and add any
+ other fields and relationships you need.
+
+Routes which SinatraOmniAuth will handle (you may override these if needed):
+ /auth
+ presents a list of configured authentication services, including the
+ user's current sign-in account and any other registered accounts.
+ This page also includes a signout link and the ability to delete
+ secondary authentication methods.
+ /auth/signout
+ Signs the user out immediately and redirects to '/'
+ /auth/<provider>/callback
+ This URL is triggered when the authentication service redirects the user's
+ browser here, after a successful authentication. The handler signs in the
+ user, who may be a new user just joining, an existing user adding a new
+ authentication method, or an existing user signing in or changing to a
+ different authentication method
+ /auth/failure
+ Sets a flash saying that the authorization failed before redirecting to .
+ /auth/:id
+ A POST here with the magic _method=delete will delete this authentication
+ method from the current user's account
+
+Views:
+ Copy views/auth.haml and css/auth.css to wherever they will be found.
+
+ Note that auth.haml uses assets helpers include_javascripts and include_stylesheets
+ to load packed or unpacked JS (jQuery required) and CSS. Youy'll be wanting to
+ style it all up yourself anyhow, but when you're there, replace the helpers as needed.
+
+Images:
+ Use the authbuttons images as noted. auth.haml expects them to be in </images/authbuttons/>
+
+Helper methods:
+ authenticate_user!
+ Redirects to /auth if the user is not already signed in
+ current_user
+ The User record of the current signed-in user
+ current_auth
+ The Authentication record with which the user is signed in.
+ Note that for most authentication services, this includes the user's name
+ and email address.
+
+Make sure you add a handler for the following routes:
+ get '/auth/welcome' - When a new user first joins
+ get '/auth/signedin' - When the user signs in
+
+ These handlers may simply set a flash and redirect to another place.
+
+Oh, did I say flash? SinatraOmniAuth uses the "rack-flash" gem, so you can say:
+
+ flash.notice = "Welcome back!"; redirect to('/')
+ ... and also access flash.error, flash.notice, etc, in your views.
== Contributing to sinatra_omniauth
@@ -37,10 +102,10 @@ To use sinatra_omniauth in your Sinatra application, you need to:
== Credits:
Omniauth: http://github.com/intridea/omniauth
-Omniauth Buttons: http://github.com/intridea/authbuttons
+authbuttons: http://github.com/intridea/authbuttons
Omniauth pure and article: Markus Proske
== Copyright
-Copyright (c) 2011 Clifford Heath. See LICENSE.txt for further details.
+Copyright (c) 2011 Clifford Heath. MIT Licensed. See LICENSE.txt for further details.
View
@@ -0,0 +1,47 @@
+/* Authentication "badge" */
+.authentication {
+ position: relative;
+ display: inline-block;
+ padding: 0.1em 0.5em 0.1em 0.5em;
+ margin: 0.5em 0.3em;
+ Xpadding: 5px;
+ min-height: 40px;
+ background-color: #EEE;
+ border-radius: 0.5em; border: 2px black;
+ -webkit-box-shadow: 0 0 5px #000; -moz-box-shadow: 0 0 5px #000; box-shadow: 0 0 5px #000;
+ background-repeat: no-repeat;
+ background-position: left center;
+ cursor: pointer;
+}
+.authentication.available {
+ padding-right: 1em;
+}
+.authentication.current {
+ padding-right: 0em;
+ cursor: default;
+}
+.authentication.available *,
+.authentication.current * {
+ margin: 3px 10px 3px 32px;
+}
+.authentication * {
+ margin: 12px 8px 12px 32px;
+}
+.authentication .provider {
+ font-weight: bold;
+}
+.authentication .remove { /* The X to delete this authentication method */
+ position: absolute;
+ right: 0px;
+ top: 0px;
+}
+
+/* Alternate auth providers */
+.auth_provider {
+ position: relative;
+ display: inline-block;
+ text-align: center;
+}
+.auth_provider * {
+ display:block;
+}
@@ -1,3 +1,89 @@
+#
+# Sinatra OmniAuth
+#
+# Copyright 2011 Clifford Heath.
+# License: MIT
+#
+# Sinatra OmniAuth provides a Sinatra extension for adding pure OmniAuth authentication
+# to your Sinatra application. "Pure" here means that you don't even need a username
+# on the system, let alone a password; you just sign in using one of your existing
+# social media accounts.
+#
+# SinatraOmniAuth uses DataMapper and Haml, though you can write your own templates too.
+# SinatraOmniAuth uses the wonderful icon set from <https://github.com/intridea/authbuttons>
+#
+# Usage:
+# In your Gemfile, add:
+#
+# gem 'sinatra_omniauth'
+#
+# In the root directory of your app (same dir as config.ru), add your API keys to "omniauth.yml"
+#
+# In your application:
+#
+# require 'sinatra/omniauth'
+#
+# set :omniauth, YAML.load_file(File.dirname(__FILE__)+"/omniauth.yml")
+#
+# register SinatraOmniAuth
+#
+# Models:
+# Copy user.rb and authentication.rb from the models directory, and add any
+# other fields and relationships you need.
+#
+# Routes which SinatraOmniAuth will handle (you may override these if needed):
+# /auth
+# presents a list of configured authentication services, including the
+# user's current sign-in account and any other registered accounts.
+# This page also includes a signout link and the ability to delete
+# secondary authentication methods.
+# /auth/signout
+# Signs the user out immediately and redirects to '/'
+# /auth/<provider>/callback
+# This URL is triggered when the authentication service redirects the user's
+# browser here, after a successful authentication. The handler signs in the
+# user, who may be a new user just joining, an existing user adding a new
+# authentication method, or an existing user signing in or changing to a
+# different authentication method
+# /auth/failure
+# Sets a flash saying that the authorization failed before redirecting to .
+# /auth/:id
+# A POST here with the magic _method=delete will delete this authentication
+# method from the current user's account
+#
+# Views:
+# Copy views/auth.haml and css/auth.css to wherever they will be found.
+#
+# Note that auth.haml uses assets helpers include_javascripts and include_stylesheets
+# to load packed or unpacked JS (jQuery required) and CSS. Youy'll be wanting to
+# style it all up yourself anyhow, but when you're there, replace the helpers as needed.
+#
+# Images:
+# Use the authbuttons images as noted. auth.haml expects them to be in </images/authbuttons/>
+#
+# Helper methods:
+# authenticate_user!
+# Redirects to /auth if the user is not already signed in
+# current_user
+# The User record of the current signed-in user
+# current_auth
+# The Authentication record with which the user is signed in.
+# Note that for most authentication services, this includes the user's name
+# and email address.
+#
+# Make sure you add a handler for the following routes:
+# get '/auth/welcome' - When a new user first joins
+# get '/auth/signedin' - When the user signs in
+#
+# These handlers may simply set a flash and redirect to another place.
+#
+# Oh, did I say flash? SinatraOmniAuth uses the "rack-flash" gem, so you can say:
+#
+# flash.notice = "Welcome back!"; redirect to('/')
+# ... and also access flash.error, flash.notice, etc, in your views.
+#
+# You're welcome :)
+#
require 'omniauth'
require 'openid/store/filesystem'
require 'rack-flash'
@@ -8,10 +94,14 @@ def current_user
@current_user ||= User.get(session[:user_id]) if session[:user_id]
end
+ def current_auth
+ @current_auth ||= Authentication.get(session[:authentication_id]) if session[:authentication_id]
+ end
+
def authenticate_user!
if !current_user
flash.error = 'You need to sign in before you can access this page!'
- redirect to('/auth/signin')
+ redirect to('/auth')
end
end
end
@@ -63,11 +153,6 @@ def self.registered app
haml :auth
end
- app.get '/auth/signin' do
- @authentications = settings.omniauth.map{|a| a['name']}
- haml :signin, :layout => :auth_layout
- end
-
app.get '/auth/:authentication/callback' do
# callback: success
# This handles signing in and adding an authentication authentication to existing accounts itself
@@ -150,16 +235,12 @@ def self.registered app
end
end
- # auth_failure
app.get '/auth/failure' do
- # {:action=>"failure", :controller=>"authentications"}
flash.error = 'There was an error at the remote authentication authentication. You have not been signed in.'
redirect to('/')
end
- # signout_authentications
app.get '/auth/signout' do
- # {:action=>"signout", :controller=>"authentications"}
authenticate_user!
session[:user_id] = nil
@@ -172,12 +253,6 @@ def self.registered app
redirect to('/')
end
- # failure_authentications
- app.get '/auth/failure' do
- # {:action=>"failure", :controller=>"authentications"}
- haml :failure
- end
-
# authentication
app.delete '/auth/:id' do
authenticate_user!
@@ -194,19 +269,5 @@ def self.registered app
redirect to('/auth')
end
- # test_users
- app.get '/users/test' do
- # {:action=>"test", :controller=>"users"}
- authenticate_user!
- haml :user_test
- end
-
- # users
- app.get '/users' do
- # {:action=>"index", :controller=>"users"}
- authenticate_user!
- haml :users
- end
-
end
end
@@ -0,0 +1,12 @@
+class Authentication
+ include DataMapper::Resource
+
+ belongs_to :user
+
+ property :id, Serial
+ property :user_id, Integer
+ property :provider, String
+ property :uid, String
+ property :user_name, String
+ property :user_email, String
+end
View
@@ -0,0 +1,12 @@
+class User
+ include DataMapper::Resource
+
+ devise :registerable, # handles signing up users through a registration process, also edit/destroy account.
+ :rememberable, # "Remember me" from a cookie
+ :trackable # Tracks sign in count, timestamps and IP address
+
+ property :id, Serial
+
+ # Each user may log in using different methods:
+ has n, :authentications
+end
Oops, something went wrong.

0 comments on commit 841fbf1

Please sign in to comment.