Skip to content
Browse files

Merging in from master.

  • Loading branch information...
2 parents 4aeed81 + d1db9e1 commit eb1a060945a74b7b89c969afd54c51984f0017df Michael Bleigh committed Jan 30, 2011
View
3 README.markdown
@@ -36,6 +36,9 @@ OmniAuth currently supports the following external providers:
* Google Apps (via OpenID)
* CAS (Central Authentication Service) (credit: [jamesarosen](https://github.com/jamesarosen))
* LDAP (credit: [pyu10055](https://github.com/pyu10055))
+* via OA-More
+ * Flickr (credit: [pchilton](http://github.com/pchilton))
+
## Usage
View
2 oa-enterprise/README.rdoc
@@ -25,7 +25,7 @@ See OmniAuth::Strategies::CAS::Configuration for more configuration options.
== LDAP
-Use the LDAP strategy as a middleware in your applicaiton:
+Use the LDAP strategy as a middleware in your application:
require 'omniauth/enterprise'
use OmniAuth::Strategies::LDAP,
View
10 oa-enterprise/lib/omniauth/strategies/ldap.rb
@@ -55,7 +55,11 @@ def callback_phase
begin
creds = session.delete 'omniauth.ldap'
@ldap_user_info = {}
- (@adaptor.bind unless @adaptor.bound?) rescue puts "failed to bind with the default credentials"
+ begin
+ (@adaptor.bind(:allow_anonymous => true) unless @adaptor.bound?)
+ rescue Exception => e
+ puts "failed to bind with the default credentials: " + e.message
+ end
@ldap_user_info = @adaptor.search(:filter => Net::LDAP::Filter.eq(@adaptor.uid, @name_proc.call(creds['username'])),:limit => 1) if @adaptor.bound?
bind_dn = creds['username']
bind_dn = @ldap_user_info[:dn].to_a.first if @ldap_user_info[:dn]
@@ -65,10 +69,10 @@ def callback_phase
@env['omniauth.auth'] = auth_hash
- call_app!
rescue Exception => e
- fail!(:invalid_credentials, e)
+ return fail!(:invalid_credentials, e)
end
+ call_app!
end
def auth_hash
View
40 oa-enterprise/lib/omniauth/strategies/ldap/adaptor.rb
@@ -15,7 +15,7 @@ class AuthenticationError < StandardError; end
class ConnectionError < StandardError; end
VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :bind_dn, :password,
- :try_sasl, :sasl_mechanisms, :uid, :base]
+ :try_sasl, :sasl_mechanisms, :uid, :base, :allow_anonymous]
MUST_HAVE_KEYS = [:host, :port, :method, :uid, :base]
@@ -33,15 +33,17 @@ def initialize(configuration={})
@disconnected = false
@bound = false
@configuration = configuration.dup
- @logger = @configuration.delete(:logger)
- message = []
- MUST_HAVE_KEYS.each do |name|
- message << name if configuration[name].nil?
- end
- raise ArgumentError.new(message.join(",") +" MUST be provided") unless message.empty?
+ @configuration[:allow_anonymous] ||= false
+ @logger = @configuration.delete(:logger)
+ message = []
+ MUST_HAVE_KEYS.each do |name|
+ message << name if configuration[name].nil?
+ end
+ raise ArgumentError.new(message.join(",") +" MUST be provided") unless message.empty?
VALID_ADAPTER_CONFIGURATION_KEYS.each do |name|
instance_variable_set("@#{name}", configuration[name])
end
+
end
def connect(options={})
@@ -81,14 +83,21 @@ def bind(options={})
bind_dn = (options[:bind_dn] || @bind_dn).to_s
try_sasl = options.has_key?(:try_sasl) ? options[:try_sasl] : @try_sasl
-
+ if options.has_key?(:allow_anonymous)
+ allow_anonymous = options[:allow_anonymous]
+ else
+ allow_anonymous = @allow_anonymous
+ end
# Rough bind loop:
# Attempt 1: SASL if available
# Attempt 2: SIMPLE with credentials if password block
+ # Attempt 3: SIMPLE ANONYMOUS if 1 and 2 fail and allow anonymous is set to true
if try_sasl and sasl_bind(bind_dn, options)
- puts "bind with sasl"
+ puts "bound with sasl"
elsif simple_bind(bind_dn, options)
- puts "bind with simple"
+ puts "bound with simple"
+ elsif allow_anonymous and bind_as_anonymous(options)
+ puts "bound as anonymous"
else
message = yield if block_given?
message ||= ('All authentication methods for %s exhausted.') % target
@@ -242,12 +251,19 @@ def simple_bind(bind_dn, options={})
args = {
:method => :simple,
:username => bind_dn,
- :password => options[:password]||@password,
+ :password => (options[:password]||@password).to_s,
}
+ begin
execute(:bind, args)
true
+ rescue Exception
+ false
end
-
+ end
+ def bind_as_anonymous(options={})
+ execute(:bind, {:method => :anonymous})
+ true
+ end
def construct_uri(host, port, ssl)
protocol = ssl ? "ldaps" : "ldap"
URI.parse("#{protocol}://#{host}:#{port}").to_s
View
6 oa-more/README.rdoc
@@ -13,4 +13,10 @@ To install just the providers in the "more" gem:
gem install oa-more
+== OmniAuth Builder
+If you want to allow multiple providers, use the OmniAuth Builder:
+
+ use OmniAuth::Builder do
+ provider :flickr, 'api_key', 'secret_key', :scope => 'read'
+ end
View
2 oa-more/lib/omniauth/more.rb
@@ -3,5 +3,7 @@
module OmniAuth
module Strategies
autoload :WindowsLive, 'omniauth/strategies/windows_live'
+ # autoload strategies here
+ autoload :Flickr, 'omniauth/strategies/flickr'
end
end
View
77 oa-more/lib/omniauth/strategies/flickr.rb
@@ -0,0 +1,77 @@
+require 'omniauth/core'
+require 'digest/md5'
+require 'rest-client'
+require 'multi_json'
+
+module OmniAuth
+ module Strategies
+ #
+ # Authenticate to Flickr
+ #
+ # @example Basic Usage
+ #
+ # use OmniAuth::Strategies::Flickr, 'API Key', 'Secret Key', :scope => 'read'
+ class Flickr
+ include OmniAuth::Strategy
+ attr_accessor :api_key, :secret_key, :options
+
+ # error catching, based on OAuth2 callback
+ class CallbackError < StandardError
+ attr_accessor :error, :error_reason
+ def initialize(error, error_reason)
+ self.error = error
+ self.error_reason = error_reason
+ end
+ end
+
+ # @param [Rack Application] app standard middleware application parameter
+ # @param [String] api_key the application id as [registered on Flickr](http://www.flickr.com/services/apps/)
+ # @param [String] secret_key the application secret as [registered on Flickr](http://www.flickr.com/services/apps/)
+ # @option options ['read','write','delete] :scope ('read') the scope of your authorization request; must be `read` or 'write' or 'delete'
+ def initialize(app, api_key, secret_key, options = {})
+ super(app, :flickr)
+ @api_key = api_key
+ @secret_key = secret_key
+ @options = {:scope => 'read'}.merge(options)
+ end
+
+ protected
+
+ def request_phase
+ params = { :api_key => api_key, :perms => options[:scope] }
+ params[:api_sig] = flickr_sign(params)
+ query_string = params.collect{ |key,value| "#{key}=#{Rack::Utils.escape(value)}" }.join('&')
+ redirect "http://flickr.com/services/auth/?#{query_string}"
+ end
+
+ def callback_phase
+ params = { :api_key => api_key, :method => 'flickr.auth.getToken', :frob => request.params['frob'], :format => 'json', :nojsoncallback => '1' }
+ params[:api_sig] = flickr_sign(params)
+
+ response = RestClient.get('http://api.flickr.com/services/rest/', { :params => params })
+ auth = MultiJson.decode(response.to_s)
+ raise CallbackError.new(auth['code'],auth['message']) if auth['stat'] == 'fail'
+
+ @user = auth['auth']['user']
+ @access_token = auth['auth']['token']['_content']
+
+ super
+ rescue CallbackError => e
+ fail!(:invalid_response, e)
+ end
+
+ def auth_hash
+ OmniAuth::Utils.deep_merge(super, {
+ 'uid' => @user['nsid'],
+ 'credentials' => { 'token' => @access_token },
+ 'user_info' => @user,
+ 'extra' => { 'user_hash' => @user }
+ })
+ end
+
+ def flickr_sign(params)
+ Digest::MD5.hexdigest(secret_key + params.sort{|a,b| a[0].to_s <=> b[0].to_s }.flatten.join)
+ end
+ end
+ end
+end
View
2 oa-more/oa-more.gemspec
@@ -14,6 +14,8 @@ Gem::Specification.new do |gem|
gem.files = Dir.glob("{lib}/**/*") + %w(README.rdoc LICENSE)
gem.add_dependency 'oa-core', version
+ gem.add_dependency 'rest-client', '~> 1.6.0'
+ gem.add_dependency 'multi_json', '~> 0.0.2'
eval File.read(File.join(File.dirname(__FILE__), '../development_dependencies.rb'))
end
View
7 oa-more/spec/omniauth/strategies/flickr_spec.rb
@@ -0,0 +1,7 @@
+require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
+
+describe 'OmniAuth::Strategies::Flickr' do
+ it 'should initialize with a consumer key and secret' do
+ lambda{OmniAuth::Strategies::Flickr.new({},'abc','def')}.should_not raise_error
+ end
+end

0 comments on commit eb1a060

Please sign in to comment.
Something went wrong with that request. Please try again.