app_rail-airtable 0.2.8 → 0.2.12

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: af89c3dbe402f9b53fc7c717de7c58d47fc8927e2388a21ca15d52464839a879
4
- data.tar.gz: 74f42c9e64fe80c364d84c9b40ab7733a0d3bb597eb0f2b2d0c261673215cef8
3
+ metadata.gz: 3093a14dafa5e25f4cc4a7791bedfc00f1c2f5941f99c6a07060ea60e12e7ff8
4
+ data.tar.gz: bd3ece807677d1ffa0d29f92b254fd484ad10b0ab7ca16312b31126c3d96bd1a
5
5
  SHA512:
6
- metadata.gz: 859b5eb8d1de6589def9b76450087c13ab8a4b02d927a9210e69f620705c4ef096630e920a0deb201d194ba97feadb5437ec4e1d4f107fd0406aa132e37f8028
7
- data.tar.gz: e4163e04b1e771930b6b338a28463a53b18678401f68285dda7342d66214f6f64b19c5be90f01ba891a01d51461100eacc7e3aa8918817b1710ba89815f9e844
6
+ metadata.gz: 5e79328b4a2eca0a521541ebc8164b91374263fc3f6e6f91d2d847774a65baabfad66bec4b4672484a8eedb8da060f6c5fc19f909537d8076e18a75b31c94384
7
+ data.tar.gz: a0eb587cb217d6c336d9cbe8fd52f72eb41dc24e582c58877ba72d5dd7ec2b034a0711ac782a00e29dcfdea944cb531e65f532b031e5fcf1de0c25827016e99a
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- app_rail-airtable (0.2.8)
4
+ app_rail-airtable (0.2.12)
5
5
  activesupport
6
6
  airrecord
7
+ bcrypt
7
8
  sinatra
8
9
  thor
9
10
 
@@ -19,6 +20,7 @@ GEM
19
20
  airrecord (1.0.7)
20
21
  faraday (>= 0.10, < 2.0)
21
22
  net-http-persistent
23
+ bcrypt (3.1.16)
22
24
  byebug (11.1.3)
23
25
  concurrent-ruby (1.1.9)
24
26
  connection_pool (2.2.5)
data/README.md CHANGED
@@ -31,7 +31,9 @@ You should create a model class for each table you want to use in your App. Mode
31
31
  To provide support for routes, models can implement
32
32
  * ar_list_item (index)
33
33
  * ar_stack (show)
34
- * self.create_as_json (create)
34
+ * self.create_as_json (create)
35
+
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.
35
37
 
36
38
  ### Servers
37
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.
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'sinatra'
25
25
  spec.add_dependency 'airrecord'
26
26
  spec.add_dependency 'thor'
27
+ spec.add_dependency 'bcrypt'
27
28
 
28
29
  spec.add_development_dependency 'rspec'
29
30
  spec.add_development_dependency 'rack-test'
@@ -0,0 +1,56 @@
1
+ require 'bcrypt'
2
+ require 'securerandom'
3
+
4
+ module AppRail
5
+ module Airtable
6
+ module Authenticatable
7
+ include BCrypt
8
+
9
+ def self.included(klass)
10
+ klass.extend(ClassMethods)
11
+ end
12
+
13
+ module ClassMethods
14
+ def create(email:, password:)
15
+ user = User.new("Email" => email, "Password Hash" => password_hash(password), "Access Token" => access_token)
16
+ user.create
17
+ user
18
+ end
19
+
20
+ def create_session_as_json(email:, password:)
21
+ user = find_by_email_and_password(email, password)
22
+ user&.oauth_session
23
+ end
24
+
25
+ def find_by_email_and_password(email, password)
26
+ user = all(filter: "{Email} = \"#{email}\"").first
27
+ user.valid_password? ? user : nil
28
+ end
29
+
30
+ def find_by_access_token(access_token)
31
+ all(filter: "{Access Token} = \"#{access_token}\"").first
32
+ end
33
+
34
+ def password_hash(password)
35
+ BCrypt::Password.create(password)
36
+ end
37
+
38
+ def access_token
39
+ SecureRandom.hex
40
+ end
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
50
+
51
+ def oauth_session
52
+ { access_token: self["Access Token"], scope: :user, refresh_token: "", token_type: :bearer, expires_in: 60000 }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,27 @@
1
+ module AppRail
2
+ module Airtable
3
+ module AuthenticationHelpers
4
+ def current_user
5
+ @current_user ||= find_current_user
6
+ end
7
+
8
+ def find_current_user
9
+ authorization_header && bearer_token ? User.find_by_access_token(bearer_token) : nil
10
+ end
11
+
12
+ def bearer_token
13
+ authorization_values = authorization_header.split(" ")
14
+ return nil unless authorization_values.count > 1
15
+ authorization_values[1]
16
+ end
17
+
18
+ def authorization_header
19
+ request.env["HTTP_AUTHORIZATION"]
20
+ end
21
+
22
+ def authenticate!
23
+ halt 401 unless current_user
24
+ end
25
+ end
26
+ end
27
+ end
@@ -31,7 +31,7 @@ module AppRail
31
31
  JSON.parse(request.body.read)
32
32
  end
33
33
 
34
- def params_and_json_body
34
+ def params_and_body_as_json
35
35
  request_body_as_json.merge(params)
36
36
  end
37
37
  end
@@ -61,7 +61,7 @@ module AppRail
61
61
  def self.create_route(name, authenticated)
62
62
  post "/#{name.to_s}" do
63
63
  authenticate! if authenticated
64
- as_json = name.classify_constantize.create_as_json(current_user: authenticated ? current_user : nil, params: params_and_json_body)
64
+ as_json = name.classify_constantize.create_as_json(current_user: authenticated ? current_user : nil, params: params_and_body_as_json)
65
65
  [201, as_json.to_json]
66
66
  end
67
67
  end
@@ -1,5 +1,5 @@
1
1
  module AppRail
2
2
  module Airtable
3
- VERSION = "0.2.8"
3
+ VERSION = "0.2.12"
4
4
  end
5
5
  end
@@ -1,8 +1,10 @@
1
1
  require "app_rail/airtable/version"
2
+ require "app_rail/airtable/string_ext"
2
3
  require "app_rail/airtable/application_record"
4
+ require "app_rail/airtable/authenticatable"
5
+ require "app_rail/airtable/authentication_helpers"
3
6
  require "app_rail/airtable/sinatra"
4
7
  require "app_rail/airtable/generator"
5
- require "app_rail/airtable/string_ext"
6
8
 
7
9
  module AppRail
8
10
  module Airtable
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.8
4
+ version: 0.2.12
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-04 00:00:00.000000000 Z
11
+ date: 2021-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bcrypt
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -116,6 +130,8 @@ files:
116
130
  - bin/setup
117
131
  - lib/app_rail/airtable.rb
118
132
  - lib/app_rail/airtable/application_record.rb
133
+ - lib/app_rail/airtable/authenticatable.rb
134
+ - lib/app_rail/airtable/authentication_helpers.rb
119
135
  - lib/app_rail/airtable/generator.rb
120
136
  - lib/app_rail/airtable/sinatra.rb
121
137
  - lib/app_rail/airtable/string_ext.rb