groot 1.0.0.beta → 2.0.0.beta

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
2
  SHA1:
3
- metadata.gz: 6d417b0a6033a346014fa1da80643f88d33782e5
4
- data.tar.gz: 416dfd442d194ac7c3413b716b1cf6cf34dbe7ec
3
+ metadata.gz: 02fd39bf89c0e097f26e5ad9af0af3eaa93ab424
4
+ data.tar.gz: 0b320981aaedaef263ecfa00e40ddf3d9a4bd731
5
5
  SHA512:
6
- metadata.gz: c01092415acfe65c21a32192b0cf463d425db972d77ab27acd098ca66cf0e7fddefcb6c4f972576368f41a28e62fe083d711b6eb827bfef39f5c9ec6887dd386
7
- data.tar.gz: f8c04a188fcb95c80bd9d1c8cf6ae16e7e4b4676948caa8e6363961be5f986942b07ece7afe887990e5968284bc184a6d47710277379d46c58d26e72c6abecc5
6
+ metadata.gz: 016c1be65ab0421e09d9caca10db02ffdbb4267808e8b65fd7de0f6cc528bc0bbc21a9c6712aaf01c8b92b822fba7bda6e16682e0a20532bb26ad15f376e35c9
7
+ data.tar.gz: 08e34a1fe263e1c0f78b4cbfe02d738abefa1665dcaf77749a615206268840b895e626bdcae8a7ebf74b1b88919b96d694e2b6e3c681dcb8e03e54e4df5f66ac
data/.gitignore CHANGED
@@ -1,16 +1,15 @@
1
1
  .bundle/
2
2
  log/*.log
3
3
  pkg/
4
- /Gemfile.lock
5
4
  spec/dummy/db/*.sqlite3
6
5
  spec/dummy/db/*.sqlite3-journal
7
6
  spec/dummy/log/*.log
8
7
  spec/dummy/tmp/
9
8
  *.gem
10
9
 
11
-
10
+ ### Vagrant ###
11
+ .vagrant/
12
12
 
13
13
 
14
14
  .DS_Store
15
15
  dump.rdb
16
-
@@ -0,0 +1,122 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ groot (2.0.0.beta)
5
+ bcrypt (~> 3.1, >= 3.1.7)
6
+ jwt (~> 1.5, >= 1.5.6)
7
+ rails (~> 5.0, >= 5.0.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actioncable (5.0.1)
13
+ actionpack (= 5.0.1)
14
+ nio4r (~> 1.2)
15
+ websocket-driver (~> 0.6.1)
16
+ actionmailer (5.0.1)
17
+ actionpack (= 5.0.1)
18
+ actionview (= 5.0.1)
19
+ activejob (= 5.0.1)
20
+ mail (~> 2.5, >= 2.5.4)
21
+ rails-dom-testing (~> 2.0)
22
+ actionpack (5.0.1)
23
+ actionview (= 5.0.1)
24
+ activesupport (= 5.0.1)
25
+ rack (~> 2.0)
26
+ rack-test (~> 0.6.3)
27
+ rails-dom-testing (~> 2.0)
28
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
29
+ actionview (5.0.1)
30
+ activesupport (= 5.0.1)
31
+ builder (~> 3.1)
32
+ erubis (~> 2.7.0)
33
+ rails-dom-testing (~> 2.0)
34
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
35
+ activejob (5.0.1)
36
+ activesupport (= 5.0.1)
37
+ globalid (>= 0.3.6)
38
+ activemodel (5.0.1)
39
+ activesupport (= 5.0.1)
40
+ activerecord (5.0.1)
41
+ activemodel (= 5.0.1)
42
+ activesupport (= 5.0.1)
43
+ arel (~> 7.0)
44
+ activesupport (5.0.1)
45
+ concurrent-ruby (~> 1.0, >= 1.0.2)
46
+ i18n (~> 0.7)
47
+ minitest (~> 5.1)
48
+ tzinfo (~> 1.1)
49
+ arel (7.1.4)
50
+ bcrypt (3.1.11)
51
+ builder (3.2.3)
52
+ concurrent-ruby (1.0.5)
53
+ erubis (2.7.0)
54
+ globalid (0.3.7)
55
+ activesupport (>= 4.1.0)
56
+ i18n (0.8.1)
57
+ jwt (1.5.6)
58
+ loofah (2.0.3)
59
+ nokogiri (>= 1.5.9)
60
+ mail (2.6.4)
61
+ mime-types (>= 1.16, < 4)
62
+ method_source (0.8.2)
63
+ mime-types (3.1)
64
+ mime-types-data (~> 3.2015)
65
+ mime-types-data (3.2016.0521)
66
+ mini_portile2 (2.1.0)
67
+ minitest (5.10.1)
68
+ nio4r (1.2.1)
69
+ nokogiri (1.7.0.1)
70
+ mini_portile2 (~> 2.1.0)
71
+ rack (2.0.1)
72
+ rack-test (0.6.3)
73
+ rack (>= 1.0)
74
+ rails (5.0.1)
75
+ actioncable (= 5.0.1)
76
+ actionmailer (= 5.0.1)
77
+ actionpack (= 5.0.1)
78
+ actionview (= 5.0.1)
79
+ activejob (= 5.0.1)
80
+ activemodel (= 5.0.1)
81
+ activerecord (= 5.0.1)
82
+ activesupport (= 5.0.1)
83
+ bundler (>= 1.3.0, < 2.0)
84
+ railties (= 5.0.1)
85
+ sprockets-rails (>= 2.0.0)
86
+ rails-dom-testing (2.0.2)
87
+ activesupport (>= 4.2.0, < 6.0)
88
+ nokogiri (~> 1.6)
89
+ rails-html-sanitizer (1.0.3)
90
+ loofah (~> 2.0)
91
+ railties (5.0.1)
92
+ actionpack (= 5.0.1)
93
+ activesupport (= 5.0.1)
94
+ method_source
95
+ rake (>= 0.8.7)
96
+ thor (>= 0.18.1, < 2.0)
97
+ rake (12.0.0)
98
+ sprockets (3.7.1)
99
+ concurrent-ruby (~> 1.0)
100
+ rack (> 1, < 3)
101
+ sprockets-rails (3.2.0)
102
+ actionpack (>= 4.0)
103
+ activesupport (>= 4.0)
104
+ sprockets (>= 3.0.0)
105
+ sqlite3 (1.3.13)
106
+ thor (0.19.4)
107
+ thread_safe (0.3.6)
108
+ tzinfo (1.2.2)
109
+ thread_safe (~> 0.1)
110
+ websocket-driver (0.6.5)
111
+ websocket-extensions (>= 0.1.0)
112
+ websocket-extensions (0.1.2)
113
+
114
+ PLATFORMS
115
+ ruby
116
+
117
+ DEPENDENCIES
118
+ groot!
119
+ sqlite3 (~> 1.3)
120
+
121
+ BUNDLED WITH
122
+ 1.14.5
@@ -1,7 +1,5 @@
1
1
  module Groot
2
- class AuthController < ApplicationController
3
-
4
- # TODO Do something to get the real model
2
+ class SessionsController < ApplicationController
5
3
  def create
6
4
  user = resource_class.find_by(email: params[:email])
7
5
  if(user && user.authenticate(params[:password]))
@@ -11,11 +9,6 @@ module Groot
11
9
  end
12
10
  end
13
11
 
14
- def destroy
15
- raise NotImplementedError
16
- end
17
-
18
-
19
12
  private
20
13
  def resource_class
21
14
  mapping.clazz
@@ -25,4 +18,4 @@ module Groot
25
18
  @mapping ||= request.env['groot.mapping']
26
19
  end
27
20
  end
28
- end
21
+ end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.license = "MIT"
19
19
 
20
20
  # spec.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
21
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
22
22
  f.match(%r{^(test|spec|features)/})
23
23
  end
24
24
  spec.add_dependency "rails", "~> 5.0", ">= 5.0.0"
@@ -0,0 +1,16 @@
1
+ module Groot
2
+ module Generators
3
+ class AuthorityGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../templates", __FILE__)
5
+ argument :authority_name, type: :string, default: "application"
6
+
7
+ def copy_initializer_file
8
+ if authority_name != "application"
9
+ template "authority_template.rb", "app/authorities/#{authority_name.downcase}_authority.rb"
10
+ else
11
+ copy_file "authority.rb", "app/authorities/application_authority.rb"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ class ApplicationAuthority
2
+ attr_reader :user, :model
3
+
4
+ def initialize(user, model)
5
+ @user = user
6
+ @model = model
7
+ end
8
+ end
@@ -0,0 +1,2 @@
1
+ class <%= authority_name %>Authority < ApplicationAuthority
2
+ end
@@ -1,3 +1,9 @@
1
1
  Groot.setup do |config|
2
2
  config.hmac_secret = "<%= SecureRandom.hex(64) %>"
3
- end
3
+
4
+ # Defines which algorithm will be used to encode the token
5
+ # config.algorithm = "HS256"
6
+
7
+ # Set true if you want security Authority
8
+ # config.include_access_authority = false
9
+ end
@@ -3,25 +3,38 @@ require "groot/engine"
3
3
  module Groot
4
4
  extend ActiveSupport::Autoload
5
5
 
6
+ autoload :Exceptions
6
7
  autoload :Mapping
8
+ autoload :AuthorityLookup
9
+ autoload :Authority
7
10
 
8
11
  module Controllers
9
12
  autoload :Helpers, 'groot/controllers/helpers'
10
13
  end
11
14
 
15
+ module Models
16
+ autoload :Helpers, 'groot/models/helpers'
17
+ end
12
18
 
13
-
19
+ mattr_accessor :include_access_authority
20
+ @@include_access_authority = false
14
21
 
15
22
  mattr_accessor :hmac_secret
16
23
  @@hmac_secret = nil
17
24
 
25
+ mattr_accessor :algorithm
26
+ @@algorithm = "HS256"
27
+
28
+ mattr_reader :mapping
29
+ @@mapping = nil
30
+
18
31
  def self.setup
19
32
  yield self
20
33
  end
21
34
 
22
- def self.mapping(resource)
23
- mapping = Mapping.new(resource)
24
- Controllers::Helpers.define_method(mapping)
35
+ def self.mapping_to(resource)
36
+ @@mapping ||= Mapping.new(resource)
37
+ Controllers::Helpers.define_helpers(mapping)
25
38
  mapping
26
39
  end
27
40
  end
@@ -0,0 +1,12 @@
1
+ module Groot
2
+ module Authority
3
+ extend ActiveSupport::Concern
4
+
5
+ def authorize(model, action = nil)
6
+ action ||= params[:action]
7
+ authority_class = AuthorityLookup.resolve(model)
8
+ authority = authority_class.new(model, current_resource)
9
+ raise AccessDeniedError unless authority.send(action)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ module Groot
2
+ module AuthorityLookup
3
+ class << self
4
+ def resolve(model)
5
+ resolve_class(model)
6
+ rescue NameError
7
+ ApplicationAuthority
8
+ end
9
+
10
+ private
11
+ def resolve_class(model)
12
+ return nil unless model
13
+ return model.authority_class if model.respond_to? :authority_class
14
+ return model.class.authority_class if model.class.respond_to? :authority_class
15
+ return "#{model.class}Authority".constantize
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,19 +3,21 @@ require 'jwt'
3
3
  module Groot
4
4
  module Controllers
5
5
  module Helpers
6
- def self.define_method(mapping)
6
+ def self.define_helpers(mapping)
7
7
  name = mapping.name
8
8
  class_eval <<-METHODS, __FILE__, __LINE__ + 1
9
9
  def authenticate_#{name}!
10
10
  decode(http_token)
11
11
  end
12
12
  def #{name}_signed_in?
13
- !!current_user
13
+ !!current_#{name}
14
14
  end
15
15
  def current_#{name}
16
16
  payload = decode(http_token)
17
- @current_user ||= #{mapping.clazz}.find(payload["id"])
17
+ @current_#{name} ||= #{mapping.clazz}.find(payload["sub"])
18
18
  end
19
+
20
+ alias_method :current_resource, :current_#{name}
19
21
  METHODS
20
22
 
21
23
  ActiveSupport.on_load(:action_controller) do
@@ -28,31 +30,43 @@ module Groot
28
30
  private
29
31
 
30
32
  def http_token
31
- @http_token ||= request.headers['Authorization'].split(' ').last if request.headers['Authorization'].present?
32
- end
33
+ token, options = ActionController::HttpAuthentication::Token.token_and_options(request)
34
+ token
35
+ end
33
36
 
34
37
  def encode(resource)
35
38
  payload = {
36
- id: resource.id,
39
+ sub: resource.id,
37
40
  exp: (Time.now + 24.hours).to_i
38
41
  }
39
- JWT.encode(payload, Groot.hmac_secret, 'HS256')
42
+ JWT.encode(payload, hmac_secret, algorithm)
40
43
  end
41
44
 
42
45
  def decode(token)
43
46
  begin
44
- options = {
45
- algorithm: 'HS256'
46
- }
47
- JWT.decode(token, Groot.hmac_secret, true, options).first
47
+ JWT.decode(token, hmac_secret, true, options).first
48
48
  rescue JWT::ExpiredSignature
49
- render json: { message: 'The token has expired.' }, status: :forbidden
49
+ render json: { message: 'The token has expired.' }, status: :unauthorized
50
50
  rescue JWT::VerificationError
51
- render json: { message: 'Invalid access token.' }, status: :forbidden
51
+ render json: { message: 'Invalid access token.' }, status: :unauthorized
52
52
  rescue JWT::DecodeError
53
- render json: { message: 'Invalid access token.' }, status: :forbidden
53
+ render json: { message: 'Invalid access token.' }, status: :unauthorized
54
54
  end
55
55
  end
56
+
57
+ def options
58
+ {
59
+ algorithm: algorithm
60
+ }
61
+ end
62
+
63
+ def hmac_secret
64
+ Groot.hmac_secret
65
+ end
66
+
67
+ def algorithm
68
+ Groot.algorithm
69
+ end
56
70
  end
57
71
  end
58
- end
72
+ end
@@ -3,9 +3,16 @@ module Groot
3
3
  class Engine < ::Rails::Engine
4
4
  isolate_namespace Groot
5
5
 
6
- initializer "groot.add_helpers" do
6
+ initializer "groot.add_controllers_helpers" do
7
7
  ActiveSupport.on_load(:action_controller) do
8
8
  include Controllers::Helpers
9
+ include Authority if Groot.include_access_authority
10
+ end
11
+ end
12
+
13
+ initializer "groot.add_models_helpers" do
14
+ ActiveSupport.on_load(:active_record) do
15
+ include Models::Helpers if Groot.include_access_authority
9
16
  end
10
17
  end
11
18
  end
@@ -0,0 +1,5 @@
1
+ module Groot
2
+ module Exceptions
3
+ class AccessDeniedError < RuntimeError; end;
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ module Groot
2
+ module Models
3
+ module Helpers
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def authority_class
8
+ "#{self}Authority".constantize
9
+ end
10
+ end
11
+
12
+ def authority_class
13
+ self.class.authority_class
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,9 +1,9 @@
1
1
  module ActionDispatch::Routing
2
2
  class Mapper
3
3
  def auth_for(resource)
4
- mapping = Groot.mapping(resource)
5
- constraint = lambda do |request|
6
- request.env['groot.mapping'] = mapping
4
+ mapping = Groot.mapping_to(resource)
5
+ constraint = lambda do |request|
6
+ request.env['groot.mapping'] = mapping
7
7
  true
8
8
  end
9
9
  constraints(constraint) do
@@ -11,12 +11,12 @@ module ActionDispatch::Routing
11
11
  end
12
12
  end
13
13
 
14
- private
14
+ private
15
15
  def auth_routes(mapping) #:nodoc:
16
- resource mapping.resource, only: [], controller: 'groot/auth' do
17
- post :create, path: mapping.path_names[:login]
18
- delete :destroy, path: mapping.path_names[:logout]
16
+ resource mapping.resource, only: [], controller: 'groot/sessions' do
17
+ post :create, path: mapping.path_names[:sign_in]
18
+ delete :destroy, path: mapping.path_names[:sign_out]
19
19
  end
20
20
  end
21
21
  end
22
- end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module Groot
2
- VERSION = '1.0.0.beta'
2
+ VERSION = '2.0.0.beta'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: groot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta
4
+ version: 2.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alisson Bruno
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-13 00:00:00.000000000 Z
11
+ date: 2017-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -94,10 +94,11 @@ extra_rdoc_files: []
94
94
  files:
95
95
  - ".gitignore"
96
96
  - Gemfile
97
+ - Gemfile.lock
97
98
  - MIT-LICENSE
98
99
  - README.md
99
100
  - Rakefile
100
- - app/controllers/groot/auth_controller.rb
101
+ - app/controllers/groot/sessions_controller.rb
101
102
  - app/helpers/groot/application_helper.rb
102
103
  - app/jobs/groot/application_job.rb
103
104
  - app/mailers/groot/application_mailer.rb
@@ -107,16 +108,23 @@ files:
107
108
  - groot.gemspec
108
109
  - lib/generators/.DS_Store
109
110
  - lib/generators/groot/auth_generator.rb
111
+ - lib/generators/groot/authority_generator.rb
110
112
  - lib/generators/groot/install_generator.rb
111
113
  - lib/generators/groot/templates/.DS_Store
114
+ - lib/generators/groot/templates/authority.rb
115
+ - lib/generators/groot/templates/authority_template.rb
112
116
  - lib/generators/groot/templates/config.rb
113
117
  - lib/generators/groot/templates/migration/create_migration.rb
114
118
  - lib/generators/groot/templates/migration/migration_existing.rb
115
119
  - lib/generators/groot/templates/model.rb
116
120
  - lib/groot.rb
121
+ - lib/groot/authority.rb
122
+ - lib/groot/authority_lookup.rb
117
123
  - lib/groot/controllers/helpers.rb
118
124
  - lib/groot/engine.rb
125
+ - lib/groot/exceptions.rb
119
126
  - lib/groot/mapping.rb
127
+ - lib/groot/models/helpers.rb
120
128
  - lib/groot/rails/routes.rb
121
129
  - lib/groot/version.rb
122
130
  - lib/tasks/groot_tasks.rake
@@ -140,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
148
  version: 1.3.1
141
149
  requirements: []
142
150
  rubyforge_project:
143
- rubygems_version: 2.5.1
151
+ rubygems_version: 2.6.8
144
152
  signing_key:
145
153
  specification_version: 4
146
154
  summary: Simple token authentication and authorization