Skip to content

Commit

Permalink
Flickr strategy for oa-more.
Browse files Browse the repository at this point in the history
  • Loading branch information
pchilton authored and benschwarz committed Feb 28, 2011
1 parent 770647d commit ae9b11a
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions oa-more/README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions oa-more/lib/omniauth/more.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
module OmniAuth
module Strategies
autoload :WindowsLive, 'omniauth/strategies/windows_live'
autoload :Flickr, 'omniauth/strategies/flickr'
end
end
77 changes: 77 additions & 0 deletions oa-more/lib/omniauth/strategies/flickr.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions oa-more/oa-more.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 7 additions & 0 deletions oa-more/spec/omniauth/strategies/flickr_spec.rb
Original file line number Diff line number Diff line change
@@ -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 ae9b11a

Please sign in to comment.