sns_endpoint 0.1

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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sns_endpoint.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Piotr Szmielew
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,59 @@
1
+ # SnsEndpoint
2
+
3
+ Simple gem containing Sinatra engine, designed to help you utilize SNS http post service.
4
+ Use inside Rails (as an engine) or outside - as a standalone application.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'sns_endpoint'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install sns_endpoint
19
+
20
+ ## Usage
21
+
22
+ Configure using SnsEndpoint.setup, providing block, like this:
23
+ ```ruby
24
+ SnsEndpoint.setup do |config|
25
+ config.topics_list = ['first_topic', 'second_topic'] #list of topics that endpoint should respond to subscription request
26
+ config.subscribe_proc = Proc.new { |message| p message } #proc that should be executed when subscribe request got received and responded to, passed argument is message (json object)
27
+ config.message_proc = Proc.new { |message| p message } #proc that should be executed when message got send to endpoint
28
+ end
29
+ ```
30
+
31
+ for example in Rails initializer.
32
+
33
+ Use as Rails engine:
34
+
35
+ * mount in routes.rb:
36
+ ```ruby
37
+ mount SnsEndpoint::Core => "/sns_endpoint"
38
+ ```
39
+
40
+ Use as a standalone app:
41
+ Example script:
42
+ ```ruby
43
+ require 'rubygems'
44
+ require 'sns_endpoint'
45
+ SnsEndpoint.setup do |config|
46
+ config.topics_list = ['first_topic', 'second_topic'] #list of topics that endpoint should respond to subscription request
47
+ config.subscribe_proc = Proc.new { |message| p message } #proc that should be executed when subscribe request got received and responded to, passed argument is message (json object)
48
+ config.message_proc = Proc.new { |message| p message } #proc that should be executed when message got send to endpoint
49
+ end
50
+ SnsEndpoint::Core.run!
51
+ ```
52
+
53
+ ## Contributing
54
+
55
+ 1. Fork it
56
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
57
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
58
+ 4. Push to the branch (`git push origin my-new-feature`)
59
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,159 @@
1
+ # Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+
15
+ #modyfied version of message.rb from Aws-sdk fork by petemounce
16
+
17
+ require 'base64'
18
+ require 'json'
19
+ require 'openssl'
20
+ require 'httparty'
21
+
22
+ module SnsEndpoint
23
+ module AWS
24
+ class SNS
25
+ class MessageWasNotAuthenticError < StandardError
26
+ end
27
+ class Message
28
+ attr_accessor :origin, :raw
29
+
30
+ def initialize sns
31
+ if sns.is_a? String
32
+ @raw = parse_from sns
33
+ else
34
+ @raw = sns
35
+ end
36
+ @origin = :sns
37
+ end
38
+
39
+ def [] key
40
+ @raw[key]
41
+ end
42
+
43
+ def authentic?
44
+ begin
45
+ decoded_from_base64 = decode signature
46
+ public_key = get_public_key_from signing_cert_url
47
+ public_key.verify OpenSSL::Digest::SHA1.new, decoded_from_base64, canonical_string
48
+ rescue MessageWasNotAuthenticError
49
+ false
50
+ end
51
+ end
52
+
53
+ def type
54
+ case when @raw['Type'] =~ /SubscriptionConfirmation/i
55
+ then :SubscriptionConfirmation
56
+ when @raw['Type'] =~ /Notification/i
57
+ then :Notification
58
+ when @raw['Type'] =~ /UnsubscribeConfirmation/i
59
+ then :UnsubscribeConfirmation
60
+ else
61
+ :unknown
62
+ end
63
+ end
64
+
65
+ def message_id
66
+ @raw['MessageId']
67
+ end
68
+
69
+ def topic_arn
70
+ @raw['TopicArn']
71
+ end
72
+
73
+ def subject
74
+ @raw['Subject']
75
+ end
76
+
77
+ def message
78
+ @raw['Message']
79
+ end
80
+
81
+ def timestamp
82
+ @raw['Timestamp']
83
+ end
84
+
85
+ def signature
86
+ @raw['Signature']
87
+ end
88
+
89
+ def signature_version
90
+ @raw['SignatureVersion']
91
+ end
92
+
93
+ def signing_cert_url
94
+ @raw['SigningCertURL']
95
+ end
96
+
97
+ def unsubscribe_url
98
+ @raw['UnsubscribeURL']
99
+ end
100
+
101
+ def subscribe_url
102
+ @raw['SubscribeURL']
103
+ end
104
+
105
+ def token
106
+ @raw['Token']
107
+ end
108
+
109
+ def parse_from json
110
+ JSON.parse json
111
+ end
112
+
113
+ protected
114
+ def decode raw
115
+ Base64.decode64 raw
116
+ end
117
+
118
+ def get_public_key_from(x509_pem_url)
119
+ cert_pem = download x509_pem_url
120
+ x509 = OpenSSL::X509::Certificate.new(cert_pem)
121
+ OpenSSL::PKey::RSA.new(x509.public_key)
122
+ end
123
+
124
+ def canonical_string
125
+ if type == :SubscriptionConfirmation
126
+ text = "Message\n#{message}\n"
127
+ text += "MessageId\n#{message_id}\n"
128
+ text += "SubscribeURL\n#{subscribe_url}\n"
129
+ text += "Timestamp\n#{timestamp}\n"
130
+ text += "Token\n#{token}\n"
131
+ text += "TopicArn\n#{topic_arn}\n"
132
+ text += "Type\n#{type}\n"
133
+ else
134
+ text = "Message\n#{message}\n"
135
+ text += "MessageId\n#{message_id}\n"
136
+ text += "Subject\n#{subject}\n" unless subject.nil? or subject.empty?
137
+ text += "Timestamp\n#{timestamp}\n"
138
+ text += "TopicArn\n#{topic_arn}\n"
139
+ text += "Type\n#{type}\n"
140
+ end
141
+ text
142
+ end
143
+
144
+ def download url
145
+ raise MessageWasNotAuthenticError, "cert is not hosted at AWS URL (https): #{url}" unless url =~ /^https.*amazonaws\.com\/.*$/i
146
+ tries = 0
147
+ begin
148
+ response = HTTParty.get url
149
+ response.body
150
+ rescue => msg
151
+ tries += 1
152
+ retry if tries <= 3
153
+ raise StandardError, "SNS signing cert could not be retrieved after #{tries} tries.\n#{msg}"
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,36 @@
1
+ require "rubygems"
2
+ require 'bundler/setup'
3
+ require "sns_endpoint/version"
4
+ require 'sinatra'
5
+ require 'json'
6
+ require 'message'
7
+
8
+ module SnsEndpoint
9
+
10
+ class << self
11
+ attr_accessor :topics_list, :subscribe_proc, :message_proc
12
+ end
13
+
14
+ def self.setup(&block)
15
+ yield self
16
+ end
17
+
18
+ class Core < Sinatra::Base
19
+
20
+ post '/' do
21
+ json = JSON.parse(request.body.read)
22
+ sns = SnsEndpoint::AWS::SNS::Message.new json
23
+ if sns.authentic?
24
+ if sns.type == :SubscriptionConfirmation
25
+ if SnsEndpoint.topics_list.include? json['TopicArn']
26
+ HTTParty.get json['SubscribeURL']
27
+ SnsEndpoint.subscribe_proc.call(json)
28
+ end
29
+ elsif sns.type == :Notification
30
+ SnsEndpoint.message_proc.call(json)
31
+ end
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module SnsEndpoint
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/sns_endpoint/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Piotr Szmielew"]
6
+ gem.email = ["p.szmielew@ava.waw.pl"]
7
+ gem.description = %q{Gem containing sinatra engine to utilize SNS notifications.}
8
+ gem.summary = %q{Gem containing sinatra engine to utilize SNS notifications.}
9
+ gem.homepage = "http://github.com/elibri/sns_endpoint"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "sns_endpoint"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = SnsEndpoint::VERSION
17
+
18
+
19
+ gem.add_runtime_dependency "httparty"
20
+ gem.add_runtime_dependency "sinatra"
21
+ gem.add_runtime_dependency "json"
22
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sns_endpoint
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Piotr Szmielew
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-06-24 00:00:00 Z
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: httparty
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 3
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: sinatra
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ hash: 3
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :runtime
46
+ version_requirements: *id002
47
+ - !ruby/object:Gem::Dependency
48
+ name: json
49
+ prerelease: false
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ type: :runtime
60
+ version_requirements: *id003
61
+ description: Gem containing sinatra engine to utilize SNS notifications.
62
+ email:
63
+ - p.szmielew@ava.waw.pl
64
+ executables: []
65
+
66
+ extensions: []
67
+
68
+ extra_rdoc_files: []
69
+
70
+ files:
71
+ - .gitignore
72
+ - Gemfile
73
+ - LICENSE
74
+ - README.md
75
+ - Rakefile
76
+ - lib/message.rb
77
+ - lib/sns_endpoint.rb
78
+ - lib/sns_endpoint/version.rb
79
+ - sns_endpoint.gemspec
80
+ homepage: http://github.com/elibri/sns_endpoint
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options: []
85
+
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ hash: 3
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ requirements: []
107
+
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.21
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Gem containing sinatra engine to utilize SNS notifications.
113
+ test_files: []
114
+