koinz 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in koinz.gemspec
4
+ gemspec
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/koinz.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "koinz/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "koinz"
7
+ s.version = Koinz::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Gautam Rege"]
10
+ s.email = ["gautam@joshsoftware.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{The koinz client library - for oauth & notification management}
13
+ s.description = %q{Koinz clients require authentication via oauth koinz provider. They can also publish/subscribe for notifications in the koinz environment. }
14
+
15
+ s.rubyforge_project = "koinz"
16
+
17
+ s.add_dependency('redis')
18
+ s.add_dependency('omniauth')
19
+ s.add_dependency('multi_json')
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+ end
@@ -0,0 +1,49 @@
1
+ require 'omniauth/oauth'
2
+ require 'multi_json'
3
+
4
+ module OmniAuth
5
+ module Strategies
6
+ class Koinz < OAuth2
7
+
8
+ def initialize(app, api_key = nil, secret_key = nil, options = {}, &block)
9
+ client_options = {
10
+ :site => KOINZ_PROVIDER_URL,
11
+ :authorize_url => "#{KOINZ_PROVIDER_URL}/auth/koinz/authorize",
12
+ :access_token_url => "#{KOINZ_PROVIDER_URL}/auth/koinz/access_token"
13
+ }
14
+ super(app, :koinz, api_key, secret_key, client_options, &block)
15
+ end
16
+
17
+ def secure_callback_url
18
+ SECURE_CALLBACK_HOST + "#{OmniAuth.config.path_prefix}/#{name}/secure_callback"
19
+ end
20
+
21
+ protected
22
+
23
+ def user_data
24
+ @data ||= MultiJson.decode(@access_token.get("/auth/koinz/user.json"))
25
+ end
26
+
27
+ def request_phase
28
+ options[:scope] ||= "read"
29
+ super
30
+ end
31
+
32
+ def user_hash
33
+ user_data
34
+ end
35
+
36
+ def auth_hash
37
+ OmniAuth::Utils.deep_merge(super, {
38
+ 'uid' => user_data["uid"],
39
+ 'user_info' => user_data['user_info'],
40
+ 'extra' => {
41
+ 'admin' => user_data['extra']['admin'],
42
+ 'first_name' => user_data['extra']['first_name'],
43
+ 'last_name' => user_data['extra']['last_name'],
44
+ }
45
+ })
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,41 @@
1
+ require 'multi_json'
2
+
3
+ module Koinz
4
+ class Notification
5
+
6
+ # subscribe - its always pattern subscribe
7
+ # This is *always* spawned in a different thread. Eact SET of events
8
+ # is subscribed to in a different thread. You can call this multiple times.
9
+ # Please remember -- if you subscribe to common patterns. eg. f* and foo,
10
+ # you will receive the callback twice!!
11
+ def self.subscribe(*events, &block)
12
+ Thread.new do
13
+ # Since we gather the events as an array an not variable arguments,
14
+ # it is necessary to flatten the event array before passing it to
15
+ # psubscribe
16
+
17
+ # Process pending messages first!
18
+ REDIS_SUB.pending_messages(events.flatten, &block)
19
+
20
+ REDIS_SUB.psubscribe(*(events.flatten)) do |on|
21
+ on.psubscribe do |event, total|
22
+ Rails.logger.info("Subscribed to ##{event} (#{total} subscriptions)")
23
+ end
24
+
25
+ on.pmessage do |pattern, event, message|
26
+ block.call(event, MultiJson.decode(message))
27
+ end
28
+
29
+ on.punsubscribe do |event, total|
30
+ Rails.logger.info("Unsubscribed for ##{event} (#{total} subscriptions)")
31
+ end
32
+ end
33
+ end
34
+ Rails.logger.info("Exiting Koinz::Notification.subscribe")
35
+ end
36
+
37
+ def self.publish(event, payload)
38
+ REDIS.publish(event, payload)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,66 @@
1
+ require 'omniauth/oauth'
2
+ require 'multi_json'
3
+ require 'net/http'
4
+
5
+ module Koinz
6
+ module OAuth2Client
7
+
8
+ class UserManager
9
+ # @param [String] the access token
10
+ # @param [String] uri for invocation on remote host
11
+ # @param [Hash] options.
12
+ # :method => :get (default) [ :put, :post, :delete ]
13
+ # Example:
14
+ # Koinz::OAuth2::UserManager.call(@user_session.auth_token, '/users/sign_out.json')
15
+ def self.call(access_token, uri, options = {})
16
+ access_token = OAuth2::AccessToken.new($KOINZ_PROVIDER.client, access_token )
17
+
18
+ method = options.fetch(:method, :get)
19
+ result = access_token.send(method, uri)
20
+ result = MultiJson.decode(result)
21
+ rescue Exception => e
22
+ return { :error => e.message }
23
+ end
24
+
25
+ end
26
+
27
+ class Application
28
+ # @param [String] the access token
29
+ # @param [String] HOST to be contacted, eg. 'http://merchant.koinz.com'
30
+ # @param [String] uri for invocation on remote host (ONLY JSON supported)
31
+ # @param [Hash] params to be passed in the URL
32
+ # TODO: Do we need to support Http-post?
33
+ # Example:
34
+ # Koinz::OAuth2Client.Application.call(@user_session.auth_token, MERCHANT_APP, '/merchant', :name => 'name'
35
+ def self.call(access_token, host, uri, params = {})
36
+ # Prepare the entire URL
37
+ request_uri = "#{host}/#{uri}?access_token=#{access_token}"
38
+
39
+ # Add the params
40
+ params.each_pair do |k,v|
41
+ request_uri += "&#{k}=#{v}"
42
+ end
43
+
44
+ response = Net::HTTP.get_response(URI.parse(request_uri))
45
+ result = ActiveSupport::JSON.decode(response.body)
46
+ return result
47
+
48
+ rescue Exception => e
49
+ return { :error => e.message }
50
+ end
51
+
52
+ def self.secure_token(strategy)
53
+ client = strategy.client
54
+
55
+ req_params = client.web_server.access_token_params(nil, { :redirect_uri => strategy.secure_callback_url})
56
+ req_params.delete('code')
57
+
58
+ response = client.request(:post, client.access_token_url, req_params)
59
+ params = MultiJson.decode(response) rescue nil
60
+ params = Rack::Utils.parse_query(response) unless params.is_a? Hash
61
+
62
+ OAuth2::AccessToken.new(client, params['access_token'], params['refresh_token'], params['expires_in'])
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,44 @@
1
+ require 'redis'
2
+ require 'multi_json'
3
+
4
+ class KoinzRedis < Redis
5
+
6
+ def initialize(options = {})
7
+ @timestamp = options[:timestamp].to_i || 0 # 0 mean -- no backlog needed
8
+ super
9
+ end
10
+
11
+ def publish(channel, message)
12
+ timestamp = Time.now.to_i
13
+ zadd(channel, timestamp, MultiJson.encode([channel, message]))
14
+ super(channel, MultiJson.encode(message))
15
+ end
16
+
17
+ # returns the pending messages [ event, payload ] pairs
18
+ # Events are ordered sets based on timstamp!
19
+ def pending_messages(channels, &block)
20
+ return if @timestamp == 0
21
+
22
+ Rails.logger.info('Processing Pending messages')
23
+ events = channels.collect {|e| keys(e)}.flatten
24
+
25
+ return if not events or events.empty? # no events to process
26
+
27
+ destination = "pending-#{Time.now.to_i}"
28
+ zunionstore(destination, events)
29
+ # We want events only after the timestamp!
30
+ messages = zrangebyscore(destination, "(#{@timestamp.to_s}", "+inf")
31
+
32
+ # Pending messages are from sorted sets (ordered by timestamp)
33
+ # No need to send the timestamp for now -- but we store it just in case!
34
+ messages.each do |message|
35
+ event, payload = MultiJson.decode(message)
36
+ block.call(event, payload)
37
+ end
38
+
39
+ # cleanup
40
+ del(destination)
41
+
42
+ Rails.logger.info('Completed processing of pending messages')
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module Koinz
2
+ VERSION = "0.0.1"
3
+ end
data/lib/koinz.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'koinz/koinz'
2
+ require 'koinz/omniauth_client'
3
+ require 'koinz/redis'
4
+ require 'koinz/notification'
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: koinz
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Gautam Rege
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-05 00:00:00 +05:30
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: redis
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: omniauth
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: multi_json
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ description: "Koinz clients require authentication via oauth koinz provider. They can also publish/subscribe for notifications in the koinz environment. "
64
+ email:
65
+ - gautam@joshsoftware.com
66
+ executables: []
67
+
68
+ extensions: []
69
+
70
+ extra_rdoc_files: []
71
+
72
+ files:
73
+ - .gitignore
74
+ - Gemfile
75
+ - README
76
+ - Rakefile
77
+ - koinz.gemspec
78
+ - lib/koinz.rb
79
+ - lib/koinz/koinz.rb
80
+ - lib/koinz/notification.rb
81
+ - lib/koinz/omniauth_client.rb
82
+ - lib/koinz/redis.rb
83
+ - lib/koinz/version.rb
84
+ has_rdoc: true
85
+ homepage: ""
86
+ licenses: []
87
+
88
+ post_install_message:
89
+ rdoc_options: []
90
+
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ hash: 3
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ requirements: []
112
+
113
+ rubyforge_project: koinz
114
+ rubygems_version: 1.3.7
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: The koinz client library - for oauth & notification management
118
+ test_files: []
119
+