spambust 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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