f1api 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source :rubygems
2
+ gem 'nokogiri'
3
+ gem 'oauth', '=0.4.4'
4
+ gem 'mocha'
5
+ gem 'activeresource'
@@ -0,0 +1,27 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.3)
5
+ activesupport (= 3.0.3)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.4)
8
+ activeresource (3.0.3)
9
+ activemodel (= 3.0.3)
10
+ activesupport (= 3.0.3)
11
+ activesupport (3.0.3)
12
+ builder (2.1.2)
13
+ i18n (0.4.2)
14
+ mocha (0.9.9)
15
+ rake
16
+ nokogiri (1.4.4)
17
+ oauth (0.4.4)
18
+ rake (0.8.7)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ activeresource
25
+ mocha
26
+ nokogiri
27
+ oauth (= 0.4.4)
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Fellowship Technologies
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,24 @@
1
+ Fellowship One REST API Ruby Client Library
2
+ ===========================================
3
+
4
+ **NOTE**: This library is of alpha quality. It is not meant for use in production apps. It's definitely not feature complete and it may have bugs.
5
+
6
+ Introduction
7
+ ------------
8
+ This library is an implementation of the Fellowship One REST API. Currently we are only fielding requests and handling the OAuth tokens. The goal is to have a library that works like ActiveResource.
9
+
10
+ Usage
11
+ -----
12
+ require 'f1api'
13
+
14
+ class Person < FellowshipOneAPI::Base
15
+ end
16
+
17
+ client.authorize!
18
+ # If using creds in YAML file:
19
+ # client.authorize! "username", "password"
20
+
21
+ Person.connect client
22
+
23
+ Person.find(12345)
24
+ Person.find("search", {:searchFor => "Dearing", :include => "communications,addresses"})
@@ -0,0 +1,38 @@
1
+ BASE_DIR = File.dirname(__FILE__)
2
+
3
+ task :test do
4
+ require 'bundler/setup'
5
+ require 'test/unit'
6
+ require 'mocha'
7
+ require "#{BASE_DIR}/test/fixtures/request_token.rb"
8
+ require "#{BASE_DIR}/test/fixtures/access_token.rb"
9
+ require "#{BASE_DIR}/test/fixtures/http.rb"
10
+ require "#{BASE_DIR}/lib/f1api"
11
+ Dir["#{BASE_DIR}/test/unit/*.rb"].each do |test|
12
+ require test
13
+ end
14
+ end
15
+
16
+ task :rdoc do
17
+ `rdoc -x 'test/*'`
18
+ end
19
+
20
+ require 'jeweler'
21
+ Jeweler::Tasks.new do |gem|
22
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
23
+ gem.name = "f1api"
24
+ gem.homepage = "http://github.com/jessedearing/f1api"
25
+ gem.license = "MIT"
26
+ gem.summary = %Q{Consume the Fellowship One API in your apps using ActiveResource}
27
+ gem.description = %Q{Consumes the Fellowship One API in your apps using ActiveResource. Implements 2nd party credentials-based authenticaion and full OAuth implementation. }
28
+ gem.email = "jdearing@fellowshiptech.com"
29
+ gem.authors = ["Jesse Dearing"]
30
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
31
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
32
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
33
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
34
+ gem.add_runtime_dependency 'oauth', '= 0.4.4'
35
+ gem.add_development_dependency 'mocha'
36
+ gem.add_runtime_dependency 'activeresource'
37
+ end
38
+ Jeweler::RubygemsDotOrgTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.9.0
@@ -0,0 +1,5 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 9
4
+ :patch: 0
5
+ :build:
@@ -0,0 +1,48 @@
1
+ development:
2
+ consumer_key: ""
3
+ consumer_secret: ""
4
+ site_url: "https://{church_code}.staging.fellowshiponeapi.com"
5
+ # Store the church code if you are writing a 2nd Party implementation
6
+ # Otherwise, you'll want to ask for the church code from the user
7
+ church_code: ""
8
+ authentication_type: "oauth" #oauth or credentials
9
+ request_token_path: "/v1/Tokens/RequestToken"
10
+ access_token_path: "/v1/Tokens/AccessToken" #OAuth only
11
+ # OAuth authentication vars
12
+ portal_authorize_path: "/v1/PortalUser/Login"
13
+ weblink_authorize_path: "/v1/WeblinkUser/Login"
14
+ # Use the following for credentials based authentication
15
+ portal_credential_token_path: "/v1/PortalUser/AccessToken"
16
+ weblink_credential_token_path: "/v1/WeblinkUser/AccessToken"
17
+ test:
18
+ consumer_key: "123456789"
19
+ consumer_secret: "12345678-90ab-cdef-0123-4567890abcde"
20
+ site_url: "https://{church_code}.staging.fellowshiponeapi.com"
21
+ # Store the church code if you are writing a 2nd Party implementation
22
+ # Otherwise, you'll want to ask for the church code from the user
23
+ church_code: "test"
24
+ authentication_type: "oauth" #oauth or credentials
25
+ request_token_path: "/V1/Tokens/RequestToken"
26
+ access_token_path: "/V1/Tokens/AccessToken" #OAuth only
27
+ # OAuth authentication vars
28
+ portal_authorize_path: "/V1/PortalUser/Login"
29
+ weblink_authorize_path: "/V1/WeblinkUser/Login"
30
+ # Use the following for credentials based authentication
31
+ portal_credential_token_path: "/V1/PortalUser/AccessToken"
32
+ weblink_credential_token_path: "/V1/WeblinkUser/AccessToken"
33
+ production:
34
+ consumer_key: ""
35
+ consumer_secret: ""
36
+ site_url: "https://{church_code}.fellowshiponeapi.com"
37
+ # Store the church code if you are writing a 2nd Party implementation
38
+ # Otherwise, you'll want to ask for the church code from the user
39
+ church_code: ""
40
+ authentication_type: "oauth" #oauth or credentials
41
+ request_token_path: "/v1/Tokens/RequestToken"
42
+ access_token_path: "/v1/Tokens/AccessToken" #OAuth only
43
+ # OAuth authentication vars
44
+ portal_authorize_path: "/v1/PortalUser/Login"
45
+ weblink_authorize_path: "/v1/WeblinkUser/Login"
46
+ # Use the following for credentials based authentication
47
+ portal_credential_token_path: "/v1/PortalUser/AccessToken"
48
+ weblink_credential_token_path: "/v1/WeblinkUser/AccessToken"
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}"
2
+ require 'bundler/setup'
3
+ require 'yaml'
4
+ require 'oauth'
5
+ require 'base64'
6
+ require 'uri'
7
+ require 'active_resource'
8
+ require "f1api/configuration"
9
+ require "f1api/oauth"
10
+ require "f1api/oauth/credentials_authentication"
11
+ require "f1api/oauth/oauth_authentication"
12
+ require "f1api/client"
13
+ require "f1api/activeresource/connection"
14
+ require "f1api/activeresource/base"
@@ -0,0 +1,19 @@
1
+ module FellowshipOneAPI # :nodoc:
2
+ # The Base class should be inherited by all model classes as it provides the facilities that the class will need
3
+ class Base < ActiveResource::Base
4
+ self.site = "#{Configuration.site_url}/v1"
5
+ # Creates a new connection
6
+ #
7
+ # ==Examples
8
+ # Person.connect(FellowshipOneAPI::Client.new)
9
+ #
10
+ # If the connection needs to be forcibly refreshed then you can pass true
11
+ # Person.connect(FellowshipOneAPI::Client.new, true)
12
+ def self.connect(client, refresh = false)
13
+ if(refresh or @connection.nil?)
14
+ @connection = Connection.new(client, client.consumer.site, format)
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ require 'nokogiri'
2
+
3
+ module FellowshipOneAPI
4
+ # Creating a wrapper for the ActiveResource::Connection class
5
+ class Connection < ActiveResource::Connection
6
+ # Pass in a new connection to the API
7
+ def initialize(f1api_connection, *args)
8
+ @f1api_connection = f1api_connection
9
+ super(*args)
10
+ end
11
+
12
+ private
13
+ # The request method that is passes the request through to the F1 API client
14
+ def request(method, path, *args)
15
+ if @f1api_connection == nil
16
+ super(method, path, *args)
17
+ else
18
+ response = @f1api_connection.request(method, path, *args)
19
+
20
+ if method == :get
21
+ response.body = transform_response response.body, path
22
+ end
23
+ handle_response(response)
24
+ end
25
+ end
26
+
27
+ #
28
+ def transform_response(response_body, path)
29
+ n = Nokogiri::XML(response_body)
30
+ res = (n/"results")
31
+ if not (res.empty?)
32
+ resource = ((path.split '/')[2]).downcase
33
+ res[0].name = resource
34
+ end
35
+
36
+ n.to_s
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,62 @@
1
+ module FellowshipOneAPI
2
+ # ==The Fellowship One API client class
3
+ # Takes an HTTP request and passes it through the OAuth library which added the approperiate headers and querystring
4
+ # parameters.
5
+ # ===Examples
6
+ # [Simple client using OAuth and default YAML config values]
7
+ # client = FellowshipOneAPI::Client.new
8
+ #
9
+ # client.authorize!
10
+ #
11
+ # client.request(:get, '/v1/People/123.xml')
12
+ #
13
+ # [Using credentials based authentication (2nd party)]
14
+ # client = FellowshipOneAPI::Client.new({:auth_type => :credentials})
15
+ #
16
+ # client.authorize!("username", "password")
17
+ #
18
+ # client.request(:get, '/v1/People/123.xml')
19
+ #
20
+ # [Authenticating against weblink passing credentials]
21
+ # client = FellowshipOneAPI::Client.new({:auth_type => :credentials, :auth_against => :weblink})
22
+ #
23
+ # client.authorize("weblinkuser", "weblinkpassword")
24
+ #
25
+ # client.request(:get, '/v1/People/123.xml')
26
+ #
27
+ # [Loading a client with an existing access token]
28
+ # client = FellowshipOneAPI::Client.new({:oauth_token => "123456", :oauth_token_secret => "987654"})
29
+ #
30
+ # client.request(:get, '/v1/People/123.xml')
31
+ class Client
32
+ # Creates a new instance of a client used to connect with the Fellowship One API
33
+ # The client can be configured with the following symbols:
34
+ # [+:auth_type+] - Can be _:credentials_ or _:oauth_ (_:oauth_ is the default)
35
+ # [+:auth_against+] - Can be _:portal_ or _:weblink_ (_:portal_ is the default)
36
+ # [+:oauth_token+] - The access token
37
+ # [+:oauth_token_secret+] - The access token secret
38
+ def initialize(args = {})
39
+ args[:auth_type] ||= Configuration.authentication_type.to_sym
40
+ if args[:auth_type] == :credentials
41
+ extend OAuth::CredentialsAuthentication
42
+ else
43
+ extend OAuth::OAuthAuthentication
44
+ end
45
+
46
+ if(args[:auth_against])
47
+ load_consumer_config args[:auth_against]
48
+ else
49
+ load_consumer_config
50
+ end
51
+
52
+ if(args[:oauth_token] and args[:oauth_token_secret])
53
+ @oauth_access_token = ::OAuth::AccessToken.from_hash(@oauth_consumer, args[:oauth_token], args[:oauth_token_secret])
54
+ end
55
+ end
56
+
57
+ # Passes through the request to the OAuth library to be signed and set out HTTP
58
+ def request(*args)
59
+ @oauth_access_token.request(*args)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,63 @@
1
+ module FellowshipOneAPI # :nodoc:
2
+ # This accesses the YAML-based F1 API config file
3
+ #
4
+ # This class was written to take rails environment variables like +RAILS_ENV+ and +Rails.root+ into account
5
+ class Configuration
6
+ # Explictly defines where the configuration file is
7
+ def self.file_path=(path)
8
+ @file_path
9
+ end
10
+
11
+ # Gets the specified key from the configuration file
12
+ # [Example] FellowshipTechAPIClient.Configuration["consumer_key"] <i># "2"</i>
13
+ #
14
+ # FellowshipTechAPIClient.Configuration["consumer_secret"] <i># "12345678-9abc-def0-1234-567890abcdef"</i>
15
+ def self.[](value)
16
+ load_yaml if @config_yaml.nil?
17
+ val = @config_yaml[self.environment][value]
18
+ # if we have the string has "{church_code}" then we'll substitute it
19
+ if val =~ /\{church_code\}/ and value != "church_code"
20
+ return val.gsub("{church_code}", self["church_code"])
21
+ end
22
+ return val
23
+ end
24
+
25
+ # Gets the current environment
26
+ def self.environment
27
+ @environment ||= "development"
28
+ @environment ||= ::Rails.env if defined? ::Rails
29
+ @environment
30
+ end
31
+
32
+ # Set the current environment
33
+ def self.environment=(env_value)
34
+ @environment = env_value
35
+ end
36
+
37
+ # Overridden method_missing to facilitate a more pleasing ruby-like syntax for accessing
38
+ # configuration values
39
+ def self.method_missing(name, *args, &block)
40
+ return self[name.to_s] unless self[name.to_s].nil?
41
+ super
42
+ end
43
+
44
+ private
45
+
46
+ # Loads the YAML file
47
+ #
48
+ # Starts by looking to see if file_path is defined then checks in current directory (.) and then your Rails.root and then the config
49
+ # directory off of the base directory of the gem
50
+ def self.load_yaml
51
+ if not @file_path.nil?
52
+ @config_yaml = YAML.load_file(@file_path)
53
+ elsif File.exists? "./f1-oauth.yml"
54
+ @config_yaml = YAML.load_file("./f1-oauth.yml")
55
+ elsif defined? ::Rails
56
+ @config_yaml = YAML.load_file("#{::Rails.root}/config/f1-oauth.yml")
57
+ else
58
+ path = File.dirname(__FILE__) + "/../../config/f1-oauth.yml"
59
+ @config_yaml = YAML.load_file(path)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,54 @@
1
+ module FellowshipOneAPI # :nodoc:
2
+ # Wrapper around the OAuth v1.0 specification using the +oauth+ gem.
3
+ #
4
+ # The Fellowship One API has two methods of authentication:
5
+ # [OAuthAuthentication] This is the default method if no method is declared. This method allows Fellowship Tech to handle
6
+ # the authentication and we redirect back to your app.
7
+ # [CredentialsAuthentication] The methods lets the consumer submit credentials and verify authentication.
8
+ module OAuth
9
+ # The OAuth consumer key.
10
+ # This will get set automatically from the YAML config file if not set explictly
11
+ attr_accessor :oauth_consumer_key
12
+ alias :consumer_key :oauth_consumer_key
13
+ alias :consumer_key= :oauth_consumer_key=
14
+
15
+ # The OAuth consumer secret.
16
+ # This will get set automatically from the YAML config file if not set explictly
17
+ attr_accessor :oauth_consumer_secret
18
+ alias :consumer_secret :oauth_consumer_secret
19
+ alias :consumer_secret= :oauth_consumer_secret=
20
+
21
+ # The OAuth access token object where all requests are made off of
22
+ attr_reader :oauth_access_token
23
+ alias :access_token :oauth_access_token
24
+
25
+ # The OAuth consumer object
26
+ attr_reader :oauth_consumer
27
+ alias :consumer :oauth_consumer
28
+
29
+ # The URI for the resource of the authenticated user
30
+ attr_reader :authenticated_user_uri
31
+
32
+ # Creates the OAuth consumer object
33
+ def load_consumer_config(type = :portal)
34
+ case type
35
+ when :portal
36
+ authorize_path = FellowshipOneAPI::Configuration.portal_authorize_path
37
+ when :weblink
38
+ authorize_path = FellowshipOneAPI::Configuration.weblink_authorize_path
39
+ end
40
+
41
+ @oauth_consumer_key ||= FellowshipOneAPI::Configuration.consumer_key
42
+ @oauth_consumer_secret ||= FellowshipOneAPI::Configuration.consumer_secret
43
+
44
+ @oauth_consumer = ::OAuth::Consumer.new(@oauth_consumer_key,
45
+ @oauth_consumer_secret,
46
+ {:site => FellowshipOneAPI::Configuration.site_url,
47
+ :request_token_path => FellowshipOneAPI::Configuration.request_token_path,
48
+ :access_token_path => FellowshipOneAPI::Configuration.access_token_path,
49
+ :authorize_path => authorize_path })
50
+ end
51
+
52
+
53
+ end
54
+ end
@@ -0,0 +1,59 @@
1
+ module FellowshipOneAPI # :nodoc:
2
+ module OAuth
3
+ # Implements the Credentials method of authentication. You must manage the credentials.
4
+ module CredentialsAuthentication
5
+ include OAuth
6
+ # Authorizes a user
7
+ # +username+:: The username of the user
8
+ # +password+:: The password of the user
9
+ # +type+:: Can be :portal or :weblink based on which credentials you want to authenticate against
10
+ # Returns the URI for the authenticated user
11
+ def authorize!(username, password, type = :portal)
12
+ load_consumer_config(type) if @oauth_consumer.nil?
13
+
14
+ @oauth_request = @oauth_consumer.get_request_token
15
+ cred = URI.encode(Base64.encode64("#{username} #{password}"))
16
+
17
+ case type
18
+ when :portal
19
+ auth_url = FellowshipOneAPI::Configuration.portal_credential_token_path
20
+ when :weblink
21
+ auth_url = FellowshipOneAPI::Configuration.weblink_credential_token_path
22
+ end
23
+
24
+ response = @oauth_consumer.request(:post, auth_url, nil, {}, "ec=#{cred}", {'Content-Type' => 'application/x-www-form-urlencoded'})
25
+
26
+ handle_response_code(response)
27
+
28
+ # Gettting the URI of the authenticated user
29
+ @authenticated_user_uri = response["Content-Location"]
30
+ end
31
+
32
+ private
33
+ def handle_response_code(response)
34
+ case response.code.to_i
35
+ when (200..299)
36
+ @oauth_access_token = ::OAuth::AccessToken.from_hash(@oauth_consumer, parse_access_token(response.body))
37
+ when (300..399)
38
+ # redirect
39
+ # TODO: actually redirect instead of throwing error
40
+ response.error!
41
+ when (400..499)
42
+ raise OAuth::Unauthorized, response
43
+ else
44
+ response.error!
45
+ end
46
+ end
47
+
48
+ # Parse returned OAuth access token key/secret pair
49
+ def parse_access_token(response)
50
+ oauth_hash = {}
51
+ response.split('&').each do |val|
52
+ kv = val.split('=')
53
+ oauth_hash.merge!({kv[0].to_sym => kv[1]})
54
+ end
55
+ oauth_hash
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,72 @@
1
+ module FellowshipOneAPI # :nodoc:
2
+ module OAuth
3
+ # Implements the pure OAuth method of authentication. This allows the Fellowship One API to
4
+ # manage the authentication process.
5
+ module OAuthAuthentication
6
+ include OAuth
7
+ # The OAuth request object
8
+ attr_reader :oauth_request
9
+
10
+ # The OAuth authorization URI
11
+ attr_reader :oauth_authorize_url
12
+ alias :authorize_url :oauth_authorize_url
13
+
14
+ # Gets a new request token and return the authorize URI
15
+ # +type+:: Can be :portal or :weblink based on which credentials you want to authenticate against
16
+ def authorize!(type = :portal)
17
+ load_consumer_config(type) if oauth_consumer.nil?
18
+
19
+ @oauth_request = oauth_consumer.get_request_token
20
+ @oauth_authorize_url = oauth_request.authorize_url
21
+
22
+ @oauth_consumer.instance_eval do
23
+ # The token request reponse is scoped only in the token_request method, but I need to get access to the response
24
+ # headers so that I can pull back the Content-Location header and get the authenticated user URI
25
+ def token_request(http_method, path, token = nil, request_options = {}, *arguments)
26
+ @tr_response = request(http_method, path, token, request_options, *arguments)
27
+ case @tr_response.code.to_i
28
+
29
+ when (200..299)
30
+ if block_given?
31
+ yield @tr_response.body
32
+ else
33
+ # symbolize keys
34
+ # TODO this could be considered unexpected behavior; symbols or not?
35
+ # TODO this also drops subsequent values from multi-valued keys
36
+ CGI.parse(@tr_response.body).inject({}) do |h,(k,v)|
37
+ h[k.strip.to_sym] = v.first
38
+ h[k.strip] = v.first
39
+ h
40
+ end
41
+ end
42
+ when (300..399)
43
+ # this is a redirect
44
+ @tr_response.error!
45
+ when (400..499)
46
+ raise OAuth::Unauthorized, @tr_response
47
+ else
48
+ @tr_response.error!
49
+ end
50
+ end
51
+
52
+ # The HTTP response from token_request
53
+ def token_request_response
54
+ @tr_response
55
+ end
56
+ end
57
+
58
+ oauth_authorize_url
59
+ end
60
+
61
+ # After a the user has been authenticated then we use the access token to access protected resources in the API.
62
+ # Since the authentication has taken place, we now know about the user that authenticated and
63
+ # have a URI to the record of that user.
64
+ #
65
+ # The URI for the authenticated user is returned.
66
+ def get_access_token
67
+ @oauth_access_token = oauth_request.get_access_token
68
+ @authenticated_user_uri = oauth_consumer.token_request_response["Content-Location"]
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'oauth'
3
+
4
+ class AccessTokenFixture
5
+ def self.get(oauth_consumer)
6
+ @token = "access"
7
+ @secret = "token"
8
+ return ::OAuth::AccessToken.new(oauth_consumer, @token, @secret)
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ class HttpFixture
2
+ def body
3
+ "oauth_token=access&oauth_token_secret=token"
4
+ end
5
+
6
+ def [](value)
7
+ {'Content-Location' => "#{FellowshipOneAPI::Configuration.site_url}/V1/People/123456"}[value]
8
+ end
9
+
10
+ def code
11
+ "200"
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'oauth'
3
+
4
+ class RequestTokenFixture
5
+ def self.get(oauth_consumer)
6
+ @token = "request"
7
+ @secret = "token"
8
+ return ::OAuth::RequestToken.new(oauth_consumer, @token, @secret)
9
+ end
10
+ end
@@ -0,0 +1,60 @@
1
+ class OAuthTest < Test::Unit::TestCase
2
+ include FellowshipOneAPI
3
+
4
+ def setup
5
+ Configuration.environment = "test"
6
+ Configuration.file_path = "#{File.dirname(__FILE__)}/../../config/f1-oauth.yml"
7
+ end
8
+
9
+ def test_method_missing
10
+ assert_raise NoMethodError do
11
+ Configuration.asdf
12
+ end
13
+
14
+ assert_nothing_raised do
15
+ Configuration.consumer_key
16
+ end
17
+
18
+ assert_equal Configuration["consumer_key"], Configuration.consumer_key
19
+ end
20
+
21
+ def test_consumer_key
22
+ assert_equal("123456789", Configuration.consumer_key)
23
+ end
24
+
25
+ def test_consumer_secret
26
+ assert_equal("12345678-90ab-cdef-0123-4567890abcde", Configuration.consumer_secret)
27
+ end
28
+
29
+ def test_site_url
30
+ assert_equal("https://test.staging.fellowshiponeapi.com", Configuration.site_url)
31
+ end
32
+
33
+ def test_church_code
34
+ assert_equal("test", Configuration.church_code)
35
+ end
36
+
37
+ def test_request_token_path
38
+ assert_equal("/V1/Tokens/RequestToken", Configuration.request_token_path)
39
+ end
40
+
41
+ def test_access_token_path
42
+ assert_equal("/V1/Tokens/AccessToken", Configuration.access_token_path)
43
+ end
44
+
45
+ def test_portal_authorize_path
46
+ assert_equal("/V1/PortalUser/Login", Configuration.portal_authorize_path)
47
+ end
48
+
49
+ def test_weblink_authorize_path
50
+ assert_equal("/V1/WeblinkUser/Login", Configuration.weblink_authorize_path)
51
+ end
52
+
53
+ def test_portal_credential_token_path
54
+ assert_equal("/V1/PortalUser/AccessToken", Configuration.portal_credential_token_path)
55
+ end
56
+
57
+ def test_weblink_credential_token_path
58
+ assert_equal("/V1/WeblinkUser/AccessToken", Configuration.weblink_credential_token_path)
59
+ end
60
+ end
@@ -0,0 +1,59 @@
1
+ class CredentialsAuthenticationTest
2
+ include FellowshipOneAPI::OAuth::CredentialsAuthentication
3
+ attr_accessor :oauth_consumer
4
+ end
5
+
6
+ class CredentialsTest < Test::Unit::TestCase
7
+ include FellowshipOneAPI
8
+ def setup
9
+ Configuration.environment = "test"
10
+ Configuration.file_path = "#{File.dirname(__FILE__)}/../../config/f1-oauth.yml"
11
+
12
+ @test_username = "testuser"
13
+ @test_password = "testpass"
14
+
15
+ @cred_test = CredentialsAuthenticationTest.new
16
+ @cred_test.load_consumer_config
17
+ @mocked_access_token = AccessTokenFixture.get(@cred_test.oauth_consumer)
18
+ @mocked_request_token = RequestTokenFixture.get(@cred_test.oauth_consumer)
19
+ cred = URI.encode(Base64.encode64("#{@test_username} #{@test_password}"))
20
+
21
+ @mocked_user_uri = "#{Configuration.site_url}/V1/People/123456"
22
+
23
+ @cred_test.oauth_consumer.stubs(:get_request_token).returns(@mocked_request_token)
24
+
25
+ @cred_test.oauth_consumer.stubs(:request).with(:post, ::FellowshipOneAPI::Configuration.portal_credential_token_path,
26
+ nil, {}, "ec=#{cred}", {'Content-Type' => 'application/x-www-form-urlencoded'}).
27
+ returns(HttpFixture.new)
28
+ end
29
+
30
+ def test_portal_authorize!
31
+ actual = @cred_test.authorize! @test_username, @test_password
32
+
33
+ assert_equal(@mocked_user_uri, actual)
34
+ end
35
+
36
+ def test_weblink_authorize!
37
+ cred = URI.encode(Base64.encode64("#{@test_username} #{@test_password}"))
38
+ @cred_test.oauth_consumer = nil
39
+ @cred_test.load_consumer_config(:weblink)
40
+ @cred_test.oauth_consumer.expects(:get_request_token).returns(@mocked_request_token).at_least_once
41
+ @cred_test.oauth_consumer.expects(:request).with(:post, ::FellowshipOneAPI::Configuration.weblink_credential_token_path,
42
+ nil, {}, "ec=#{cred}", {'Content-Type' => 'application/x-www-form-urlencoded'}).returns(
43
+ HttpFixture.new).at_least_once
44
+ @cred_test.authorize! @test_username, @test_password, :weblink
45
+ end
46
+
47
+ def test_get_access_token
48
+ @cred_test.authorize! @test_username, @test_password
49
+
50
+ assert_equal("access", @cred_test.access_token.token)
51
+ assert_equal("token", @cred_test.access_token.secret)
52
+ end
53
+
54
+ def test_authorized_user_uri
55
+ @cred_test.authorize! @test_username, @test_password
56
+
57
+ assert_equal(@mocked_user_uri, @cred_test.authenticated_user_uri)
58
+ end
59
+ end
@@ -0,0 +1,74 @@
1
+ class OAuthAuthenticationTest
2
+ include FellowshipOneAPI::OAuth::OAuthAuthentication
3
+ attr_accessor :oauth_consumer
4
+ end
5
+
6
+ class OAuthTest < Test::Unit::TestCase
7
+ include FellowshipOneAPI
8
+ def setup
9
+ Configuration.environment = "test"
10
+ Configuration.file_path = "#{File.dirname(__FILE__)}/../../config/f1-oauth.yml"
11
+
12
+ @oauth_test = OAuthAuthenticationTest.new
13
+ @oauth_test.load_consumer_config
14
+ @mocked_request_token = RequestTokenFixture.get(@oauth_test.oauth_consumer)
15
+ @mocked_access_token = AccessTokenFixture.get(@oauth_test.oauth_consumer)
16
+ @oauth_test.oauth_consumer.stubs(:get_request_token).returns(@mocked_request_token)
17
+ end
18
+
19
+ def test_portal_authorize!
20
+ @oauth_test.oauth_consumer.expects(:get_request_token).returns(@mocked_request_token)
21
+
22
+ assert_equal("#{Configuration.site_url}#{Configuration.portal_authorize_path}?oauth_token=request", @oauth_test.authorize!)
23
+
24
+ assert_equal("request", @oauth_test.oauth_request.token)
25
+ assert_equal("token", @oauth_test.oauth_request.secret)
26
+ assert_equal("#{Configuration.site_url}#{Configuration.portal_authorize_path}?oauth_token=#{@oauth_test.oauth_request.token}", @oauth_test.authorize_url)
27
+ end
28
+
29
+ def test_weblink_authorize!
30
+ @oauth_test.oauth_consumer = nil
31
+ @oauth_test.load_consumer_config(:weblink)
32
+ @mocked_request_token = RequestTokenFixture.get(@oauth_test.oauth_consumer)
33
+ @oauth_test.oauth_consumer.expects(:get_request_token).returns(@mocked_request_token)
34
+
35
+ @oauth_test.authorize!(:weblink)
36
+
37
+ assert_equal("request", @oauth_test.oauth_request.token)
38
+ assert_equal("token", @oauth_test.oauth_request.secret)
39
+ assert_equal("#{Configuration.site_url}#{Configuration.weblink_authorize_path}?oauth_token=#{@oauth_test.oauth_request.token}", @oauth_test.authorize_url)
40
+ end
41
+
42
+ def test_get_access_token
43
+ @oauth_test.authorize!
44
+
45
+ @oauth_test.oauth_request.expects(:get_access_token).returns(@mocked_access_token)
46
+ @oauth_test.oauth_consumer.expects(:token_request_response).returns({"Content-Location" => ""})
47
+ @oauth_test.get_access_token
48
+
49
+ assert_equal("access", @oauth_test.access_token.token)
50
+ assert_equal("token", @oauth_test.access_token.secret)
51
+ end
52
+
53
+ def test_authorized_user_uri
54
+ mocked_user_uri = "#{Configuration.site_url}/V1/People/123456"
55
+
56
+ @oauth_test.authorize!
57
+
58
+ @oauth_test.oauth_request.expects(:get_access_token).returns(@mocked_access_token)
59
+ @oauth_test.oauth_consumer.expects(:token_request_response).returns({"Content-Location" => mocked_user_uri})
60
+ @oauth_test.get_access_token
61
+
62
+ assert_equal(mocked_user_uri, @oauth_test.authenticated_user_uri)
63
+ end
64
+
65
+ def test_change_auth_types
66
+ @oauth_test.authorize!
67
+ assert_equal("#{Configuration.site_url}#{Configuration.portal_authorize_path}", @oauth_test.oauth_consumer.authorize_url)
68
+ @oauth_test.load_consumer_config(:weblink)
69
+ @oauth_test.oauth_consumer.stubs(:get_request_token).returns(@mocked_request_token)
70
+ @oauth_test.authorize!
71
+ assert_equal("#{Configuration.site_url}#{Configuration.weblink_authorize_path}", @oauth_test.oauth_consumer.authorize_url)
72
+ end
73
+
74
+ end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: f1api
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 9
8
+ - 0
9
+ version: 0.9.0
10
+ platform: ruby
11
+ authors:
12
+ - Jesse Dearing
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-19 00:00:00 -06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: nokogiri
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ prerelease: false
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: oauth
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - "="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 0
42
+ - 4
43
+ - 4
44
+ version: 0.4.4
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: mocha
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ type: :runtime
59
+ prerelease: false
60
+ version_requirements: *id003
61
+ - !ruby/object:Gem::Dependency
62
+ name: activeresource
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: *id004
74
+ - !ruby/object:Gem::Dependency
75
+ name: oauth
76
+ requirement: &id005 !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - "="
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
83
+ - 4
84
+ - 4
85
+ version: 0.4.4
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: *id005
89
+ - !ruby/object:Gem::Dependency
90
+ name: mocha
91
+ requirement: &id006 !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *id006
102
+ - !ruby/object:Gem::Dependency
103
+ name: activeresource
104
+ requirement: &id007 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ type: :runtime
113
+ prerelease: false
114
+ version_requirements: *id007
115
+ description: "Consumes the Fellowship One API in your apps using ActiveResource. Implements 2nd party credentials-based authenticaion and full OAuth implementation. "
116
+ email: jdearing@fellowshiptech.com
117
+ executables: []
118
+
119
+ extensions: []
120
+
121
+ extra_rdoc_files:
122
+ - LICENSE
123
+ - README.md
124
+ files:
125
+ - Gemfile
126
+ - Gemfile.lock
127
+ - LICENSE
128
+ - README.md
129
+ - Rakefile
130
+ - VERSION
131
+ - VERSION.yml
132
+ - config/f1-oauth.yml
133
+ - lib/f1api.rb
134
+ - lib/f1api/activeresource/base.rb
135
+ - lib/f1api/activeresource/connection.rb
136
+ - lib/f1api/client.rb
137
+ - lib/f1api/configuration.rb
138
+ - lib/f1api/oauth.rb
139
+ - lib/f1api/oauth/credentials_authentication.rb
140
+ - lib/f1api/oauth/oauth_authentication.rb
141
+ - test/fixtures/access_token.rb
142
+ - test/fixtures/http.rb
143
+ - test/fixtures/request_token.rb
144
+ - test/unit/configuration_test.rb
145
+ - test/unit/credentials_test.rb
146
+ - test/unit/oauth_test.rb
147
+ has_rdoc: true
148
+ homepage: http://github.com/jessedearing/f1api
149
+ licenses:
150
+ - MIT
151
+ post_install_message:
152
+ rdoc_options: []
153
+
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ none: false
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ segments:
162
+ - 0
163
+ version: "0"
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ none: false
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ segments:
170
+ - 0
171
+ version: "0"
172
+ requirements: []
173
+
174
+ rubyforge_project:
175
+ rubygems_version: 1.3.7
176
+ signing_key:
177
+ specification_version: 3
178
+ summary: Consume the Fellowship One API in your apps using ActiveResource
179
+ test_files:
180
+ - test/fixtures/access_token.rb
181
+ - test/fixtures/http.rb
182
+ - test/fixtures/request_token.rb
183
+ - test/unit/configuration_test.rb
184
+ - test/unit/credentials_test.rb
185
+ - test/unit/oauth_test.rb