diversion 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +193 -0
- data/Rakefile +7 -0
- data/diversion.gemspec +40 -0
- data/lib/diversion.rb +35 -0
- data/lib/diversion/client.rb +21 -0
- data/lib/diversion/configurable.rb +100 -0
- data/lib/diversion/decode.rb +21 -0
- data/lib/diversion/decode/json.rb +47 -0
- data/lib/diversion/decode/params.rb +55 -0
- data/lib/diversion/encode.rb +67 -0
- data/lib/diversion/encode/json.rb +31 -0
- data/lib/diversion/encode/params.rb +26 -0
- data/lib/diversion/error.rb +2 -0
- data/lib/diversion/error/bad_url_data_format.rb +6 -0
- data/lib/diversion/error/configuration_error.rb +6 -0
- data/lib/diversion/error/key_missing_error.rb +6 -0
- data/lib/diversion/error/uri_missing_error.rb +6 -0
- data/lib/diversion/mailer.rb +11 -0
- data/lib/diversion/signing.rb +19 -0
- data/lib/diversion/url.rb +43 -0
- data/lib/diversion/version.rb +17 -0
- data/spec/coverage/assets/0.7.1/application.css +1110 -0
- data/spec/coverage/assets/0.7.1/application.js +626 -0
- data/spec/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
- data/spec/coverage/assets/0.7.1/favicon_green.png +0 -0
- data/spec/coverage/assets/0.7.1/favicon_red.png +0 -0
- data/spec/coverage/assets/0.7.1/favicon_yellow.png +0 -0
- data/spec/coverage/assets/0.7.1/loading.gif +0 -0
- data/spec/coverage/assets/0.7.1/magnify.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/coverage/index.html +3146 -0
- data/spec/diversion/client_spec.rb +23 -0
- data/spec/diversion/configurable_spec.rb +128 -0
- data/spec/diversion/decode/json_decode_spec.rb +70 -0
- data/spec/diversion/decode/params_decode_spec.rb +74 -0
- data/spec/diversion/decode_spec.rb +12 -0
- data/spec/diversion/encode/json_encode_spec.rb +39 -0
- data/spec/diversion/encode/params_encode_spec.rb +39 -0
- data/spec/diversion/encode_spec.rb +30 -0
- data/spec/diversion/mailer_spec.rb +31 -0
- data/spec/diversion/support/global_shared_context.rb +29 -0
- data/spec/diversion/url_spec.rb +36 -0
- data/spec/fixtures/mail.html +13 -0
- data/spec/fixtures/sample_email.multipart +39 -0
- data/spec/fixtures/sample_email.text +12 -0
- data/spec/spec_helper.rb +84 -0
- metadata +323 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e1d9abf9fb297a4097cb0d52b23e802b1df837a2
|
4
|
+
data.tar.gz: 6aaa3057c3e72b0a835a84828375c8a057d9976c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ad2b860ce09fe117ec736c249fdce3809fec2d3d42ae98c28090a684e84dbda60f3d16f3124292626d7534cde33f116a5fdbc95c721fe0b0fbf8c888d6ad7589
|
7
|
+
data.tar.gz: 5c68a4ce1c9488aab7c2a6a1c1677a9ceabc84287e6764f3c0333a36ff3785b24e5e84a71b0f238819da4bbc8acf8ea6b1ab07175d0b599d0181ac0b56a0a2da
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Richard Hollis
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
# Diversion Ruby Gem
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/diversion.png)][gem]
|
4
|
+
[![Build Status](https://secure.travis-ci.org/richhollis/diversion.png?branch=master)][travis]
|
5
|
+
[![Dependency Status](https://gemnasium.com/richhollis/diversion.png?travis)][gemnasium]
|
6
|
+
[![Coverage Status](https://coveralls.io/repos/richhollis/diversion/badge.png?branch=master)][coveralls]
|
7
|
+
|
8
|
+
[gem]: https://rubygems.org/gems/diversion
|
9
|
+
[travis]: http://travis-ci.org/richhollis/diversion
|
10
|
+
[gemnasium]: https://gemnasium.com/richhollis/diversion
|
11
|
+
[coveralls]: https://coveralls.io/r/richhollis/diversion
|
12
|
+
|
13
|
+
Redirect HTML links through your preferred redirection URL
|
14
|
+
|
15
|
+
Diversion aims are simple - to be a framework agnostic way to redirect all URLs via another path whilst leaving the original URL intact, leaving you to perform the actual implementation of the redirection logic.
|
16
|
+
|
17
|
+
Link redirection is particularly desirable for some Rails mailers where you want to track a link click first before redirecting the user to the original link.
|
18
|
+
|
19
|
+
Diversion was created specifically with a Rails use case in mind but can be used without Rails/ActionMailer.
|
20
|
+
|
21
|
+
A Rails mailer helper is provided if you are using ActionMailer.
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
gem install diversion
|
26
|
+
|
27
|
+
To ensure the code you're installing hasn't been tampered with, it's recommended that you verify the signature. To do this, you need to add my public key as a trusted certificate (you only need to do this once):
|
28
|
+
|
29
|
+
gem cert --add <(curl -Ls https://gist.github.com/richhollis/5301656/raw/richhollis.pem)
|
30
|
+
|
31
|
+
Then, install the gem with the high security trust policy:
|
32
|
+
|
33
|
+
gem install twitter -P HighSecurity
|
34
|
+
|
35
|
+
Add this line to your application's Gemfile:
|
36
|
+
|
37
|
+
gem 'diversion'
|
38
|
+
|
39
|
+
And then execute:
|
40
|
+
|
41
|
+
$ bundle
|
42
|
+
|
43
|
+
Or install it yourself as:
|
44
|
+
|
45
|
+
$ gem install diversion
|
46
|
+
|
47
|
+
## Quick Start Guide & Example
|
48
|
+
|
49
|
+
Configure your redirection settings:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
Diversion.configure do |config|
|
53
|
+
config.host = 'http://localhost.domain'
|
54
|
+
config.path = '/redirect/'
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
Example usage:
|
59
|
+
|
60
|
+
Encode takes an HTML body and encodes all anchor links to the new redirection location.
|
61
|
+
|
62
|
+
You can specifiy additional parameters for each url by using a "data-" attribute, for example:
|
63
|
+
|
64
|
+
```html
|
65
|
+
<a data-from="welcome_email" href="http://www.youtube.com/watch?v=feeA-Dr0XGw">Portlandia Intro</a>
|
66
|
+
```
|
67
|
+
|
68
|
+
The data-from attribute will be added to the encoded parameters and will be available when the URL is decoded.
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
Diversion::encode('<a data-from="welcome_email" href="http://www.youtube.com/watch?v=feeA-Dr0XGw">Portlandia Intro</a>')
|
72
|
+
# => "<a href=\"http://localhost.domain/redirect/1/?d=from%3Dwelcome_email%26url%3Dhttp%253A%252F%252Fwww.youtube.com%252Fwatch%253Fv%253DfeeA-Dr0XGw\">Portlandia Intro</a>"
|
73
|
+
```
|
74
|
+
|
75
|
+
Then to get the original data (this might be in say your Redirect controller) we parse the parameters of the URL:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
Diversion::decode('d=from%3Dwelcome_email%26url%3Dhttp%253A%252F%252Fwww.youtube.com%252Fwatch%253Fv%253DfeeA-Dr0XGw')
|
79
|
+
# => {:key_presented=>"", :parsed=>true, :signed=>false, :key_expected=>"", :key_verified=>false, :from=>"welcome_email", :url=>"http://www.youtube.com/watch?v=feeA-Dr0XGw"}
|
80
|
+
```
|
81
|
+
|
82
|
+
## Global data parameters
|
83
|
+
|
84
|
+
You can specify parameters that should be present for all encoded URLs. This might typically be an ID or something similar.
|
85
|
+
Specify these parameters in the second parameter to the encode (or diversion mailer) method with a hash of the parameters you wish to add.
|
86
|
+
|
87
|
+
Example:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
Diversion::encode('<a data-from="welcome_email" href="http://www.youtube.com/watch?v=feeA-Dr0XGw">Portlandia Intro</a>', {:id => 1} )
|
91
|
+
# => => "<a href=\"http://localhost.domain/redirect/1/?d=from%3Dwelcome_email%26id%3D1%26url%3Dhttp%253A%252F%252Fwww.youtube.com%252Fwatch%253Fv%253DfeeA-Dr0XGw\">Portlandia Intro</a>"
|
92
|
+
```
|
93
|
+
|
94
|
+
## Overriding configuration parameters
|
95
|
+
|
96
|
+
You can the global configuration by specifying a third parameter to encode (or diversion mailer) with a hash of the parameters you wish to override.
|
97
|
+
|
98
|
+
Example:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
Diversion::encode('<a data-from="welcome_email" href="http://www.youtube.com/watch?v=feeA-Dr0XGw">Portlandia Intro</a>', {:id => 1}, {:encode_uris => ['https']} )
|
102
|
+
# => "<a data-from=\"welcome_email\" href=\"http://www.youtube.com/watch?v=feeA-Dr0XGw\">Portlandia Intro</a>"
|
103
|
+
```
|
104
|
+
|
105
|
+
Note: Because we've overridden the encode_uris setting to only encode https urls our URL hasn't been redirected.
|
106
|
+
|
107
|
+
## Enabling Url 'Signing'
|
108
|
+
|
109
|
+
You can 'sign' the url which works by appending a parameter with a hash of the URL. The hash can be as long as 32 characters. When you enable signing, but setting the sign_length configuration option you can choose between 0-32, where 0 is disabled. The hash is generated using HMAC::MD5.
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
Diversion.configure do |config|
|
113
|
+
config.sign_length = 2
|
114
|
+
config.sign_key = 'yoursecretkey'
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
## Changing the Encoding Method
|
119
|
+
|
120
|
+
The default encoding method is query string parameters (Encode::Params/Decode::Params). This can be changed for JSON if you wish (Encode::Json/Decode::Json).
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
Diversion.configure do |config|
|
124
|
+
config.url_encoding = Encode::Json
|
125
|
+
config.url_decoding = Decode::Json
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
## Rails Mailer Example
|
130
|
+
|
131
|
+
app/views/test_mailer/welcome_email.html.erb:
|
132
|
+
|
133
|
+
```html
|
134
|
+
<p>Hey</p>
|
135
|
+
|
136
|
+
<p>Click on the following link to view some great content:</p>
|
137
|
+
|
138
|
+
<a data-type="video" href="http://www.youtube.com/watch?v=feeA-Dr0XGw">Portlandia</a>
|
139
|
+
```
|
140
|
+
|
141
|
+
app/mailers/test_mailer.rb:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
class TestMailer < ActionMailer::Base
|
145
|
+
default from: "from@example.com"
|
146
|
+
|
147
|
+
def welcome_email
|
148
|
+
# Note: we're adding a global parameter user_id - this is optional
|
149
|
+
mail(:to => 'somebody@no.where', :subject => "Welcome to My Awesome Site").diversion({:user_id => 1})
|
150
|
+
end
|
151
|
+
end
|
152
|
+
```
|
153
|
+
|
154
|
+
Note: Remember you can also add global parameters and override config options buy passing these to the diversion helper too - e.g.
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
mail(:to => 'somebody@no.where', :subject => "Welcome to My Awesome Site").diversion({:user_id => 1}, {:encode_uris => ['http']} )
|
158
|
+
```
|
159
|
+
|
160
|
+
app/controllers/redirect_controller.rb:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
class RedirectController < ApplicationController
|
164
|
+
|
165
|
+
respond_to :html
|
166
|
+
|
167
|
+
def show
|
168
|
+
hash = Diversion::decode(request.query_string)
|
169
|
+
|
170
|
+
# do something with parameters hash like save request in database
|
171
|
+
|
172
|
+
# output parameters
|
173
|
+
render :text => hash
|
174
|
+
|
175
|
+
# or redirect
|
176
|
+
# redirect_to(hash[:url])
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
```
|
181
|
+
|
182
|
+
Sample Redirect Controller output:
|
183
|
+
|
184
|
+
{:key_presented=>"", :parsed=>true, :signed=>false, :key_expected=>"", :key_verified=>false, :from=>"welcome_email", :url=>"http://www.youtube.com/watch?v=feeA-Dr0XGw", :user_id => 1}
|
185
|
+
|
186
|
+
## Contributing
|
187
|
+
|
188
|
+
1. Fork it
|
189
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
190
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
191
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
192
|
+
5. Provide tests for the changes
|
193
|
+
6. Create new Pull Request
|
data/Rakefile
ADDED
data/diversion.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'diversion/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "diversion"
|
8
|
+
gem.version = Diversion::Version
|
9
|
+
gem.authors = ["Richard Hollis"]
|
10
|
+
gem.email = ["richhollis@gmail.com"]
|
11
|
+
gem.description = %q{Redirect HTML links through your preferred redirection URL}
|
12
|
+
gem.summary = gem.description
|
13
|
+
gem.homepage = "https://github.com/richhollis/diversion/"
|
14
|
+
|
15
|
+
gem.cert_chain = ['certs/richhollis.pem']
|
16
|
+
gem.signing_key = File.expand_path("~/.gem/private_key.pem") if $0 =~ /gem\z/
|
17
|
+
|
18
|
+
gem.files = %w(LICENSE.txt README.md Rakefile diversion.gemspec)
|
19
|
+
gem.files += Dir.glob("lib/**/*.rb")
|
20
|
+
gem.files += Dir.glob("spec/**/*")
|
21
|
+
|
22
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
23
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
24
|
+
gem.require_paths = ["lib"]
|
25
|
+
gem.test_files = Dir.glob('spec/**/*')
|
26
|
+
|
27
|
+
gem.licenses = ['MIT']
|
28
|
+
|
29
|
+
gem.add_dependency "activesupport", ['>= 3.0', '< 4.1']
|
30
|
+
gem.add_dependency "nokogiri"
|
31
|
+
gem.add_dependency "ruby-hmac"
|
32
|
+
gem.add_dependency 'multi_json', '~> 1.0'
|
33
|
+
|
34
|
+
gem.add_development_dependency "actionmailer", ['>= 3.0', '< 4.1']
|
35
|
+
gem.add_development_dependency "rspec"
|
36
|
+
gem.add_development_dependency "simplecov" if RUBY_VERSION >= '1.9'
|
37
|
+
gem.add_development_dependency "coveralls"
|
38
|
+
|
39
|
+
end
|
40
|
+
|
data/lib/diversion.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
if defined?(ActionMailer)
|
2
|
+
require 'action_mailer/version'
|
3
|
+
require 'diversion/mailer'
|
4
|
+
end
|
5
|
+
|
6
|
+
require "diversion/error"
|
7
|
+
require "diversion/client"
|
8
|
+
require "diversion/version"
|
9
|
+
|
10
|
+
module Diversion
|
11
|
+
|
12
|
+
class << self
|
13
|
+
include Diversion::Configurable
|
14
|
+
|
15
|
+
# Delegate to a Diversion::Client
|
16
|
+
#
|
17
|
+
# @return [Diversion::Client]
|
18
|
+
def client
|
19
|
+
@client = Diversion::Client.new(options) unless defined?(@client) && @client.hash == options.hash
|
20
|
+
@client
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to_missing?(method_name, include_private=false); client.respond_to?(method_name, include_private); end if RUBY_VERSION >= "1.9"
|
24
|
+
def respond_to?(method_name, include_private=false); client.respond_to?(method_name, include_private) || super; end if RUBY_VERSION < "1.9"
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def method_missing(method_name, *args, &block)
|
29
|
+
return super unless client.respond_to?(method_name)
|
30
|
+
client.send(method_name, *args, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Diversion.setup
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'diversion/configurable'
|
2
|
+
require 'diversion/encode'
|
3
|
+
require 'diversion/decode'
|
4
|
+
|
5
|
+
module Diversion
|
6
|
+
|
7
|
+
class Client
|
8
|
+
|
9
|
+
include Configurable
|
10
|
+
include Encode
|
11
|
+
include Decode
|
12
|
+
|
13
|
+
def initialize(options={})
|
14
|
+
Diversion::Configurable.keys.each do |key|
|
15
|
+
instance_variable_set(:"@#{key}", options[key] || Diversion.instance_variable_get(:"@#{key}"))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'diversion/error/configuration_error'
|
3
|
+
|
4
|
+
module Diversion
|
5
|
+
module Configurable
|
6
|
+
extend Forwardable
|
7
|
+
attr_accessor :host, :port, :path, :sign_key, :sign_length, :encode_uris
|
8
|
+
attr_accessor :url_encoding, :url_decoding
|
9
|
+
def_delegator :options, :hash
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def keys
|
14
|
+
@keys ||= [
|
15
|
+
:host,
|
16
|
+
:port,
|
17
|
+
:path,
|
18
|
+
:sign_key,
|
19
|
+
:sign_length,
|
20
|
+
:encode_uris,
|
21
|
+
:url_encoding,
|
22
|
+
:url_decoding
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def configure
|
29
|
+
yield self
|
30
|
+
validate_configuration!
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset!
|
35
|
+
@host = 'http://localhost.domain'
|
36
|
+
@port = 80
|
37
|
+
@path = '/redirect/1/'
|
38
|
+
@sign_length = 0
|
39
|
+
@sign_key = nil
|
40
|
+
@encode_uris = ['http','https']
|
41
|
+
@url_encoding = Encode::Params
|
42
|
+
@url_decoding = Decode::Params
|
43
|
+
validate_configuration!
|
44
|
+
self
|
45
|
+
end
|
46
|
+
alias setup reset!
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# @return [Hash]
|
51
|
+
def options
|
52
|
+
Hash[Diversion::Configurable.keys.map{|key| [key, instance_variable_get(:"@#{key}")]}]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Ensures that all configuration parameters are of an expected type.
|
56
|
+
#
|
57
|
+
# @raise [Diversion::Error::ConfigurationError] Error is raised when
|
58
|
+
# supplied configuration is not of expected type
|
59
|
+
def validate_configuration!
|
60
|
+
unless @host.is_a?(String) && @host.length > 0
|
61
|
+
raise(Error::ConfigurationError, "Invalid host specified: Host must contain the host to redirect to.")
|
62
|
+
end
|
63
|
+
if @host.end_with?('/')
|
64
|
+
raise(Error::ConfigurationError, "Invalid host specified: #{@host} should not end with a trailing slash.")
|
65
|
+
end
|
66
|
+
|
67
|
+
unless @path.is_a?(String) && @path.length > 0
|
68
|
+
raise(Error::ConfigurationError, "Invalid path specified: Path must contain a path to redirect to.")
|
69
|
+
end
|
70
|
+
unless @path.end_with?('/')
|
71
|
+
raise(Error::ConfigurationError, "Invalid path specified: #{@path} should end with a trailing slash.")
|
72
|
+
end
|
73
|
+
|
74
|
+
unless @port.is_a?(Integer) && @port > 0
|
75
|
+
raise(Error::ConfigurationError, "Invalid port specified: #{@port} must be an integer and non-zero.")
|
76
|
+
end
|
77
|
+
|
78
|
+
if !@sign_key.nil? && !@sign_key.is_a?(String)
|
79
|
+
raise(Error::ConfigurationError, "Invalid sign_key specified: #{@sign_key} must be a String.")
|
80
|
+
end
|
81
|
+
|
82
|
+
unless @sign_length.is_a?(Integer) && @sign_length.between?(0, Signing::MAX_SIGN_LENGTH)
|
83
|
+
raise(Error::ConfigurationError, "Invalid sign_length specified: #{@sign_length} must be an integer between 0-#{Signing::MAX_SIGN_LENGTH}.")
|
84
|
+
end
|
85
|
+
|
86
|
+
unless @encode_uris.is_a?(Array) && @encode_uris.count > 0
|
87
|
+
raise(Error::ConfigurationError, "Invalid encode_uris specified: #{@encode_uris} must be an array with at least one URI scheme.")
|
88
|
+
end
|
89
|
+
|
90
|
+
unless @url_encoding.is_a?(Module) && Encode::ENCODERS.include?(@url_encoding)
|
91
|
+
raise(Error::ConfigurationError, "Invalid url_encoding specified: #{@url_encoding} must be a valid encoder module.")
|
92
|
+
end
|
93
|
+
|
94
|
+
unless @url_decoding.is_a?(Module) && Decode::DECODERS.include?(@url_decoding)
|
95
|
+
raise(Error::ConfigurationError, "Invalid url_decoding specified: #{@url_decoding} must be a valid decoder module.")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'diversion/decode/json'
|
2
|
+
require 'diversion/decode/params'
|
3
|
+
|
4
|
+
module Diversion
|
5
|
+
module Decode
|
6
|
+
include Base64
|
7
|
+
include Signing
|
8
|
+
|
9
|
+
DECODERS = [ Params, Json ]
|
10
|
+
|
11
|
+
def decode(data, opts = {})
|
12
|
+
raise ArgumentError if data.length == 0
|
13
|
+
|
14
|
+
opts = options.merge(opts)
|
15
|
+
|
16
|
+
# get hash for required type
|
17
|
+
hash = opts[:url_decoding].get_hash(data, opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|