spambust 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- N2Y5N2VjMzdhODdmN2NkMTQwMjFkNDllN2U3YzZlOGMwNDc2NmUxZA==
5
- data.tar.gz: !binary |-
6
- NDY1NDEzNWIxNzU5MjE4OWJiZDJhYzRlZTIzMmU5OWQ2MDE1MDMxMg==
2
+ SHA1:
3
+ metadata.gz: fa2b64be89004072d0059f05723151f73a279afb
4
+ data.tar.gz: c867ae7f94d6be8d8f42be325f938e093cc7a551
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- OGI4YWQwOWMzYmU4NWViODY3Njg1MTE5MDRiOTQzNTAxZDkwNTA1YjdmN2Y1
10
- NjFmM2IwN2Q2NTYxZjA0ZTAwMGU3ZmFlZGFmYmQxYjQ2MTk3ZDliNGQxOGUy
11
- ZWFmYjhkY2MwNzQ1NzJlNjUyNTk0OGZkMTVlY2Q1OTU2YjM2YjA=
12
- data.tar.gz: !binary |-
13
- NzM0NWZkM2FkYjc5YjZhNDg0ODc1ODYzZmY1YWE1ZDFhMzc0NTI1NDVjMDlh
14
- ZDVhZWE5OTU3YTczOGJhNTY5NTgxNDAxZmNlY2VkNzU3OTEwNGVjMzRhY2Yy
15
- NjUxNjA1NDcxMTI4OTllOWZjZjM0MmEyMTg4ZTJhM2Y5ZDc4MjA=
6
+ metadata.gz: 10de6ad17e986655a2a413a8703e7c1b6d49e63b926759ee3174c189b9c5143c6fdea28f8666f90ab11f4a31095d5b6edc646c0dcb30c5f3ecf176dcdca1d1ca
7
+ data.tar.gz: 23fa457d817bde24764c503b217c8b85a87402677aa8b3d536837c8ad59b255de0d51dbf50164d1f00068b54d62b69f927b49a1e3c4f868fb559edba3e59c9e9
data/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ v0.2.0
2
+ ======
3
+
4
+ * Drop support for ruby 1.8.x
5
+ * Remove CSS class, style options from off-screen tag
6
+
7
+ v0.1.4
8
+ ======
9
+
10
+ * Include license in gem specification
11
+
12
+ v0.1.3
13
+ ======
14
+
15
+ * Render trap elements off screen. A spam bot might not fill hidden fields
16
+ * Measure code coverage
17
+
18
+ v0.1.2
19
+ ======
20
+
21
+ * Add documentation
22
+
23
+ v0.1.1
24
+ ======
25
+
26
+ * Add decryption logic to the gem
27
+
28
+ v0.1.0
29
+ ======
30
+
31
+ * Initial release
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2013 Chirantan Mitra
3
+ Copyright (c) 2013-2016 Chirantan Mitra
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  [![Build Status](https://secure.travis-ci.org/chiku/spambust.png?branch=master)](https://travis-ci.org/chiku/spambust)
2
+ [![Gem Version](https://badge.fury.io/rb/spambust.svg)](http://badge.fury.io/rb/spambust)
2
3
  [![Code Climate](https://codeclimate.com/github/chiku/spambust.png)](https://codeclimate.com/github/chiku/spambust)
3
4
 
4
5
  spambust
@@ -26,7 +27,7 @@ Usage
26
27
 
27
28
  **app.rb**
28
29
 
29
- ``` ruby
30
+ ```ruby
30
31
  class TestApp < Sinatra::Base
31
32
  helpers Spambust::FormHelpers
32
33
 
@@ -36,7 +37,7 @@ class TestApp < Sinatra::Base
36
37
  end
37
38
 
38
39
  def direct_script_execution?
39
- app_file == $0
40
+ app_file == $PROGRAM_NAME
40
41
  end
41
42
  end
42
43
 
@@ -55,27 +56,27 @@ end
55
56
 
56
57
  **index.erb**
57
58
 
58
- ``` erb
59
+ ```erb
59
60
  <html>
60
- <head>
61
- <title>Sample Sinatra application</title>
62
- </head>
63
- <body>
64
- <div id="result"><%= result %></div>
61
+ <head>
62
+ <title>Sample Sinatra application</title>
63
+ </head>
64
+ <body>
65
+ <div id="result"><%= result %></div>
65
66
 
66
- <form method="post" action="/">
67
- <label for="user-first-name">First name</label>
68
- <%= input ["user", "first_name"], :id => "user-first-name" %>
67
+ <form method="post" action="/">
68
+ <label for="user-first-name">First name</label>
69
+ <%= input ["user", "first_name"], :id => "user-first-name" %>
69
70
 
70
- <label for="user-last-name">Last name</label>
71
- <%= input ["user", "last_name"], :id => "user-last-name" %>
71
+ <label for="user-last-name">Last name</label>
72
+ <%= input ["user", "last_name"], :id => "user-last-name" %>
72
73
 
73
- <label for="user-email">Email</label>
74
- <%= input ["user", "email"], :size => 40, :id => "user-email" %>
74
+ <label for="user-email">Email</label>
75
+ <%= input ["user", "email"], :size => 40, :id => "user-email" %>
75
76
 
76
- <%= submit "Create account", :id => "user-submit" %>
77
- </form>
78
- </body>
77
+ <%= submit "Create account", :id => "user-submit" %>
78
+ </form>
79
+ </body>
79
80
  </html>
80
81
  ```
81
82
 
@@ -89,12 +90,14 @@ end
89
90
  How does it work?
90
91
  -----------------
91
92
 
92
- The server will render obfustated input tags for the user to fill. The input tags for the user will be hidden. A spam bot would see the input tags will meaningful names and fill it in. The server will figure out that this response came from a bot and take approriate action.
93
+ The server will render obfuscated input tags for the user to fill. The input tags for the user will be hidden. A spam bot would see the input tags will meaningful names and fill it in. The server will figure out that this response came from a bot and take approriate action.
93
94
 
94
95
  Running tests
95
96
  -------------
96
97
 
97
- Clone the repository and run `rake` from the root directory.
98
+ 1. Clone the repository.
99
+ 2. run `bundle` from the root directory.
100
+ 3. run `rake` from the root directory.
98
101
 
99
102
  Contributing
100
103
  ------------
data/lib/spambust.rb CHANGED
@@ -1 +1,7 @@
1
- require_relative "spambust/form_helpers"
1
+ # spambust.rb
2
+ #
3
+ # Author:: Chirantan Mitra
4
+ # Copyright:: Copyright (c) 2013-2016. All rights reserved
5
+ # License:: MIT
6
+
7
+ require_relative 'spambust/form_helpers'
@@ -1,139 +1,155 @@
1
- require "digest/md5"
2
-
3
- # form_helper.rb
1
+ # form_helpers.rb
4
2
  #
5
3
  # Author:: Chirantan Mitra
6
- # Copyright:: Copyright (c) 2013. All rights reserved
4
+ # Copyright:: Copyright (c) 2013-2016. All rights reserved
7
5
  # License:: MIT
8
- #
9
6
 
10
- module Spambust
11
- # This module provides form helpers for sinatra or alike DSLs/frameworks to test for spams
12
- #
13
- # Example:
14
- # class TestApp < Sinatra::Base
15
- # helpers Spambust::FormHelpers
16
- #
17
- # class << self
18
- # def start_app
19
- # run!
20
- # end
7
+ require 'digest/md5'
8
+
9
+ module Spambust # :nodoc:
10
+ ##
11
+ # <b>Form helpers for sinatra or similar DSLs/frameworks to block for spams</b>
21
12
  #
22
- # def direct_script_execution?
23
- # app_file == $0
24
- # end
25
- # end
13
+ # == Examples
26
14
  #
27
- # get "/" do
28
- # erb :index, :locals => { :result => "..." }
29
- # end
15
+ # === app.rb
30
16
  #
31
- # post '/' do
32
- # result = valid?("user", params) ? "Users is #{decrypt("user", params)}" : "Faking is bad"
33
- # erb :index, :locals => { :result => result }
34
- # end
17
+ # class TestApp < Sinatra::Base
18
+ # helpers Spambust::FormHelpers
35
19
  #
36
- # start_app if direct_script_execution? && ENV["environment"] != "test"
37
- # end
20
+ # class << self
21
+ # def start_app
22
+ # run!
23
+ # end
38
24
  #
39
- # index.erb
25
+ # def direct_script_execution?
26
+ # app_file == $PROGRAM_NAME
27
+ # end
28
+ # end
40
29
  #
41
- # <html>
42
- # <head>
43
- # <title>Sample Sinatra application</title>
44
- # </head>
45
- # <body>
46
- # <div id="result"><%= result %></div>
30
+ # get '/' do
31
+ # erb :index, :locals => { :result => '...' }
32
+ # end
47
33
  #
48
- # <form method="post" action="/">
49
- # <label for="user-first-name">First name</label>
50
- # <%= input ["user", "first_name"], :id => "user-first-name" %>
34
+ # post '/' do
35
+ # valid = valid?('user', params)
36
+ # result = valid ? "Users is #{decrypt('user', params)}" : 'Faker!'
37
+ # erb :index, locals: { result: result }
38
+ # end
51
39
  #
52
- # <label for="user-last-name">Last name</label>
53
- # <%= input ["user", "last_name"], :id => "user-last-name" %>
40
+ # start_app if direct_script_execution? && ENV['environment'] != 'test'
41
+ # end
54
42
  #
55
- # <label for="user-email">Email</label>
56
- # <%= input ["user", "email"], :size => 40, :id => "user-email" %>
43
+ # === index.erb
57
44
  #
58
- # <%= submit "Create account", :id => "user-submit" %>
59
- # </form>
60
- # </body>
61
- # </html>
62
-
45
+ # <html>
46
+ # <head>
47
+ # <title>Sample Sinatra application</title>
48
+ # </head>
49
+ # <body>
50
+ # <div id="result"><%= result %></div>
51
+ # <form method="post" action="/">
52
+ # <label for="user-first-name">First name</label>
53
+ # <%= input ["user", "first_name"], :id => "user-first-name" %>
54
+ # <label for="user-last-name">Last name</label>
55
+ # <%= input ["user", "last_name"], :id => "user-last-name" %>
56
+ # <label for="user-email">Email</label>
57
+ # <%= input ["user", "email"], :size => 40, :id => "user-email" %>
58
+ # <%= submit "Create account", :id => "user-submit" %>
59
+ # </form>
60
+ # </body>
61
+ # </html>
63
62
  module FormHelpers
64
- # Returns obfustated input tags together with its fake input tags that are rendered off the screen
63
+ HIDING = 'position:absolute;top:-10000px;left:-10000px;' # :nodoc:
64
+ BLOCKED_OPTIONS = [:id, :class, :style] # :nodoc:
65
+
66
+ ##
67
+ # Returns obfuscated input tags together with its fake input tags that are
68
+ # rendered off the screen
65
69
  #
66
- # Use inside your templates to generate an obfuscated input field. This is the field that the server will use.
67
- # If the server sees that fields with original names are filled, the server should assume it be be a spam.
68
- # It also accepts options for input type and other CSS properties.
70
+ # Use inside your templates to generate an obfuscated input field. This is
71
+ # the field that the server will use. If the server sees that fields with
72
+ # original names are filled, the server should assume it be be a spam.
73
+ # It also accepts options for input type and other CSS properties.
69
74
  #
70
- # input(["user", "name"])
71
- # # => <input type="text" name="#{user_md5}[#{name_md5}]" /><input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" />
75
+ # input(['user', 'name'])
76
+ # # => <input type="text" name="#{user_digest}[#{name_digest}]" />\
77
+ # # <input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" />
72
78
  #
73
- # input(["user", "name"], :type => "password")
74
- # # => <input type="password" name="#{user_md5}[#{name_md5}]" /><input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" />
79
+ # input(['user', 'name'], type: 'password')
80
+ # # => <input type="password" name="#{user_digest}[#{name_digest}]" />\
81
+ # # <input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" />
75
82
  #
76
- # input(["user", "name"], :id => "name", :class => "name")
77
- # # => <input type="text" name="#{user_md5}[#{name_md5}]" id="name" class="name" /><input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" class="name" />
83
+ # input(['user', 'name'], id: 'name', class: 'name')
84
+ # # => <input type="text" name="#{user_digest}[#{name_digest}]" id="name" class="name" />\
85
+ # # <input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" class="name" />
78
86
  def input(paths, options = {})
79
- type = options.delete(:type) || "text"
80
- options_without_id = options.select { |key, value| key != :id }
81
- others = hash_to_options(options)
82
- others_without_id = hash_to_options(options_without_id)
83
- digested_paths = paths.map { |path| Digest::MD5.hexdigest(path) }
84
- %Q(<input type="#{type}" name="#{namify digested_paths}"#{others} /><input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="#{namify paths}"#{others_without_id} />)
87
+ type = options.delete(:type) || 'text'.freeze
88
+ sanitized_options = options.reject { |key, _value| BLOCKED_OPTIONS.include?(key) }
89
+ digested_paths = paths.map { |path| digest(path) }
90
+ visible_tag_options = options.merge(type: type, name: namify(digested_paths))
91
+ hidden_tag_options = sanitized_options.merge(type: 'text', name: namify(paths), style: HIDING)
92
+ visible_tag = %(<input #{hash_to_options visible_tag_options} />)
93
+ hidden_tag = %(<input #{hash_to_options hidden_tag_options} />)
94
+ "#{visible_tag}#{hidden_tag}"
85
95
  end
86
96
 
97
+ ##
87
98
  # Returns submit tags
88
99
  #
89
- # Use inside your templates to generate a submit tag.
90
- # It also accepts options for CSS properties.
100
+ # Use inside your templates to generate a submit tag.
101
+ # It also accepts for CSS options.
91
102
  #
92
- # submit("Submit")
103
+ # submit('Submit')
93
104
  # # => <input type="submit" value="Submit" />
94
105
  #
95
106
  # submit("Submit", :id => "submit", :class => "submit")
96
107
  # # => <input type="submit" value="Submit" id="submit" class="submit" />
97
108
  def submit(text, options = {})
98
- others = hash_to_options(options)
99
- %Q(<input type="submit" value="#{text}"#{others} />)
109
+ visible_tag_options = options.merge(type: 'submit'.freeze, value: text)
110
+ %(<input #{hash_to_options visible_tag_options} />).gsub(' ', ' ')
100
111
  end
101
112
 
102
113
  def namify(paths) # :nodoc:
103
114
  first = paths[0]
104
- rest = paths[1..-1].reduce("") { |acc, path| acc << "[#{path}]" }
115
+ rest = paths[1..-1].reduce('') { |a, e| a << "[#{e}]" }
105
116
  "#{first}#{rest}"
106
117
  end
107
118
 
119
+ ##
108
120
  # Returns decrypted hash of user submitted POST parameters
109
- #
110
- # Use inside your application.
121
+ # Use inside your application.
111
122
  #
112
123
  # decrypt("user", params)
113
124
  def decrypt(lookup, global)
114
125
  fake = global[lookup] || {}
115
- hashed_lookup = Digest::MD5.hexdigest(lookup)
126
+ hashed_lookup = digest(lookup)
116
127
  subset = global[hashed_lookup] || {}
117
128
 
118
- fake.reduce({}) do |real, (key, value)|
119
- real[key] = subset[Digest::MD5.hexdigest(key)]
120
- real
129
+ fake.each_with_object({}) do |(key, _value), real|
130
+ real[key] = subset[digest(key)]
121
131
  end
122
132
  end
123
133
 
134
+ ##
124
135
  # Returns if any POST data was present in the fake input fields
125
136
  #
126
- # Use inside your application.
137
+ # Use inside your application.
127
138
  #
128
- # valid?("user", params)
139
+ # valid?('user', params)
129
140
  def valid?(lookup, global)
130
141
  fake = global[lookup] || {}
131
- fake.none? { |key, value| value != "" }
142
+ fake.values.all?(&:empty?)
132
143
  end
133
144
 
134
145
  def hash_to_options(hash) # :nodoc:
135
- hash.reduce("") { |acc, (key, value)| acc << %Q( #{key}="#{value}") }
146
+ hash.map { |key, value| %(#{key}="#{value}") }.join(' ')
136
147
  end
137
148
  private :hash_to_options
149
+
150
+ def digest(item) # :nodoc:
151
+ Digest::MD5.hexdigest(item)
152
+ end
153
+ private :digest
138
154
  end
139
155
  end
@@ -1,3 +1,9 @@
1
- module Spambust
2
- VERSION = "0.1.4" # :nodoc:
1
+ # version.rb
2
+ #
3
+ # Author:: Chirantan Mitra
4
+ # Copyright:: Copyright (c) 2013-2016. All rights reserved
5
+ # License:: MIT
6
+
7
+ module Spambust # :nodoc:
8
+ VERSION = '0.2.0' # :nodoc:
3
9
  end
@@ -1,7 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "sinatra"
4
- require File.expand_path "../../lib/spambust/form_helpers", File.dirname(__FILE__)
3
+ # demo_app.rb
4
+ #
5
+ # Author:: Chirantan Mitra
6
+ # Copyright:: Copyright (c) 2013-2016. All rights reserved
7
+ # License:: MIT
8
+
9
+ require 'tilt/erb'
10
+ require 'sinatra'
11
+
12
+ require_relative '../../lib/spambust/form_helpers'
5
13
 
6
14
  module Spambust
7
15
  class TestApp < Sinatra::Base
@@ -13,19 +21,20 @@ module Spambust
13
21
  end
14
22
 
15
23
  def direct_script_execution?
16
- app_file == $0
24
+ app_file == $PROGRAM_NAME
17
25
  end
18
26
  end
19
27
 
20
- get "/" do
21
- erb :index, :locals => { :result => "..." }
28
+ get '/' do
29
+ erb :index, locals: { result: '...' }
22
30
  end
23
31
 
24
32
  post '/' do
25
- result = valid?("user", params) ? "Users is #{decrypt("user", params)}" : "Faking is bad"
26
- erb :index, :locals => { :result => result }
33
+ valid = valid?('user', params)
34
+ result = valid ? "User is #{decrypt('user', params)}" : 'Faking is bad'
35
+ erb :index, locals: { result: result }
27
36
  end
28
37
 
29
- start_app if direct_script_execution? && ENV["environment"] != "test"
38
+ start_app if direct_script_execution? && ENV['environment'] != 'test'
30
39
  end
31
40
  end
@@ -1,62 +1,71 @@
1
- require File.expand_path "../spec_helper", File.dirname(__FILE__)
2
- require File.expand_path "demo_app", File.dirname(__FILE__)
1
+ # form_helpers_integration_spec.rb
2
+ #
3
+ # Author:: Chirantan Mitra
4
+ # Copyright:: Copyright (c) 2013-2016. All rights reserved
5
+ # License:: MIT
3
6
 
4
- describe "test application" do
7
+ require_relative '../spec_helper'
8
+ require_relative 'demo_app'
9
+
10
+ describe 'Test application' do
5
11
  include Rack::Test::Methods
6
12
 
7
- let(:app) { Spambust::TestApp }
13
+ let(:app) { Spambust::TestApp }
8
14
 
9
- let(:user_md5) { Digest::MD5.hexdigest("user") }
10
- let(:first_name_md5) { Digest::MD5.hexdigest("first_name") }
11
- let(:last_name_md5) { Digest::MD5.hexdigest("last_name") }
12
- let(:email_md5) { Digest::MD5.hexdigest("email") }
15
+ let(:user_digest) { Digest::MD5.hexdigest('user') }
16
+ let(:first_name_digest) { Digest::MD5.hexdigest('first_name') }
17
+ let(:last_name_digest) { Digest::MD5.hexdigest('last_name') }
18
+ let(:email_digest) { Digest::MD5.hexdigest('email') }
19
+ let(:hiding) { 'position:absolute;top:-10000px;left:-10000px;' }
13
20
 
14
- describe "when loading a form" do
15
- it "contains hidden input fields" do
16
- get "/"
21
+ describe 'when loading a form' do
22
+ it 'contains hidden input fields' do
23
+ get '/'
17
24
 
18
- last_response.body.must_include %Q(<input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[email]" size="40" />)
25
+ last_response.body.must_include %(<input size="40" type="text" \
26
+ name="user[email]" style="#{hiding}" />)
19
27
  end
20
28
  end
21
29
 
22
- describe "when posting a form" do
30
+ describe 'when posting a form' do
23
31
  describe "when hidden fields aren't filled" do
24
- it "is accepted" do
32
+ it 'is accepted' do
25
33
  params = {
26
- user_md5 => {
27
- first_name_md5 => "True first name",
28
- last_name_md5 => "True last name",
29
- email_md5 => "True email",
34
+ user_digest => {
35
+ first_name_digest => 'True first name',
36
+ last_name_digest => 'True last name',
37
+ email_digest => 'True email'
30
38
  },
31
- "user" => {
32
- "first_name" => "",
33
- "last_name" => "",
34
- "email" => "",
39
+ 'user' => {
40
+ 'first_name' => '',
41
+ 'last_name' => '',
42
+ 'email' => ''
35
43
  }
36
44
  }
37
45
 
38
- post "/", params
39
- last_response.body.must_include %Q({"first_name"=>"True first name", "last_name"=>"True last name", "email"=>"True email"})
46
+ post '/', params
47
+ last_response.body.must_include %({"first_name"=>"True first name", \
48
+ "last_name"=>"True last name", "email"=>"True email"})
40
49
  end
41
50
  end
42
51
 
43
- describe "when hidden fields aren't filled" do
44
- it "is is identified as fake" do
52
+ describe 'when hidden fields are filled' do
53
+ it 'is identified as fake' do
45
54
  params = {
46
- user_md5 => {
47
- first_name_md5 => "True first name",
48
- last_name_md5 => "True last name",
49
- email_md5 => "True email",
55
+ user_digest => {
56
+ first_name_digest => 'True first name',
57
+ last_name_digest => 'True last name',
58
+ email_digest => 'True email'
50
59
  },
51
- "user" => {
52
- "first_name" => "Fake first name",
53
- "last_name" => "Fake last name",
54
- "email" => "Fake email",
60
+ 'user' => {
61
+ 'first_name' => 'Fake first name',
62
+ 'last_name' => 'Fake last name',
63
+ 'email' => 'Fake email'
55
64
  }
56
65
  }
57
66
 
58
- post "/", params
59
- last_response.body.must_include "Faking is bad"
67
+ post '/', params
68
+ last_response.body.must_include 'Faking is bad'
60
69
  end
61
70
  end
62
71
  end
@@ -1,134 +1,167 @@
1
- require "digest/md5"
1
+ # form_helpers_spec.rb
2
+ #
3
+ # Author:: Chirantan Mitra
4
+ # Copyright:: Copyright (c) 2013-2016. All rights reserved
5
+ # License:: MIT
2
6
 
3
- require File.expand_path "../spec_helper", File.dirname(__FILE__)
4
- require File.expand_path "../../lib/spambust/form_helpers", File.dirname(__FILE__)
7
+ require 'digest/md5'
8
+
9
+ require_relative '../spec_helper'
10
+ require_relative '../../lib/spambust/form_helpers'
5
11
 
6
12
  class TestApp
7
13
  include Spambust::FormHelpers
8
14
  end
9
15
 
10
- describe "Bustspam::FormHelpers" do
16
+ describe 'Spambust::FormHelpers' do
11
17
  subject { TestApp.new }
12
18
 
13
- let(:user_md5) { Digest::MD5.hexdigest("user") }
14
- let(:name_md5) { Digest::MD5.hexdigest("name") }
19
+ let(:user_digest) { Digest::MD5.hexdigest('user') }
20
+ let(:name_digest) { Digest::MD5.hexdigest('name') }
21
+ let(:hiding) { 'position:absolute;top:-10000px;left:-10000px;' }
15
22
 
16
- describe "#input" do
17
- describe "when type is not mentioned" do
23
+ describe '#input' do
24
+ describe 'when type is not mentioned' do
18
25
  it "renders an input tag of type 'text'" do
19
- subject.input(["user", "name"]).must_equal %Q(<input type="text" name="#{user_md5}[#{name_md5}]" /><input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" />)
26
+ subject.input(%w(user name)).must_equal %(\
27
+ <input type="text" name="#{user_digest}[#{name_digest}]" />\
28
+ <input type="text" name="user[name]" style="#{hiding}" />)
20
29
  end
21
30
  end
22
31
 
23
- describe "when type is mentioned" do
24
- it "renders an input tag of specified type" do
25
- subject.input(["user", "name"], :type => "password").must_equal %Q(<input type="password" name="#{user_md5}[#{name_md5}]" /><input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" />)
32
+ describe 'when type is mentioned' do
33
+ it 'renders an input tag of specified type' do
34
+ subject.input(%w(user name), type: 'password').must_equal %(\
35
+ <input type="password" name="#{user_digest}[#{name_digest}]" />\
36
+ <input type="text" name="user[name]" style="#{hiding}" />)
26
37
  end
27
38
  end
28
39
 
29
- describe "when other options are mentioned" do
30
- it "renders the options" do
31
- subject.input(["user", "name"], :class => "name").must_equal %Q(<input type="text" name="#{user_md5}[#{name_md5}]" class="name" /><input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" class="name" />)
40
+ describe 'when CSS options are mentioned' do
41
+ it 'renders the options' do
42
+ subject.input(%w(user name), maxlength: '40').must_equal %(\
43
+ <input maxlength="40" type="text" name="#{user_digest}[#{name_digest}]" />\
44
+ <input maxlength="40" type="text" name="user[name]" style="#{hiding}" />)
32
45
  end
33
46
  end
34
47
 
35
- describe "when other options include 'id'" do
48
+ describe "when CSS options include 'id'" do
36
49
  it "doesn't repeat the 'id'" do
37
- subject.input(["user", "name"], :id => "name").must_equal %Q(<input type="text" name="#{user_md5}[#{name_md5}]" id="name" /><input type="text" style="position:absolute;top:-10000px;left:-10000px;" name="user[name]" />)
50
+ subject.input(%w(user name), id: 'name').must_equal %(\
51
+ <input id="name" type="text" name="#{user_digest}[#{name_digest}]" />\
52
+ <input type="text" name="user[name]" style="#{hiding}" />)
53
+ end
54
+ end
55
+
56
+ describe "when CSS options include 'class'" do
57
+ it "doesn't repeat the 'class'" do
58
+ subject.input(%w(user name), class: 'name').must_equal %(\
59
+ <input class="name" type="text" name="#{user_digest}[#{name_digest}]" />\
60
+ <input type="text" name="user[name]" style="#{hiding}" />)
61
+ end
62
+ end
63
+
64
+ describe "when CSS options include 'style'" do
65
+ it "uses the 'style' to hide the fake input tag" do
66
+ subject.input(%w(user name), style: 'padding-top: 2px;').must_equal %(\
67
+ <input style="padding-top: 2px;" type="text" name="#{user_digest}[#{name_digest}]" />\
68
+ <input type="text" name="user[name]" style="#{hiding}" />)
38
69
  end
39
70
  end
40
71
  end
41
72
 
42
- describe "#submit" do
43
- describe "when type is mentioned" do
73
+ describe '#submit' do
74
+ describe 'when type is mentioned' do
44
75
  it "renders an input tag of specified 'submit" do
45
- subject.submit("Submit").must_equal %Q(<input type="submit" value="Submit" />)
76
+ tag = %(<input type="submit" value="Submit" />)
77
+ subject.submit('Submit').must_equal tag
46
78
  end
47
79
  end
48
80
 
49
- describe "when other options are mentioned" do
50
- it "renders the options" do
51
- subject.submit("Submit", :id => "submit", :class => "submit").must_equal %Q(<input type="submit" value="Submit" id="submit" class="submit" />)
81
+ describe 'when CSS options are mentioned' do
82
+ it 'renders the options' do
83
+ subject.submit('Submit', id: 'submit', class: 'submit').must_equal %(\
84
+ <input id="submit" class="submit" type="submit" value="Submit" />)
52
85
  end
53
86
  end
54
87
  end
55
88
 
56
- describe "#namify" do
57
- describe "when size is one" do
58
- it "is the word itself" do
59
- subject.namify(["user"]).must_equal "user"
89
+ describe '#namify' do
90
+ describe 'when size is one' do
91
+ it 'is the word itself' do
92
+ subject.namify(['user']).must_equal 'user'
60
93
  end
61
94
  end
62
95
 
63
- describe "when size is more than one" do
64
- it "nests the items in successive square brackets" do
65
- subject.namify(["user", "name", "first"]).must_equal "user[name][first]"
96
+ describe 'when size is more than one' do
97
+ it 'nests the items in successive square brackets' do
98
+ subject.namify(%w(user name first)).must_equal 'user[name][first]'
66
99
  end
67
100
  end
68
101
  end
69
102
 
70
- describe "#decrypt" do
71
- it "pulls the values corresponding to decrypted the keys under the lookup" do
103
+ describe '#decrypt' do
104
+ it 'fetches the actual value of the lookup up key' do
72
105
  params = {
73
- "user" => { "name" => "spam value"},
74
- user_md5 => { name_md5 => "true value" }
106
+ 'user' => { 'name' => 'spam value' },
107
+ user_digest => { name_digest => 'true value' }
75
108
  }
76
109
 
77
- subject.decrypt("user", params).must_equal("name" => "true value")
110
+ subject.decrypt('user', params).must_equal('name' => 'true value')
78
111
  end
79
112
 
80
113
  describe "when lookup doesn't exist" do
81
- it "is empty" do
114
+ it 'is empty' do
82
115
  params = {
83
- "user" => { "name" => "spam value"},
84
- user_md5 => { name_md5 => "true value" }
116
+ 'user' => { 'name' => 'spam value' },
117
+ user_digest => { name_digest => 'true value' }
85
118
  }
86
- subject.decrypt("missing_user", params).must_equal({})
119
+ subject.decrypt('missing_user', params).must_equal({})
87
120
  end
88
121
  end
89
122
 
90
123
  describe "when fake keys don't conform to the decrypted keys" do
91
- it "populates the key with a nil value" do
124
+ it 'populates the key with a nil value' do
92
125
  params = {
93
- "user" => { "name" => "spam value"},
94
- user_md5.succ => { name_md5 => "true value" }
126
+ 'user' => { 'name' => 'spam value' },
127
+ user_digest.succ => { name_digest => 'true value' }
95
128
  }
96
- subject.decrypt("user", params).must_equal({"name" => nil})
129
+ subject.decrypt('user', params).must_equal('name' => nil)
97
130
  end
98
131
  end
99
132
  end
100
133
 
101
- describe "#valid?" do
102
- describe "when none of the paths under lookup are populated" do
103
- it "is true" do
134
+ describe '#valid?' do
135
+ describe 'when none of the paths under lookup are populated' do
136
+ it 'is true' do
104
137
  params = {
105
- "user" => { "name" => ""},
106
- user_md5 => { name_md5 => "true value" }
138
+ 'user' => { 'name' => '' },
139
+ user_digest => { name_digest => 'true value' }
107
140
  }
108
141
 
109
- subject.valid?("user", params).must_equal true
142
+ subject.valid?('user', params).must_equal true
110
143
  end
111
144
  end
112
145
 
113
- describe "when one of the paths under lookup is populated" do
114
- it "is false" do
146
+ describe 'when one of the paths under lookup is populated' do
147
+ it 'is false' do
115
148
  params = {
116
- "user" => { "name" => "spam value"},
117
- user_md5 => { name_md5 => "true value" }
149
+ 'user' => { 'name' => 'spam value' },
150
+ user_digest => { name_digest => 'true value' }
118
151
  }
119
152
 
120
- subject.valid?("user", params).must_equal false
153
+ subject.valid?('user', params).must_equal false
121
154
  end
122
155
  end
123
156
 
124
157
  describe "when lookup doesn't exist" do
125
- it "is true" do
158
+ it 'is true' do
126
159
  params = {
127
- "user" => { "name" => "spam value"},
128
- user_md5 => { name_md5 => "true value" }
160
+ 'user' => { 'name' => 'spam value' },
161
+ user_digest => { name_digest => 'true value' }
129
162
  }
130
163
 
131
- subject.valid?("user_missing", params).must_equal true
164
+ subject.valid?('user_missing', params).must_equal true
132
165
  end
133
166
  end
134
167
  end
@@ -1,21 +1,21 @@
1
1
  <html>
2
- <head>
3
- <title>Sample Sinatra application</title>
4
- </head>
5
- <body>
6
- <div id="result"><%= result %></div>
2
+ <head>
3
+ <title>Sample Sinatra application</title>
4
+ </head>
5
+ <body>
6
+ <div id="result"><%= result %></div>
7
7
 
8
- <form method="post" action="/">
9
- <label for="user-first-name">First name</label>
10
- <%= input ["user", "first_name"], :id => "user-first-name" %>
8
+ <form method="post" action="/">
9
+ <label for="user-first-name">First name</label>
10
+ <%= input ["user", "first_name"], :id => "user-first-name" %>
11
11
 
12
- <label for="user-last-name">Last name</label>
13
- <%= input ["user", "last_name"], :id => "user-last-name" %>
12
+ <label for="user-last-name">Last name</label>
13
+ <%= input ["user", "last_name"], :id => "user-last-name" %>
14
14
 
15
- <label for="user-email">Email</label>
16
- <%= input ["user", "email"], :size => 40, :id => "user-email" %>
15
+ <label for="user-email">Email</label>
16
+ <%= input ["user", "email"], :size => 40, :id => "user-email" %>
17
17
 
18
- <%= submit "Create account", :id => "user-submit" %>
19
- </form>
20
- </body>
18
+ <%= submit "Create account", :id => "user-submit" %>
19
+ </form>
20
+ </body>
21
21
  </html>
@@ -1,8 +1,8 @@
1
1
  <html>
2
- <head>
3
- <title>Sample Sinatra application</title>
4
- </head>
5
- <body>
6
- <%= yield %>
7
- </body>
2
+ <head>
3
+ <title>Sample Sinatra application</title>
4
+ </head>
5
+ <body>
6
+ <%= yield %>
7
+ </body>
8
8
  </html>
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,28 @@
1
- require "rack/test"
2
- require "sinatra/base"
1
+ # spec_helper.rb
2
+ #
3
+ # Author:: Chirantan Mitra
4
+ # Copyright:: Copyright (c) 2013-2016. All rights reserved
5
+ # License:: MIT
6
+
7
+ ENV['environment'] = 'test'
3
8
 
4
9
  begin
5
- require "simplecov"
10
+ require 'simplecov'
11
+ require 'coveralls'
12
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new [
13
+ SimpleCov::Formatter::HTMLFormatter,
14
+ Coveralls::SimpleCov::Formatter
15
+ ]
6
16
  SimpleCov.start do
7
- add_filter "/spec|test|vendor/"
17
+ add_filter '/spec|test|vendor/'
8
18
  end
9
19
  rescue LoadError
10
- puts "\nPlease install simplecov to generate coverage report!\n\n"
20
+ puts "\nPlease install simplecov & coveralls to generate coverage report!\n\n"
11
21
  end
12
22
 
13
- gem "minitest"
14
- require "minitest/autorun"
23
+ gem 'minitest'
15
24
 
16
- ENV["environment"] = "test"
25
+ require 'minitest/autorun'
26
+ require 'minitest/spec'
27
+ require 'rack/test'
28
+ require 'sinatra/base'
metadata CHANGED
@@ -1,123 +1,149 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spambust
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chirantan Mitra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-14 00:00:00.000000000 Z
11
+ date: 2016-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rdoc
42
+ name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: minitest
56
+ name: rack-test
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rack-test
70
+ name: simplecov
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ! '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ! '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: simplecov
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: coveralls
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rdoc
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
- - - ! '>='
115
+ - - ">="
88
116
  - !ruby/object:Gem::Version
89
117
  version: '0'
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
- - - ! '>='
122
+ - - ">="
95
123
  - !ruby/object:Gem::Version
96
124
  version: '0'
97
- description: ! 'Render input tags with a masked name. The input tags with proper names
98
- are hidden.
99
-
100
- A spam bot is expected to fill the incorrect input tags. The server would indentify
101
- this and respond appropriately.
102
-
103
- '
125
+ description: |
126
+ Render input tags with a masked name. The original input names names are
127
+ hidden. A spam bot would fill the incorrect but visible input tags. The server
128
+ would identify this and respond appropriately.
104
129
  email:
105
130
  - chirantan.mitra@gmail.com
106
131
  executables: []
107
132
  extensions: []
108
133
  extra_rdoc_files: []
109
134
  files:
135
+ - CHANGELOG.md
136
+ - LICENSE
137
+ - README.md
138
+ - lib/spambust.rb
110
139
  - lib/spambust/form_helpers.rb
111
140
  - lib/spambust/version.rb
112
- - lib/spambust.rb
113
141
  - spec/spambust/demo_app.rb
114
142
  - spec/spambust/form_helpers_integration_spec.rb
115
143
  - spec/spambust/form_helpers_spec.rb
116
144
  - spec/spambust/views/index.erb
117
145
  - spec/spambust/views/layout.erb
118
146
  - spec/spec_helper.rb
119
- - LICENSE
120
- - README.md
121
147
  homepage: https://github.com/chiku/spambust
122
148
  licenses:
123
149
  - MIT
@@ -128,17 +154,17 @@ require_paths:
128
154
  - lib
129
155
  required_ruby_version: !ruby/object:Gem::Requirement
130
156
  requirements:
131
- - - ! '>='
157
+ - - ">="
132
158
  - !ruby/object:Gem::Version
133
159
  version: '0'
134
160
  required_rubygems_version: !ruby/object:Gem::Requirement
135
161
  requirements:
136
- - - ! '>='
162
+ - - ">="
137
163
  - !ruby/object:Gem::Version
138
164
  version: '0'
139
165
  requirements: []
140
166
  rubyforge_project: spambust
141
- rubygems_version: 2.1.10
167
+ rubygems_version: 2.5.1
142
168
  signing_key:
143
169
  specification_version: 4
144
170
  summary: Sinatra form helper to reduce spams
@@ -146,6 +172,6 @@ test_files:
146
172
  - spec/spambust/demo_app.rb
147
173
  - spec/spambust/form_helpers_integration_spec.rb
148
174
  - spec/spambust/form_helpers_spec.rb
149
- - spec/spambust/views/index.erb
150
175
  - spec/spambust/views/layout.erb
176
+ - spec/spambust/views/index.erb
151
177
  - spec/spec_helper.rb