napa 0.1.7 → 0.1.10

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.
data/README.md CHANGED
@@ -131,7 +131,7 @@ rake deploy:staging
131
131
  rake deploy:production
132
132
  ```
133
133
 
134
- **Please Note:** These tasks rely on two environment variables - `GITHUB_OAUTH_TOKEN` and `GITHUB_REPO`. For more information, see **Environment Variables** below.
134
+ **Please Note:** These tasks rely on two environment variables - `GITHUB_OAUTH_TOKEN` and `GITHUB_REPO`. For more information, see **Environment Variables** below.
135
135
 
136
136
  ### Grape Specific Features
137
137
  At Belly we use the [Grape Micro-Framework](https://github.com/intridea/grape) for many services, so we've included a few common features.
@@ -158,6 +158,30 @@ Used to grant access to your application on Github for deployment tagging
158
158
  #### GITHUB_REPO
159
159
  Your application's Github repo. i.e. `bellycard/napa`
160
160
 
161
+ ## Middlewares
162
+ Napa includes a number of Rack middlewares that can be enabled to add functionality to your project.
163
+
164
+ ### Authentication
165
+ The Authentication middleware will add a simple header based authentication layer to all requests. This is just looking for a header of `'Password' = 'Your Password'`. The passwords are defined in the `.env` file. You can allow multiple passwords by supplying a comma separated list. For example:
166
+
167
+ `HEADER_PASSWORDS='password1,password2'`
168
+
169
+ If your application doesn't require authentication, you can simply remove the middleware.
170
+
171
+ ### Health Check
172
+ The Health Check middleware will add an endpoint at `/health` that will return some data about your app. This was created to allow monitoring tools a standardized way to monitor multiple services. This endpoint will return a response similar to this:
173
+
174
+ ```
175
+ {
176
+ "name": "service-name",
177
+ "hostname": "host-name",
178
+ "revision": "current-git-sha-of-app",
179
+ "pid": 1234,
180
+ "parent_pid": 1233,
181
+ "napa_revision": "running-version-of-napa"
182
+ }
183
+ ```
184
+
161
185
  ## Contributing
162
186
 
163
187
  1. Fork it
@@ -6,12 +6,13 @@ require './app'
6
6
  # resource '*', headers: :any, methods: :any
7
7
  # end
8
8
  # end
9
- #
9
+ #
10
10
  # use Honeybadger::Rack
11
11
  # use Napa::Middleware::Logger
12
12
 
13
13
  use Napa::Middleware::AppMonitor
14
+ use Napa::Middleware::Authentication
14
15
  use ActiveRecord::ConnectionAdapters::ConnectionManagement
15
16
 
16
17
  run HelloService::API # <-- boot your service here --
17
-
18
+
@@ -0,0 +1,8 @@
1
+ module Napa
2
+ class Authentication
3
+ def self.password_header
4
+ raise 'header_password_not_configured' unless ENV['HEADER_PASSWORD']
5
+ { 'Password' => ENV['HEADER_PASSWORD'] }
6
+ end
7
+ end
8
+ end
data/lib/napa/identity.rb CHANGED
@@ -7,7 +7,7 @@ module Napa
7
7
  revision: revision,
8
8
  pid: pid,
9
9
  parent_pid: parent_pid,
10
- platform_revision: platform_revision
10
+ napa_revision: napa_revision
11
11
  }
12
12
  end
13
13
 
@@ -31,7 +31,7 @@ module Napa
31
31
  @ppid ||= Process.ppid
32
32
  end
33
33
 
34
- def self.platform_revision
34
+ def self.napa_revision
35
35
  Napa::VERSION
36
36
  end
37
37
  end
@@ -0,0 +1,32 @@
1
+ module Napa
2
+ class Middleware
3
+ class Authentication
4
+ def initialize(app)
5
+ @app = app
6
+
7
+ if ENV['HEADER_PASSWORDS']
8
+ @allowed_passwords = ENV['HEADER_PASSWORDS'].split(',').map { |pw| pw.strip }.freeze
9
+ end
10
+ end
11
+
12
+ def call(env)
13
+ if authenticated_request?(env)
14
+ @app.call(env)
15
+ else
16
+ if @allowed_passwords
17
+ error_response = Napa::JsonError.new('bad_password', 'bad password').to_json
18
+ else
19
+ error_response = Napa::JsonError.new('not_configured', 'password not configured').to_json
20
+ end
21
+
22
+ [401, { 'Content-type' => 'application/json' }, Array.wrap(error_response)]
23
+ end
24
+
25
+ end
26
+
27
+ def authenticated_request?(env)
28
+ @allowed_passwords.include? env['HTTP_PASSWORD'] unless @allowed_passwords.nil?
29
+ end
30
+ end
31
+ end
32
+ end
data/lib/napa/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Napa
2
- VERSION = '0.1.7'
2
+ VERSION = '0.1.10'
3
3
 
4
4
  class Version
5
5
  class << self
data/lib/napa.rb CHANGED
@@ -16,7 +16,9 @@ require 'napa/grape_extensions/error_formatter'
16
16
  require 'napa/grape_extensions/error_presenter'
17
17
  require 'napa/middleware/logger'
18
18
  require 'napa/middleware/app_monitor'
19
+ require 'napa/middleware/authentication'
19
20
  require 'napa/activerecord'
21
+ require 'napa/authentication'
20
22
  require 'napa/grape_api'
21
23
  require 'generators/scaffold'
22
24
 
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'napa/authentication'
3
+
4
+ describe Napa::Authentication do
5
+ context '#password_header' do
6
+ it "returns a password hash for the request header" do
7
+ ENV['HEADER_PASSWORD'] = 'foo'
8
+ Napa::Authentication.password_header.class.should eq(Hash)
9
+ Napa::Authentication.password_header.should eq('Password' => 'foo')
10
+ end
11
+
12
+ it 'raises when the HEADER_PASSWORD env var is not defined' do
13
+ ENV['HEADER_PASSWORD'] = nil
14
+ expect{Napa::Authentication.password_header}.to raise_error
15
+ end
16
+ end
17
+ end
@@ -42,9 +42,9 @@ describe Napa::Identity do
42
42
  end
43
43
  end
44
44
 
45
- context '#platform_revision' do
45
+ context '#napa_revision' do
46
46
  it 'returns the current version of the platform gem' do
47
- Napa::Identity.platform_revision.should == Napa::VERSION
47
+ Napa::Identity.napa_revision.should == Napa::VERSION
48
48
  end
49
49
  end
50
50
  end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'napa/middleware/authentication'
3
+ require 'pry'
4
+
5
+ describe Napa::Identity do
6
+ before do
7
+ ENV['HEADER_PASSWORDS'] = 'foo'
8
+ end
9
+
10
+ context 'Authenticated Request' do
11
+ it 'allows the request to continue if given a correct password header' do
12
+ app = lambda { |env| [200, {'Content-Type' => 'application/json'}, Array.new] }
13
+ middleware = Napa::Middleware::Authentication.new(app)
14
+ env = Rack::MockRequest.env_for('/test', {'HTTP_PASSWORD' => 'foo'})
15
+ status, headers, body = middleware.call(env)
16
+
17
+ status.should be(200)
18
+ end
19
+ end
20
+
21
+ context 'Failed Authentication Request' do
22
+ it 'returns an error message if the Password header is not supplied' do
23
+ app = lambda { |env| [200, {'Content-Type' => 'application/json'}, Array.new] }
24
+ middleware = Napa::Middleware::Authentication.new(app)
25
+ env = Rack::MockRequest.env_for('/test')
26
+ status, headers, body = middleware.call(env)
27
+
28
+ status.should be(401)
29
+ body.should eq([Napa::JsonError.new('bad_password', 'bad password').to_json])
30
+ end
31
+
32
+ it 'returns an error message if an incorrect Password header is supplied' do
33
+ app = lambda { |env| [200, {'Content-Type' => 'application/json'}, Array.new] }
34
+ middleware = Napa::Middleware::Authentication.new(app)
35
+ env = Rack::MockRequest.env_for('/test', {'HTTP_PASSWORD' => 'incorrect'})
36
+ status, headers, body = middleware.call(env)
37
+
38
+ status.should be(401)
39
+ body.should eq([Napa::JsonError.new('bad_password', 'bad password').to_json])
40
+ end
41
+
42
+ it 'returns an error message if HEADER_PASSWORDS is not configured' do
43
+ ENV['HEADER_PASSWORDS'] = nil
44
+
45
+ app = lambda { |env| [200, {'Content-Type' => 'application/json'}, Array.new] }
46
+ middleware = Napa::Middleware::Authentication.new(app)
47
+ env = Rack::MockRequest.env_for('/test', {'HTTP_PASSWORD' => 'incorrect'})
48
+ status, headers, body = middleware.call(env)
49
+
50
+ status.should be(401)
51
+ body.should eq([Napa::JsonError.new('not_configured', 'password not configured').to_json])
52
+ end
53
+ end
54
+ end
data/tasks/version.rake CHANGED
@@ -29,14 +29,14 @@ namespace :version do
29
29
  git.add('lib/napa/version.rb')
30
30
  git.commit("Version bump: #{release_tag}")
31
31
  git.add_tag(release_tag)
32
- git.push(git.remote('origin'), git.branch, release_tag) if git.remote('origin')
32
+ git.push(git.remote('upstream'), git.branch, release_tag) if git.remote('upstream')
33
33
  puts "Version bumped: #{release_tag}"
34
34
  end
35
35
  end
36
36
 
37
37
  def write_update
38
38
  filedata = File.read('lib/napa/version.rb')
39
- changed_filedata = filedata.gsub("VERSION = \"#{Napa::VERSION}\"\n", "VERSION = \"#{@new_version}\"\n")
39
+ changed_filedata = filedata.gsub("VERSION = '#{Napa::VERSION}'\n", "VERSION = '#{@new_version}'\n")
40
40
  File.open('lib/napa/version.rb',"w"){|file| file.puts changed_filedata}
41
41
  end
42
42
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: napa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-10 00:00:00.000000000 Z
12
+ date: 2013-12-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -233,12 +233,12 @@ files:
233
233
  - lib/generators/templates/scaffold/config/initializers/active_record.rb
234
234
  - lib/generators/templates/scaffold/config/middleware/honeybadger.rb
235
235
  - lib/generators/templates/scaffold/console
236
- - lib/generators/templates/scaffold/lib/password_protected_helpers.rb
237
236
  - lib/generators/templates/scaffold/spec/apis/hello_api_spec.rb
238
237
  - lib/generators/templates/scaffold/spec/factories/.gitkeep
239
238
  - lib/generators/templates/scaffold/spec/spec_helper.rb
240
239
  - lib/napa.rb
241
240
  - lib/napa/activerecord.rb
241
+ - lib/napa/authentication.rb
242
242
  - lib/napa/grape_api.rb
243
243
  - lib/napa/grape_extensions/error_formatter.rb
244
244
  - lib/napa/grape_extensions/error_presenter.rb
@@ -247,6 +247,7 @@ files:
247
247
  - lib/napa/logger/log_transaction.rb
248
248
  - lib/napa/logger/logger.rb
249
249
  - lib/napa/middleware/app_monitor.rb
250
+ - lib/napa/middleware/authentication.rb
250
251
  - lib/napa/middleware/logger.rb
251
252
  - lib/napa/version.rb
252
253
  - lib/tasks/db.rake
@@ -254,10 +255,12 @@ files:
254
255
  - lib/tasks/git.rake
255
256
  - lib/tasks/routes.rake
256
257
  - napa.gemspec
258
+ - spec/authentication_spec.rb
257
259
  - spec/grape_extensions/error_formatter_spec.rb
258
260
  - spec/identity_spec.rb
259
261
  - spec/json_error_spec.rb
260
262
  - spec/logger/log_transaction_spec.rb
263
+ - spec/middleware/authentication_spec.rb
261
264
  - spec/spec_helper.rb
262
265
  - spec/version_spec.rb
263
266
  - tasks/version.rake
@@ -275,7 +278,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
275
278
  version: '0'
276
279
  segments:
277
280
  - 0
278
- hash: 1127754833673535971
281
+ hash: -1469408987136937011
279
282
  required_rubygems_version: !ruby/object:Gem::Requirement
280
283
  none: false
281
284
  requirements:
@@ -284,7 +287,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
284
287
  version: '0'
285
288
  segments:
286
289
  - 0
287
- hash: 1127754833673535971
290
+ hash: -1469408987136937011
288
291
  requirements: []
289
292
  rubyforge_project:
290
293
  rubygems_version: 1.8.25
@@ -292,9 +295,11 @@ signing_key:
292
295
  specification_version: 3
293
296
  summary: A simple framework for building APIs with Grape
294
297
  test_files:
298
+ - spec/authentication_spec.rb
295
299
  - spec/grape_extensions/error_formatter_spec.rb
296
300
  - spec/identity_spec.rb
297
301
  - spec/json_error_spec.rb
298
302
  - spec/logger/log_transaction_spec.rb
303
+ - spec/middleware/authentication_spec.rb
299
304
  - spec/spec_helper.rb
300
305
  - spec/version_spec.rb
@@ -1,17 +0,0 @@
1
- module PasswordProtectedHelpers
2
- if ENV['HEADER_PASSWORDS']
3
- PW_ARRAY = ENV['HEADER_PASSWORDS'].split(',').map { |pw| pw.strip }.freeze
4
- else
5
- PW_ARRAY = [nil].freeze
6
- end
7
-
8
- def authenticate(headers)
9
- error!(error: {
10
- code: 'bad_password',
11
- message: 'bad password' }
12
- ) unless PW_ARRAY.include? headers['Password']
13
- end
14
-
15
- # extend all endpoints to include this
16
- Grape::Endpoint.send :include, self
17
- end