problem_child 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e282b0323f0d971146fde3f02147126f0438a506
4
- data.tar.gz: 3b16247f802e2e3f03ce29f8ca6168fe155b9ddd
3
+ metadata.gz: bba9a9faf97164a454765c969947cdd01c0483f8
4
+ data.tar.gz: c6dc44c535d6cd7e83ccad88c078dfa593b82029
5
5
  SHA512:
6
- metadata.gz: f9fea889ff77fccd9640e02f278ca3399a5ca00629773c1b3954f661ccc20af84c3e6505f79cf516904a5a32f1ca568025f80d1e4bb18c85509d271dbbbe4bda
7
- data.tar.gz: 37edf7116f0aaa52c0e0e83dc073b1faf7621d72617d5581920a0308ea342cca047329145940be156324e1a241175da0accdd808d5373f8b8064e80c4b266ffe
6
+ metadata.gz: 9fb22eb689fc603aad6e6ca036bdf258faf5fbaf3ec7b167145f8ae89ad6ef0cb0a341eb36af97fb223a2b77c8873b6942d29f29a0452da04f230ad4fd46b542
7
+ data.tar.gz: cd2d71646e61d08cd32ab36a9aa5e5d65372a2f9338f96c3822423f3c240e73d2625475d04bed3a6b672b66aeb07f6bf8f1befea0f12a55be3aafdd30424f1a0
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Allows authenticated or anonymous users to fill out a standard web form to create GitHub issues.
4
4
 
5
- [![Build Status](https://travis-ci.org/benbalter/problem_child.svg)](https://travis-ci.org/benbalter/problem_child)
5
+ [![Build Status](https://travis-ci.org/benbalter/problem_child.svg)](https://travis-ci.org/benbalter/problem_child) [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy)
6
6
 
7
7
  ## How it works
8
8
 
@@ -14,11 +14,13 @@ Allows authenticated or anonymous users to fill out a standard web form to creat
14
14
 
15
15
  1. Create a `Gemfile` and add `gem "problem_child"`
16
16
  2. Create a `config.ru` file and add the following:
17
- ```ruby
18
- require "problem_child"
19
- run ProblemChild::App
20
- ```
21
- 3. Follow the configuration options below
17
+
18
+ ```ruby
19
+ require "problem_child"
20
+ run ProblemChild::App
21
+ ```
22
+
23
+ Then, follow the configuration options below.
22
24
 
23
25
  ## Requirements
24
26
 
@@ -41,13 +43,19 @@ You must also set **one** of the following:
41
43
  * `GITHUB_ORG_ID` - The GitHub Org ID e.g, `@whitehouse` if you'd like all users to authenticate against a GitHub Org prior to being presented the form
42
44
  * `GITHUB_TEAM_ID` - The numeric Team ID (e.g., 1234) if you'd like all users to authenticate against a GitHub Team prior to being presented the form
43
45
 
46
+ You can also set a variable to enable Google reCAPTCHA support:
47
+
48
+ * `REACAPTCHA_SITE_KEY` - The key created for your reCAPTCHA site via https://www.google.com/recaptcha/admin
49
+
50
+ If set, the Problem child default form will include a bit of JavaScript to test if the reCAPTCHA test was passed before submitting.
51
+
44
52
  *Pro-tip*: When developing locally, you can add these values to a `.env` file in the project root, and they will be automatically read in on load
45
53
 
46
54
  ## Customizing
47
55
 
48
56
  By default, Problem Child will prompt the user with a simple form that contains only the title and body. If you'd like to customize the form, you must do the following:
49
57
 
50
- 1. Create a new folder called `views`
58
+ 1. Create a new directory called `views`
51
59
  2. Create a `layout.erb` and `form.erb`
52
60
  3. Customize both the layout and form as a standard HTML form. Check out [these examples](lib/problem_child/views) to get started.
53
61
  4. Add the following (middle) line to your `config.ru` file:
@@ -73,9 +81,37 @@ or as a checkbox:
73
81
  <input type="checkbox" name="labels[]" value="suggestion" />
74
82
  ```
75
83
 
84
+ *Pro-tip III*: Set the public directory
85
+
86
+ By default Problem child points to an internal public directory which includes jQuery and Twitter Bootstrap. You can add them to your custom layout.erb:
87
+
88
+ ```html
89
+ <link href="/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
90
+
91
+ <script src="/vender/jquery/dist/jquery.min.js"></script>
92
+ ```
93
+
94
+ However, if you would like to add more files to your form app (e.g., favicon, custom CSS & JS files, etc.), you can redefine where the public directory points:
95
+
96
+ ```ruby
97
+ require "problem_child"
98
+ ProblemChild.views_dir = "/path/to/your/views/directory"
99
+ ProblemChild.public_dir = Rails.public_path
100
+ run ProblemChild::App
101
+ ```
102
+
103
+ Note that you will lose access to the bundled jQuery & Bootstrap libraries and will have to put copies into your new public directory to use them.
104
+
76
105
  ## Creating pull requests
77
106
 
78
- Problem child can also be used to create pull requests. Simply add one or more file inputs to your form. The uploaded files will be committed to a newly created feature branch, and a pull request will be created against the repo's primary branch with the rest of the form content.
107
+ Problem child can also be used to create pull requests. Simply add one or more file inputs to your form. The uploaded files will be committed to a newly created feature branch, and a pull request will be created against the repo's primary branch with the rest of the form content. You'll also want to change the form type to `enctype="multipart/form-data"`.
108
+
109
+ ```html
110
+ <form method="post" enctype="multipart/form-data">
111
+ <input type="file" name="file" />
112
+ <input type="submit" />
113
+ </form>
114
+ ```
79
115
 
80
116
  ## Contributing
81
117
 
@@ -84,3 +120,4 @@ Problem child can also be used to create pull requests. Simply add one or more f
84
120
  3. Commit your changes (`git commit -am 'Add some feature'`)
85
121
  4. Push to the branch (`git push origin my-new-feature`)
86
122
  5. Create a new Pull Request
123
+
data/app.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "Problem Child",
3
+ "description": "Allows authenticated or anonymous users to fill out a standard web form to creat GitHub issues.",
4
+ "repository": "https://github.com/benbalter/problem_child",
5
+ "addons": [
6
+ "heroku-redis:hobby-dev"
7
+ ],
8
+ "env": {
9
+ "GITHUB_CLIENT_ID": {
10
+ "description": "The ID of your GitHub OAuth application, created via https://github.com/settings/applications/new",
11
+ "required": "true"
12
+ },
13
+ "GITHUB_CLIENT_SECRET": {
14
+ "description": "The secret key of your GitHub OAuth application, created via https://github.com/settings/applications/new",
15
+ "required": "true"
16
+ },
17
+ "GITHUB_REPO": {
18
+ "description": "The repository against which to open issues submitted via Problem Child",
19
+ "required": "true"
20
+ },
21
+ "GITHUB_TOKEN": {
22
+ "description": "A personal access token for a bot account with the ability to create an issue in the GITHUB_REPO if you would like all submissions to be anonymous",
23
+ "required": "false"
24
+ },
25
+ "GITHUB_TEAM_ID": {
26
+ "description": "The GitHub Org ID e.g, @whitehouse if you'd like all users to authenticate against a GitHub Org prior to being presented the form",
27
+ "required": "false"
28
+ },
29
+ "GITHUB_ORG_ID": {
30
+ "description": "The numeric Team ID (e.g., 1234) if you'd like all users to authenticate against a GitHub Team prior to being presented the form",
31
+ "required": "false"
32
+ }
33
+ }
34
+ }
@@ -17,6 +17,10 @@ module ProblemChild
17
17
  end
18
18
  end
19
19
 
20
+ def recaptcha
21
+ ENV["RECAPTCHA_SITE_KEY"] unless ENV["RECAPTCHA_SITE_KEY"].nil? || ENV["RECAPTCHA_SITE_KEY"].to_s.empty?
22
+ end
23
+
20
24
  def client
21
25
  @client ||= Octokit::Client.new :access_token => token
22
26
  end
@@ -25,8 +29,16 @@ module ProblemChild
25
29
  halt erb template, :layout => :layout, :locals => locals.merge({ :template => template })
26
30
  end
27
31
 
32
+ def issue_title
33
+ form_data["title"]
34
+ end
35
+
28
36
  def issue_body
29
- form_data.reject { |key, value| key == "title" || value.empty? || key == "labels" || value.is_a?(Hash) }.map { |key,value| "* **#{key.humanize}**: #{value}"}.join("\n")
37
+ form_data.reject { |key, value|
38
+ key == "title" || value.empty? || key == "labels" || value.is_a?(Hash)
39
+ }.except( "g-recaptcha-response" ).map { |key, value|
40
+ "* **#{key.humanize}**: #{value}"
41
+ }.join("\n")
30
42
  end
31
43
 
32
44
  # abstraction to allow cached form data to be used in place of default params
@@ -1,3 +1,3 @@
1
1
  module ProblemChild
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -5,12 +5,22 @@
5
5
  <% end %>
6
6
  </h1>
7
7
 
8
+ <div class="alert alert-warning alert-recaptcha hidden" role="alert">
9
+ Please verify that you are not a robot.
10
+ </div>
11
+
8
12
  <% if issue %>
9
13
  <div class="alert alert-success" role="alert">
10
14
  Your issue was successfully submitted<% if access %> as <a href="http://github.com/<%= repo %>/issues/<%= issue %>"><%= repo %>#<%= issue %></a><% end %>.
11
15
  </div>
12
16
  <% end %>
13
17
 
18
+ <% if flash %>
19
+ <div class="alert alert-info" role="alert">
20
+ <%= flash %>
21
+ </div>
22
+ <% end %>
23
+
14
24
  <form method="post">
15
25
  <div class="form-group">
16
26
  <label for="title">Title</label>
@@ -21,5 +31,9 @@
21
31
  <textarea class="form-control" rows="10" id="body" name="body"></textarea>
22
32
  </div>
23
33
 
34
+ <% if recaptcha.present? %>
35
+ <div class="g-recaptcha" data-sitekey="<%= recaptcha %>"></div>
36
+ <% end %>
37
+
24
38
  <button type="submit" class="btn btn-default">Submit</button>
25
39
  </form>
@@ -16,6 +16,13 @@
16
16
  <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
17
17
  <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
18
18
  <![endif]-->
19
+
20
+ <% if recaptcha.present? %>
21
+ <script src='https://www.google.com/recaptcha/api.js'></script>
22
+ <% end %>
23
+
24
+ <script src='https://www.google.com/recaptcha/api.js'></script>
25
+
19
26
  </head>
20
27
  <body>
21
28
  <div class="container">
@@ -23,5 +30,25 @@
23
30
  <%= yield %>
24
31
 
25
32
  </div>
33
+
34
+ <% if recaptcha.present? %>
35
+ <script src="/vendor/jquery/dist/jquery.min.js"></script>
36
+
37
+ <script>
38
+ $( 'form' ).submit( function( e ) {
39
+ var prevent = false;
40
+
41
+ if ( !grecaptcha.getResponse() ) {
42
+ $( '.alert-recaptcha' ).removeClass( 'hidden' );
43
+ prevent = true;
44
+ }
45
+
46
+ if ( prevent ) {
47
+ e.preventDefault();
48
+ return false;
49
+ }
50
+ } );
51
+ </script>
52
+ <% end %>
26
53
  </body>
27
54
  </html>
data/lib/problem_child.rb CHANGED
@@ -24,6 +24,14 @@ module ProblemChild
24
24
  @views_dir = dir
25
25
  end
26
26
 
27
+ def self.public_dir
28
+ @public_dir ||= File.expand_path "public", ProblemChild.root
29
+ end
30
+
31
+ def self.public_dir=(dir)
32
+ @public_dir = dir
33
+ end
34
+
27
35
  class App < Sinatra::Base
28
36
 
29
37
  include ProblemChild::Helpers
@@ -44,19 +52,26 @@ module ProblemChild
44
52
 
45
53
  set :views, Proc.new { ProblemChild.views_dir }
46
54
  set :root, Proc.new { ProblemChild.root }
47
- set :public_folder, Proc.new { File.expand_path "public", ProblemChild.root }
55
+ set :public_folder, Proc.new { ProblemChild.public_dir }
48
56
 
49
57
  get "/" do
58
+ flash = nil
59
+ issue = nil
60
+ access = false
61
+
50
62
  if session[:form_data]
51
- issue = uploads.empty? ? create_issue : create_pull_request
52
- session[:form_data] = nil
53
- access = repo_access?
63
+ if issue_title.empty?
64
+ flash = 'Please enter a title.'
65
+ else
66
+ issue = uploads.empty? ? create_issue : create_pull_request
67
+ session[:form_data] = nil
68
+ access = repo_access?
69
+ end
54
70
  else
55
- issue = nil
56
- access = false
57
71
  auth!
58
72
  end
59
- halt erb :form, :layout => :layout, :locals => { :repo => repo, :anonymous => anonymous_submissions?, :issue => issue, :access => access }
73
+
74
+ halt erb :form, :layout => :layout, :locals => { :repo => repo, :anonymous => anonymous_submissions?, :flash => flash, :issue => issue, :access => access }
60
75
  end
61
76
 
62
77
  post "/" do
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency "rack-ssl-enforcer", "~> 0.2"
24
24
  spec.add_dependency "sinatra_auth_github", "~> 1.0"
25
25
  spec.add_dependency "activesupport", "~> 4.2"
26
- spec.add_dependency "rack", "1.5.2"
26
+ spec.add_dependency "rack", "1.6"
27
27
  spec.add_dependency "redis", "~> 3.2"
28
28
  spec.add_dependency "moneta", "~> 0.8"
29
29
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: problem_child
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Balter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-29 00:00:00.000000000 Z
11
+ date: 2015-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 1.5.2
103
+ version: '1.6'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 1.5.2
110
+ version: '1.6'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: redis
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -249,6 +249,7 @@ files:
249
249
  - Procfile
250
250
  - README.md
251
251
  - Rakefile
252
+ - app.json
252
253
  - bower.json
253
254
  - config.ru
254
255
  - lib/problem_child.rb
@@ -329,7 +330,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
329
330
  version: '0'
330
331
  requirements: []
331
332
  rubyforge_project:
332
- rubygems_version: 2.2.3
333
+ rubygems_version: 2.5.0
333
334
  signing_key:
334
335
  specification_version: 4
335
336
  summary: Allows authenticated or anonymous users to fill out a standard web form to
@@ -339,3 +340,4 @@ test_files:
339
340
  - spec/problem_child_helpers_spec.rb
340
341
  - spec/problem_child_spec.rb
341
342
  - spec/spec_helper.rb
343
+ has_rdoc: