knocknock 0.0.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.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +206 -0
  4. data/Rakefile +37 -0
  5. data/app/controllers/knocknock/auth_tokens_controller.rb +54 -0
  6. data/app/model/knocknock/auth_token.rb +69 -0
  7. data/config/routes.rb +2 -0
  8. data/lib/generators/knocknock/install_generator.rb +20 -0
  9. data/lib/generators/knocknock/token_controller_generator.rb +25 -0
  10. data/lib/generators/templates/access_token.rb.erb +17 -0
  11. data/lib/generators/templates/create_access_token.rb +9 -0
  12. data/lib/generators/templates/knocknock.rb +50 -0
  13. data/lib/generators/templates/resource_tokens_controller.rb.erb +2 -0
  14. data/lib/knocknock.rb +25 -0
  15. data/lib/knocknock/authenticatable.rb +47 -0
  16. data/lib/knocknock/engine.rb +6 -0
  17. data/lib/knocknock/version.rb +3 -0
  18. data/lib/tasks/knocknock_tasks.rake +4 -0
  19. data/test/dummy/README.rdoc +28 -0
  20. data/test/dummy/Rakefile +6 -0
  21. data/test/dummy/app/controllers/admin_protected_controller.rb +7 -0
  22. data/test/dummy/app/controllers/admin_tokens_controller.rb +2 -0
  23. data/test/dummy/app/controllers/application_controller.rb +3 -0
  24. data/test/dummy/app/controllers/user_protected_controller.rb +7 -0
  25. data/test/dummy/app/controllers/user_tokens_controller.rb +2 -0
  26. data/test/dummy/app/helpers/application_helper.rb +2 -0
  27. data/test/dummy/app/models/access_token.rb +3 -0
  28. data/test/dummy/app/models/admin.rb +5 -0
  29. data/test/dummy/app/models/user.rb +5 -0
  30. data/test/dummy/bin/bundle +3 -0
  31. data/test/dummy/bin/rails +4 -0
  32. data/test/dummy/bin/rake +4 -0
  33. data/test/dummy/bin/setup +29 -0
  34. data/test/dummy/config.ru +4 -0
  35. data/test/dummy/config/application.rb +23 -0
  36. data/test/dummy/config/boot.rb +5 -0
  37. data/test/dummy/config/database.yml +25 -0
  38. data/test/dummy/config/environment.rb +5 -0
  39. data/test/dummy/config/environments/development.rb +56 -0
  40. data/test/dummy/config/environments/production.rb +82 -0
  41. data/test/dummy/config/environments/test.rb +44 -0
  42. data/test/dummy/config/initializers/assets.rb +11 -0
  43. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  44. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  45. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  46. data/test/dummy/config/initializers/inflections.rb +16 -0
  47. data/test/dummy/config/initializers/mime_types.rb +4 -0
  48. data/test/dummy/config/initializers/session_store.rb +3 -0
  49. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/test/dummy/config/locales/en.yml +23 -0
  51. data/test/dummy/config/routes.rb +6 -0
  52. data/test/dummy/config/secrets.yml +22 -0
  53. data/test/dummy/db/development.sqlite3 +0 -0
  54. data/test/dummy/db/migrate/20150713101607_create_users.rb +10 -0
  55. data/test/dummy/db/migrate/20150922015152_create_admins.rb +10 -0
  56. data/test/dummy/db/migrate/20160218200351_create_access_tokens.rb +11 -0
  57. data/test/dummy/db/schema.rb +40 -0
  58. data/test/dummy/db/test.sqlite3 +0 -0
  59. data/test/dummy/log/development.log +52 -0
  60. data/test/dummy/log/test.log +9320 -0
  61. data/test/dummy/public/404.html +67 -0
  62. data/test/dummy/public/422.html +67 -0
  63. data/test/dummy/public/500.html +66 -0
  64. data/test/dummy/public/favicon.ico +0 -0
  65. data/test/dummy/test/controllers/admin_protected_controller_test.rb +49 -0
  66. data/test/dummy/test/controllers/admin_tokens_controller_test.rb +22 -0
  67. data/test/dummy/test/controllers/user_protected_controller_test.rb +49 -0
  68. data/test/dummy/test/controllers/user_tokens_controller_test.rb +23 -0
  69. data/test/dummy/test/fixtures/access_tokens.yml +11 -0
  70. data/test/dummy/test/models/access_token_test.rb +7 -0
  71. data/test/dummy/test/models/admin_test.rb +4 -0
  72. data/test/dummy/test/models/user_test.rb +4 -0
  73. data/test/fixtures/admins.yml +5 -0
  74. data/test/fixtures/users.yml +9 -0
  75. data/test/generators/install_generator_test.rb +15 -0
  76. data/test/generators/token_controller_generator_test.rb +19 -0
  77. data/test/knocknock_test.rb +9 -0
  78. data/test/model/knocknock/auth_token_test.rb +50 -0
  79. data/test/support/generators_test_helper.rb +9 -0
  80. data/test/test_helper.rb +38 -0
  81. data/test/tmp/app/controllers/admin_tokens_controller.rb +2 -0
  82. data/test/tmp/app/controllers/user_tokens_controller.rb +2 -0
  83. data/test/tmp/config/routes.rb +8 -0
  84. metadata +253 -0
@@ -0,0 +1,17 @@
1
+ <% if Rails.version.starts_with? '5' %>
2
+ class AccessToken < ApplicationRecord
3
+ <% else %>
4
+ class AccessToken < ActiveRecord::Base
5
+ <% end %>
6
+ belongs_to :authenticatee, polymorphic: true
7
+
8
+ before_create :generate_token
9
+
10
+ private
11
+
12
+ def generate_token
13
+ begin
14
+ self.token = SecureRandom.uuid
15
+ end while self.class.exists?(token: token)
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ class CreateAccessToken < ActiveRecord::Migration[5.0]
2
+ def change
3
+ create_table :access_tokens do |t|
4
+ t.string :token
5
+ t.references :authenticatee, polymorphic: true
6
+ end
7
+ add_index :access_tokens, :token
8
+ end
9
+ end
@@ -0,0 +1,50 @@
1
+ Knocknock.setup do |config|
2
+
3
+ ## Expiration claim
4
+ ## ----------------
5
+ ##
6
+ ## How long before a token is expired.
7
+ ##
8
+ ## Default:
9
+ # config.token_lifetime = 1.day
10
+
11
+
12
+ ## Audience claim
13
+ ## --------------
14
+ ##
15
+ ## Configure the audience claim to identify the recipients that the token
16
+ ## is intended for.
17
+ ##
18
+ ## Default:
19
+ # config.token_audience = nil
20
+
21
+ ## If using Auth0, uncomment the line below
22
+ # config.token_audience = -> { Rails.application.secrets.auth0_client_id }
23
+
24
+ ## Signature algorithm
25
+ ## -------------------
26
+ ##
27
+ ## Configure the algorithm used to encode the token
28
+ ##
29
+ ## Default:
30
+ # config.token_signature_algorithm = 'HS256'
31
+
32
+ ## Signature key
33
+ ## -------------
34
+ ##
35
+ ## Configure the key used to sign tokens.
36
+ ##
37
+ ## Default:
38
+ # config.token_secret_signature_key = -> { Rails.application.secrets.secret_key_base }
39
+
40
+ ## If using Auth0, uncomment the line below
41
+ # config.token_secret_signature_key = -> { JWT.base64url_decode Rails.application.secrets.auth0_client_secret }
42
+
43
+ ## Public key
44
+ ## ----------
45
+ ##
46
+ ## Configure the public key used to decode tokens, if required.
47
+ ##
48
+ ## Default:
49
+ # config.token_public_key = nil
50
+ end
@@ -0,0 +1,2 @@
1
+ class <%= resource_name.capitalize %>TokensController < Knock::AuthTokensController
2
+ end
@@ -0,0 +1,25 @@
1
+ require "knocknock/engine"
2
+
3
+ module Knocknock
4
+
5
+ mattr_accessor :token_lifetime
6
+ self.token_lifetime = 1.day
7
+
8
+ mattr_accessor :token_audience
9
+ self.token_audience = nil
10
+
11
+ mattr_accessor :token_signature_algorithm
12
+ self.token_signature_algorithm = 'HS256'
13
+
14
+ mattr_accessor :token_secret_signature_key
15
+ self.token_secret_signature_key = -> { Rails.application.secrets.secret_key_base }
16
+
17
+ mattr_accessor :token_public_key
18
+ self.token_public_key = nil
19
+
20
+ # Default way to setup Knocknock. Run `rails generate knocknock:install` to
21
+ #create a fresh initializer and AccessToken model.
22
+ def self.setup
23
+ yield self
24
+ end
25
+ end
@@ -0,0 +1,47 @@
1
+ module Knocknock::Authenticatable
2
+
3
+ def authenticate_for resource_class
4
+ token = token_from_request_headers
5
+ return head(:unauthorized) if token.nil?
6
+
7
+ begin
8
+ @resource = Knocknock::AuthToken.new(token: token).resource(resource_class)
9
+ return head(:unauthorized) unless @resource
10
+ define_current_resource_getter(resource_class)
11
+ rescue
12
+ return head(:unauthorized)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def method_missing(method, *args)
19
+ prefix, *parts = method.to_s.split('_')
20
+ if prefix == 'authenticate'
21
+ resource_class = constant_from_parts(parts)
22
+ send(:authenticate_for, resource_class)
23
+ else
24
+ super
25
+ end
26
+ end
27
+
28
+ def token_from_request_headers
29
+ unless request.headers['Authorization'].nil?
30
+ request.headers['Authorization'].split.last
31
+ end
32
+ end
33
+
34
+ def define_current_resource_getter resource_class
35
+ underscored_resource = resource_class.to_s.underscore
36
+ self.class.send(:define_method, "current_#{underscored_resource}") do
37
+ @resource
38
+ end
39
+ end
40
+
41
+ # Not rescuing from NameError on purpose.
42
+ # If trying to use `authenticate_user` but no `User` constant exists,
43
+ # it makes more sense to raise NameError than NoMethodError.
44
+ def constant_from_parts parts
45
+ parts.map(&:capitalize).join.constantize
46
+ end
47
+ end
@@ -0,0 +1,6 @@
1
+ module Knocknock
2
+ class Engine < ::Rails::Engine
3
+ config.autoload_paths += Dir["#{config.root}/lib/**/"]
4
+ isolate_namespace Knocknock
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module Knocknock
2
+ VERSION = '0.0.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :knock do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,7 @@
1
+ class AdminProtectedController < ApplicationController
2
+ before_action :authenticate_admin
3
+
4
+ def index
5
+ head :ok
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ class AdminTokensController < Knocknock::AuthTokensController
2
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::API
2
+ include Knocknock::Authenticatable
3
+ end
@@ -0,0 +1,7 @@
1
+ class UserProtectedController < ApplicationController
2
+ before_action :authenticate_user
3
+
4
+ def index
5
+ head :ok
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ class UserTokensController < Knocknock::AuthTokensController
2
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,3 @@
1
+ class AccessToken < ActiveRecord::Base
2
+ belongs_to :authenticatee, polymorphic: true
3
+ end
@@ -0,0 +1,5 @@
1
+ class Admin < ActiveRecord::Base
2
+ has_many :access_tokens, as: :authenticatee
3
+
4
+ has_secure_password
5
+ end
@@ -0,0 +1,5 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :access_tokens, as: :authenticatee
3
+
4
+ has_secure_password
5
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
+ load Gem.bin_path('bundler', 'bundle')
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../config/boot'
3
+ require 'rake'
4
+ Rake.application.run
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+
4
+ # path to your application root.
5
+ APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
6
+
7
+ Dir.chdir APP_ROOT do
8
+ # This script is a starting point to setup your application.
9
+ # Add necessary setup steps to this file:
10
+
11
+ puts "== Installing dependencies =="
12
+ system "gem install bundler --conservative"
13
+ system "bundle check || bundle install"
14
+
15
+ # puts "\n== Copying sample files =="
16
+ # unless File.exist?("config/database.yml")
17
+ # system "cp config/database.yml.sample config/database.yml"
18
+ # end
19
+
20
+ puts "\n== Preparing database =="
21
+ system "bin/rake db:setup"
22
+
23
+ puts "\n== Removing old logs and tempfiles =="
24
+ system "rm -f log/*"
25
+ system "rm -rf tmp/cache"
26
+
27
+ puts "\n== Restarting application server =="
28
+ system "touch tmp/restart.txt"
29
+ end
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Rails.application
@@ -0,0 +1,23 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require(*Rails.groups)
6
+ require "knocknock"
7
+
8
+ module Dummy
9
+ class Application < Rails::Application
10
+ # Settings in config/environments/* take precedence over those specified here.
11
+ # Application configuration should go into files in config/initializers
12
+ # -- all .rb files in that directory are automatically loaded.
13
+
14
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
15
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
16
+ # config.time_zone = 'Central Time (US & Canada)'
17
+
18
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
19
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
20
+ # config.i18n.default_locale = :de
21
+ end
22
+ end
23
+
@@ -0,0 +1,5 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
5
+ $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,25 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3
3
+ #
4
+ # Ensure the SQLite 3 gem is defined in your Gemfile
5
+ # gem 'sqlite3'
6
+ #
7
+ default: &default
8
+ adapter: sqlite3
9
+ pool: 5
10
+ timeout: 5000
11
+
12
+ development:
13
+ <<: *default
14
+ database: db/development.sqlite3
15
+
16
+ # Warning: The database defined as "test" will be erased and
17
+ # re-generated from your development database when you run "rake".
18
+ # Do not set this db to the same as development or production.
19
+ test:
20
+ <<: *default
21
+ database: db/test.sqlite3
22
+
23
+ production:
24
+ <<: *default
25
+ database: db/production.sqlite3
@@ -0,0 +1,5 @@
1
+ # Load the Rails application.
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the Rails application.
5
+ Rails.application.initialize!
@@ -0,0 +1,56 @@
1
+ Rails.application.configure do
2
+ # Settings specified here will take precedence over those in config/application.rb.
3
+
4
+ # In the development environment your application's code is reloaded on
5
+ # every request. This slows down response time but is perfect for development
6
+ # since you don't have to restart the web server when you make code changes.
7
+ config.cache_classes = false
8
+
9
+ # Do not eager load code on boot.
10
+ config.eager_load = false
11
+
12
+ # Show full error reports.
13
+ config.consider_all_requests_local = true
14
+
15
+ # Enable/disable caching. By default caching is disabled.
16
+ if Rails.root.join('tmp/caching-dev.txt').exist?
17
+ config.action_controller.perform_caching = true
18
+ config.cache_store = :memory_store
19
+ config.public_file_server.headers = {
20
+ 'Cache-Control' => 'public, max-age=172800'
21
+ }
22
+ else
23
+ config.action_controller.perform_caching = false
24
+ config.cache_store = :null_store
25
+ end
26
+
27
+ # Don't care if the mailer can't send.
28
+ config.action_mailer.raise_delivery_errors = false
29
+
30
+ # Print deprecation notices to the Rails logger.
31
+ config.active_support.deprecation = :log
32
+
33
+ # Raise an error on page load if there are pending migrations.
34
+ config.active_record.migration_error = :page_load
35
+
36
+ # Debug mode disables concatenation and preprocessing of assets.
37
+ # This option may cause significant delays in view rendering with a large
38
+ # number of complex assets.
39
+ config.assets.debug = true
40
+
41
+ # Asset digests allow you to set far-future HTTP expiration dates on all assets,
42
+ # yet still be able to expire them through the digest params.
43
+ config.assets.digest = true
44
+
45
+ # Adds additional error checking when serving assets at runtime.
46
+ # Checks for improperly declared sprockets dependencies.
47
+ # Raises helpful error messages.
48
+ config.assets.raise_runtime_errors = true
49
+
50
+ # Raises error for missing translations
51
+ # config.action_view.raise_on_missing_translations = true
52
+
53
+ # Use an evented file watcher to asynchronously detect changes in source code,
54
+ # routes, locales, etc. This feature depends on the listen gem.
55
+ # config.file_watcher = ActiveSupport::EventedFileUpdateChecker
56
+ end
@@ -0,0 +1,82 @@
1
+ Rails.application.configure do
2
+ # Settings specified here will take precedence over those in config/application.rb.
3
+
4
+ # Code is not reloaded between requests.
5
+ config.cache_classes = true
6
+
7
+ # Eager load code on boot. This eager loads most of Rails and
8
+ # your application in memory, allowing both threaded web servers
9
+ # and those relying on copy on write to perform better.
10
+ # Rake tasks automatically ignore this option for performance.
11
+ config.eager_load = true
12
+
13
+ # Full error reports are disabled and caching is turned on.
14
+ config.consider_all_requests_local = false
15
+ config.action_controller.perform_caching = true
16
+
17
+ # Disable serving static files from the `/public` folder by default since
18
+ # Apache or NGINX already handles this.
19
+ config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
20
+
21
+ # Compress JavaScripts and CSS.
22
+ config.assets.js_compressor = :uglifier
23
+ # config.assets.css_compressor = :sass
24
+
25
+ # Do not fallback to assets pipeline if a precompiled asset is missed.
26
+ config.assets.compile = false
27
+
28
+ # Asset digests allow you to set far-future HTTP expiration dates on all assets,
29
+ # yet still be able to expire them through the digest params.
30
+ config.assets.digest = true
31
+
32
+ # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
33
+
34
+ # Enable serving of images, stylesheets, and JavaScripts from an asset server.
35
+ # config.action_controller.asset_host = 'http://assets.example.com'
36
+
37
+ # Specifies the header that your server uses for sending files.
38
+ # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
39
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
40
+
41
+ # Action Cable endpoint configuration
42
+ # config.action_cable.url = 'wss://example.com/cable'
43
+ # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
44
+
45
+ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
46
+ config.force_ssl = true
47
+
48
+ # Use the lowest log level to ensure availability of diagnostic information
49
+ # when problems arise.
50
+ config.log_level = :debug
51
+
52
+ # Prepend all log lines with the following tags.
53
+ # config.log_tags = [ :subdomain, :request_id ]
54
+
55
+ # Use a different logger for distributed setups.
56
+ # require 'syslog/logger'
57
+ # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
58
+
59
+ # Use a different cache store in production.
60
+ # config.cache_store = :mem_cache_store
61
+
62
+ # Use a real queuing backend for Active Job (and separate queues per environment)
63
+ # config.active_job.queue_adapter = :resque
64
+ # config.active_job.queue_name_prefix = "senyore_#{Rails.env}"
65
+
66
+ # Ignore bad email addresses and do not raise email delivery errors.
67
+ # Set this to true and configure the email server for immediate delivery to raise delivery errors.
68
+ # config.action_mailer.raise_delivery_errors = false
69
+
70
+ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
71
+ # the I18n.default_locale when a translation cannot be found).
72
+ config.i18n.fallbacks = true
73
+
74
+ # Send deprecation notices to registered listeners.
75
+ config.active_support.deprecation = :notify
76
+
77
+ # Use default logging formatter so that PID and timestamp are not suppressed.
78
+ config.log_formatter = ::Logger::Formatter.new
79
+
80
+ # Do not dump schema after migrations.
81
+ config.active_record.dump_schema_after_migration = false
82
+ end