bullet_train-api 1.1.15 → 1.2.1

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
  SHA256:
3
- metadata.gz: 14acbfaa73e947b800255ed5e8d31afeaa9d453e7da85ee6f46684bd2f824d8a
4
- data.tar.gz: 698e7d97b1c9bce05d5ed049bc8552002b7a769ed97b3f7e7d0690bf6ef19bce
3
+ metadata.gz: e3cec04f6456085bc115f66416e2f5fcaf249c0685166e8a46a88b79b4bd1978
4
+ data.tar.gz: 0b14b88a2aa523a9ce4d75de6ce79c4f0e81a46d0394085ca16e6b477bf66037
5
5
  SHA512:
6
- metadata.gz: 99eef514f9a218014d19576d8b17e0ecff0a475e672922c227a177203c6041e8db178ebc996a090919ffcb47b5b53d0adaadf70344de811501b7d8e4d49a8d09
7
- data.tar.gz: 016203f358c8cbb80069d6975ab3d44fbad04ac8fe172ca6ff2f888cf744367f948b06ac8596e9fbd0c4098f54cff2ac13053b332d6ce50a37eca75c597c40da
6
+ metadata.gz: ae4e8eaf3d5c89797e736de09866fc071427244120ed45b9fdced3881f433e91660e3372dfda36bda508c5af59a2db8ddb4e55354a7fc7dc3344e3a65b0cd106
7
+ data.tar.gz: 6551bce70c06a57a8b82511db07cbebbebf87f8f385bfb3bd4910166a2d7d5d5c4cbfa7a3c334d9bef1bbaf975eddf75b5a64175a16cae446a85d1cf9460ddd0
@@ -21,6 +21,23 @@ class Account::Platform::ApplicationsController < Account::ApplicationController
21
21
  def edit
22
22
  end
23
23
 
24
+ def provision
25
+ if ENV["TESTING_PROVISION_KEY"].present? && params[:key] == ENV["TESTING_PROVISION_KEY"]
26
+ user = User.create(email: "test@#{SecureRandom.hex}.example.com", password: (password = SecureRandom.hex), password_confirmation: password)
27
+ provision_team = current_user.teams.create(name: "provision-team-#{SecureRandom.hex}", time_zone: user.time_zone)
28
+ test_application = Platform::Application.new(name: "test-application-#{SecureRandom.hex}", team: provision_team)
29
+
30
+ if test_application.save
31
+ access_token = test_application.create_access_token
32
+ render json: {message: I18n.t("platform/applications.notifications.test_application_created"), team_id: provision_team.id, access_token: access_token.token}
33
+ else
34
+ render json: {errors: test_application.errors, status: :unprocessable_entity}
35
+ end
36
+ else
37
+ render json: {message: I18n.t("platform/applications.notifications.test_application_failure")}
38
+ end
39
+ end
40
+
24
41
  # POST /account/teams/:team_id/platform/applications
25
42
  # POST /account/teams/:team_id/platform/applications.json
26
43
  def create
@@ -6,6 +6,7 @@ module OpenApiHelper
6
6
  lines.unshift(first_line).join.html_safe
7
7
  end
8
8
 
9
+ # TODO: Remove this method? It's not being used anywhere
9
10
  def components_for(model)
10
11
  for_model model do
11
12
  indent(render("api/#{@version}/open_api/#{model.name.underscore.pluralize}/components"), 2)
@@ -73,15 +74,20 @@ module OpenApiHelper
73
74
 
74
75
  def attribute(attribute)
75
76
  heading = t("#{current_model.name.underscore.pluralize}.fields.#{attribute}.heading")
76
- # TODO A lot of logic to be done here.
77
- indent("#{attribute}:\n description: \"#{heading}\"\n type: string", 2)
78
- end
79
-
80
- def parameter(attribute)
81
- heading = t("#{current_model.name.underscore.pluralize}.fields.#{attribute}.heading")
82
- # TODO A lot of logic to be done here.
83
- indent("#{attribute}:\n description: \"#{heading}\"\n type: string", 2)
77
+ attribute_data = current_model.columns_hash[attribute.to_s]
78
+
79
+ # TODO: File fields don't show up in the columns_hash. How should we handle these?
80
+ # Default to `string` when the type returns nil.
81
+ type = attribute_data.nil? ? "string" : attribute_data.type
82
+
83
+ attribute_block = <<~YAML
84
+ #{attribute}:
85
+ description: "#{heading}"
86
+ type: #{type}
87
+ YAML
88
+ indent(attribute_block.chomp, 2)
84
89
  end
90
+ alias_method :parameter, :attribute
85
91
  end
86
92
 
87
93
  class Api::OpenApiController < ApplicationController
@@ -4,10 +4,6 @@ require "pagy_cursor/pagy/extras/uuid_cursor"
4
4
  module Api::Controllers::Base
5
5
  extend ActiveSupport::Concern
6
6
 
7
- # TODO Why doesn't `before_action :doorkeeper_authorize!` throw an exception?
8
- class NotAuthenticatedError < StandardError
9
- end
10
-
11
7
  included do
12
8
  include ActionController::Helpers
13
9
  helper ApplicationHelper
@@ -16,14 +12,13 @@ module Api::Controllers::Base
16
12
  include Pagy::Backend
17
13
 
18
14
  before_action :set_default_response_format
19
- before_action :doorkeeper_authorize!
20
15
  after_action :set_pagination_headers
21
16
 
22
17
  def modify_url_params(url, new_params)
23
18
  uri = URI.parse(url)
24
19
  query = Rack::Utils.parse_query(uri.query)
25
20
  new_params.each do |key, value|
26
- query[key] = value
21
+ query[key.to_s] = value
27
22
  end
28
23
  uri.query = Rack::Utils.build_query(query)
29
24
  uri.to_s
@@ -35,8 +30,9 @@ module Api::Controllers::Base
35
30
  if @pagy.has_more?
36
31
  if (collection = instance_variable_get(collection_variable))
37
32
  next_cursor = collection.last.id
38
- # TODO Probably not great that we're clobbering any `Link` header that might be set.
39
- response.headers["Link"] = "<#{modify_url_params(request.url, after: next_cursor)}>; rel=next"
33
+ link_header = response.headers["Link"]
34
+ link_value = "<#{modify_url_params(request.url, after: next_cursor)}>; rel=\"next\""
35
+ response.headers["Link"] = link_header ? "#{link_header}, #{link_value}" : link_value
40
36
  response.headers["Pagination-Next"] = next_cursor
41
37
  end
42
38
  end
@@ -46,10 +42,6 @@ module Api::Controllers::Base
46
42
  render json: {error: "Not found"}, status: :not_found
47
43
  end
48
44
 
49
- rescue_from NotAuthenticatedError do |exception|
50
- render json: {error: "Invalid token"}, status: :unauthorized
51
- end
52
-
53
45
  before_action :apply_pagination, only: [:index]
54
46
  end
55
47
 
@@ -65,7 +57,7 @@ module Api::Controllers::Base
65
57
  end
66
58
 
67
59
  def current_user
68
- raise NotAuthenticatedError unless doorkeeper_token.present?
60
+ raise Doorkeeper::Errors::InvalidToken unless doorkeeper_token.present?
69
61
  # TODO Remove this rescue once workspace clusters can write to this column on the identity server.
70
62
  # TODO Make this logic configurable so that downstream developers can write different methods for this column getting updated.
71
63
  begin
@@ -95,8 +87,12 @@ module Api::Controllers::Base
95
87
  end
96
88
 
97
89
  class_methods do
90
+ def controller_namespace
91
+ name.split("::").first(2).join("::")
92
+ end
93
+
98
94
  def regex_to_remove_controller_namespace
99
- /^#{name.split("::").first(2).join("::") + "::"}/
95
+ /^#{controller_namespace + "::"}/
100
96
  end
101
97
  end
102
98
  end
@@ -11,6 +11,9 @@ module Api::V1::Users::ControllerBase
11
11
  :last_name,
12
12
  :time_zone,
13
13
  :locale,
14
+ :current_password,
15
+ :password,
16
+ :password_confirmation,
14
17
  # 🚅 super scaffolding will insert new fields above this line.
15
18
  *permitted_arrays,
16
19
  # 🚅 super scaffolding will insert new arrays above this line.
@@ -34,7 +34,7 @@ class Platform::Application < ApplicationRecord
34
34
  def create_user_and_membership
35
35
  faux_password = SecureRandom.hex
36
36
  create_user(email: "noreply+#{SecureRandom.hex}@bullettrain.co", password: faux_password, password_confirmation: faux_password, first_name: label_string)
37
- create_membership(team: team, user: user)
37
+ create_membership(team: team, user: user, platform_agent: true)
38
38
  membership.roles << Role.admin
39
39
  end
40
40
 
@@ -13,22 +13,23 @@
13
13
  required: true
14
14
  schema:
15
15
  type: string
16
+ - $ref: "#/components/parameters/after"
16
17
  responses:
17
18
  "404":
18
19
  description: "Not Found"
19
20
  "200":
20
21
  description: "OK"
22
+ headers:
23
+ Pagination-Next:
24
+ $ref: "#/components/headers/PaginationNext"
25
+ Link:
26
+ $ref: "#/components/headers/Link"
21
27
  content:
22
28
  application/json:
23
29
  schema:
24
- type: object
25
- properties:
26
- data:
27
- type: array
28
- items:
29
- $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingAttributes"
30
- has_more:
31
- type: boolean
30
+ type: array
31
+ items:
32
+ $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingAttributes"
32
33
  <% end %>
33
34
  <% unless except.include?(:create) %>
34
35
  post:
@@ -42,6 +43,17 @@
42
43
  required: true
43
44
  schema:
44
45
  type: string
46
+ requestBody:
47
+ description: "Information about a new Tangible Thing"
48
+ required: true
49
+ content:
50
+ application/json:
51
+ schema:
52
+ type: object
53
+ properties:
54
+ scaffolding_completely_concrete_tangible_thing:
55
+ type: object
56
+ $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingParameters"
45
57
  responses:
46
58
  "404":
47
59
  description: "Not Found"
@@ -50,7 +62,7 @@
50
62
  content:
51
63
  application/json:
52
64
  schema:
53
- $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingParameters"
65
+ $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingAttributes"
54
66
  <% end %>
55
67
  <% end %>
56
68
  <% unless except.include?(:show) && except.include?(:update) && except.include?(:destroy) %>
@@ -81,6 +93,17 @@
81
93
  operationId: updateScaffoldingCompletelyConcreteTangibleThings
82
94
  parameters:
83
95
  - $ref: "#/components/parameters/id"
96
+ requestBody:
97
+ description: "Information about updated fields in Tangible Thing"
98
+ required: true
99
+ content:
100
+ application/json:
101
+ schema:
102
+ type: object
103
+ properties:
104
+ scaffolding_completely_concrete_tangible_thing:
105
+ type: object
106
+ $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingParameters"
84
107
  responses:
85
108
  "404":
86
109
  description: "Not Found"
@@ -89,7 +112,7 @@
89
112
  content:
90
113
  application/json:
91
114
  schema:
92
- $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingParameters"
115
+ $ref: "#/components/schemas/ScaffoldingCompletelyConcreteTangibleThingAttributes"
93
116
  <% end %>
94
117
  <% unless except.include?(:destroy) %>
95
118
  delete:
@@ -102,7 +125,7 @@
102
125
  responses:
103
126
  "404":
104
127
  description: "Not Found"
105
- "200":
106
- description: "OK"
128
+ "204":
129
+ description: "No Content"
107
130
  <% end %>
108
131
  <% end %>
@@ -4,22 +4,24 @@
4
4
  - Teams
5
5
  summary: "List Teams"
6
6
  operationId: listTeams
7
+ parameters:
8
+ - $ref: "#/components/parameters/after"
7
9
  responses:
8
10
  "404":
9
11
  description: "Not Found"
10
12
  "200":
11
13
  description: "OK"
14
+ headers:
15
+ Pagination-Next:
16
+ $ref: "#/components/headers/PaginationNext"
17
+ Link:
18
+ $ref: "#/components/headers/Link"
12
19
  content:
13
20
  application/json:
14
21
  schema:
15
- type: object
16
- properties:
17
- data:
18
- type: array
19
- items:
20
- $ref: "#/components/schemas/TeamAttributes"
21
- has_more:
22
- type: boolean
22
+ type: array
23
+ items:
24
+ $ref: "#/components/schemas/TeamAttributes"
23
25
  /teams/{id}:
24
26
  get:
25
27
  tags:
@@ -44,6 +46,17 @@
44
46
  operationId: updateTeam
45
47
  parameters:
46
48
  - $ref: "#/components/parameters/id"
49
+ requestBody:
50
+ description: "Information about updated fields in Team"
51
+ required: true
52
+ content:
53
+ application/json:
54
+ schema:
55
+ type: object
56
+ properties:
57
+ team:
58
+ type: object
59
+ $ref: "#/components/schemas/TeamParameters"
47
60
  responses:
48
61
  "404":
49
62
  description: "Not Found"
@@ -52,4 +65,4 @@
52
65
  content:
53
66
  application/json:
54
67
  schema:
55
- $ref: "#/components/schemas/TeamParameters"
68
+ $ref: "#/components/schemas/TeamAttributes"
@@ -4,22 +4,24 @@
4
4
  - Users
5
5
  summary: "List Users"
6
6
  operationId: listUsers
7
+ parameters:
8
+ - $ref: "#/components/parameters/after"
7
9
  responses:
8
10
  "404":
9
11
  description: "Not Found"
10
12
  "200":
11
13
  description: "OK"
14
+ headers:
15
+ Pagination-Next:
16
+ $ref: "#/components/headers/PaginationNext"
17
+ Link:
18
+ $ref: "#/components/headers/Link"
12
19
  content:
13
20
  application/json:
14
21
  schema:
15
- type: object
16
- properties:
17
- data:
18
- type: array
19
- items:
20
- $ref: "#/components/schemas/UserAttributes"
21
- has_more:
22
- type: boolean
22
+ type: array
23
+ items:
24
+ $ref: "#/components/schemas/UserAttributes"
23
25
  /users/{id}:
24
26
  get:
25
27
  tags:
@@ -44,6 +46,17 @@
44
46
  operationId: updateUser
45
47
  parameters:
46
48
  - $ref: "#/components/parameters/id"
49
+ requestBody:
50
+ description: "Information about updated fields in User"
51
+ required: true
52
+ content:
53
+ application/json:
54
+ schema:
55
+ type: object
56
+ properties:
57
+ user:
58
+ type: object
59
+ $ref: "#/components/schemas/UserParameters"
47
60
  responses:
48
61
  "404":
49
62
  description: "Not Found"
@@ -52,4 +65,4 @@
52
65
  content:
53
66
  application/json:
54
67
  schema:
55
- $ref: "#/components/schemas/UserParameters"
68
+ $ref: "#/components/schemas/UserAttributes"
@@ -81,6 +81,8 @@ en:
81
81
  created: Platform Application was successfully created.
82
82
  updated: Platform Application was successfully updated.
83
83
  destroyed: Platform Application was successfully destroyed.
84
+ test_application_created: Test Platform Application was successfully created.
85
+ test_application_failure: You must provide the proper testing provision key to create a test application.
84
86
  account:
85
87
  platform:
86
88
  applications: *applications
data/config/routes.rb CHANGED
@@ -17,6 +17,10 @@ Rails.application.routes.draw do
17
17
  end
18
18
  end
19
19
 
20
+ if ENV["TESTING_PROVISION_KEY"].present?
21
+ get "/testing/provision", to: "account/platform/applications#provision"
22
+ end
23
+
20
24
  namespace :api do
21
25
  match "*version/openapi.yaml" => "open_api#index", :via => :get
22
26
 
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module Api
3
- VERSION = "1.1.15"
3
+ VERSION = "1.2.1"
4
4
  end
5
5
  end
@@ -1,4 +1,76 @@
1
- # desc "Explaining what the task does"
2
- # task :bullet_train_api do
3
- # # Task goes here
4
- # end
1
+ require "scaffolding"
2
+ require "scaffolding/file_manipulator"
3
+
4
+ namespace :bullet_train do
5
+ namespace :api do
6
+ desc "Bump the current version of application's API"
7
+ task :bump_version do
8
+ # Calculate new version.
9
+ initializer_content = File.new("config/initializers/api.rb").readline
10
+ previous_version = initializer_content.scan(/v\d+/).pop
11
+ new_version = "v#{previous_version.scan(/\d+/).pop.to_i + 1}"
12
+
13
+ # Update initializer.
14
+ File.write("config/initializers/api.rb", initializer_content.gsub(previous_version, new_version))
15
+
16
+ [
17
+ "app/controllers/api/#{new_version}",
18
+ "app/views/api/#{new_version}",
19
+ "test/controllers/api/#{new_version}"
20
+ ].each do |dir|
21
+ Dir.mkdir(dir)
22
+ end
23
+
24
+ files_to_update = [
25
+ "config/routes/api/#{previous_version}.rb",
26
+ Dir.glob("app/controllers/api/#{previous_version}/**/*.rb") +
27
+ Dir.glob("app/views/api/#{previous_version}/**/*.json.jbuilder") +
28
+ Dir.glob("test/controllers/api/#{previous_version}/**/*.rb")
29
+ ].flatten
30
+
31
+ files_to_update.each do |file_name|
32
+ previous_file_contents = File.open(file_name).readlines
33
+ new_file_name = file_name.gsub(previous_version, new_version)
34
+
35
+ updated_file_contents = previous_file_contents.map do |line|
36
+ if line.match?(previous_version)
37
+ line.gsub(previous_version, new_version)
38
+ else
39
+ line.gsub("Api::#{previous_version.upcase}", "Api::#{new_version.upcase}")
40
+ end
41
+ end
42
+
43
+ # We can't create new files unless each directory under #{api/previous_version}
44
+ # has been created under the new api directory. For example, we have to create
45
+ # the `projects` directory before we can create the file `api/v2/projects/pages.json.jbuilder.`
46
+ new_version_dir, dir_hierarchy = new_file_name.split(/(?<=#{new_version})\//)
47
+ if dir_hierarchy.present? && dir_hierarchy.match?("/")
48
+ dir_hierarchy = dir_hierarchy.split("/")
49
+ dir_hierarchy.inject(new_version_dir) do |base, child_dir_or_file|
50
+ # Stop making new directories if the string has an extention like ".rb"
51
+ break if child_dir_or_file.match?(/\./)
52
+
53
+ new_hierarchy = "#{base}/#{child_dir_or_file}"
54
+ Dir.mkdir(new_hierarchy) unless Dir.exist?(new_hierarchy)
55
+ new_hierarchy
56
+ end
57
+ end
58
+ Scaffolding::FileManipulator.write(new_file_name, updated_file_contents)
59
+ end
60
+
61
+ # Here we make sure config/api/#{new_version}.rb is called from within the main routes file.
62
+ previous_file_contents = File.open("config/routes.rb").readlines
63
+ updated_file_contents = previous_file_contents.map do |line|
64
+ if line.match?("draw \"api/#{previous_version}\"")
65
+ new_version_draw_line = line.gsub(previous_version, new_version)
66
+ line + new_version_draw_line
67
+ else
68
+ line
69
+ end
70
+ end
71
+ Scaffolding::FileManipulator.write("config/routes.rb", updated_file_contents)
72
+
73
+ puts "Finished bumping to #{new_version}"
74
+ end
75
+ end
76
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.15
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-16 00:00:00.000000000 Z
11
+ date: 2022-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: standard