SSO for an installed Google App
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#app/models/user.rb | |
class User < ActiveRecord::Base | |
attr_accessible :email, :first_name, :last_name, | |
:full_name, :image_url, :uid | |
def domain | |
email.split("@").last | |
end | |
def self.create_with_omniauth(auth) | |
create! do |user| | |
user.uid = auth["uid"] | |
user.first_name = auth["info"]["first_name"] | |
user.last_name = auth["info"]["last_name"] | |
user.full_name = auth["info"]["name"] | |
user.email = auth["info"]["email"] | |
user.image_url = auth['info']['image'] | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#app/controllers/application_controller.rb | |
class ApplicationController < ActionController::Base | |
before_filter :authenticate_user! | |
helper_method :current_user, :user_signed_in?, :current_users | |
def authenticate_user! | |
redirect_to '/auth/google_apps' unless user_signed_in? | |
end | |
private | |
def current_user | |
@current_user ||= User.find_by_id(session[:user_id]) if user_signed_in? | |
end | |
def user_signed_in? | |
session[:user_id] && User.find_by_id(session[:user_id]) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lib/google/client.rb | |
require 'oauth' | |
require 'rexml/document' | |
module Google | |
class Client | |
attr_accessor :version | |
def self.get(base, query_parameters, version = '2.0') | |
make_request(:get, url(base, query_parameters), version) | |
end | |
private | |
def self.make_request(method, url, version) | |
oauth_consumer = OAuth::Consumer.new(GOOGLE_APP_ID, GOOGLE_APP_SECRET) | |
access_token = OAuth::AccessToken.new(oauth_consumer) | |
response = access_token.request(method, url, {'GData-Version' => version}) | |
if response.is_a?(Net::HTTPFound) | |
return make_request(method, response['Location'], version) | |
end | |
return unless response.is_a?(Net::HTTPSuccess) | |
feed = REXML::Document.new(response.body) | |
throw :halt, [500, "Unable to query feed"] if feed.nil? | |
feed | |
end | |
def self.url(base, query_parameters={}) | |
url = base | |
unless query_parameters.empty? | |
url += '?' | |
query_parameters.each { |key, value| url += "#{CGI::escape(key)}=#{CGI::escape(value)}&" } | |
url.chop! | |
end | |
url | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lib/google/contact.rb | |
module Google | |
class Contact | |
attr_accessor :full_name, :first_name, :last_name, :email, :company, :title, :notes | |
def self.all(email) | |
feed = Google::Client.get("https://www.google.com/m8/feeds/contacts/default/full", { | |
'xoauth_requestor_id' => email | |
}, '3.0') | |
feed.elements.collect('//entry') do |entry| | |
new( | |
:full_name => entry.elements["gd:name"].elements["gd:fullName"].text, | |
:first_name => entry.elements["gd:name"].elements["gd:givenName"].text, | |
:last_name => entry.elements["gd:name"].elements["gd:familyName"].text, | |
:email => entry.elements["gd:email"].attribute("address").value, | |
:company => entry.elements["gd:organization"].elements["gd:orgName"].text, | |
:title => entry.elements["gd:organization"].elements["gd:orgTitle"].text, | |
:notes => entry.elements["content"].text | |
) | |
end | |
end | |
def initialize(options = {}) | |
@full_name = options[:full_name] | |
@first_name = options[:first_name] | |
@last_name = options[:last_name] | |
@email = options[:email] | |
@company = options[:company] | |
@title = options[:title] | |
@notes = options[:notes] | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Gemfile | |
source 'https://rubygems.org' | |
... | |
gem 'oauth' | |
gem 'omniauth-google-apps' | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#config/initializers/omniauth.rb | |
require 'openid/store/filesystem' | |
Rails.application.config.middleware.use OmniAuth::Builder do | |
provider :google_apps, :store => OpenID::Store::Filesystem.new('./tmp') | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#config/routes.rb | |
... | |
match "/auth/:provider/callback" => "sessions#create" | |
match "/signout" => "sessions#destroy", :as => :signout | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#app/controllers/sessions_controller.rb | |
class SessionsController < ApplicationController | |
skip_before_filter :authenticate_user!, only: :create | |
def create | |
auth = request.env["omniauth.auth"] | |
user = User.find_by_uid(auth["uid"]) || User.create_with_omniauth(auth) | |
session[:user_id] = user.id | |
redirect_to root_url, :notice => "Signed in!" | |
end | |
def destroy | |
session[:user_id] = nil | |
redirect_to root_url, :notice => "Signed out!" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lib/google/user.rb | |
module Google | |
class User | |
attr_accessor :login, :first_name, :last_name | |
def self.all(domain) | |
feed = Google::Client.get("https://apps-apis.google.com/a/feeds/#{domain}/user/2.0", { | |
'get' => 'all' | |
}) | |
feed.elements.collect('//entry') { |e| new_from_entry(e) } | |
end | |
def self.find(domain, login) | |
feed = Google::Client.get("https://apps-apis.google.com/a/feeds/#{domain}/user/2.0/#{login}", {}) | |
feed.elements.collect('//entry') { |e| new_from_entry(e) } | |
end | |
def initialize(options ={}) | |
@login = options[:login] | |
@first_name = options[:first_name] | |
@last_name = options[:last_name] | |
end | |
private | |
def self.new_from_entry(entry) | |
new( | |
:login => entry.elements["apps:login"].attribute("userName").value, | |
:first_name => entry.elements["apps:name"].attribute("givenName").value, | |
:last_name => entry.elements["apps:name"].attribute("familyName").value, | |
) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
any update since then ?
what is the route the google app market will use to redirect the user to arrive and be logged in ?
Google app market docs describe that domain name will be passed with but, using the omniauth-google-apps gem I cannot find the entry point that is supposed to receive such information. (users keep being presented with the "enter domain name" form before being redirected to google for auth, then back to the app, logged in).