secretkeeper 0.1.0 → 0.1.1

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,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 84593075dabb8014b00ac2efb375f56c5fdbc7db
4
- data.tar.gz: 9bf59fb59e734f7c4bbe77b93bbe4e8d991475ca
2
+ SHA256:
3
+ metadata.gz: 4aaccaa792079587f03048814194318bda9674d49349d0b718198ae056695820
4
+ data.tar.gz: bbcadf0fcb47cd9a74a9cf8d2ea09877b2325df7ab6490fc1c01927f0db82cee
5
5
  SHA512:
6
- metadata.gz: ce4af121133d3dd16483d845f601f769259528aee732d71101973dc06f73b4c9dde33c088ac9939df7bad2903b57331c5bc5fc3d950be34cfbb71ca49e9dde63
7
- data.tar.gz: bb5a2be005753e563a499b46c0ba81792035c53cb1c06b07127381a80dae13e46dddf0ecfc1ac39273966d794d6fc6aaf808306838065032da71f89f8ecf0631
6
+ metadata.gz: 5ed5e626b3ed28f2965672f4cde83e154cb3d162caff25d08e258269ffdb730cc06ffd756b0c249f7b89a91ff930f4389e4cf65cdfb3a0c689d0d776f39eed9f
7
+ data.tar.gz: 61799d52dc349a0639d6677d88411a87a5bbbf343e22eeee747417933e2122a3128d4fa2f44a080ab5c1508c6315f2b0a3895b94ac1f34a9a684086ae0bf1495
data/README.md CHANGED
@@ -1,10 +1,8 @@
1
1
  # Secretkeeper
2
- Short description and motivation.
3
-
4
- ## Usage
5
- How to use my plugin.
2
+ Token based authentication.
6
3
 
7
4
  ## Installation
5
+
8
6
  Add this line to your application's Gemfile:
9
7
 
10
8
  ```ruby
@@ -26,5 +24,38 @@ Run the installation generator with:
26
24
  rails generate secretkeeper:install
27
25
  ```
28
26
 
27
+ ## Usage
28
+
29
+ ### Authorizing requests
30
+
31
+ ``` ruby
32
+ class Api::BaseController < ActionController::API
33
+ before_action :secretkeeper_authorize!
34
+ end
35
+ ```
36
+
37
+ ### Authenticating
38
+
39
+ `config/initializers/secretkeeper.rb`:
40
+
41
+ ``` ruby
42
+ Secretkeeper.reflect do |on|
43
+ on.resource_owner do |params|
44
+ User.authenticate!(params[:name], params[:password])
45
+ end
46
+ end
47
+ ```
48
+
49
+ ### Routes
50
+
51
+ The installation script will also automatically add the Secretkeeper routes into your app.
52
+
53
+ ``` ruby
54
+ Rails.application.routes.draw do
55
+ secretkeeper
56
+ end
57
+ ```
58
+
29
59
  ## License
60
+
30
61
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
- require "bundler/setup"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  # begin
5
7
  # require 'bundler/setup'
@@ -17,11 +19,6 @@ require "rspec/core/rake_task"
17
19
  # rdoc.rdoc_files.include('lib/**/*.rb')
18
20
  # end
19
21
 
20
-
21
-
22
-
23
-
24
-
25
22
  # require 'bundler/gem_tasks'
26
23
 
27
24
  # require 'rake/testtask'
@@ -32,10 +29,10 @@ require "rspec/core/rake_task"
32
29
  # t.verbose = false
33
30
  # end
34
31
 
35
- desc "Default: run specs."
32
+ desc 'Default: run specs.'
36
33
  task default: :spec
37
34
 
38
- desc "Run all specs"
35
+ desc 'Run all specs'
39
36
  RSpec::Core::RakeTask.new(:spec) do |config|
40
37
  config.verbose = false
41
38
  end
@@ -1,41 +1,45 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Secretkeeper
2
4
  class AuthController < ActionController::Metal
3
5
  include AbstractController::Rendering
4
- include ActionController::Rendering
5
- include ActionController::Renderers
6
6
  include ActionController::Head
7
+ include ActionController::Renderers
8
+ include ActionController::Rendering
7
9
 
8
10
  use_renderers :json
9
11
 
10
12
  def create_token
11
13
  resource_owner = Secretkeeper.reflection_resource_owner.call(params)
12
- if resource_owner.present?
13
- access_token = Secretkeeper::AccessToken.create(owner: resource_owner)
14
- render json: {
15
- access_token: access_token.token,
16
- expires_in: access_token.expires_in,
17
- refresh_token: access_token.refresh_token,
18
- created_at: access_token.created_at.to_i
19
- }, status: 201
20
- else
21
- head 401
22
- end
14
+
15
+ return head 401 if resource_owner.nil?
16
+
17
+ @access_token = Secretkeeper::AccessToken.create(owner: resource_owner)
18
+ render json: success, status: 201
23
19
  end
24
20
 
25
21
  def refresh_token
26
- token = Secretkeeper::AccessToken.find_by(refresh_token: params[:refresh_token])
27
- if token.present? && token.refreshable?
28
- token.revoke!
29
- new_token = Secretkeeper::AccessToken.create(owner: token.owner)
30
- render json: {
31
- access_token: new_token.token,
32
- expires_in: new_token.expires_in,
33
- refresh_token: new_token.refresh_token,
34
- created_at: DateTime.now.to_i
35
- }
36
- else
37
- head 403
38
- end
22
+ return head 403 unless old_token&.refreshable?
23
+
24
+ old_token.revoke!
25
+ @access_token = Secretkeeper::AccessToken.create(owner: old_token.owner)
26
+ render json: success
27
+ end
28
+
29
+ private
30
+
31
+ def success
32
+ {
33
+ access_token: @access_token.token,
34
+ expires_in: @access_token.expires_in,
35
+ refresh_token: @access_token.refresh_token,
36
+ created_at: @access_token.created_at.to_i
37
+ }
38
+ end
39
+
40
+ def old_token
41
+ @old_token ||=
42
+ Secretkeeper::AccessToken.find_by(refresh_token: params[:refresh_token])
39
43
  end
40
44
  end
41
45
  end
@@ -1,28 +1,36 @@
1
- require "rails/generators/active_record"
1
+ # frozen_string_literal: true
2
2
 
3
- class Secretkeeper::InstallGenerator < ::Rails::Generators::Base
4
- include Rails::Generators::Migration
3
+ require 'rails/generators/active_record'
5
4
 
6
- source_root File.expand_path("../templates", __FILE__)
5
+ module Secretkeeper
6
+ class InstallGenerator < ::Rails::Generators::Base
7
+ include ::Rails::Generators::Migration
7
8
 
8
- def install
9
- copy_file "initializer.rb", "config/initializers/secretkeeper.rb"
10
- migration_template(
11
- "migration.rb",
12
- "db/migrate/create_secretkeeper_tables.rb",
13
- migration_version: migration_version
14
- )
15
- route "secretkeeper"
16
- end
9
+ source_root File.expand_path('templates', __dir__)
17
10
 
18
- def self.next_migration_number(dirname)
19
- next_migration_number = current_migration_number(dirname) + 1
20
- ActiveRecord::Migration.next_migration_number(next_migration_number)
21
- end
11
+ def install
12
+ copy_file 'initializer.rb', 'config/initializers/secretkeeper.rb'
13
+ migration_template(
14
+ 'migration.rb',
15
+ 'db/migrate/create_secretkeeper_tables.rb',
16
+ migration_version: migration_version
17
+ )
18
+ route 'secretkeeper'
19
+ end
20
+
21
+ def self.next_migration_number(dirname)
22
+ next_migration_number = current_migration_number(dirname) + 1
23
+ ActiveRecord::Migration.next_migration_number(next_migration_number)
24
+ end
25
+
26
+ private
27
+
28
+ def migration_version
29
+ formatted_version if ::Rails.version >= '5.0.0'
30
+ end
22
31
 
23
- def migration_version
24
- if Rails.version >= "5.0.0"
25
- "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
32
+ def formatted_version
33
+ "[#{::Rails::VERSION::MAJOR}.#{::Rails::VERSION::MINOR}]"
26
34
  end
27
35
  end
28
36
  end
@@ -1,7 +1,7 @@
1
1
  class CreateSecretkeeperTables < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
3
  create_table :secretkeeper_access_tokens do |t|
4
- t.references :owner, polymorphic: true, index: true
4
+ t.references :owner, polymorphic: true, index: true, null: false
5
5
  t.string :token, null: false, index: true, unique: true
6
6
  t.string :refresh_token, null: false, index: true, unique: true
7
7
  t.integer :expires_in
@@ -1,4 +1,6 @@
1
- require "secretkeeper/config"
2
- require "secretkeeper/access_token"
3
- require "secretkeeper/engine"
4
- require "secretkeeper/rails/router"
1
+ # frozen_string_literal: true
2
+
3
+ require 'secretkeeper/rails/router'
4
+ require 'secretkeeper/access_token'
5
+ require 'secretkeeper/configuration'
6
+ require 'secretkeeper/engine'
@@ -1,23 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Secretkeeper
2
4
  class AccessToken < ::ActiveRecord::Base
3
- self.table_name = "secretkeeper_access_tokens"
5
+ self.table_name = 'secretkeeper_access_tokens'
6
+
4
7
  belongs_to :owner, polymorphic: true
5
8
 
6
9
  def initialize(attributes = {})
7
- access_token, refresh_token, expires_in = nil
8
10
  loop do
9
- access_token = AccessToken.generate
10
- refresh_token = AccessToken.generate
11
- break unless AccessToken.exists?(token: access_token, refresh_token: refresh_token)
11
+ @access_token = AccessToken.generate
12
+ @r_token = AccessToken.generate
13
+ break unless token_exists?
12
14
  end
13
- expires_in = Secretkeeper.configuration.access_token_expires_in
14
- super((attributes || {}).merge({
15
- token: access_token, refresh_token: refresh_token, expires_in: expires_in
16
- }))
15
+ @token_expires_in = Secretkeeper.configuration.access_token_expires_in
16
+ super((attributes || {}).merge(token_params))
17
17
  end
18
18
 
19
19
  def revoke!
20
- revoked_at.nil? && update_attribute(:revoked_at, DateTime.now)
20
+ revoked_at.nil? && update(revoked_at: Time.zone.now)
21
21
  end
22
22
 
23
23
  def accessible?
@@ -29,7 +29,7 @@ module Secretkeeper
29
29
  end
30
30
 
31
31
  def expired?
32
- created_at + expires_in.seconds <= DateTime.now
32
+ created_at + expires_in.seconds <= Time.zone.now
33
33
  end
34
34
 
35
35
  def refreshable?
@@ -39,5 +39,21 @@ module Secretkeeper
39
39
  def self.generate
40
40
  SecureRandom.hex(32)
41
41
  end
42
+
43
+ private
44
+
45
+ attr_reader :access_token, :r_token, :token_expires_in
46
+
47
+ def token_exists?
48
+ AccessToken.exists?(token: access_token, refresh_token: r_token)
49
+ end
50
+
51
+ def token_params
52
+ {
53
+ token: access_token,
54
+ refresh_token: r_token,
55
+ expires_in: token_expires_in
56
+ }
57
+ end
42
58
  end
43
59
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Secretkeeper
4
+ class << self
5
+ attr_reader :reflection_resource_owner
6
+
7
+ def configuration
8
+ @configuration ||= Configuration.new
9
+ end
10
+
11
+ def configure
12
+ yield(configuration)
13
+ end
14
+
15
+ def reflect(&block)
16
+ class_eval(&block)
17
+ end
18
+
19
+ def resource_owner(&block)
20
+ @reflection_resource_owner = block
21
+ end
22
+ end
23
+
24
+ class Configuration
25
+ attr_accessor :access_token_expires_in
26
+ end
27
+ end
@@ -1,8 +1,10 @@
1
- require "secretkeeper/rails/helpers"
1
+ # frozen_string_literal: true
2
+
3
+ require 'secretkeeper/rails/helpers'
2
4
 
3
5
  module Secretkeeper
4
6
  class Engine < ::Rails::Engine
5
- initializer "secretkeeper.controller_helpers" do
7
+ initializer 'secretkeeper.controller_helpers' do
6
8
  ActiveSupport.on_load(:action_controller) do
7
9
  include Secretkeeper::Rails::Helpers
8
10
  end
@@ -1,17 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Secretkeeper
2
4
  module Rails
3
5
  module Helpers
4
6
  extend ActiveSupport::Concern
5
7
 
6
8
  def secretkeeper_authorize!
7
- header = request.headers["Authorization"]
8
- if header && header.start_with?("Bearer ")
9
- token = Secretkeeper::AccessToken.find_by(token: header[7..-1])
10
- if token.present? && token.accessible?
11
- @resource_owner = token.owner
12
- return true
13
- end
14
- end
9
+ return secretkeeper_render_error unless secretkeeper_token_acceptable?
10
+
11
+ @resource_owner = secretkeeper_access_token.owner
12
+ end
13
+
14
+ private
15
+
16
+ def secretkeeper_token_acceptable?
17
+ secretkeeper_auth_header_valid? &&
18
+ secretkeeper_access_token.owner.present?
19
+ end
20
+
21
+ def secretkeeper_auth_header_valid?
22
+ request.headers['Authorization']&.start_with?('Bearer ') &&
23
+ secretkeeper_access_token&.accessible?
24
+ end
25
+
26
+ def secretkeeper_access_token
27
+ @secretkeeper_access_token ||= Secretkeeper::AccessToken.find_by(
28
+ token: request.headers['Authorization'][7..-1]
29
+ )
30
+ end
31
+
32
+ def secretkeeper_render_error
15
33
  head 401
16
34
  end
17
35
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionDispatch
2
4
  module Routing
3
5
  class Mapper
4
6
  def secretkeeper
5
- resources :auth, module: "secretkeeper", only: [] do
7
+ resources :auth, module: 'secretkeeper', only: [] do
6
8
  collection do
7
9
  post :create_token
8
10
  post :refresh_token
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Secretkeeper
2
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
3
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secretkeeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Korepanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-13 00:00:00.000000000 Z
11
+ date: 2019-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -25,62 +25,88 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rspec-rails
28
+ name: factory_bot
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '3.6'
33
+ version: '5.0'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 5.0.2
34
37
  type: :development
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - "~>"
39
42
  - !ruby/object:Gem::Version
40
- version: '3.6'
43
+ version: '5.0'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 5.0.2
41
47
  - !ruby/object:Gem::Dependency
42
- name: rspec-activemodel-mocks
48
+ name: generator_spec
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '1.0'
53
+ version: 0.9.4
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '1.0'
60
+ version: 0.9.4
55
61
  - !ruby/object:Gem::Dependency
56
- name: factory_girl_rails
62
+ name: rspec-json_expectations
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: '4.8'
67
+ version: '2.2'
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 2.2.0
62
71
  type: :development
63
72
  prerelease: false
64
73
  version_requirements: !ruby/object:Gem::Requirement
65
74
  requirements:
66
75
  - - "~>"
67
76
  - !ruby/object:Gem::Version
68
- version: '4.8'
77
+ version: '2.2'
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 2.2.0
69
81
  - !ruby/object:Gem::Dependency
70
- name: generator_spec
82
+ name: rspec-rails
71
83
  requirement: !ruby/object:Gem::Requirement
72
84
  requirements:
73
85
  - - "~>"
74
86
  - !ruby/object:Gem::Version
75
- version: 0.9.4
87
+ version: '3.6'
76
88
  type: :development
77
89
  prerelease: false
78
90
  version_requirements: !ruby/object:Gem::Requirement
79
91
  requirements:
80
92
  - - "~>"
81
93
  - !ruby/object:Gem::Version
82
- version: 0.9.4
83
- description:
94
+ version: '3.6'
95
+ - !ruby/object:Gem::Dependency
96
+ name: sqlite3
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '1.3'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '1.3'
109
+ description: Token based authentication
84
110
  email:
85
111
  - secretkeeper.gem@gmail.com
86
112
  executables: []
@@ -96,7 +122,7 @@ files:
96
122
  - lib/generators/secretkeeper/templates/migration.rb
97
123
  - lib/secretkeeper.rb
98
124
  - lib/secretkeeper/access_token.rb
99
- - lib/secretkeeper/config.rb
125
+ - lib/secretkeeper/configuration.rb
100
126
  - lib/secretkeeper/engine.rb
101
127
  - lib/secretkeeper/rails/helpers.rb
102
128
  - lib/secretkeeper/rails/router.rb
@@ -121,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
147
  version: '0'
122
148
  requirements: []
123
149
  rubyforge_project:
124
- rubygems_version: 2.6.14
150
+ rubygems_version: 2.7.6
125
151
  signing_key:
126
152
  specification_version: 4
127
153
  summary: Token based authentication
@@ -1,30 +0,0 @@
1
- module Secretkeeper
2
- class << self
3
- attr_accessor :configuration
4
- attr_accessor :reflection_resource_owner
5
- end
6
-
7
- def self.configuration
8
- @configuration ||= Configuration.new
9
- end
10
-
11
- def self.configure
12
- yield(configuration)
13
- end
14
-
15
- def self.reflect(&block)
16
- class_eval(&block)
17
- end
18
-
19
- def self.resource_owner(&block)
20
- @reflection_resource_owner = block
21
- end
22
-
23
- class Configuration
24
- attr_accessor :access_token_expires_in
25
-
26
- def initialize
27
- @access_token_expires_in = 1.hour
28
- end
29
- end
30
- end