hephaestus 0.8.11 → 0.8.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +6 -0
  4. data/README.md +3 -1
  5. data/bin/hephaestus +31 -13
  6. data/lib/hephaestus/app_builder.rb +23 -145
  7. data/lib/hephaestus/app_name.rb +33 -0
  8. data/lib/hephaestus/generators/app_generator.rb +70 -72
  9. data/lib/hephaestus/generators/config_generator.rb +3 -114
  10. data/lib/hephaestus/generators/core_generator.rb +18 -58
  11. data/lib/hephaestus/generators/db_generator.rb +12 -0
  12. data/lib/hephaestus/generators/deployment_generator.rb +1 -6
  13. data/lib/hephaestus/generators/lib_generator.rb +0 -10
  14. data/lib/hephaestus/generators/license_generator.rb +4 -1
  15. data/lib/hephaestus/generators/rubocop_generator.rb +1 -1
  16. data/lib/hephaestus/version.rb +1 -1
  17. data/lib/hephaestus.rb +2 -0
  18. data/templates/Dockerfile +7 -75
  19. data/templates/Gemfile +73 -0
  20. data/templates/Procfile +2 -0
  21. data/templates/app/controllers/app_controller.rb.tt +35 -0
  22. data/templates/app/controllers/application_controller.rb +1 -7
  23. data/templates/app/controllers/concerns/authable.rb.tt +50 -0
  24. data/templates/app/controllers/settings_controller.rb +5 -28
  25. data/templates/app/controllers/yetto_controller.rb +9 -10
  26. data/templates/app/lib/body_parameter/yetto_parameters.rb +8 -29
  27. data/templates/app/lib/{constants/app.rb → constants.rb} +1 -3
  28. data/templates/app/services/{http_service.rb → app_service.rb.tt} +6 -6
  29. data/templates/app/views/settings/new.json.jbuilder.tt +18 -0
  30. data/templates/bin/bundle +115 -0
  31. data/templates/bin/docker-entrypoint +20 -10
  32. data/templates/bin/foreman +27 -0
  33. data/templates/bin/jobs +7 -0
  34. data/templates/bin/rails +6 -0
  35. data/templates/bin/rake +6 -0
  36. data/templates/bin/setup +28 -0
  37. data/templates/bin/tapioca +27 -0
  38. data/templates/config/application.rb.tt +36 -0
  39. data/templates/config/boot.rb +7 -0
  40. data/templates/config/environment.rb +8 -0
  41. data/templates/config/environments/blank.rb +7 -0
  42. data/templates/config/initializers/environment.rb +2 -36
  43. data/templates/config/locales/en.yml +5 -31
  44. data/templates/config/puma.rb +5 -0
  45. data/templates/config/routes.rb.tt +28 -0
  46. data/templates/config.ru +9 -0
  47. data/templates/db/queue_schema.rb +132 -0
  48. data/templates/db/schema.rb +17 -0
  49. data/templates/lib/schemas/api/2023-03-06/components/parameters/headers/yetto.json +42 -0
  50. data/templates/lib/schemas/api/2023-03-06/components/parameters/plugInstallation.json +12 -0
  51. data/templates/lib/schemas/api/2023-03-06/components/schemas/plug.json +9 -0
  52. data/templates/lib/schemas/api/2023-03-06/components/schemas/responses.json +64 -0
  53. data/templates/lib/schemas/api/2023-03-06/components/schemas/yetto.json +116 -0
  54. data/templates/lib/schemas/api/2023-03-06/openapi.json +30 -0
  55. data/templates/lib/schemas/api/2023-03-06/paths/app.json +90 -0
  56. data/templates/lib/schemas/api/2023-03-06/paths/yetto/message_created.json +51 -0
  57. data/templates/lib/schemas/api/2023-03-06/paths/yetto/plug_installation_created.json +51 -0
  58. data/templates/script/docker-build-prod.tt +11 -0
  59. data/templates/script/docker-run.tt +8 -0
  60. data/templates/script/edit-credentials +12 -3
  61. data/templates/script/hmac_text +1 -1
  62. data/templates/script/ngrok.tt +7 -0
  63. data/templates/script/server +6 -45
  64. data/templates/test/controllers/app_controller_test.rb.tt +188 -0
  65. data/templates/test/controllers/settings_controller_test.rb.tt +125 -0
  66. data/templates/test/controllers/yetto_controller_test.rb +100 -71
  67. data/templates/test/fixtures/files/plug_installation_settings/valid.json +1 -1
  68. data/templates/test/support/rails.rb +16 -36
  69. data/templates/test/support/webmocks/app_webmock.rb.tt +29 -0
  70. data/templates/test/test_helper.rb +1 -31
  71. data/templates/vendor/fly/{fly-production.toml → fly-production.toml.tt} +24 -11
  72. data/templates/vendor/fly/{fly-staging.toml → fly-staging.toml.tt} +18 -15
  73. metadata +46 -71
  74. data/templates/Gemfile.erb +0 -120
  75. data/templates/Procfile.debug +0 -2
  76. data/templates/Procfile.dev +0 -2
  77. data/templates/app/controllers/app_controller.rb +0 -72
  78. data/templates/app/controllers/concerns/authable.rb +0 -50
  79. data/templates/app/controllers/staff_controller.rb +0 -15
  80. data/templates/app/jobs/update_yetto_job.rb +0 -26
  81. data/templates/app/lib/headers/yetto.rb +0 -19
  82. data/templates/app/lib/headers.rb +0 -5
  83. data/templates/app/lib/path_parameter/settings_parameters.rb +0 -22
  84. data/templates/app/lib/path_parameter/yetto_parameters.rb +0 -28
  85. data/templates/app/lib/path_parameter.rb +0 -8
  86. data/templates/app/lib/plug_app/http.rb +0 -37
  87. data/templates/app/lib/plug_app/middleware/malformed_request.rb +0 -110
  88. data/templates/app/lib/plug_app/middleware/openapi_validation.rb +0 -83
  89. data/templates/app/lib/plug_app/middleware/tracing_attributes.rb +0 -46
  90. data/templates/app/lib/query_parameter.rb +0 -6
  91. data/templates/app/serializers/error_serializer.rb +0 -16
  92. data/templates/app/services/yetto_service.rb +0 -51
  93. data/templates/app/views/settings/new.json.jbuilder +0 -21
  94. data/templates/compose.yml +0 -5
  95. data/templates/config/initializers/000-oj.rb +0 -6
  96. data/templates/config/initializers/cors.rb +0 -19
  97. data/templates/config/initializers/filter_parameter_logging.rb +0 -25
  98. data/templates/config/initializers/inflections.rb +0 -20
  99. data/templates/config/initializers/lograge.rb +0 -25
  100. data/templates/config/initializers/opentelemetry.rb +0 -32
  101. data/templates/config/initializers/sidekiq.rb +0 -11
  102. data/templates/config/initializers/slack_webhook_logger.rb +0 -17
  103. data/templates/config/sidekiq.yml +0 -20
  104. data/templates/script/ngrok +0 -5
  105. data/templates/test/controllers/settings_controller_test.rb +0 -27
  106. data/templates/test/fixtures/plug_installation_settings/invalid.json +0 -3
  107. data/templates/test/fixtures/plug_installation_settings/valid.json +0 -3
  108. data/templates/test/jobs/update_yetto_job_test.rb +0 -26
  109. data/templates/test/support/api.rb +0 -76
  110. data/templates/test/support/webmocks/slack_webmock.rb +0 -24
  111. data/templates/test/support/webmocks/yetto_webmock.rb +0 -119
  112. data/templates/test/support/webmocks.rb +0 -5
@@ -5,121 +5,10 @@ require_relative "base"
5
5
 
6
6
  module Hephaestus
7
7
  class ConfigGenerator < Generators::Base
8
- def application
9
- config = <<~CONFIG
8
+ include Hephaestus::AppName
10
9
 
11
-
12
- if ENV.fetch("DEBUG", false) && defined?(Rails::Server) && Rails.env.development?
13
- require "debug/open_nonstop"
14
- end
15
-
16
- CONFIG
17
-
18
- inject_into_file(
19
- "config/application.rb",
20
- config,
21
- after: "require \"rails/test_unit/railtie\"",
22
- )
23
- inject_into_file(
24
- "config/application.rb",
25
- "\n CURRENT_VERSION = \"2023-03-06\"\n\n",
26
- before: "class Application < Rails::Application",
27
- )
28
-
29
- raltie_overload = <<~CONFIG
30
-
31
- # Load dotenv only in development environment
32
- Dotenv::Rails.overwrite = true if Rails.env.development?
33
- CONFIG
34
- inject_into_file(
35
- "config/application.rb",
36
- raltie_overload,
37
- after: "Bundler.require(*Rails.groups)",
38
- )
39
-
40
- config = <<~CONFIG
41
-
42
- # Only loads a smaller set of middleware suitable for API-only Rails.
43
- # Middleware like session, flash, cookies can be added back manually.
44
- # Skip views, helpers and assets when generating a new resource.
45
- config.api_only = true
46
-
47
- Rails.root.glob("app/lib/#{app_name.underscore}/middleware/*.{rb}").each { |file| require_relative file }
48
-
49
- config.middleware.insert(0, PlugApp::Middleware::TracingAttributes)
50
- config.middleware.insert(0, PlugApp::Middleware::MalformedRequest)
51
-
52
- config.middleware.use(PlugApp::Middleware::OpenapiValidation)
53
-
54
- GIT_SHA = %x(git rev-parse HEAD).chomp
55
- CONFIG
56
-
57
- inject_into_file(
58
- "config/application.rb",
59
- config,
60
- before: "\n end",
61
- )
62
-
63
- replace_in_file(
64
- "config/application.rb",
65
- "require \"rails\"\n",
66
- "",
67
- )
68
-
69
- comment_lines("config/application.rb", "require \"active_model/railtie\"")
70
- uncomment_lines("config/application.rb", "require \"active_job/railtie\"")
71
- end
72
-
73
- def boot
74
- boot = "require \"bootsnap/setup\" # Speed up boot time by caching expensive operations."
75
- inject_into_file(
76
- "config/boot.rb",
77
- boot,
78
- )
79
- end
80
-
81
- def initializers
82
- remove_dir("config/initializers")
83
- directory("config/initializers", "config/initializers")
84
- end
85
-
86
- def configure_routes
87
- routes = <<~ROUTES
88
- root "root#index"
89
-
90
- # events into the plug, usually from yetto
91
- get "/api/2023-03-06/settings", to: "settings#new"
92
- post "/api/2023-03-06/:record_type/:event", to: "yetto#event"
93
-
94
- # inbound message
95
- post "/$app/2023-03-06/webhook/inbound", to: "app#webhook"
96
-
97
- # Staff pages
98
- get "staff", to: "staff#index"
99
- require "sidekiq/web"
100
- constraints ->(request) { StaffController.staff_request?(request) } do
101
- mount Sidekiq::Web => "staff/sidekiq"
102
- end
103
-
104
- #############################################
105
- # error pages -- these MUST be at the end! ##
106
- #############################################
107
-
108
- get "/500", to: "application#render500" if Rails.env.production? || Rails.env.staging?
109
-
110
- match "/", to: "application#not_found", via: :all
111
- match "/*unmatched_route", to: "application#not_found", via: :all
112
- ROUTES
113
-
114
- replace_in_file(
115
- "config/routes.rb",
116
- "# root \"articles#index\"",
117
- routes,
118
- )
119
- end
120
-
121
- def sidekiq
122
- copy_file("config/sidekiq.yml", "config/sidekiq.yml")
10
+ def config_application
11
+ directory("config", "config", force: true, exclude_pattern: /blank.rb/)
123
12
  end
124
13
 
125
14
  def credentials
@@ -1,78 +1,38 @@
1
1
  # typed: false
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative "base"
4
+ # require_relative "base"
5
5
 
6
6
  module Hephaestus
7
7
  class CoreGenerator < Generators::Base
8
- def controllers
9
- remove_file("app/controllers/application_controller.rb")
10
- copy_file("app/controllers/application_controller.rb", "app/controllers/application_controller.rb")
11
-
12
- copy_file("app/controllers/root_controller.rb", "app/controllers/root_controller.rb")
13
- copy_file("app/controllers/settings_controller.rb", "app/controllers/settings_controller.rb")
14
- copy_file("app/controllers/staff_controller.rb", "app/controllers/staff_controller.rb")
15
- copy_file("app/controllers/yetto_controller.rb", "app/controllers/yetto_controller.rb")
16
- copy_file("app/controllers/app_controller.rb", "app/controllers/#{short_app_name}_controller.rb")
17
-
18
- copy_file("app/controllers/concerns/authable.rb", "app/controllers/concerns/authable.rb")
19
- end
8
+ include Hephaestus::AppName
20
9
 
21
- def jobs
22
- copy_file("app/jobs/application_job.rb", "app/jobs/application_job.rb", force: true)
23
- copy_file("app/jobs/update_yetto_job.rb", "app/jobs/update_yetto_job.rb")
10
+ def gemfile
11
+ # we do this to specify the template source, otherwise the generator wants to use Rails own `controllers` dir
12
+ source = File.join(Hephaestus::Engine.root, "templates", "Gemfile")
13
+ copy_file(source, "Gemfile", force: true)
24
14
  end
25
15
 
26
- def libs
27
- copy_file("app/lib/body_parameter/yetto_parameters.rb", "app/lib/body_parameter/yetto_parameters.rb")
28
- copy_file("app/lib/constants/app.rb", "app/lib/constants/plug_#{short_app_name}.rb")
29
- copy_file("app/lib/headers/yetto.rb", "app/lib/headers/yetto.rb")
30
-
31
- path_parameters_content = <<~CONTENT
32
- # typed: false
33
- # frozen_string_literal: true
34
-
35
- module PathParameter
36
- module AppParameters
37
- extend T::Sig
38
- end
39
- end
40
- CONTENT
41
-
42
- create_file("app/lib/path_parameter/#{short_app_name}_parameters.rb", path_parameters_content)
43
-
44
- body_parameters_content = <<~CONTENT
45
- # typed: false
46
- # frozen_string_literal: true
47
-
48
- module BodyParameter
49
- module AppParameters
50
- extend T::Sig
51
- end
52
- end
53
- CONTENT
54
-
55
- create_file("app/lib/body_parameter/#{short_app_name}_parameters.rb", body_parameters_content)
56
-
57
- copy_file("app/lib/path_parameter/settings_parameters.rb", "app/lib/path_parameter/settings_parameters.rb")
58
- copy_file("app/lib/path_parameter/yetto_parameters.rb", "app/lib/path_parameter/yetto_parameters.rb")
59
- directory("app/lib/plug_app", "app/lib/#{app_name.underscore}")
60
-
61
- copy_file("app/lib/body_parameter.rb", "app/lib/body_parameter.rb")
62
- copy_file("app/lib/headers.rb", "app/lib/headers.rb")
63
- copy_file("app/lib/path_parameter.rb", "app/lib/path_parameter.rb")
16
+ def controllers
17
+ # we do this to specify the template source, otherwise the generator wants to use Rails own `controllers` dir
18
+ source = File.join(Hephaestus::Engine.root, "templates", "app", "controllers")
19
+ directory(source, "app/controllers", force: true)
64
20
  end
65
21
 
66
- def serializers
67
- copy_file("app/serializers/error_serializer.rb", "app/serializers/error_serializer.rb")
22
+ def jobs
23
+ # we do this to specify the template source, otherwise the generator wants to use Rails own `jobs` dir
24
+ source = File.join(Hephaestus::Engine.root, "templates", "app", "jobs")
25
+ directory(source, "app/jobs", force: true)
68
26
  end
69
27
 
70
28
  def services
71
- copy_file("app/services/yetto_service.rb", "app/services/yetto_service.rb")
29
+ source = File.join(Hephaestus::Engine.root, "templates", "app", "services")
30
+ directory(source, "app/services", force: true)
72
31
  end
73
32
 
74
33
  def views
75
- copy_file("app/views/settings/new.json.jbuilder", "app/views/settings/new.json.jbuilder")
34
+ source = File.join(Hephaestus::Engine.root, "templates", "app", "views")
35
+ directory(source, "app/views", force: true)
76
36
  end
77
37
  end
78
38
  end
@@ -0,0 +1,12 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "base"
5
+
6
+ module Hephaestus
7
+ class DbGenerator < Generators::Base
8
+ def database
9
+ directory("db", "db")
10
+ end
11
+ end
12
+ end
@@ -6,8 +6,7 @@ require_relative "base"
6
6
  module Hephaestus
7
7
  class DeploymentGenerator < Generators::Base
8
8
  def procfile
9
- copy_file("Procfile.dev", "Procfile.dev")
10
- copy_file("Procfile.debug", "Procfile.debug")
9
+ copy_file("Procfile", "Procfile")
11
10
  end
12
11
 
13
12
  def dotenv
@@ -16,15 +15,11 @@ module Hephaestus
16
15
  end
17
16
 
18
17
  def docker
19
- copy_file("compose.yml", "compose.yml")
20
18
  copy_file("Dockerfile", "Dockerfile")
21
- copy_file("bin/docker-entrypoint", "bin/docker-entrypoint")
22
19
  end
23
20
 
24
21
  def fly
25
22
  directory("vendor/fly", "vendor/fly")
26
- copy_file("Dockerfile", "Dockerfile")
27
- copy_file("bin/docker-entrypoint", "bin/docker-entrypoint")
28
23
  end
29
24
  end
30
25
  end
@@ -5,18 +5,8 @@ require_relative "base"
5
5
 
6
6
  module Hephaestus
7
7
  class LibGenerator < Generators::Base
8
- def lib_plug
9
- directory("lib/plug_app", "lib/#{app_name.underscore}")
10
- remove_file("lib/constants/plug-#{short_app_name}.rb")
11
- end
12
-
13
8
  def lib_tasks
14
9
  directory("lib/tasks", "lib/tasks")
15
10
  end
16
-
17
- def plug_schema
18
- copy_file("lib/plug_app/schemas/api/2023-03-06/paths/plug.json", "lib/#{app_name.underscore}/schemas/api/2023-03-06/paths/#{short_app_name.underscore}.json")
19
- remove_file("lib/#{app_name.underscore}/schemas/api/2023-03-06/paths/plug.json") # cleanup
20
- end
21
11
  end
22
12
  end
@@ -10,7 +10,10 @@ module Hephaestus
10
10
  end
11
11
 
12
12
  def generate_licenses
13
- run("script/licenses --update")
13
+ unless run("script/licenses --update", abort_on_failure: false)
14
+ say(set_color("Error generating licenses. When this is all over, run `script/licenses --update`.", :red))
15
+ sleep(3)
16
+ end
14
17
  end
15
18
  end
16
19
  end
@@ -6,7 +6,7 @@ require_relative "base"
6
6
  module Hephaestus
7
7
  class RubocopGenerator < Generators::Base
8
8
  def rubocop
9
- copy_file(".rubocop.yml", ".rubocop.yml")
9
+ copy_file(".rubocop.yml", ".rubocop.yml", force: true)
10
10
  end
11
11
 
12
12
  def lint
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Hephaestus
5
- VERSION = "0.8.11"
5
+ VERSION = "0.8.12"
6
6
  RAILS_VERSION = ">= 8.0"
7
7
  RUBY_VERSION = File
8
8
  .read("#{File.dirname(__FILE__)}/../../.ruby-version")
data/lib/hephaestus.rb CHANGED
@@ -16,6 +16,7 @@ require "hephaestus/exit_on_failure"
16
16
  require "hephaestus/generators/app_generator"
17
17
  require "hephaestus/generators/config_generator"
18
18
  require "hephaestus/generators/core_generator"
19
+ require "hephaestus/generators/db_generator"
19
20
  require "hephaestus/generators/deployment_generator"
20
21
  require "hephaestus/generators/lib_generator"
21
22
  require "hephaestus/generators/license_generator"
@@ -23,6 +24,7 @@ require "hephaestus/generators/rubocop_generator"
23
24
  require "hephaestus/generators/sorbet_generator"
24
25
 
25
26
  require "hephaestus/actions"
27
+ require "hephaestus/app_name"
26
28
  require "hephaestus/actions/strip_comments_action"
27
29
  require "hephaestus/app_builder"
28
30
 
data/templates/Dockerfile CHANGED
@@ -1,79 +1,11 @@
1
- # syntax = docker/dockerfile:1
1
+ # syntax = docker/dockerfile:1.11
2
2
 
3
- # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
4
- ARG RUBY_VERSION=3.3.0
5
- FROM ruby:$RUBY_VERSION-slim as base
3
+ ARG REGISTRY
6
4
 
7
- # The plug-app code lives here
8
- WORKDIR /plug-app
5
+ # Base Rails Image
6
+ FROM ${REGISTRY}yettoapp/base-rails:main AS builder
9
7
 
10
- # Set production environment
11
- ARG RAILS_ENV="production"
12
- ENV RAILS_ENV=${RAILS_ENV} \
13
- BUNDLE_WITHOUT="staging:development:test" \
14
- BUNDLE_DEPLOYMENT="1"
8
+ # App Plug Image
9
+ FROM ${REGISTRY}yettoapp/app-plug-ruby:main AS base
15
10
 
16
- # Update gems and bundler
17
- RUN gem update --system --no-document && \
18
- gem install -N bundler
19
-
20
-
21
- # Throw-away build stages to reduce size of final image
22
- FROM base as prebuild
23
-
24
- # Install packages needed to build gems
25
- RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
26
- --mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
27
- apt-get update -qq && \
28
- apt-get install --no-install-recommends -y build-essential curl git libpq-dev libvips pkg-config python-is-python3 ca-certificates iptables iproute2
29
-
30
-
31
- FROM prebuild as build
32
-
33
- # Install application gems
34
- COPY --link Gemfile Gemfile.lock .ruby-version ./
35
- RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
36
- bundle config set app_config .bundle && \
37
- bundle config set path /srv/vendor && \
38
- bundle install && \
39
- bundle exec bootsnap precompile --gemfile && \
40
- bundle clean && \
41
- mkdir -p vendor && \
42
- bundle config set path vendor && \
43
- cp -ar /srv/vendor .
44
-
45
- # Copy application code
46
- COPY --link . .
47
-
48
- # Precompile bootsnap code for faster boot times
49
- RUN bundle exec bootsnap precompile app/ lib/
50
-
51
- # Adjust binfiles to set current working directory
52
- RUN grep -l '#!/usr/bin/env ruby' /plug-app/bin/* | xargs sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)'
53
-
54
- # Final stage for app image
55
- FROM base
56
-
57
- # Install packages needed for deployment
58
- RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
59
- --mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
60
- apt-get update -qq && \
61
- apt-get install --no-install-recommends -y imagemagick libvips postgresql-client sudo git
62
-
63
- # Copy built artifacts: gems, application
64
- COPY --from=build /usr/local/bundle /usr/local/bundle
65
- COPY --from=build /plug-app /plug-app
66
-
67
- # Deployment options
68
- ENV RAILS_LOG_TO_STDOUT="1" \
69
- RAILS_SERVE_STATIC_FILES="true" \
70
- RUBY_YJIT_ENABLE="1" \
71
- LD_PRELOAD=${LD_PRELOAD_PATH} \
72
- MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true"
73
-
74
- # Entrypoint sets up the container.
75
- ENTRYPOINT ["/plug-app/bin/docker-entrypoint"]
76
-
77
- # Start the server by default, this can be overwritten at runtime
78
- EXPOSE 3000
79
- CMD ["./bin/rails", "server"]
11
+ USER app
data/templates/Gemfile ADDED
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) do |repo_name|
6
+ repo_name = "#{repo_name}/#{repo_name}" if repo_name.exclude?("/")
7
+ "https://github.com/#{repo_name}.git"
8
+ end
9
+
10
+ ruby File.read(".ruby-version").strip
11
+
12
+ gem "hephaestus", "~> 0.8"
13
+
14
+ # !!! TODO: put your platform's dependencies here !!!
15
+
16
+ # the one and only
17
+ gem "octokit", "~> 9.1"
18
+ gem "faraday-retry", "~> 2.2"
19
+
20
+ group :development, :test do
21
+ # better debug output with `ap`
22
+ gem "amazing_print"
23
+
24
+ # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
25
+ gem "debug", platforms: [:mri, :mingw, :x64_mingw], require: false
26
+
27
+ gem "faker", "~> 3.4"
28
+ gem "rubocop", require: false
29
+ gem "rubocop-standard", require: false
30
+ end
31
+
32
+ group :development do
33
+ gem "dotenv-rails"
34
+
35
+ gem "foreman", "~> 0.88"
36
+
37
+ gem "licensed", "~> 4.4"
38
+
39
+ gem "ruby-lsp", "~> 0.17", require: false
40
+
41
+ gem "spoom"
42
+ gem "sorbet"
43
+ gem "tapioca", require: false
44
+ end
45
+ gem "sorbet-runtime"
46
+
47
+ group :test do
48
+ gem "simplecov", "~> 0.18", require: false
49
+ gem "simplecov-console", "~> 0.7", require: false
50
+
51
+ # track down flakey tests
52
+ gem "minitest-bisect"
53
+
54
+ # mocking lib
55
+ gem "mocha"
56
+
57
+ # allow easier middleware testing
58
+ gem "rack-test", "~> 2.0"
59
+
60
+ # navigate website
61
+ gem "selenium-webdriver"
62
+
63
+ # jump around through time
64
+ gem "timecop", "~> 0.9"
65
+
66
+ # prevents real http requests
67
+ gem "webmock", "~> 3.23"
68
+ end
69
+
70
+ group :ci do
71
+ gem "brakeman", "~> 6.1"
72
+ gem "bundle-audit", "~> 0.1"
73
+ end
@@ -0,0 +1,2 @@
1
+ web: $SERVER_CMD # defined in script/server
2
+ supervisor: bin/jobs -c "$(bundle show hephaestus)/config/queue.yml"
@@ -0,0 +1,35 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ class <%= capital_plug_name %>Controller < ApplicationController
5
+ include Authable
6
+
7
+ include Constants
8
+
9
+ before_action :webhook_from_<%= plug_name %>?, only: [:webhook]
10
+ before_action :<%= plug_name %>_calling_back?, only: [:callback]
11
+
12
+ def webhook
13
+ body = request.body.read
14
+
15
+ payload = JSON.parse(body, symbolize_names: true)
16
+ # TODO: Get the event and action that triggered the webhook
17
+ #
18
+ # Then, queue up some work to be done in a background job
19
+
20
+ okay
21
+ end
22
+
23
+ def callback
24
+ code = params[:code]
25
+ state = params[:state]
26
+
27
+ state_obj = parse_state(state)
28
+ plug_installation_id = state_obj.fetch(:plug_installation_id, "")
29
+ redirect_to = state_obj.fetch(:redirect_to, "")
30
+
31
+ # TODO: Store access credentials you've been given back in Yetto
32
+
33
+ redirect_to(redirect_to, allow_other_host: true)
34
+ end
35
+ end
@@ -1,13 +1,7 @@
1
1
  # typed: false
2
2
  # frozen_string_literal: true
3
3
 
4
- class ApplicationController < ActionController::Base
5
- include ActionController::MimeResponds
6
-
7
- include Hephaestus::Responses
8
-
9
- rescue_from ActionController::UnknownFormat, with: :not_acceptable
10
-
4
+ class ApplicationController < Hephaestus::ApplicationController
11
5
  before_action :set_request_span_context
12
6
  def set_request_span_context
13
7
  end
@@ -0,0 +1,50 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Authable
5
+ extend T::Sig
6
+
7
+ include ActionDispatch::Http::Cache::Response
8
+
9
+ include ActionController::Helpers::ClassMethods
10
+ include ActionController::HttpAuthentication::Basic::ControllerMethods
11
+ include BodyParameter::YettoParameters
12
+
13
+ SHA256_DIGEST = OpenSSL::Digest.new("sha256")
14
+
15
+ sig { void }
16
+ def <%= plug_name %>_calling_back?
17
+ state = params.fetch(:state, "")
18
+ state = params.fetch(:state, "")
19
+
20
+ state_obj = parse_state(state)
21
+ nonce = state_obj.fetch(:nonce, "")
22
+
23
+ return true if ActiveSupport::SecurityUtils.secure_compare(nonce, <%= upcase_plug_name %>_APP_NONCE)
24
+
25
+ self.status = Hephaestus::HTTP::BAD_REQUEST_I
26
+ self.response_body = ::Hephaestus::ErrorSerializer.format(Hephaestus::HTTP::BAD_REQUEST)
27
+ end
28
+
29
+ sig { void }
30
+ def webhook_from_<%= plug_name %>?
31
+ # TODO: do whatever needs to be done to ensure that the webhook is coming from <%= plug_name %>
32
+
33
+ # github_header = request.headers[::Constants::GITHUB_HTTP_X_HUB_SIGNATURE_256_HEADER]
34
+
35
+ # if github_header.blank?
36
+ # self.status = Hephaestus::HTTP::NOT_FOUND_I
37
+ # self.response_body = ::Hephaestus::ErrorSerializer.format(Hephaestus::HTTP::NOT_FOUND)
38
+
39
+ # return false
40
+ # end
41
+
42
+ # body = request.body.read
43
+ # signature = "sha256=#{OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), GITHUB_SECRET_TOKEN, body)}"
44
+
45
+ # return true if Rack::Utils.secure_compare(signature, github_header)
46
+
47
+ # self.status = Hephaestus::HTTP::BAD_REQUEST_I
48
+ # self.response_body = ::Hephaestus::ErrorSerializer.format(Hephaestus::HTTP::BAD_REQUEST)
49
+ end
50
+ end
@@ -1,45 +1,22 @@
1
- # typed: strict
1
+ # typed: false
2
2
  # frozen_string_literal: true
3
3
 
4
4
  class SettingsController < ApplicationController
5
5
  extend T::Sig
6
6
 
7
- include PathParameter::SettingsParameters
8
-
9
7
  before_action :ensure_json_request
10
- sig { void }
11
- def ensure_json_request
12
- return if request.format.json?
13
-
14
- not_acceptable
15
- end
16
-
17
- sig { void }
18
- def new
19
- @step = T.let(params.fetch(:step, 1).to_i || 1, T.nilable(Integer))
20
- end
21
8
 
22
9
  sig { void }
23
10
  def edit
24
11
  @step = params.fetch(:step, 1).to_i || 1
25
12
 
26
- response = YettoService.get_plug_installation(pparam_plug_installation_id)
13
+ plug_installation_id = params[:plug_installation_id]
14
+ response = ::Hephaestus::YettoService.get_plug_installation(plug_installation_id)
27
15
 
28
16
  if response.unavailable?
29
- logger.error("Fetching Yetto inbox failed: `#{response}`")
30
-
31
- return not_acceptable
32
- end
17
+ logger.error("Fetching plug installation failed: `#{response}`")
33
18
 
34
- plug_installation = response.parsed_json_body
35
- access_token = plug_installation.fetch("credentials", {}).fetch("access_token", "")
36
-
37
- if access_token.blank?
38
- logger.error("Fetching Yetto access_token failed: `#{response}`")
39
-
40
- return not_acceptable
19
+ not_acceptable
41
20
  end
42
-
43
- not_found
44
21
  end
45
22
  end