keyper 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +97 -0
- data/Rakefile +33 -0
- data/app/assets/config/tb_apis_manifest.js +2 -0
- data/app/assets/javascripts/tb_api_keys/application.js +13 -0
- data/app/assets/stylesheets/tb_api_keys/application.css +15 -0
- data/app/controllers/concerns/keyper/api_key_authentication.rb +43 -0
- data/app/controllers/keyper/api_keys_controller.rb +62 -0
- data/app/controllers/keyper/application_controller.rb +5 -0
- data/app/helpers/keyper/application_helper.rb +4 -0
- data/app/jobs/keyper/application_job.rb +4 -0
- data/app/mailers/keyper/application_mailer.rb +6 -0
- data/app/models/application_record.rb +3 -0
- data/app/models/concerns/keyper/has_api_keys.rb +23 -0
- data/app/models/keyper/api_key.rb +25 -0
- data/app/models/keyper/authentication.rb +30 -0
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20161025210140_create_keyper_api_keys.rb +14 -0
- data/lib/keyper.rb +6 -0
- data/lib/keyper/configuration.rb +17 -0
- data/lib/keyper/engine.rb +27 -0
- data/lib/keyper/errors.rb +3 -0
- data/lib/keyper/version.rb +3 -0
- data/lib/tasks/keyper_tasks.rake +4 -0
- metadata +187 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ca507246830d7b92ea2613584e66ac99c14894b2
|
4
|
+
data.tar.gz: f0527aa75dfe5753902c530a218afd5d6b5123ed
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9c1aeca8bfe2477853465b72f33fe912732fdfa841355095e1c7230d1d09e330b61d47550050d32bb3451f03abe90c0a49f2298f8c0ebfcc76868c8c1239e9f6
|
7
|
+
data.tar.gz: 8cdffbdf880e7760263ace646a97ab85f0cf28e60a6dc32a0f7f2e5a5d566ca344d63634d0d8f3a85dacfac979df85efd919fd54e7771432deca53ad80b5b367
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 Greg Woods
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# Keyper
|
2
|
+
|
3
|
+
This engine adds basic API functionality to a Ruby on Rails application. It enables mobile apps to login to your web service, request a set of API credentials, and then authenticate subsequent requests with key and secret headers.
|
4
|
+
|
5
|
+
## Compatibility
|
6
|
+
|
7
|
+
Keyper has been built with common Rails authentication practices in mind, and can work well with tools such as [has_secure_password](http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password) or [Authlogic](https://github.com/binarylogic/authlogic).
|
8
|
+
|
9
|
+
Broadly speaking, Keyper assumes your application has `User` and `UserSession` models, as well as the following controller methods:
|
10
|
+
|
11
|
+
- `require_user`
|
12
|
+
- `current_user`
|
13
|
+
- `current_user_session`
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'keyper'
|
21
|
+
```
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
```bash
|
25
|
+
$ bundle
|
26
|
+
```
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
```bash
|
30
|
+
$ gem install keyper
|
31
|
+
```
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
Mount the engine in our application's `routes.rb` file. This will determine the base path for API login.
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
Rails.application.routes.draw do
|
39
|
+
mount Keyper::Engine => "/api"
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
API key authentication is not enabled globally. Instead, you should include the `Keyper::ApiKeyAuthentication` module selectively in any controllers you wish to expose.
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
class ProtectedStuffController < ApplicationController
|
47
|
+
include Keyper::ApiKeyAuthentication
|
48
|
+
before_action :require_user
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
You can then optionally configure the engine, or leave it at the [default settings](lib/keyper/configuration.rb).
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
Keyper.configure do |config|
|
56
|
+
config.invalidate_keys_on_password_change = true
|
57
|
+
config.attribute_refresh_interval = 1.minute
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
## Authentication
|
62
|
+
|
63
|
+
Your mobile application should first attempt to create an API key. Make a POST request to the `/api/api_keys` endpoint, passing `:username` and `:password` parameters.
|
64
|
+
|
65
|
+
```
|
66
|
+
curl -X POST -F 'user_session[username]=username' -F 'user_session[password]=password' http://localhost:3000/api/api_keys
|
67
|
+
```
|
68
|
+
|
69
|
+
Sample response:
|
70
|
+
|
71
|
+
```json
|
72
|
+
{
|
73
|
+
"api_key":"06e374a582721189a58192413190600a",
|
74
|
+
"api_secret":"6240aa5521b44041d6a6874bf1001852"
|
75
|
+
}
|
76
|
+
```
|
77
|
+
|
78
|
+
Store those values securely in your application. You can then make authenticated requests by passing those values as `Api-Key` and `Api-Secret` headers, respectively.
|
79
|
+
|
80
|
+
```
|
81
|
+
curl --header "Api-Key: 06e374a582721189a58192413190600a" --header "Api-Secret: 6240aa5521b44041d6a6874bf1001852" http://localhost:3000/protected_stuff
|
82
|
+
```
|
83
|
+
|
84
|
+
You can hit the `/api/api_keys/check` endpoint to quickly check the validity of your keys. A 200 response means your keys are good.
|
85
|
+
|
86
|
+
```
|
87
|
+
curl --header "Api-Key: 06e374a582721189a58192413190600a" --header "Api-Secret: 6240aa5521b44041d6a6874bf1001852" http://localhost:3000/api/api_keys/check
|
88
|
+
```
|
89
|
+
|
90
|
+
When your user logs out, it is a good idea to delete the associated API key. You can do that by making a DELETE request. Pass the key and secret headers as you normally would, then specify which key you wish to delete in the restful url parameter.
|
91
|
+
|
92
|
+
```
|
93
|
+
curl -X DELETE \
|
94
|
+
--header "Api-Key: 06e374a582721189a58192413190600a" \
|
95
|
+
--header "Api-Secret: 6240aa5521b44041d6a6874bf1001852" \
|
96
|
+
http://localhost:3000/api/api_keys/06e374a582721189a58192413190600a
|
97
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Keyper'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
load 'rails/tasks/statistics.rake'
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'lib'
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
task default: :test
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Keyper::ApiKeyAuthentication
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
API_KEY = 'Api-Key'
|
6
|
+
API_SECRET = 'Api-Secret'
|
7
|
+
|
8
|
+
# Override the default current_user functionality
|
9
|
+
#
|
10
|
+
def current_user
|
11
|
+
return @current_user if defined?(@current_user)
|
12
|
+
@current_user = if passed_api_keys?
|
13
|
+
authenticate_with_api_keys
|
14
|
+
elsif current_user_session && current_user_session.record
|
15
|
+
current_user_session.record
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# True if the api key headers are present
|
22
|
+
#
|
23
|
+
def passed_api_keys?
|
24
|
+
request.headers.key?(API_KEY) && request.headers.key?(API_SECRET)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Check the validity of the keys
|
28
|
+
#
|
29
|
+
def authenticate_with_api_keys
|
30
|
+
key = Keyper::ApiKey.find_by(api_key: request.headers[API_KEY])
|
31
|
+
unless key && key.authenticate(request.headers[API_SECRET])
|
32
|
+
raise Keyper::ApiKeyError, I18n.t(:api_key, scope: [:keyper, :errors])
|
33
|
+
end
|
34
|
+
if key.should_update_attributes?
|
35
|
+
key.update(
|
36
|
+
last_used_at: Time.zone.now,
|
37
|
+
last_used_ip: request.remote_ip,
|
38
|
+
last_used_ua: request.user_agent
|
39
|
+
)
|
40
|
+
end
|
41
|
+
key.user
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class Keyper::ApiKeysController < ApplicationController
|
2
|
+
include Keyper::ApiKeyAuthentication
|
3
|
+
before_action :require_user, except: [:create, :check]
|
4
|
+
skip_before_action :verify_authenticity_token
|
5
|
+
|
6
|
+
respond_to :json if defined?(ActionController::Responder)
|
7
|
+
|
8
|
+
def index
|
9
|
+
@api_keys = Keyper::ApiKey.where(user: current_user).map do |api_key|
|
10
|
+
{
|
11
|
+
api_key: api_key.api_key,
|
12
|
+
last_used_at: api_key.last_used_at
|
13
|
+
}
|
14
|
+
end
|
15
|
+
render json: @api_keys
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
authentication = Keyper::Authentication.new(user_session_params)
|
20
|
+
if authentication.valid?
|
21
|
+
@api_key = Keyper::ApiKey.create(user: authentication.user)
|
22
|
+
render json: {
|
23
|
+
api_key: @api_key.api_key,
|
24
|
+
api_secret: @api_key.password
|
25
|
+
}
|
26
|
+
elsif defined?(ActionController::Responder)
|
27
|
+
respond_with authentication
|
28
|
+
else
|
29
|
+
render json: {
|
30
|
+
errors: authentication.errors
|
31
|
+
}, status: :unprocessable_entity
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def destroy
|
36
|
+
@api_key = Keyper::ApiKey.find_by!(
|
37
|
+
api_key: params[:id],
|
38
|
+
user: current_user
|
39
|
+
)
|
40
|
+
@api_key.destroy
|
41
|
+
head :ok
|
42
|
+
end
|
43
|
+
|
44
|
+
def check
|
45
|
+
key = Keyper::ApiKey.find_by(api_key: check_api_key_params[:api_key])
|
46
|
+
if key.present? && key.authenticate(check_api_key_params[:api_secret])
|
47
|
+
head :ok
|
48
|
+
else
|
49
|
+
head :unauthorized
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def user_session_params
|
56
|
+
params.require(:user_session).permit(:username, :password)
|
57
|
+
end
|
58
|
+
|
59
|
+
def check_api_key_params
|
60
|
+
params.require(:api_key).permit(:api_key, :api_secret)
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Keyper::HasApiKeys
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
has_many :api_keys, class_name: 'Keyper::ApiKey', foreign_key: :user_id, dependent: :destroy
|
6
|
+
before_update :invalidate_api_keys
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def invalidate_api_keys
|
12
|
+
return unless Keyper.invalidate_keys_on_password_change
|
13
|
+
method_candidates = [
|
14
|
+
:password_digest_changed?, :password_changed?
|
15
|
+
]
|
16
|
+
method_candidates.each do |method|
|
17
|
+
if respond_to?(method, true) && send(method)
|
18
|
+
api_keys.destroy_all
|
19
|
+
break
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Keyper
|
2
|
+
class ApiKey < ApplicationRecord
|
3
|
+
self.table_name = :keyper_api_keys
|
4
|
+
has_secure_password
|
5
|
+
belongs_to :user,
|
6
|
+
class_name: Keyper.user_class_name
|
7
|
+
|
8
|
+
before_validation :generate_api_key_and_secret, on: :create
|
9
|
+
validates :api_key, :user, presence: true
|
10
|
+
|
11
|
+
def should_update_attributes?
|
12
|
+
return last_used_at.nil? || last_used_at < Keyper.attribute_refresh_interval.ago
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def generate_api_key_and_secret
|
18
|
+
self.api_key = loop do
|
19
|
+
key = SecureRandom.hex(16)
|
20
|
+
break key unless Keyper::ApiKey.exists?(api_key: key)
|
21
|
+
end
|
22
|
+
self.password = SecureRandom.hex(16)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Keyper
|
2
|
+
class Authentication
|
3
|
+
include ActiveModel::Model
|
4
|
+
|
5
|
+
attr_accessor :user, :username, :password
|
6
|
+
validates :username, :password, presence: true
|
7
|
+
validate :username_and_password_are_correct
|
8
|
+
|
9
|
+
def username_and_password_are_correct
|
10
|
+
user_class = Object.const_get(Keyper.user_class_name)
|
11
|
+
@user = user_class.find_by(
|
12
|
+
Keyper.user_finder_field => @username
|
13
|
+
)
|
14
|
+
unless @user && user_authenticated?(@user, password)
|
15
|
+
errors.add(:base, I18n.t(:login_failed, scope: [:keyper, :errors]))
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def user_authenticated?(user, password)
|
21
|
+
method_candidates = [
|
22
|
+
:valid_password?, :authenticate
|
23
|
+
]
|
24
|
+
method_candidates.each do |method|
|
25
|
+
return true if user.respond_to?(method) && user.send(method, password)
|
26
|
+
end
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateKeyperApiKeys < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :keyper_api_keys do |t|
|
4
|
+
t.references :user, foreign_key: false
|
5
|
+
t.string :api_key, null: false
|
6
|
+
t.index :api_key, unique: true
|
7
|
+
t.string :password_digest, null: false
|
8
|
+
t.datetime :last_used_at
|
9
|
+
t.string :last_used_ip
|
10
|
+
t.string :last_used_ua
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/keyper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Keyper
|
2
|
+
include ActiveSupport::Configurable
|
3
|
+
config_accessor :user_class_name, :user_finder_field,
|
4
|
+
:invalidate_keys_on_password_change, :attribute_refresh_interval
|
5
|
+
|
6
|
+
# The class name of your User model
|
7
|
+
self.user_class_name = 'User'.freeze
|
8
|
+
|
9
|
+
# What field should we use in the finder
|
10
|
+
self.user_finder_field = :username
|
11
|
+
|
12
|
+
# If true, api keys will be destroyed any time the user changes their password
|
13
|
+
self.invalidate_keys_on_password_change = true
|
14
|
+
|
15
|
+
# How often should we update the api key tracking attributes
|
16
|
+
self.attribute_refresh_interval = 1.minute
|
17
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'bcrypt'
|
2
|
+
|
3
|
+
module Keyper
|
4
|
+
class Engine < ::Rails::Engine
|
5
|
+
engine_name 'keyper'
|
6
|
+
# isolate_namespace Keyper
|
7
|
+
# config.autoload_paths += Dir["#{config.root}/lib/**/"]
|
8
|
+
|
9
|
+
config.generators do |g|
|
10
|
+
g.test_framework :rspec, fixture: false
|
11
|
+
g.fixture_replacement :factory_girl, dir: 'spec/factories'
|
12
|
+
g.assets false
|
13
|
+
g.helper true
|
14
|
+
end
|
15
|
+
|
16
|
+
initializer 'keyper.filter_parameters' do
|
17
|
+
Rails.application.config.filter_parameters += [:api_secret]
|
18
|
+
end
|
19
|
+
|
20
|
+
initializer 'keyper.models' do |_config|
|
21
|
+
ActiveSupport.on_load(:active_record) do
|
22
|
+
user_class = Object.const_get(Keyper.user_class_name)
|
23
|
+
user_class.send :include, Keyper::HasApiKeys
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: keyper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Greg Woods
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.0.0
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 5.0.0.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 5.0.0
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 5.0.0.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bcrypt
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: pg
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.15'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.15'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec-rails
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: factory_girl_rails
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: database_cleaner
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: simplecov
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rubocop
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
description: Add API keys to a Ruby on Rails application
|
132
|
+
email:
|
133
|
+
- greg.woods@moserit.com
|
134
|
+
executables: []
|
135
|
+
extensions: []
|
136
|
+
extra_rdoc_files: []
|
137
|
+
files:
|
138
|
+
- MIT-LICENSE
|
139
|
+
- README.md
|
140
|
+
- Rakefile
|
141
|
+
- app/assets/config/tb_apis_manifest.js
|
142
|
+
- app/assets/javascripts/tb_api_keys/application.js
|
143
|
+
- app/assets/stylesheets/tb_api_keys/application.css
|
144
|
+
- app/controllers/concerns/keyper/api_key_authentication.rb
|
145
|
+
- app/controllers/keyper/api_keys_controller.rb
|
146
|
+
- app/controllers/keyper/application_controller.rb
|
147
|
+
- app/helpers/keyper/application_helper.rb
|
148
|
+
- app/jobs/keyper/application_job.rb
|
149
|
+
- app/mailers/keyper/application_mailer.rb
|
150
|
+
- app/models/application_record.rb
|
151
|
+
- app/models/concerns/keyper/has_api_keys.rb
|
152
|
+
- app/models/keyper/api_key.rb
|
153
|
+
- app/models/keyper/authentication.rb
|
154
|
+
- config/locales/en.yml
|
155
|
+
- config/routes.rb
|
156
|
+
- db/migrate/20161025210140_create_keyper_api_keys.rb
|
157
|
+
- lib/keyper.rb
|
158
|
+
- lib/keyper/configuration.rb
|
159
|
+
- lib/keyper/engine.rb
|
160
|
+
- lib/keyper/errors.rb
|
161
|
+
- lib/keyper/version.rb
|
162
|
+
- lib/tasks/keyper_tasks.rake
|
163
|
+
homepage: https://github.com/moser-inc/keyper
|
164
|
+
licenses:
|
165
|
+
- MIT
|
166
|
+
metadata: {}
|
167
|
+
post_install_message:
|
168
|
+
rdoc_options: []
|
169
|
+
require_paths:
|
170
|
+
- lib
|
171
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
requirements: []
|
182
|
+
rubyforge_project:
|
183
|
+
rubygems_version: 2.5.1
|
184
|
+
signing_key:
|
185
|
+
specification_version: 4
|
186
|
+
summary: Add API keys to a Ruby on Rails application
|
187
|
+
test_files: []
|