enigma 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ --- {}
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rack', :require => 'rack'
4
+ gem 'httparty', :require => 'httparty'
5
+
6
+ group :test do
7
+ gem 'rspec'
8
+ gem 'rack-test'
9
+ gem 'sinatra'
10
+ end
@@ -0,0 +1,32 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ crack (0.1.8)
5
+ diff-lcs (1.1.2)
6
+ httparty (0.7.4)
7
+ crack (= 0.1.8)
8
+ rack (1.2.2)
9
+ rack-test (0.5.7)
10
+ rack (>= 1.0)
11
+ rspec (2.5.0)
12
+ rspec-core (~> 2.5.0)
13
+ rspec-expectations (~> 2.5.0)
14
+ rspec-mocks (~> 2.5.0)
15
+ rspec-core (2.5.1)
16
+ rspec-expectations (2.5.0)
17
+ diff-lcs (~> 1.1.2)
18
+ rspec-mocks (2.5.0)
19
+ sinatra (1.2.0)
20
+ rack (~> 1.1)
21
+ tilt (>= 1.2.2, < 2.0)
22
+ tilt (1.2.2)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ httparty
29
+ rack
30
+ rack-test
31
+ rspec
32
+ sinatra
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 teejayvanslyke
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,97 +1,17 @@
1
1
  = enigma
2
2
 
3
- * http://github.com/teejayvanslyke/enigma
3
+ Description goes here.
4
4
 
5
- == DESCRIPTION:
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
6
14
 
7
- Key/secret authentication for your web services
15
+ == Copyright
8
16
 
9
- == FEATURES/PROBLEMS:
10
-
11
- * I just started implementing this today, so it's really not ready for use. I
12
- would love your opinions about the current API and possible improvements.
13
-
14
- == SYNOPSIS:
15
-
16
- Let's say you have a web service endpoint coded in Sinatra that says "Hello,
17
- world":
18
-
19
- # app.rb
20
- get '/' do
21
- "Hello, world!"
22
- end
23
-
24
- Enigma will allow you to authenticate the service using a key/secret scheme:
25
-
26
- >> Enigma.generate_key
27
- => "03637dee19a1c96c1547f8834ca5e96c"
28
- >> Enigma.generate_secret
29
- => "1f430a0481601697898a566ae54fde5a"
30
-
31
- # app.rb
32
-
33
- Enigma.find_secret do |key|
34
- # Usually, you'd have these stored in your database.
35
- # For this example, we'll just return the secret if we have a matching
36
- # key.
37
- if key == "03637dee19a1c96c1547f8834ca5e96c"
38
- return "1f430a0481601697898a566ae54fde5a"
39
- end
40
- end
41
-
42
- get '/' do
43
- if (params = Enigma.authenticate(params))
44
- "Hello, world."
45
- else
46
- "Not authorized."
47
- end
48
- end
49
-
50
- It provides a wrapper for the rest-client gem which properly encodes URI
51
- parameters on the query string for consumption by Enigma:
52
-
53
- # client.rb
54
-
55
- client = Enigma::Client.new(
56
- "03637dee19a1c96c1547f8834ca5e96c",
57
- "1f430a0481601697898a566ae54fde5a"
58
- )
59
-
60
- client.get("http://localhost:4567").body
61
- => "Hello, world."
62
-
63
- The Enigma.authenticate method returns the unencoded parameters if the
64
- authentication is successful; otherwise it returns nil.
65
-
66
- == REQUIREMENTS:
67
-
68
- * ezcrypto
69
-
70
- == INSTALL:
71
-
72
- sudo gem install enigma
73
-
74
- == LICENSE:
75
-
76
- (The MIT License)
77
-
78
- Copyright (c) 2010 FIXME full name
79
-
80
- Permission is hereby granted, free of charge, to any person obtaining
81
- a copy of this software and associated documentation files (the
82
- 'Software'), to deal in the Software without restriction, including
83
- without limitation the rights to use, copy, modify, merge, publish,
84
- distribute, sublicense, and/or sell copies of the Software, and to
85
- permit persons to whom the Software is furnished to do so, subject to
86
- the following conditions:
87
-
88
- The above copyright notice and this permission notice shall be
89
- included in all copies or substantial portions of the Software.
90
-
91
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
92
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
93
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
94
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
95
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
96
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
97
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ Copyright (c) 2010 teejayvanslyke. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,26 +1,49 @@
1
- require 'rubygems'
2
- gem 'hoe', '>= 2.1.0'
3
- require 'hoe'
4
- require 'fileutils'
5
- require './lib/enigma'
6
-
7
- Hoe.plugin :newgem
8
- # Hoe.plugin :website
9
- # Hoe.plugin :cucumberfeatures
10
-
11
- # Generate all the Rake tasks
12
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
- $hoe = Hoe.spec 'enigma' do
14
- self.developer 'T.J. VanSlyke', 'teejay.vanslyke@gmail.com'
15
- self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
16
- self.rubyforge_name = self.name # TODO this is default value
17
- self.extra_deps = [['ezcrypto', '>= 0.7.2']]
18
-
19
- end
20
-
21
- require 'newgem/tasks'
22
- Dir['tasks/**/*.rake'].each { |t| load t }
23
-
24
- # TODO - want other tests/tasks run by default? Add them to the list
25
- # remove_task :default
26
- # task :default => [:spec, :features]
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "enigma"
8
+ gem.summary = %Q{Key/secret authentication gem for your web services}
9
+ gem.description = %Q{Key/secret authentication gem for your web services}
10
+ gem.email = "teejay.vanslyke@gmail.com"
11
+ gem.homepage = "http://github.com/teejayvanslyke/enigma"
12
+ gem.authors = ["teejayvanslyke"]
13
+ gem.add_development_dependency "rspec", ">= 2.0.0"
14
+ gem.add_development_dependency 'rack-test'
15
+ gem.add_development_dependency 'sinatra'
16
+ gem.add_dependency 'rack'
17
+ gem.add_dependency 'httparty'
18
+ gem.add_dependency 'addressable'
19
+ gem.add_dependency 'rest_client'
20
+ end
21
+ Jeweler::GemcutterTasks.new
22
+ rescue LoadError
23
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
24
+ end
25
+
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rdoc/task'
42
+ RDoc::Task.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "campistrano #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.3
@@ -0,0 +1,76 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "enigma"
8
+ s.version = "0.0.3"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["teejayvanslyke"]
12
+ s.date = "2014-02-03"
13
+ s.description = "Key/secret authentication gem for your web services"
14
+ s.email = "teejay.vanslyke@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".bundle/config",
21
+ ".document",
22
+ ".rspec",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "enigma.gemspec",
30
+ "lib/enigma.rb",
31
+ "spec/enigma_spec.rb",
32
+ "spec/rack_test_client.rb",
33
+ "spec/spec_helper.rb"
34
+ ]
35
+ s.homepage = "http://github.com/teejayvanslyke/enigma"
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = "1.8.25"
38
+ s.summary = "Key/secret authentication gem for your web services"
39
+
40
+ if s.respond_to? :specification_version then
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<rack>, [">= 0"])
45
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
46
+ s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
47
+ s.add_development_dependency(%q<rack-test>, [">= 0"])
48
+ s.add_development_dependency(%q<sinatra>, [">= 0"])
49
+ s.add_runtime_dependency(%q<rack>, [">= 0"])
50
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
51
+ s.add_runtime_dependency(%q<addressable>, [">= 0"])
52
+ s.add_runtime_dependency(%q<rest_client>, [">= 0"])
53
+ else
54
+ s.add_dependency(%q<rack>, [">= 0"])
55
+ s.add_dependency(%q<httparty>, [">= 0"])
56
+ s.add_dependency(%q<rspec>, [">= 2.0.0"])
57
+ s.add_dependency(%q<rack-test>, [">= 0"])
58
+ s.add_dependency(%q<sinatra>, [">= 0"])
59
+ s.add_dependency(%q<rack>, [">= 0"])
60
+ s.add_dependency(%q<httparty>, [">= 0"])
61
+ s.add_dependency(%q<addressable>, [">= 0"])
62
+ s.add_dependency(%q<rest_client>, [">= 0"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<rack>, [">= 0"])
66
+ s.add_dependency(%q<httparty>, [">= 0"])
67
+ s.add_dependency(%q<rspec>, [">= 2.0.0"])
68
+ s.add_dependency(%q<rack-test>, [">= 0"])
69
+ s.add_dependency(%q<sinatra>, [">= 0"])
70
+ s.add_dependency(%q<rack>, [">= 0"])
71
+ s.add_dependency(%q<httparty>, [">= 0"])
72
+ s.add_dependency(%q<addressable>, [">= 0"])
73
+ s.add_dependency(%q<rest_client>, [">= 0"])
74
+ end
75
+ end
76
+
@@ -1,123 +1,90 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
-
4
1
  require 'rubygems'
5
- require 'cgi'
6
- require 'yaml'
7
- require 'rest_client'
8
- require 'addressable/uri'
9
- require "digest/sha1"
10
- require 'ezcrypto'
2
+ require 'bundler/setup'
3
+ require 'rack'
4
+ require 'rack/test'
11
5
 
12
6
  module Enigma
13
- VERSION = '0.0.1'
14
-
15
- KEY_LENGTH = 32
16
- SECRET_LENGTH = 32
17
-
18
-
19
- class Query < Hash
20
-
21
- def initialize(key, secret, params)
22
- self[:key] = key
23
- self[:params] = Enigma.encode_params(secret, params)
24
- end
25
-
26
- def to_params
27
- params = ''
28
- stack = []
29
-
30
- each do |k, v|
31
- if v.is_a?(Hash)
32
- stack << [k,v]
33
- else
34
- params << "#{k}=#{v}&"
35
- end
36
- end
37
-
38
- stack.each do |parent, hash|
39
- hash.each do |k, v|
40
- if v.is_a?(Hash)
41
- stack << ["#{parent}[#{k}]", v]
42
- else
43
- params << "#{parent}[#{k}]=#{v}&"
44
- end
45
- end
46
- end
47
-
48
- params.chop! # trailing &
49
- params
50
- end
51
- end
52
-
53
- class KeyGenerator
54
- def self.generate(length = 10)
55
- Digest::SHA1.hexdigest(Time.now.to_s + rand(12341234).to_s)[1..length]
56
- end
57
- end
7
+ SIGNATURE_HEADER = "X_ENIGMA_SIGNATURE"
58
8
 
59
- def self.generate_key
60
- KeyGenerator.generate(KEY_LENGTH)
61
- end
62
-
63
- def self.generate_secret
64
- KeyGenerator.generate(SECRET_LENGTH)
65
- end
66
-
67
- def self.find_secret(&block)
68
- @find_secret = block
69
- end
70
-
71
- def self.authenticate(params={})
72
- if @find_secret.nil?
73
- raise "Pass a block to #{self.name}.find_secret which returns
74
- secret for the given key. See documentation for details."
75
- end
76
-
77
- self.decode_params(@find_secret.call(params[:key]), params[:params])
78
- end
9
+ extend self
79
10
 
80
- def self.encrypt(secret, data)
81
- key = EzCrypto::Key.with_password(secret, "salt")
82
- key.encrypt(data)
11
+ def self.server_key=(server_key)
12
+ @server_key = server_key
83
13
  end
84
14
 
85
- def self.decrypt(secret, data)
86
- key = EzCrypto::Key.with_password(secret, "salt")
87
- key.decrypt(data)
15
+ def self.server_key
16
+ @server_key
88
17
  end
89
18
 
90
- def self.encode_params(secret, params)
91
- CGI::escape(
92
- encrypt(
93
- secret, [ YAML::dump(params.sort {|a,b| a[0].to_s <=> b[0].to_s}) ].
94
- pack('m')
95
- )
96
- )
97
- end
19
+ def signature(method, path, payload)
20
+ message = [method, path, payload].map(&:to_s).inject(&:+)
98
21
 
99
- def self.decode_params(secret, signed_params)
100
- begin
101
- params = {}
102
- YAML::load(decrypt(secret, CGI::unescape(signed_params)).unpack('m').first).each do |key, value|
103
- params[key] = value
104
- end
105
- return params
106
- rescue
107
- return nil
108
- end
22
+ digest = OpenSSL::Digest::Digest.new("sha512")
23
+ OpenSSL::HMAC.hexdigest(digest, self.server_key, message).to_s
109
24
  end
110
25
 
111
- class Client
112
- def initialize(key, secret)
113
- @key = key
114
- @secret = secret
26
+ def matches?(actual_signature, method, path, payload)
27
+ matched = true
28
+ expected_signature = self.signature(method, path, payload)
29
+ expected_signature.each_char.zip(actual_signature.to_s.each_char).each do |expected, actual|
30
+ matched = false if expected != actual
115
31
  end
116
32
 
117
- def get(url, params={})
118
- query = Query.new(@key, @secret, params)
119
- RestClient.get("#{url}?#{query.to_params}")
120
- end
33
+ matched
121
34
  end
122
35
 
36
+ class Client
37
+ def initialize(options)
38
+ @host = options[:host] || 'localhost'
39
+ @port = options[:port] || 80
40
+ @ssl = options[:ssl] || false
41
+ @certificate = options[:certificate]
42
+ end
43
+
44
+ attr_reader :host, :port, :ssl, :certificate, :version
45
+
46
+ HTTP_METHODS = [:get, :post, :put, :delete]
47
+ HTTP_METHODS.each do |method|
48
+ define_method(method) do |path, *args|
49
+ payload = args.first
50
+ execute method, path, payload
51
+ end
52
+ end
53
+
54
+ def http
55
+ base = "#{ssl ? "https" : "http"}://#{host}:#{port}"
56
+ Class.new do
57
+ include HTTParty
58
+ base_uri base
59
+ end
60
+ end
61
+
62
+ def execute(method, path, payload)
63
+ response = http.send(method, path,
64
+ :headers => headers(method, path, payload),
65
+ :body => payload,
66
+ :timeout => TIMEOUT
67
+ )
68
+
69
+ response.body
70
+ end
71
+
72
+ TIMEOUT = 60 * 5
73
+
74
+ private
75
+
76
+ def headers(method, url, payload)
77
+ {Enigma::SIGNATURE_HEADER =>
78
+ Enigma.signature(method, url, payload)
79
+ }
80
+ end
81
+
82
+ def scheme
83
+ @ssl ? 'https' : 'http'
84
+ end
85
+
86
+ def base_url
87
+ "#{scheme}://#{host}:#{port}"
88
+ end
89
+ end
123
90
  end
@@ -1,106 +1,64 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe Enigma do
4
4
 
5
- describe "when generating an API key" do
6
- it "should be a string" do
7
- Enigma.generate_key.should be_a(String)
8
- end
9
-
10
- it "should be 32 digits long" do
11
- Enigma.generate_key.length.should == 32
5
+ Enigma.server_key = "abcd1234abcd1234"
6
+
7
+ class TestApp < Sinatra::Base
8
+ get '/' do
9
+ signature = request.env["HTTP_" + Enigma::SIGNATURE_HEADER]
10
+ method = request.request_method.downcase
11
+ path = request.path
12
+ payload = request.body.read
13
+
14
+ if Enigma.matches?(signature, method, path, payload)
15
+ status 200
16
+ else
17
+ status 403
18
+ end
12
19
  end
13
20
  end
14
21
 
15
- describe "when generating an API secret" do
16
- it "should be a string" do
17
- Enigma.generate_secret.should be_a(String)
18
- end
19
-
20
- it "should be 64 digits long" do
21
- Enigma.generate_secret.length.should == 32
22
- end
22
+ def app
23
+ @app ||= TestApp.new
23
24
  end
24
25
 
25
- describe "when authenticating" do
26
- before :each do
27
- @key = Enigma.generate_key
28
- # Sigh, has to be global to be seen below...
29
- @secret = $secret = Enigma.generate_secret
30
- @params = { :p1 => 1, :p2 => 2 }
31
- @signed_params = Enigma.encode_params(@secret, @params)
32
-
33
- end
34
-
35
- context "with a valid key/secret pair" do
36
- before :each do
37
- # Let's just return the secret, straight up.
38
- Enigma.find_secret do |key|
39
- $secret
40
- end
41
- end
42
-
43
- it "should return the decoded parameters" do
44
- Enigma.authenticate(:key => @key, :params => @signed_params).should == @params
45
- end
46
- end
47
-
48
- context "with an invalid key/secret pair" do
49
- before :each do
50
- # And now, let's return the wrong one.
51
- Enigma.find_secret do |key|
52
- Enigma.generate_secret
53
- end
54
- end
26
+ def client
27
+ @client ||= Enigma::Spec::RackTestClient.new(app)
28
+ end
55
29
 
56
- it "should not be able to decode the params using the invalid secret" do
57
- Enigma.decode_params(Enigma.generate_secret, @signed_params).should be_nil
58
- end
30
+ describe "with correct authentication" do
31
+ it "should be successful" do
32
+ response = client.execute(
33
+ :method => :get,
34
+ :path => "/",
35
+ :headers => {"X_ENIGMA_SIGNATURE" => Enigma.signature('get', '/', '')}
36
+ )
59
37
 
60
- it "should return nil" do
61
- Enigma.authenticate(:key => @key, :params => @signed_params).should be_nil
62
- end
38
+ response.code.should == 200
63
39
  end
64
40
  end
65
41
 
66
- describe "when encoding parameters" do
67
- before :each do
68
- @secret = Enigma.generate_secret
69
- @params = { 'param1' => '1', 'param2' => 2 }
70
- end
42
+ describe "with incorrect authentication" do
43
+ it "should be forbidden" do
44
+ response = client.execute(
45
+ :method => :get,
46
+ :path => "/",
47
+ :headers => {"X_ENIGMA_SIGNATURE" => "h4x0r"}
48
+ )
71
49
 
72
- it "should be able to decode them" do
73
- Enigma.decode_params(@secret, Enigma.encode_params(@secret, @params)).should == @params
50
+ response.code.should == 403
74
51
  end
75
52
  end
76
53
 
77
- end
54
+ describe "with empty authorization" do
55
+ it "should be forbidden" do
56
+ response = client.execute(
57
+ :method => :get,
58
+ :path => "/",
59
+ :headers => {})
78
60
 
79
- describe Enigma::Client do
80
- describe "get" do
81
- before :each do
82
- @key = Enigma.generate_key
83
- @secret = Enigma.generate_secret
84
- @client = Enigma::Client.new(@key, @secret)
85
- @params = { 'p1' => 'value' }
86
- @signed_params = Enigma.encode_params(@secret, @params)
87
- end
88
-
89
- it "should send a GET request with the key and signed params" do
90
- RestClient.should_receive(:get).with("http://some.service?params=#{@signed_params}&key=#{@key}")
91
- @client.get("http://some.service", @params)
61
+ response.code.should == 403
92
62
  end
93
63
  end
94
64
  end
95
-
96
- =begin
97
- get '/' do
98
- user = User.find_by_key(params[:key])
99
- Enigma.authenticate(params[:key], user.secret, params[:params])
100
- end
101
-
102
- Enigma.generate_key
103
- Enigma.generate_secret
104
-
105
- =end
106
-
@@ -0,0 +1,44 @@
1
+ module Enigma
2
+ module Spec
3
+ class RackTestClient
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ attr_reader :app
9
+
10
+ def session
11
+ Rack::Test::Session.new(Rack::MockSession.new(app))
12
+ end
13
+
14
+ def execute(opts)
15
+ method = opts[:method]
16
+ path = opts[:path]
17
+ body = opts[:payload] || ""
18
+ headers = opts[:headers].inject({}) {|_, (k, v)| _.merge(convert_header(k) => v) }
19
+
20
+ rack_response = session.send(method, path, body, headers)
21
+
22
+ OpenStruct.new :code => rack_response.status.to_i, :body => rack_response.body
23
+
24
+ end
25
+
26
+ [:get, :post, :put, :delete].each do |method|
27
+ define_method(method) do |path, options|
28
+ execute(
29
+ :method => method,
30
+ :path => path,
31
+ :payload => options[:body],
32
+ :headers => options[:headers]
33
+ )
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def convert_header(header)
40
+ "HTTP_" + header.to_s.upcase.gsub("-", "_")
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,10 +1,10 @@
1
- begin
2
- require 'spec'
3
- rescue LoadError
4
- require 'rubygems' unless ENV['NO_RUBYGEMS']
5
- gem 'rspec'
6
- require 'spec'
7
- end
8
-
9
- $:.unshift(File.dirname(__FILE__) + '/../lib')
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
10
3
  require 'enigma'
4
+ require 'sinatra/base'
5
+ require 'rspec'
6
+ require File.dirname(__FILE__) + '/rack_test_client'
7
+
8
+ RSpec.configure do |config|
9
+
10
+ end
metadata CHANGED
@@ -1,110 +1,207 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: enigma
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
5
6
  platform: ruby
6
- authors:
7
- - T.J. VanSlyke
7
+ authors:
8
+ - teejayvanslyke
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
-
12
- date: 2010-04-03 00:00:00 -07:00
13
- default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: ezcrypto
12
+ date: 2014-02-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
17
22
  type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 0.7.2
24
- version:
25
- - !ruby/object:Gem::Dependency
26
- name: rubyforge
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: httparty
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 2.0.0
27
54
  type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 2.0.3
34
- version:
35
- - !ruby/object:Gem::Dependency
36
- name: gemcutter
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.0.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: rack-test
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
37
70
  type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: 0.5.0
44
- version:
45
- - !ruby/object:Gem::Dependency
46
- name: hoe
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: sinatra
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
47
86
  type: :development
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: 2.5.0
54
- version:
55
- description: Key/secret authentication for your web services
56
- email:
57
- - teejay.vanslyke@gmail.com
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rack
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: httparty
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: addressable
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: rest_client
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ description: Key/secret authentication gem for your web services
159
+ email: teejay.vanslyke@gmail.com
58
160
  executables: []
59
-
60
161
  extensions: []
61
-
62
- extra_rdoc_files:
63
- - History.txt
64
- - Manifest.txt
65
- - PostInstall.txt
66
- files:
67
- - History.txt
68
- - Manifest.txt
69
- - PostInstall.txt
162
+ extra_rdoc_files:
163
+ - LICENSE
164
+ - README.rdoc
165
+ files:
166
+ - .bundle/config
167
+ - .document
168
+ - .rspec
169
+ - Gemfile
170
+ - Gemfile.lock
171
+ - LICENSE
70
172
  - README.rdoc
71
173
  - Rakefile
174
+ - VERSION
175
+ - enigma.gemspec
72
176
  - lib/enigma.rb
73
- - script/console
74
- - script/destroy
75
- - script/generate
76
177
  - spec/enigma_spec.rb
77
- - spec/spec.opts
178
+ - spec/rack_test_client.rb
78
179
  - spec/spec_helper.rb
79
- - tasks/rspec.rake
80
- has_rdoc: true
81
180
  homepage: http://github.com/teejayvanslyke/enigma
82
181
  licenses: []
83
-
84
- post_install_message: PostInstall.txt
85
- rdoc_options:
86
- - --main
87
- - README.rdoc
88
- require_paths:
182
+ post_install_message:
183
+ rdoc_options: []
184
+ require_paths:
89
185
  - lib
90
- required_ruby_version: !ruby/object:Gem::Requirement
91
- requirements:
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- version: "0"
95
- version:
96
- required_rubygems_version: !ruby/object:Gem::Requirement
97
- requirements:
98
- - - ">="
99
- - !ruby/object:Gem::Version
100
- version: "0"
101
- version:
186
+ required_ruby_version: !ruby/object:Gem::Requirement
187
+ none: false
188
+ requirements:
189
+ - - ! '>='
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ segments:
193
+ - 0
194
+ hash: 2594529284062009951
195
+ required_rubygems_version: !ruby/object:Gem::Requirement
196
+ none: false
197
+ requirements:
198
+ - - ! '>='
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
102
201
  requirements: []
103
-
104
- rubyforge_project: enigma
105
- rubygems_version: 1.3.5
202
+ rubyforge_project:
203
+ rubygems_version: 1.8.25
106
204
  signing_key:
107
205
  specification_version: 3
108
- summary: Key/secret authentication for your web services
206
+ summary: Key/secret authentication gem for your web services
109
207
  test_files: []
110
-
@@ -1,4 +0,0 @@
1
- === 0.0.1 2010-04-02
2
-
3
- * 1 major enhancement:
4
- * Initial release
@@ -1,13 +0,0 @@
1
- History.txt
2
- Manifest.txt
3
- PostInstall.txt
4
- README.rdoc
5
- Rakefile
6
- lib/enigma.rb
7
- script/console
8
- script/destroy
9
- script/generate
10
- spec/enigma_spec.rb
11
- spec/spec.opts
12
- spec/spec_helper.rb
13
- tasks/rspec.rake
@@ -1,7 +0,0 @@
1
-
2
- For more information on enigma, see http://enigma.rubyforge.org
3
-
4
- NOTE: Change this information in PostInstall.txt
5
- You can also delete it if you don't want it.
6
-
7
-
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # File: script/console
3
- irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
-
5
- libs = " -r irb/completion"
6
- # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
- # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
- libs << " -r #{File.dirname(__FILE__) + '/../lib/enigma.rb'}"
9
- puts "Loading enigma gem"
10
- exec "#{irb} #{libs} --simple-prompt"
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
- APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
-
4
- begin
5
- require 'rubigen'
6
- rescue LoadError
7
- require 'rubygems'
8
- require 'rubigen'
9
- end
10
- require 'rubigen/scripts/destroy'
11
-
12
- ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
- RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
- RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
- APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
-
4
- begin
5
- require 'rubigen'
6
- rescue LoadError
7
- require 'rubygems'
8
- require 'rubigen'
9
- end
10
- require 'rubigen/scripts/generate'
11
-
12
- ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
- RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
- RubiGen::Scripts::Generate.new.run(ARGV)
@@ -1 +0,0 @@
1
- --colour
@@ -1,21 +0,0 @@
1
- begin
2
- require 'spec'
3
- rescue LoadError
4
- require 'rubygems' unless ENV['NO_RUBYGEMS']
5
- require 'spec'
6
- end
7
- begin
8
- require 'spec/rake/spectask'
9
- rescue LoadError
10
- puts <<-EOS
11
- To use rspec for testing you must install rspec gem:
12
- gem install rspec
13
- EOS
14
- exit(0)
15
- end
16
-
17
- desc "Run the specs under spec/models"
18
- Spec::Rake::SpecTask.new do |t|
19
- t.spec_opts = ['--options', "spec/spec.opts"]
20
- t.spec_files = FileList['spec/**/*_spec.rb']
21
- end