hobby-auth 0.0.1 → 0.0.2

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: a695f776bd20babf3742458ff066a82b5afafe90
4
- data.tar.gz: 625b7448fe38eb6e59abb4b29f6dac9f75113694
3
+ metadata.gz: 0fd7308d5de3ee1087bf4829558efeb555f18433
4
+ data.tar.gz: 383fd2c09d0fc8a72d63e0f6f6857df11439b690
5
5
  SHA512:
6
- metadata.gz: cb4684a95506dead682cb9b696f41f2a980723e69aa420dcc9d9b188135fdbc4aa80fffd1e9a31e965eae2f04e082809ccde27a98bcd33827a12d97638fa1ace
7
- data.tar.gz: e72b29085e987c5c16ce5a83b2e0839baa3f716a0ecde1cf4bec877e10f0ed7eb5672cecbb762958a8528a31a58063d9ce2119d53ae74870410fe657e0ad6e09
6
+ metadata.gz: bfc2f279d0e4f7979ea66adb086067c19f5e4320ea0a9aea0a7cb865ae6a9c4b5939e2e305902db56b222f0567b707c5c8ef3d14790d9bbc4f6e9492d9639345
7
+ data.tar.gz: c57175fc1f465f1524d0000342b36c2f1a192dfd37da8c5a78167ed409ab42d93a5487895eedfd0d9be4f3b33ce1ca715ae9c53340c9c2787979aa359e9e82b5
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  Gemfile.lock
2
+ *.gem
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'hobby-devtools', '>=0.0.7'
3
+ gem 'hobby-devtools', '>=0.0.11'
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |g|
2
2
  g.name = 'hobby-auth'
3
3
  g.files = `git ls-files`.split($/)
4
- g.version = '0.0.1'
5
- g.summary = 'Authorize Hobby routes'
4
+ g.version = '0.0.2'
5
+ g.summary = 'A Hobby extension to authorize routes.'
6
6
  g.authors = ['Anatoly Chernow']
7
7
  end
@@ -1,10 +1,12 @@
1
1
  module Hobby
2
2
  module Auth
3
3
  def self.[] *user_models
4
+ pairs = find_pairs user_models
5
+
4
6
  Module.new do
5
7
  define_singleton_method :included do |app|
6
- user_models.each do |user_model|
7
- app.define_singleton_method short_name_of user_model do |route|
8
+ pairs.each do |name, user_model|
9
+ app.define_singleton_method name do |route|
8
10
  action = route.action
9
11
  route.action = -> do
10
12
  if user = (user_model.find_by_token env['HTTP_AUTHORIZATION'])
@@ -19,12 +21,35 @@ module Hobby
19
21
  end
20
22
  end
21
23
 
22
- def self.short_name_of user_model
23
- user_model.name.split('::').last.downcase
24
- end
25
-
26
24
  attr_reader :user
27
25
  end
28
26
  end
27
+
28
+ class SameNames < StandardError
29
+ def initialize models, name
30
+ first, second = models
31
+ message = "The short names of #{first} and #{second} are the same: #{name}."
32
+ super message
33
+ end
34
+ end
35
+
36
+ def self.find_pairs user_models
37
+ pairs = user_models.map { |um| [(short_name_of um), um] }
38
+
39
+ names = {}
40
+ pairs.each do |name, model|
41
+ if first_model_with_that_name = names[name]
42
+ fail SameNames.new [first_model_with_that_name, model], name
43
+ else
44
+ names[name] = model
45
+ end
46
+ end
47
+
48
+ pairs
49
+ end
50
+
51
+ def self.short_name_of user_model
52
+ user_model.name.split('::').last.downcase
53
+ end
29
54
  end
30
- end # Ends should be optional. Block nesting can be inferred from two-space indent.
55
+ end
@@ -0,0 +1,95 @@
1
+ = Hobby-Auth
2
+
3
+ This repository provides a https://github.com/ch1c0t/hobby[Hobby] extension
4
+ to authorize routes.
5
+
6
+ == Installation
7
+
8
+ [source,bash]
9
+ ----
10
+ gem install hobby-auth
11
+ ----
12
+
13
+ == Introduction
14
+
15
+ You are expected to pass your user models as arguments to `Hobby::Auth.[]`:
16
+
17
+ [source,ruby]
18
+ ----
19
+ require 'hobby'
20
+ require 'hobby/auth'
21
+
22
+ class YourApp
23
+ include Hobby
24
+ include Auth[*array_of_user_models]
25
+
26
+ # some route defining logic goes here, after 'includes'
27
+ end
28
+ ----
29
+
30
+ A user model is any object that responds to these two methods:
31
+
32
+ * `.name` which returns a `String` which might be in
33
+ https://ruby-doc.org/core/Module.html#method-i-name[Module#name].
34
+ * `.find_by_token` which takes one argument(a token `String`),
35
+ and returns `nil`(if no user were found) or a user(which
36
+ can be any object you would like to consider a user in your application).
37
+
38
+ You can access that user via `user` method.
39
+
40
+ Consider an example app where you need two user roles: managers and drivers.
41
+ You can define `Manager` class as follows:
42
+
43
+ [source,ruby]
44
+ ----
45
+ class Manager
46
+ def self.find_by_token token
47
+ new if token == 'the only valid token at the moment'
48
+ end
49
+ end
50
+ ----
51
+ and `Driver` class similarly.
52
+
53
+ Then, you can use them in your app:
54
+
55
+ [source,ruby]
56
+ ----
57
+ class App
58
+ include Hobby
59
+ include Auth[Manager, Driver]
60
+
61
+ manager post('/managers_route') {
62
+ # do something only managers can do
63
+ user # will return a `Manager` instance
64
+ }
65
+
66
+ driver get('/drivers_route') {
67
+ # do something only drivers can do
68
+ user # will return a `Driver` instance
69
+ }
70
+ end
71
+ ----
72
+
73
+ The token is expected to be passed via
74
+ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization[Authorization header].
75
+ If no user were found, the response's status will be set to
76
+ https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403[403].
77
+
78
+ NOTE: If your user models have names leading to the same decorator name
79
+ (for example, `Manager` and `SomeNamespace::Manager`),
80
+ a `Hobby::Auth::SameNames` error will be raised.
81
+
82
+ == Development
83
+
84
+ To run the specs:
85
+
86
+ [source,bash]
87
+ ----
88
+ bundle exec rspec
89
+ ----
90
+
91
+ To perform mutation analysis:
92
+ [source,bash]
93
+ ----
94
+ bundle exec mutant --use rspec 'Hobby::Auth*'
95
+ ----
@@ -0,0 +1,22 @@
1
+ - get:
2
+ path: /decorator
3
+
4
+ response:
5
+ status: 403
6
+
7
+ - get:
8
+ path: /decorator
9
+ headers:
10
+ Authorization: invalid token
11
+
12
+ response:
13
+ status: 403
14
+
15
+ - get:
16
+ path: /decorator
17
+ headers:
18
+ Authorization: first valid getter token
19
+
20
+ response:
21
+ status: 200
22
+ body: decorator append
@@ -10,6 +10,15 @@ Hobby::Devtools::RSpec.describe do
10
10
 
11
11
  getter get { 'oh my get' }
12
12
  poster post { "the user's token is #{user.token}" }
13
+
14
+
15
+ def self.append_decorator route
16
+ action = route.action
17
+ route.action = -> { "#{instance_exec(&action)} append" }
18
+ route
19
+ end
20
+
21
+ append_decorator getter get('/decorator') { 'decorator' }
13
22
  end.new
14
23
  end
15
24
  end
@@ -0,0 +1,27 @@
1
+ require 'helper'
2
+
3
+ class Same
4
+ def self.find_by_token _token
5
+ new
6
+ end
7
+ end
8
+
9
+ module Namespaced
10
+ class Same
11
+ def self.find_by_token _token
12
+ new
13
+ end
14
+ end
15
+ end
16
+
17
+ describe Hobby::Auth do
18
+ it 'raises an error when the short names are the same' do
19
+ expect {
20
+ Class.new do
21
+ include Hobby
22
+ include Hobby::Auth[Same, Namespaced::Same]
23
+ end
24
+ }.to raise_error Hobby::Auth::SameNames,
25
+ 'The short names of Same and Namespaced::Same are the same: same.'
26
+ end
27
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hobby-auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anatoly Chernow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-03 00:00:00.000000000 Z
11
+ date: 2017-06-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -20,10 +20,13 @@ files:
20
20
  - Gemfile
21
21
  - hobby-auth.gemspec
22
22
  - lib/hobby/auth.rb
23
+ - readme.adoc
23
24
  - spec/helper.rb
24
25
  - spec/http/getter.yml
26
+ - spec/http/getter_decorator.yml
25
27
  - spec/http/poster.yml
26
28
  - spec/http_spec.rb
29
+ - spec/name_shadowing_spec.rb
27
30
  - spec/seed_users.rb
28
31
  homepage:
29
32
  licenses: []
@@ -44,8 +47,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
44
47
  version: '0'
45
48
  requirements: []
46
49
  rubyforge_project:
47
- rubygems_version: 2.5.2
50
+ rubygems_version: 2.6.11
48
51
  signing_key:
49
52
  specification_version: 4
50
- summary: Authorize Hobby routes
53
+ summary: A Hobby extension to authorize routes.
51
54
  test_files: []