secretkeeper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 84593075dabb8014b00ac2efb375f56c5fdbc7db
4
+ data.tar.gz: 9bf59fb59e734f7c4bbe77b93bbe4e8d991475ca
5
+ SHA512:
6
+ metadata.gz: ce4af121133d3dd16483d845f601f769259528aee732d71101973dc06f73b4c9dde33c088ac9939df7bad2903b57331c5bc5fc3d950be34cfbb71ca49e9dde63
7
+ data.tar.gz: bb5a2be005753e563a499b46c0ba81792035c53cb1c06b07127381a80dae13e46dddf0ecfc1ac39273966d794d6fc6aaf808306838065032da71f89f8ecf0631
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2017 Igor
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,30 @@
1
+ # Secretkeeper
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'secretkeeper'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install secretkeeper
22
+ ```
23
+
24
+ Run the installation generator with:
25
+ ```bash
26
+ rails generate secretkeeper:install
27
+ ```
28
+
29
+ ## License
30
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require "bundler/setup"
2
+ require "rspec/core/rake_task"
3
+
4
+ # begin
5
+ # require 'bundler/setup'
6
+ # rescue LoadError
7
+ # puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
8
+ # end
9
+
10
+ # require 'rdoc/task'
11
+
12
+ # RDoc::Task.new(:rdoc) do |rdoc|
13
+ # rdoc.rdoc_dir = 'rdoc'
14
+ # rdoc.title = 'Secretkeeper'
15
+ # rdoc.options << '--line-numbers'
16
+ # rdoc.rdoc_files.include('README.md')
17
+ # rdoc.rdoc_files.include('lib/**/*.rb')
18
+ # end
19
+
20
+
21
+
22
+
23
+
24
+
25
+ # require 'bundler/gem_tasks'
26
+
27
+ # require 'rake/testtask'
28
+
29
+ # Rake::TestTask.new(:test) do |t|
30
+ # t.libs << 'test'
31
+ # t.pattern = 'test/**/*_test.rb'
32
+ # t.verbose = false
33
+ # end
34
+
35
+ desc "Default: run specs."
36
+ task default: :spec
37
+
38
+ desc "Run all specs"
39
+ RSpec::Core::RakeTask.new(:spec) do |config|
40
+ config.verbose = false
41
+ end
@@ -0,0 +1,41 @@
1
+ module Secretkeeper
2
+ class AuthController < ActionController::Metal
3
+ include AbstractController::Rendering
4
+ include ActionController::Rendering
5
+ include ActionController::Renderers
6
+ include ActionController::Head
7
+
8
+ use_renderers :json
9
+
10
+ def create_token
11
+ 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
23
+ end
24
+
25
+ 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
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,28 @@
1
+ require "rails/generators/active_record"
2
+
3
+ class Secretkeeper::InstallGenerator < ::Rails::Generators::Base
4
+ include Rails::Generators::Migration
5
+
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
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
17
+
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
22
+
23
+ def migration_version
24
+ if Rails.version >= "5.0.0"
25
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ Secretkeeper.configure do |config|
2
+ config.access_token_expires_in = 12.hours
3
+ end
4
+
5
+ Secretkeeper.reflect do |on|
6
+ on.resource_owner do |params|
7
+ User.authenticate!(params[:name], params[:password])
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ class CreateSecretkeeperTables < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ create_table :secretkeeper_access_tokens do |t|
4
+ t.references :owner, polymorphic: true, index: true
5
+ t.string :token, null: false, index: true, unique: true
6
+ t.string :refresh_token, null: false, index: true, unique: true
7
+ t.integer :expires_in
8
+ t.datetime :revoked_at
9
+ t.timestamps null: false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,43 @@
1
+ module Secretkeeper
2
+ class AccessToken < ::ActiveRecord::Base
3
+ self.table_name = "secretkeeper_access_tokens"
4
+ belongs_to :owner, polymorphic: true
5
+
6
+ def initialize(attributes = {})
7
+ access_token, refresh_token, expires_in = nil
8
+ loop do
9
+ access_token = AccessToken.generate
10
+ refresh_token = AccessToken.generate
11
+ break unless AccessToken.exists?(token: access_token, refresh_token: refresh_token)
12
+ 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
+ }))
17
+ end
18
+
19
+ def revoke!
20
+ revoked_at.nil? && update_attribute(:revoked_at, DateTime.now)
21
+ end
22
+
23
+ def accessible?
24
+ !revoked? && !expired?
25
+ end
26
+
27
+ def revoked?
28
+ revoked_at.present?
29
+ end
30
+
31
+ def expired?
32
+ created_at + expires_in.seconds <= DateTime.now
33
+ end
34
+
35
+ def refreshable?
36
+ !revoked?
37
+ end
38
+
39
+ def self.generate
40
+ SecureRandom.hex(32)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,30 @@
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
@@ -0,0 +1,11 @@
1
+ require "secretkeeper/rails/helpers"
2
+
3
+ module Secretkeeper
4
+ class Engine < ::Rails::Engine
5
+ initializer "secretkeeper.controller_helpers" do
6
+ ActiveSupport.on_load(:action_controller) do
7
+ include Secretkeeper::Rails::Helpers
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ module Secretkeeper
2
+ module Rails
3
+ module Helpers
4
+ extend ActiveSupport::Concern
5
+
6
+ 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
15
+ head 401
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ module ActionDispatch
2
+ module Routing
3
+ class Mapper
4
+ def secretkeeper
5
+ resources :auth, module: "secretkeeper", only: [] do
6
+ collection do
7
+ post :create_token
8
+ post :refresh_token
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Secretkeeper
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ require "secretkeeper/config"
2
+ require "secretkeeper/access_token"
3
+ require "secretkeeper/engine"
4
+ require "secretkeeper/rails/router"
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: secretkeeper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Igor Korepanov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-11-13 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: '4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-activemodel-mocks
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: factory_girl_rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: generator_spec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.9.4
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.9.4
83
+ description:
84
+ email:
85
+ - secretkeeper.gem@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - MIT-LICENSE
91
+ - README.md
92
+ - Rakefile
93
+ - app/controllers/secretkeeper/auth_controller.rb
94
+ - lib/generators/secretkeeper/install_generator.rb
95
+ - lib/generators/secretkeeper/templates/initializer.rb
96
+ - lib/generators/secretkeeper/templates/migration.rb
97
+ - lib/secretkeeper.rb
98
+ - lib/secretkeeper/access_token.rb
99
+ - lib/secretkeeper/config.rb
100
+ - lib/secretkeeper/engine.rb
101
+ - lib/secretkeeper/rails/helpers.rb
102
+ - lib/secretkeeper/rails/router.rb
103
+ - lib/secretkeeper/version.rb
104
+ homepage: https://github.com/igorkorepanov/secretkeeper
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.6.14
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: Token based authentication
128
+ test_files: []