secretkeeper 0.1.0 → 0.1.1

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
- 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