app_rail-airtable 0.2.10 → 0.3.0

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
  SHA256:
3
- metadata.gz: 3e57f8d279b01f1a7672be43fce5dda36da9df13bc3152399646f5be729d522c
4
- data.tar.gz: 7928368ae9d1b4edfd75c651af688be2aa0e7697f31fd5c87afb1a9e96e3945c
3
+ metadata.gz: 592d97e9fc6dbe4177847fdbfbc5c003620d179caee7887efb23f91d5f736ca7
4
+ data.tar.gz: 985e3ac9e23f4fe318c4944c2c3720a656faead5b5de3e3149fe58013aaa173c
5
5
  SHA512:
6
- metadata.gz: 5eef1c52f304ffe1b0050ff5a7278e47c825dce1e7e08a7af69550894070e23a465dc719fce7dddabfa06de9336f2b63d230685098d09a5c02711b17fe43394d
7
- data.tar.gz: e3629a453d333d78aac608f45ac04b303b27c636f4350fb0f5c2b42c739756a274faabd55a08278b0cc445a5777f62ae57431acea477dae20575ff1cfac53e59
6
+ metadata.gz: 80ae0eea7fbd168f1b469a5bfc9255940f0c62875d232427fd654d123e3b02aab822646cf6fa23313ca3fe7e653d0d73935927b8c6dff74dec8a01acf5edd431
7
+ data.tar.gz: 83e8736f2dc7dc42d276c45a83d8597c98d1f38faee8cf09e581f19256f22f64de81fa34a1acf9f290f9e4638a4bc00f14e25787d29bf2507d2bc3bbba44a13b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- app_rail-airtable (0.2.10)
4
+ app_rail-airtable (0.3.0)
5
5
  activesupport
6
6
  airrecord
7
7
  bcrypt
data/README.md CHANGED
@@ -36,7 +36,18 @@ To provide support for routes, models can implement
36
36
  In order to support authentication you should create a class (normally `User`) and inherit from `AppRail::Airtable::AuthenticationRecord`. Your table needs `Email`, `Password Hash` and `Access Token` columns.
37
37
 
38
38
  ### Servers
39
- You should create a single server which extends `AppRail::Airtable::Sinatra`, then add routes with the `resources` macro to add `index`, `show` and `create` routes. You can also provide your own routes.
39
+ You should create a single server which extends `AppRail::Airtable::Sinatra`.
40
+
41
+ App Rail Airtable provides two helpers to generate routes
42
+
43
+ **resources(name, only:)**
44
+ Creates routes that map to a table. It delegates from the route to a model method
45
+ * `index` to `ar_list_item`
46
+ * `show` to `ar_stack`
47
+ * `create` to `self.create_as_json`
48
+
49
+ **authenticable_resources(name, , only:)**
50
+ Acts as `resources` but also takes a block of routes. Those nested routes will all call the `authenticate!` helper method before running. The `authenticate!` helper will call a lookup helper `find_authenticatable_resource(access_token:)` with the bearer token found in the `HTTP_AUTHORIZATION` header, which should be used to look up the correct object or return nil if none is found (resulting in a 401 response).
40
51
 
41
52
  ## License
42
53
 
@@ -23,9 +23,10 @@ module AppRail
23
23
  end
24
24
 
25
25
  def find_by_email_and_password(email, password)
26
- all(filter: "AND({Email} = \"#{email}\",{Password Hash} = \"#{password_hash(password)}\")").first
26
+ user = all(filter: "{Email} = \"#{email}\"").first
27
+ user.valid_password?(password) ? user : nil
27
28
  end
28
-
29
+
29
30
  def find_by_access_token(access_token)
30
31
  all(filter: "{Access Token} = \"#{access_token}\"").first
31
32
  end
@@ -38,6 +39,14 @@ module AppRail
38
39
  SecureRandom.hex
39
40
  end
40
41
  end
42
+
43
+ def valid_password?(password)
44
+ BCrypt::Password.new(password_hash) == password
45
+ end
46
+
47
+ def password_hash
48
+ self["Password Hash"]
49
+ end
41
50
 
42
51
  def oauth_session
43
52
  { access_token: self["Access Token"], scope: :user, refresh_token: "", token_type: :bearer, expires_in: 60000 }
@@ -6,7 +6,7 @@ module AppRail
6
6
  end
7
7
 
8
8
  def find_current_user
9
- authorization_header && bearer_token ? User.find_by_access_token(bearer_token) : nil
9
+ authorization_header && bearer_token ? find_authenticatable_resource(access_token: bearer_token) : nil
10
10
  end
11
11
 
12
12
  def bearer_token
@@ -24,6 +24,7 @@ end
24
24
  module AppRail
25
25
  module Airtable
26
26
  class Sinatra < Sinatra::Base
27
+ @@authenticated_route = false
27
28
 
28
29
  helpers do
29
30
  def request_body_as_json
@@ -35,36 +36,52 @@ module AppRail
35
36
  request_body_as_json.merge(params)
36
37
  end
37
38
  end
39
+
40
+ def self.authenticatable_resources(name, only: [:index, :show, :create])
41
+
42
+ # If authentication is used then include the correct helpers
43
+ # Allowing the routes to use `authenticate!` and `current_user`
44
+ helpers AppRail::Airtable::AuthenticationHelpers
45
+
46
+ resources(name, only: only)
47
+ @@authenticated_route = true
48
+ yield
49
+ @@authenticated_route = false
50
+ end
38
51
 
39
- def self.resources(name, only: [:index, :show, :create], authenticated: false)
52
+ def self.resources(name, only: [:index, :show, :create])
40
53
  only = [only] if only.is_a?(Symbol)
41
54
 
42
- index_route(name, authenticated) if only.include?(:index)
43
- show_route(name, authenticated) if only.include?(:show)
44
- create_route(name, authenticated) if only.include?(:create)
55
+ index_route(name, authenticated_route?) if only.include?(:index)
56
+ show_route(name, authenticated_route?) if only.include?(:show)
57
+ create_route(name, authenticated_route?) if only.include?(:create)
45
58
  end
46
59
 
47
- def self.index_route(name, authenticated)
60
+ def self.index_route(name, authenticated_route)
48
61
  get "/#{name.to_s}" do
49
- authenticate! if authenticated
50
- name.classify_constantize.index(user: authenticated ? current_user : nil).map(&:ar_list_item_as_json).to_json
62
+ authenticate! if authenticated_route
63
+ name.classify_constantize.index(user: authenticated_route ? current_user : nil).map(&:ar_list_item_as_json).to_json
51
64
  end
52
65
  end
53
66
 
54
- def self.show_route(name, authenticated)
67
+ def self.show_route(name, authenticated_route)
55
68
  get "/#{name.to_s}/:id" do
56
- authenticate! if authenticated
69
+ authenticate! if authenticated_route
57
70
  name.classify_constantize.find(params['id']).ar_stack_as_json.to_json
58
71
  end
59
72
  end
60
73
 
61
- def self.create_route(name, authenticated)
74
+ def self.create_route(name, authenticated_route)
62
75
  post "/#{name.to_s}" do
63
- authenticate! if authenticated
64
- as_json = name.classify_constantize.create_as_json(current_user: authenticated ? current_user : nil, params: params_and_body_as_json)
76
+ authenticate! if authenticated_route
77
+ as_json = name.classify_constantize.create_as_json(current_user: authenticated_route ? current_user : nil, params: params_and_body_as_json)
65
78
  [201, as_json.to_json]
66
79
  end
67
80
  end
81
+
82
+ def self.authenticated_route?
83
+ @@authenticated_route
84
+ end
68
85
  end
69
86
  end
70
87
  end
@@ -1,5 +1,5 @@
1
1
  module AppRail
2
2
  module Airtable
3
- VERSION = "0.2.10"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app_rail-airtable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.10
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brooke-Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-06 00:00:00.000000000 Z
11
+ date: 2021-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport