groot 1.0.0.beta → 2.0.0.beta

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