apress-api 1.22.0

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.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/.drone.yml +30 -0
  3. data/.gitignore +15 -0
  4. data/.rspec +4 -0
  5. data/Appraisals +31 -0
  6. data/CHANGELOG.md +227 -0
  7. data/Gemfile +8 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +31 -0
  10. data/Rakefile +2 -0
  11. data/app/controllers/apress/api/deprecated_versions_controller.rb +15 -0
  12. data/app/controllers/apress/api/v1/callbacks_controller.rb +30 -0
  13. data/app/controllers/apress/api/v1/tokens_controller.rb +24 -0
  14. data/app/docs/schema/api/v1/types/apress/api/link.rb +29 -0
  15. data/app/docs/schema/api/v1/types/apress/api/links.rb +24 -0
  16. data/app/docs/swagger/v1/controllers/apress/api/tokens_controller.rb +64 -0
  17. data/app/docs/swagger/v1/default_responses/bad_request.rb +16 -0
  18. data/app/docs/swagger/v1/default_responses/not_found.rb +16 -0
  19. data/app/docs/swagger/v1/default_responses/unauthenticated.rb +16 -0
  20. data/app/docs/swagger/v1/default_responses/unauthorized.rb +16 -0
  21. data/app/docs/swagger/v1/default_responses/unprocessable.rb +16 -0
  22. data/app/docs/swagger/v1/default_responses/updates_locked.rb +13 -0
  23. data/app/docs/swagger/v1/models/apress/api/client.rb +53 -0
  24. data/app/docs/swagger/v1/models/apress/api/simple_error.rb +27 -0
  25. data/app/docs/swagger/v1/models/apress/api/unproccesable_error.rb +16 -0
  26. data/app/docs/swagger/v1/models/apress/api/unprocessable_error.rb +37 -0
  27. data/app/docs/swagger/v1/root.rb +28 -0
  28. data/app/interactors/apress/api/callbacks/base_callback.rb +42 -0
  29. data/app/interactors/apress/api/delayed_fire_callback.rb +25 -0
  30. data/app/jobs/apress/api/event_handler_enqueueing_job.rb +19 -0
  31. data/app/jobs/apress/api/fire_callback_job.rb +25 -0
  32. data/app/models/apress/api/client.rb +60 -0
  33. data/app/policies/apress/api/callback_policy.rb +15 -0
  34. data/app/services/apress/api/auth_service.rb +37 -0
  35. data/app/views/apress/api/shared/_exception.json.jbuilder +4 -0
  36. data/app/views/apress/api/shared/error.json.jbuilder +5 -0
  37. data/app/views/apress/api/shared/parameter_missing_errors.json.jbuilder +9 -0
  38. data/app/views/apress/api/shared/unprocessable_errors.json.jbuilder +9 -0
  39. data/app/views/apress/api/v1/clients/_client.json.jbuilder +2 -0
  40. data/app/views/apress/api/v1/tokens/create.json.jbuilder +4 -0
  41. data/apress-api.gemspec +46 -0
  42. data/config/routes.rb +17 -0
  43. data/db/migrate/20150716000000_create_api_clients.rb +38 -0
  44. data/dip.yml +48 -0
  45. data/docker-compose.development.yml +18 -0
  46. data/docker-compose.drone.yml +7 -0
  47. data/docker-compose.yml +20 -0
  48. data/lib/apress-api.rb +1 -0
  49. data/lib/apress/api.rb +25 -0
  50. data/lib/apress/api/api_controller/authentification.rb +33 -0
  51. data/lib/apress/api/api_controller/base.rb +63 -0
  52. data/lib/apress/api/api_controller/compatibility.rb +26 -0
  53. data/lib/apress/api/api_controller/pagination.rb +60 -0
  54. data/lib/apress/api/api_controller/pagination_helper.rb +55 -0
  55. data/lib/apress/api/api_controller/rescue.rb +89 -0
  56. data/lib/apress/api/api_controller/responds.rb +25 -0
  57. data/lib/apress/api/callbacks/config.rb +56 -0
  58. data/lib/apress/api/callbacks/fire_callback_error.rb +12 -0
  59. data/lib/apress/api/callbacks/integration.rb +28 -0
  60. data/lib/apress/api/callbacks/repeat_callback_error.rb +12 -0
  61. data/lib/apress/api/engine.rb +33 -0
  62. data/lib/apress/api/extensions/jbuilder/jbuilder_template.rb +41 -0
  63. data/lib/apress/api/rspec.rb +48 -0
  64. data/lib/apress/api/rspec/utils.rb +17 -0
  65. data/lib/apress/api/testing/json_matcher.rb +9 -0
  66. data/lib/apress/api/version.rb +5 -0
  67. data/lib/tasks/docs.rake +12 -0
  68. data/spec/controllers/api_controller/authentification_spec.rb +79 -0
  69. data/spec/controllers/api_controller/pagination_spec.rb +199 -0
  70. data/spec/controllers/api_controller/rescue_spec.rb +167 -0
  71. data/spec/controllers/deprecated_versions_controller_spec.rb +10 -0
  72. data/spec/controllers/v1/callbacks_controller_spec.rb +50 -0
  73. data/spec/controllers/v1/tokens_controller_spec.rb +53 -0
  74. data/spec/factories/client_factory.rb +4 -0
  75. data/spec/helpers/paginating_cache_spec.rb +72 -0
  76. data/spec/interactors/apress/api/delayed_fire_callback_spec.rb +43 -0
  77. data/spec/internal/app/integrations/error_client/fire_callback.rb +14 -0
  78. data/spec/internal/app/integrations/service_client/fire_callback.rb +7 -0
  79. data/spec/internal/app/jobs/handler_job.rb +5 -0
  80. data/spec/internal/app/jobs/second_handler_job.rb +5 -0
  81. data/spec/internal/app/models/dummy_model.rb +15 -0
  82. data/spec/internal/config/database.yml +5 -0
  83. data/spec/internal/config/environments/test.rb +5 -0
  84. data/spec/internal/config/initializers/api.rb +10 -0
  85. data/spec/internal/config/routes.rb +3 -0
  86. data/spec/internal/db/schema.rb +5 -0
  87. data/spec/internal/log/.gitignore +1 -0
  88. data/spec/jobs/apress/api/event_handler_equeueing_job_spec.rb +31 -0
  89. data/spec/jobs/apress/api/fire_callback_job_spec.rb +34 -0
  90. data/spec/lib/apress/api/callbacks/integration_spec.rb +24 -0
  91. data/spec/models/client_spec.rb +25 -0
  92. data/spec/services/auth_service_spec.rb +64 -0
  93. data/spec/spec_helper.rb +34 -0
  94. metadata +518 -0
@@ -0,0 +1,29 @@
1
+ module Schema
2
+ module Api
3
+ module V1
4
+ module Types
5
+ module Apress
6
+ module Api
7
+ class Link < ::Apress::Api::Swagger::Schema
8
+ swagger_schema name.to_sym do
9
+ key :required, [:href]
10
+ key :description, 'A representation of a link object'
11
+
12
+ property :href do
13
+ key :type, :string
14
+ key :description, 'A string containing the link’s URL'
15
+ key :example, 'https://www.example.com/api/v1/review_comments'
16
+ end
17
+
18
+ property :meta do
19
+ key :type, :object
20
+ key :description, 'A meta object containing non-standard meta-information about the link'
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ module Schema
2
+ module Api
3
+ module V1
4
+ module Types
5
+ module Apress
6
+ module Api
7
+ class Links < ::Apress::Api::Swagger::Schema
8
+ swagger_schema name.to_sym do
9
+ key :description, 'A representation of a links object (http://jsonapi.org/format/#document-links)'
10
+ key :type, :object
11
+ key :additionalProperties, {
12
+ oneOf: [
13
+ {'type': 'string'},
14
+ {'$ref' => '#/definitions/Schema::Api::V1::Types::Apress::Api::Link'}
15
+ ]
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,64 @@
1
+ module Swagger
2
+ module V1
3
+ module Controllers
4
+ module Apress
5
+ module Api
6
+ class TokensController < ::Apress::Api::Swagger::Schema
7
+ swagger_path '/clients/{access_id}/tokens' do
8
+ operation :post do
9
+ key :produces, ['application/json']
10
+
11
+ key :description, 'Refreshes token for client with given access_id'
12
+ key :operationId, 'refreshToken'
13
+ key :tags, ['clients']
14
+
15
+ parameter do
16
+ key :name, :access_id
17
+ key :in, :path
18
+ key :description, "client's access_id"
19
+ key :required, true
20
+ key :type, :string
21
+ end
22
+
23
+ parameter do
24
+ key :name, 'refresh_token'
25
+ key :in, :body
26
+ key :description, "Client's refresh token"
27
+ key :required, true
28
+ schema type: :object do
29
+ property :refresh_token do
30
+ key :type, :string
31
+ end
32
+ end
33
+ end
34
+
35
+ response 200 do
36
+ key :description, 'Success response'
37
+ schema type: 'object' do
38
+ property :client do
39
+ key :'$ref', :'Swagger::V1::Models::Apress::Api::Client'
40
+ end
41
+ end
42
+ end
43
+
44
+ response 400 do
45
+ key :description, 'refresh token not valid for current access_id'
46
+ schema do
47
+ key :'$ref', :'Swagger::V1::Models::Apress::Api::SimpleError'
48
+ end
49
+ end
50
+
51
+ response 403 do
52
+ key :description, 'refresh token is expired'
53
+ schema do
54
+ key :'$ref', :'Swagger::V1::Models::Apress::Api::SimpleError'
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,16 @@
1
+ module Swagger
2
+ module V1
3
+ module DefaultResponses
4
+ module BadRequest
5
+ def self.extended(base)
6
+ base.response 400 do
7
+ key :description, "Переданные параметры не могут быть обработаны"
8
+ schema do
9
+ key :'$ref', :'Swagger::V1::::Models::Apress::Api::UnprocessableError'
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Swagger
2
+ module V1
3
+ module DefaultResponses
4
+ module NotFound
5
+ def self.extended(base)
6
+ base.response 404 do
7
+ key :description, "Запрашиваемый ресурс не найден"
8
+ schema do
9
+ key :'$ref', :'Swagger::V1::::Models::Apress::Api::SimpleError'
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Swagger
2
+ module V1
3
+ module DefaultResponses
4
+ module Unauthenticated
5
+ def self.extended(base)
6
+ base.response 401 do
7
+ key :description, "Запрос не прошел аутентификацию (проблема с подписью запроса)"
8
+ schema do
9
+ key :'$ref', :'Swagger::V1::::Models::Apress::Api::SimpleError'
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Swagger
2
+ module V1
3
+ module DefaultResponses
4
+ module Unauthorized
5
+ def self.extended(base)
6
+ base.response 403 do
7
+ key :description, "Нет доступа к ресурсу"
8
+ schema do
9
+ key :'$ref', :'Swagger::V1::::Models::Apress::Api::SimpleError'
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Swagger
2
+ module V1
3
+ module DefaultResponses
4
+ module Unprocessable
5
+ def self.extended(base)
6
+ base.response 422 do
7
+ key :description, "Переданные параметры не валидны"
8
+ schema do
9
+ key :'$ref', :'Swagger::V1::::Models::Apress::Api::UnprocessableError'
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module Swagger
2
+ module V1
3
+ module DefaultResponses
4
+ module UpdatedLocked
5
+ def self.extended(base)
6
+ base.response 503 do
7
+ key :description, "Закрыто редактирование"
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,53 @@
1
+ module Swagger
2
+ module V1
3
+ module Models
4
+ module Apress
5
+ module Api
6
+ class Client < ::Apress::Documentation::Swagger::Schema
7
+ swagger_schema name.to_sym do
8
+ key :required, [
9
+ :id,
10
+ :access_id,
11
+ :secret_token_expire_at,
12
+ :secret_token,
13
+ :refresh_token_expire_at,
14
+ :refresh_token,
15
+ :user_agent,
16
+ :updated_at,
17
+ :created_at
18
+ ]
19
+
20
+ property :id do
21
+ key :type, :integer
22
+ key :format, :int64
23
+ end
24
+
25
+ {
26
+ access_id: '6760dc04-db3e-4c18-b7a3-5cd68718e869',
27
+ secret_token: 'fflnVd5JyQAlH4EICLEV/c49RQRj0MaINNKFAVsuxngfcQHzLw7L9uF7fnOm/mbn4SBs3ssCUjvjcTjb4nQ==',
28
+ refresh_token: 'kmwCUAQxg2YOCZg2ENLQ4t4hfH8DYKPb6e+6ZkSl1K/zOyAXflUeL9Ef/jL7rEMTfuu0QqbrMm8SNsEnww==',
29
+ secret_token_expire_at: Time.current,
30
+ refresh_token_expire_at: Time.current,
31
+ user_agent: nil
32
+ }.each do |k, v|
33
+ property k do
34
+ key :type, :string
35
+ key :example, v if v
36
+ end
37
+ end
38
+
39
+ [:created_at, :updated_at].each do |k|
40
+ property k do
41
+ key :type, :string
42
+ key :format, :date
43
+ end
44
+ end
45
+ end
46
+
47
+ ActiveSupport.run_load_hooks(:'swagger/models/v1/apress/api/client', self)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ module Swagger
2
+ module V1
3
+ module Models
4
+ module Apress
5
+ module Api
6
+ class SimpleError < ::Apress::Documentation::Swagger::Schema
7
+ swagger_schema name.to_sym do
8
+ keys = [
9
+ :status,
10
+ :message,
11
+ :backtrace
12
+ ]
13
+
14
+ key :required, keys
15
+
16
+ keys.each do |k|
17
+ property k do
18
+ key :type, :string
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'unprocessable_error'
2
+
3
+ module Swagger
4
+ module V1
5
+ module Models
6
+ module Apress
7
+ module Api
8
+ # Deprecated: Please use `UnprocessableError` instead
9
+ class UnproccesableError < ::Apress::Documentation::Swagger::Schema
10
+ include UnprocessableError::Schema
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,37 @@
1
+ module Swagger
2
+ module V1
3
+ module Models
4
+ module Apress
5
+ module Api
6
+ class UnprocessableError < ::Apress::Documentation::Swagger::Schema
7
+ module Schema
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ swagger_schema name.to_sym do
12
+ key :required, [:errors, :status]
13
+
14
+ property :status do
15
+ key :type, :string
16
+ end
17
+
18
+ property :errors do
19
+ key :type, :array
20
+ items do
21
+ key :type, :object
22
+ property :error do
23
+ key :type, :object
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ include Schema
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ module Swagger
2
+ module V1
3
+ class Root < ::Apress::Documentation::Swagger::Schema
4
+ swagger_root do
5
+ key :swagger, '2.0'
6
+ info do
7
+ key :version, '1.0.0'
8
+ key :title, 'Apress API'
9
+ key :description, 'Apress API'
10
+ key :termsOfService, 'None'
11
+ contact do
12
+ key :name, 'Abak-Press Team'
13
+ end
14
+ end
15
+
16
+ key :basePath, '/api/v1'
17
+ key :produces, ['application/json']
18
+
19
+ security_definition :APIAuth do
20
+ key :type, :apiKey
21
+ key :in, :header
22
+ key :name, 'Authorization'
23
+ key :description, 'Authentication by access_id token based on HMAC'
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,42 @@
1
+ module Apress
2
+ module Api
3
+ module Callbacks
4
+ class BaseCallback
5
+ include Interactor
6
+
7
+ def self.retry_exceptions
8
+ @retry_exceptions ||= Set.new
9
+ end
10
+
11
+ def self.repeat_exceptions
12
+ @repeat_exceptions ||= Set.new
13
+ end
14
+
15
+ def self.add_retry_exceptions(*errors)
16
+ retry_exceptions.merge(errors)
17
+ end
18
+
19
+ def self.add_repeat_exceptions(*errors)
20
+ repeat_exceptions.merge(errors)
21
+ retry_exceptions.merge(errors)
22
+ end
23
+
24
+ def self.inherited(other)
25
+ other.around do |interactor|
26
+ begin
27
+ interactor.call
28
+ rescue Exception => error
29
+ if self.class.repeat_exceptions.any? { |ex| ex === error }
30
+ raise Apress::Api::Callbacks::RepeatCallbackError.new(error.message, error.backtrace)
31
+ elsif self.class.retry_exceptions.any? { |ex| error.is_a?(Class) && ex >= error || ex === error }
32
+ raise Apress::Api::Callbacks::FireCallbackError.new(error.message, error.backtrace)
33
+ else
34
+ raise error
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,25 @@
1
+ module Apress
2
+ module Api
3
+ class DelayedFireCallback
4
+ include Interactor
5
+
6
+ delegate :event, :params, to: :context
7
+ def call
8
+ services = Apress::Api::Callbacks::Config.services(event)
9
+
10
+ return if services.blank?
11
+
12
+ ::Resque.redis.multi do
13
+ services.each do |service|
14
+ ::Resque.enqueue(
15
+ ::Apress::Api::FireCallbackJob,
16
+ service,
17
+ event,
18
+ params
19
+ )
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end