app_rail-airtable 0.4.3 → 0.4.6

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: f789fb754083245cc062131945cb235ac19070edd2e3ae154e5a233b1533f76b
4
- data.tar.gz: '08a45094b4ba5b5882a8a1baed2acc39c3345adaa8d8557b8ae2daaa3a2bb96c'
3
+ metadata.gz: 3e4126f9d575a705e24ba998e9adb2ecd3dc95c567e13668a733b246fe9401fc
4
+ data.tar.gz: 58b0c53b463db9b7689c580b1fc5d7284c0d72ddf10e51f5eeeee1e63a65fc65
5
5
  SHA512:
6
- metadata.gz: e9bdf986a03d4ce2e00368f7a4ac5048a8b2271778647d1ea27adce3c8b8fa185854e339b2769ee0e0acfce5bfb6dc985cdafc3b4787a8f78fad2da5fdda1681
7
- data.tar.gz: 995431a75366484398c7d90e1e12a3950ac47c23ca6ebe78b9410320dd17224cf08d401df7f613f60b62dca8458103f506d5ebe3e6d5bb0aea0a60a726cce2dc
6
+ metadata.gz: f5969fbe95e911778f4b44104137c6ffe13163e55ea0a57aa13d6b03746ea4ef00daec15b6af9eb1a1c5d58fd2da5903e6cc2e90c71d7cd222dbacfa69b9f11f
7
+ data.tar.gz: b73be3571e4711e835b2a287a38132e8b38c071d433672de505ccce12c2e1658206fb35fdf4985dcc7ef6b32853cf69996e81589ac50fbfec431b6fed261cfe1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.4.6
2
+ * Add authenticatable_resource POST / DELETE `/<resource>/session` routes for sign in and sign out
3
+ * Simplify sign in methods & remove Authenticatable#create_session_as_json
4
+
1
5
  # 0.4.0
2
6
 
3
7
  ### Breaking changes
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- app_rail-airtable (0.4.3)
4
+ app_rail-airtable (0.4.6)
5
5
  activesupport
6
6
  airrecord
7
7
  app_rail-steps
@@ -14,16 +14,16 @@ PATH
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- activesupport (7.0.2.3)
17
+ activesupport (7.0.2.4)
18
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
19
19
  i18n (>= 1.6, < 2)
20
20
  minitest (>= 5.1)
21
21
  tzinfo (~> 2.0)
22
- airrecord (1.0.9)
23
- faraday (>= 0.10, < 3.0)
22
+ airrecord (1.0.10)
23
+ faraday (>= 1.0, < 3.0)
24
24
  faraday-net_http_persistent
25
25
  net-http-persistent
26
- app_rail-steps (0.2.0)
26
+ app_rail-steps (0.2.9)
27
27
  bcrypt (3.1.17)
28
28
  byebug (11.1.3)
29
29
  concurrent-ruby (1.1.10)
@@ -26,9 +26,9 @@ Gem::Specification.new do |spec|
26
26
  spec.executables << 'ara_generator'
27
27
 
28
28
  spec.require_paths = ['lib']
29
- spec.add_dependency 'app_rail-steps'
30
29
  spec.add_dependency 'activesupport'
31
30
  spec.add_dependency 'airrecord'
31
+ spec.add_dependency 'app_rail-steps'
32
32
  spec.add_dependency 'bcrypt'
33
33
  spec.add_dependency 'faraday', '~> 2.2'
34
34
  spec.add_dependency 'faraday-net_http_persistent', '~> 2.0' # workaround to make Faraday work after upgrading to 2.2.0
@@ -6,6 +6,8 @@ require 'securerandom'
6
6
  module AppRail
7
7
  module Airtable
8
8
  module Authenticatable
9
+ class AlreadyExistsError < StandardError; end
10
+
9
11
  include BCrypt
10
12
 
11
13
  def self.included(klass)
@@ -15,25 +17,22 @@ module AppRail
15
17
 
16
18
  module ClassMethods
17
19
  def create(email:, password:)
20
+ raise AlreadyExistsError if find_by_email(email)
21
+
18
22
  user = new('Email' => email, 'Password Hash' => password_hash(password), 'Access Token' => next_access_token)
19
23
  user.create
20
24
  user
21
25
  end
22
26
 
23
- def create_session_as_json(email:, password:)
24
- user = find_by_email_and_password(email, password)
25
- return nil unless user
26
-
27
- user['Access Token'] = next_access_token
28
- user.save
29
- user&.oauth_session
30
- end
31
-
32
27
  def find_by_email_and_password(email, password)
33
- user = all(filter: "{Email} = \"#{email}\"").first
28
+ user = find_by_email(email)
34
29
  user&.valid_password?(password) ? user : nil
35
30
  end
36
31
 
32
+ def find_by_email(email)
33
+ all(filter: "{Email} = \"#{email}\"").first
34
+ end
35
+
37
36
  def find_by_access_token(access_token)
38
37
  all(filter: "{Access Token} = \"#{access_token}\"").first
39
38
  end
@@ -66,7 +65,21 @@ module AppRail
66
65
  end
67
66
 
68
67
  def oauth_session
69
- { access_token: self['Access Token'], scope: :user, refresh_token: '', token_type: :bearer, expires_in: 60_000 }
68
+ ensure_access_token!
69
+
70
+ {
71
+ access_token: self['Access Token'],
72
+ scope: :user,
73
+ token_type: :bearer,
74
+ expires_in: 31_536_000 # 1 year
75
+ }
76
+ end
77
+
78
+ def ensure_access_token!
79
+ unless self['Access Token']
80
+ self['Access Token'] = User.next_access_token
81
+ save
82
+ end
70
83
  end
71
84
  end
72
85
  end
@@ -12,6 +12,10 @@ class Symbol
12
12
  ActiveSupport::Inflector.pluralize(self)
13
13
  end
14
14
 
15
+ def singularize
16
+ ActiveSupport::Inflector.singularize(self)
17
+ end
18
+
15
19
  def classify
16
20
  ActiveSupport::Inflector.classify(self)
17
21
  end
@@ -42,6 +46,8 @@ module AppRail
42
46
  # Allowing the routes to use `authenticate!` and `current_user`
43
47
  helpers AppRail::Airtable::AuthenticationHelpers
44
48
 
49
+ sign_in_route(name)
50
+ sign_out_route(name)
45
51
  resources(name, only: only)
46
52
 
47
53
  return unless block_given?
@@ -60,6 +66,26 @@ module AppRail
60
66
  update_route(name, authenticated_route?) if only.include?(:update)
61
67
  end
62
68
 
69
+ def self.sign_in_route(name)
70
+ post "/#{name}/session" do
71
+ resource = name.classify_constantize.authenticate_by_params(params)
72
+ halt 401 unless resource
73
+
74
+ resource.oauth_session.to_json
75
+ end
76
+ end
77
+
78
+ def self.sign_out_route(name)
79
+ delete "/#{name}/session" do
80
+ authenticate!
81
+ current_user.access_token = nil
82
+ current_user.save
83
+
84
+ # Assume that the client will reload and trigger a 401
85
+ [].to_json
86
+ end
87
+ end
88
+
63
89
  def self.index_route(name, authenticated_route)
64
90
  get "/#{name}" do
65
91
  authenticate! if authenticated_route
@@ -77,9 +103,13 @@ module AppRail
77
103
  def self.create_route(name, authenticated_route)
78
104
  post "/#{name}" do
79
105
  authenticate! if authenticated_route
80
- as_json = name.classify_constantize.create_as_json(current_user: authenticated_route ? current_user : nil,
81
- params: params_and_body_as_json)
82
- [201, as_json.to_json]
106
+ begin
107
+ as_json = name.classify_constantize.create_as_json(current_user: authenticated_route ? current_user : nil,
108
+ params: params_and_body_as_json)
109
+ [201, as_json.to_json]
110
+ rescue AppRail::Airtable::Authenticatable::AlreadyExistsError
111
+ [422, { error: "#{name.singularize} already exists" }.to_json]
112
+ end
83
113
  end
84
114
  end
85
115
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module AppRail
4
4
  module Airtable
5
- VERSION = '0.4.3'
5
+ VERSION = '0.4.6'
6
6
  end
7
7
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV['RACK_ENV'] ||= 'development'
4
+
5
+ require 'dotenv/load' if ENV['RACK_ENV'] == 'development'
6
+
7
+ require 'bundler'
8
+ Bundler.require(:default, ENV['RACK_ENV'].to_sym)
@@ -1,13 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  $stdout.sync = true
4
-
5
- ENV['RACK_ENV'] ||= 'development'
6
- require 'dotenv/load' if ENV['RACK_ENV'] == 'development'
7
- require 'bundler'
8
- Bundler.require(:default, ENV['RACK_ENV'].to_sym)
9
-
10
- require 'dotenv/load' if ENV['RACK_ENV'] == 'development'
11
-
4
+ require './boot'
12
5
  require './lib/server'
13
6
  run Server
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app_rail-airtable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.6
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: 2022-04-18 00:00:00.000000000 Z
11
+ date: 2022-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: app_rail-steps
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activesupport
28
+ name: airrecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: airrecord
42
+ name: app_rail-steps
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -187,6 +187,7 @@ files:
187
187
  - templates/project/.gitignore
188
188
  - templates/project/Gemfile
189
189
  - templates/project/app.json
190
+ - templates/project/boot.rb
190
191
  - templates/project/config.ru
191
192
  - templates/project/lib/server.rb.tt
192
193
  - templates/project/spec/server_spec.rb.tt