care 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +0 -0
  4. data/.rubocop.yml +10 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +0 -0
  7. data/CODE_OF_CONDUCT.md +84 -0
  8. data/Gemfile +27 -0
  9. data/Gemfile.lock +206 -0
  10. data/README.md +40 -0
  11. data/Rakefile +12 -0
  12. data/bin/console +0 -0
  13. data/bin/setup +0 -0
  14. data/care.gemspec +49 -0
  15. data/exe/care +0 -0
  16. data/lib/care.rb +27 -0
  17. data/lib/care/auto_finder/by_ids.rb +24 -0
  18. data/lib/care/auto_finder/findable.rb +68 -0
  19. data/lib/care/auto_finder/finder_methods.rb +28 -0
  20. data/lib/care/auto_finder/paginateble.rb +30 -0
  21. data/lib/care/auto_finder/searchable.rb +56 -0
  22. data/lib/care/auto_finder/searcher.rb +101 -0
  23. data/lib/care/auto_finder/sortable.rb +41 -0
  24. data/lib/care/finder.rb +17 -0
  25. data/lib/care/jwt_service.rb +24 -0
  26. data/lib/care/rspec.rb +15 -0
  27. data/lib/care/seed.rb +21 -0
  28. data/lib/care/support/authorization_helper.rb +20 -0
  29. data/lib/care/support/error_collection.rb +43 -0
  30. data/lib/care/support/factory_bot.rb +5 -0
  31. data/lib/care/support/pagination.rb +9 -0
  32. data/lib/care/support/parameters.rb +39 -0
  33. data/lib/care/support/request_helper.rb +11 -0
  34. data/lib/care/version.rb +5 -0
  35. data/lib/generators/care/install/USAGE +19 -0
  36. data/lib/generators/care/install/install_generator.rb +33 -0
  37. data/lib/generators/care/install/templates/.env.local.example +62 -0
  38. data/lib/generators/care/install/templates/active_model_serializer.rb +1 -0
  39. data/lib/generators/care/install/templates/centrifuge.rb +4 -0
  40. data/lib/generators/care/install/templates/rswag-ui.rb +3 -0
  41. data/lib/generators/care/install/templates/rswag_api.rb +3 -0
  42. data/lib/generators/care/install/templates/swagger.yml +76 -0
  43. data/lib/generators/care/install/templates/swagger_helper.rb +24 -0
  44. data/lib/patch/action_controller/api.rb +17 -0
  45. data/lib/patch/action_controller/concerns/authentication.rb +50 -0
  46. data/lib/patch/action_controller/concerns/authorization.rb +46 -0
  47. data/lib/patch/action_controller/concerns/exception_handler.rb +67 -0
  48. data/lib/patch/action_controller/concerns/filter_sort_pagination.rb +98 -0
  49. metadata +321 -0
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Модуль с фунциями для авторизации
4
+ module Authorization
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include CanCan::ControllerAdditions
9
+ # before_action :authorize_profile!
10
+ cattr_accessor :authorized_permissions
11
+ attr_reader :actual_permission_ids,
12
+ :current_organization_id,
13
+ :current_account_id,
14
+ :permissions, :restrictions
15
+
16
+ check_authorization
17
+
18
+ def current_ability
19
+ @current_ability ||= Ability.new(permissions, restrictions, current_organization_id, current_account_id)
20
+ end
21
+
22
+ def current_account_id
23
+ access_token[:account][:id]
24
+ end
25
+
26
+ def current_organization_id
27
+ @current_organization_id ||= request.headers[:organization_id]
28
+ end
29
+
30
+ def permissions
31
+ @permissions ||= access_token[:permissions][current_organization_id]&.map(&:to_sym) || []
32
+ end
33
+
34
+ def restrictions
35
+ @restrictions ||= access_token[:permissions][current_organization_id]&.map(&:to_sym) || []
36
+ end
37
+
38
+ def include_permission?(permission)
39
+ permissions.include?(permission)
40
+ end
41
+
42
+ def include_restriction?(restriction)
43
+ restrictions.include?(restriction)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require 'jwt'
4
+ require "cancancan"
5
+ require "active_support/rescuable"
6
+
7
+ module ExceptionHandler
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ # Вернуть 400 - Bad Request, если параметры ошибочны
12
+ rescue_from ActiveRecord::StatementInvalid, ActionController::ParameterMissing do |e|
13
+ Rails.logger.error e.to_s
14
+ render json: { errors: [e.message] }, status: :bad_request
15
+ end
16
+
17
+ # Вернуть 401 - unauthorized, если учетная запись неавторизована
18
+ rescue_from Authentication::AuthenticationError, ::JWT::DecodeError do |e|
19
+ render json: { errors: [e.message] }, status: :unauthorized
20
+ end
21
+
22
+ # Вернуть 403 - Forbidden
23
+ rescue_from ::CanCan::AccessDenied do |_e|
24
+ render json: { errors: ["У вас нет прав доступа к этому ресурсу"] },
25
+ status: :forbidden
26
+ end
27
+
28
+ # Вернуть 404 - Not Found
29
+ rescue_from ProfileNotBindedError do |e|
30
+ render json: { errors: [e.message] }, status: :not_found
31
+ end
32
+
33
+ # Вернуть 404 - Not Found, если запись в БД отсутствует
34
+ rescue_from ActiveRecord::RecordNotFound do |_e|
35
+ render json: { errors: ["Запись не найдена"] }, status: :not_found
36
+ end
37
+
38
+ # Вернуть 422 - Unprocessable Entity, если при записе в БД произошли ошибки, либо не пройдена валидация
39
+ # в ответ возвращаем дополнительно структуру с описанием ошибок
40
+ rescue_from ActiveRecord::RecordInvalid do |e|
41
+ render json: { errors: [e.message], source: e.record.errors.as_json }, status: :unprocessable_entity
42
+ end
43
+ end
44
+
45
+ #
46
+ # Используется для сигнализации ошибки, что аккаунт не прикреплен ни к одному профилю
47
+ #
48
+ class ProfileNotBindedError < StandardError
49
+ attr_reader :param
50
+
51
+ def initialize(param)
52
+ @param = param
53
+ super("No active profile: #{param}")
54
+ end
55
+ end
56
+
57
+ #
58
+ # Используется для сигнализации ошибки, что нельзя отвязать аккаунт
59
+ #
60
+ class AccountUnbindDisallowedError < StandardError
61
+ attr_reader :param
62
+
63
+ def initialize
64
+ super("Невозможно отвязать аккаунт от профиля, если это единственный или активный профиль")
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Методы фильтрации сортировки и паджинации
4
+ # rubocop:disable Metrics/CyclomaticComplexity
5
+ # rubocop:disable Metrics/PerceivedComplexity
6
+ module FilterSortPagination
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ prepend_after_action :set_filter_headers
11
+
12
+ # Установить(добавить) информацию о пагинации в заголовок ответа
13
+ #
14
+ # @param [String, Symbol] collection_name имя переменной в которой хранится коллекция
15
+ # @param [Hash] options дополнительные параметры для колбека
16
+ def self.set_pagination_headers(collection_name, options = {})
17
+ after_action(options) do |_controller|
18
+ if params[:page].present?
19
+ collection = instance_variable_get("@#{collection_name}")
20
+
21
+ request_params = request.query_parameters
22
+ unless request_params.empty?
23
+ url_without_params = request.original_url.slice(0..(request.original_url.index("?") - 1))
24
+ end
25
+ url_without_params ||= request.original_url
26
+
27
+ page = {}
28
+ if collection.total_pages > 1 && !collection.first_page?
29
+ page[:first] = 1
30
+ end
31
+ if collection.total_pages > 1 && !collection.last_page?
32
+ page[:last] = collection.total_pages
33
+ end
34
+ page[:next] = collection.current_page + 1 unless collection.last_page?
35
+ unless collection.first_page?
36
+ page[:prev] = collection.current_page - 1
37
+ end
38
+
39
+ pagination_links = []
40
+ page.each do |k, v|
41
+ new_request_hash = request_params.merge(page: v)
42
+ pagination_links << "<#{url_without_params}?#{new_request_hash.to_param}>; rel=\"#{k}\""
43
+ end
44
+
45
+ headers["Link"] = pagination_links.join(", ")
46
+ headers["X-Pagination-Count"] = collection.total_count
47
+ headers["X-Pagination-Page"] = collection.current_page
48
+ headers["X-Pagination-Limit"] = collection.limit_value
49
+
50
+ # TODO : удалить после того как UI переделают под новый формат заголовка
51
+ #
52
+ headers["X-Pagination"] = {
53
+ limit: collection.limit_value,
54
+ total_pages: collection.total_pages,
55
+ prev_page: collection.prev_page,
56
+ current_page: collection.current_page,
57
+ next_page: collection.next_page,
58
+ first_page: collection.first_page?,
59
+ last_page: collection.last_page?,
60
+ out_of_range: collection.out_of_range?,
61
+ }.to_json
62
+ end
63
+ end
64
+ end
65
+
66
+ # Optional query parameters
67
+ #
68
+ # - limit ограничение количества записей в выборке
69
+ # (пример: ?limit=5)
70
+ #
71
+ # - page номер страницы(по умолчанию 15 записей на одну страницу)
72
+ # (пример: ?page=1)
73
+ #
74
+ # - sort сортировка, указывается поле и порядок сортировки
75
+ # (пример: ?sort=created_asc)
76
+ #
77
+ # - search поиск по совпадению с частью вводимого значения
78
+ # (пример: ?search=wat_name_part)
79
+ #
80
+ # - name поиск по совпадению с частью вводимого значения(search alias)
81
+ # (пример: ?name=wat_name_part)
82
+ #
83
+ def filter_params
84
+ params.permit(:page, :limit, :sort, :search, :name).to_h
85
+ end
86
+
87
+ def set_filter_headers
88
+ if filter_params[:search].present?
89
+ headers["X-Search"] = filter_params[:search]
90
+ end
91
+ if filter_params[:sort].present?
92
+ headers["X-Sort"] = filter_params[:sort]
93
+ end
94
+ end
95
+ end
96
+ end
97
+ # rubocop:enable Metrics/CyclomaticComplexity
98
+ # rubocop:enable Metrics/PerceivedComplexity
metadata ADDED
@@ -0,0 +1,321 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: care
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Валерий Маханов
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-11-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jwt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord-import
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: active_model_serializers
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.10.10
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.10.10
55
+ - !ruby/object:Gem::Dependency
56
+ name: centrifuge
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: prometheus-client
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: cancancan
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: kaminari
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: faker
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec-rails
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: shoulda-matchers
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: factory_bot_rails
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '5.1'
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 5.1.1
163
+ type: :runtime
164
+ prerelease: false
165
+ version_requirements: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - "~>"
168
+ - !ruby/object:Gem::Version
169
+ version: '5.1'
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: 5.1.1
173
+ - !ruby/object:Gem::Dependency
174
+ name: dotenv-rails
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :runtime
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ - !ruby/object:Gem::Dependency
188
+ name: database_cleaner-active_record
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ type: :runtime
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ - !ruby/object:Gem::Dependency
202
+ name: bundler
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - "~>"
206
+ - !ruby/object:Gem::Version
207
+ version: '2.0'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - "~>"
213
+ - !ruby/object:Gem::Version
214
+ version: '2.0'
215
+ - !ruby/object:Gem::Dependency
216
+ name: rake
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - "~>"
220
+ - !ruby/object:Gem::Version
221
+ version: '10.0'
222
+ type: :development
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - "~>"
227
+ - !ruby/object:Gem::Version
228
+ version: '10.0'
229
+ - !ruby/object:Gem::Dependency
230
+ name: rspec
231
+ requirement: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - "~>"
234
+ - !ruby/object:Gem::Version
235
+ version: '3.0'
236
+ type: :development
237
+ prerelease: false
238
+ version_requirements: !ruby/object:Gem::Requirement
239
+ requirements:
240
+ - - "~>"
241
+ - !ruby/object:Gem::Version
242
+ version: '3.0'
243
+ description: Common concerns for docshell microservices
244
+ email:
245
+ - v.mahanov@isoit.ru
246
+ executables:
247
+ - care
248
+ extensions: []
249
+ extra_rdoc_files: []
250
+ files:
251
+ - ".gitignore"
252
+ - ".rspec"
253
+ - ".rubocop.yml"
254
+ - ".ruby-gemset"
255
+ - ".ruby-version"
256
+ - CODE_OF_CONDUCT.md
257
+ - Gemfile
258
+ - Gemfile.lock
259
+ - README.md
260
+ - Rakefile
261
+ - bin/console
262
+ - bin/setup
263
+ - care.gemspec
264
+ - exe/care
265
+ - lib/care.rb
266
+ - lib/care/auto_finder/by_ids.rb
267
+ - lib/care/auto_finder/findable.rb
268
+ - lib/care/auto_finder/finder_methods.rb
269
+ - lib/care/auto_finder/paginateble.rb
270
+ - lib/care/auto_finder/searchable.rb
271
+ - lib/care/auto_finder/searcher.rb
272
+ - lib/care/auto_finder/sortable.rb
273
+ - lib/care/finder.rb
274
+ - lib/care/jwt_service.rb
275
+ - lib/care/rspec.rb
276
+ - lib/care/seed.rb
277
+ - lib/care/support/authorization_helper.rb
278
+ - lib/care/support/error_collection.rb
279
+ - lib/care/support/factory_bot.rb
280
+ - lib/care/support/pagination.rb
281
+ - lib/care/support/parameters.rb
282
+ - lib/care/support/request_helper.rb
283
+ - lib/care/version.rb
284
+ - lib/generators/care/install/USAGE
285
+ - lib/generators/care/install/install_generator.rb
286
+ - lib/generators/care/install/templates/.env.local.example
287
+ - lib/generators/care/install/templates/active_model_serializer.rb
288
+ - lib/generators/care/install/templates/centrifuge.rb
289
+ - lib/generators/care/install/templates/rswag-ui.rb
290
+ - lib/generators/care/install/templates/rswag_api.rb
291
+ - lib/generators/care/install/templates/swagger.yml
292
+ - lib/generators/care/install/templates/swagger_helper.rb
293
+ - lib/patch/action_controller/api.rb
294
+ - lib/patch/action_controller/concerns/authentication.rb
295
+ - lib/patch/action_controller/concerns/authorization.rb
296
+ - lib/patch/action_controller/concerns/exception_handler.rb
297
+ - lib/patch/action_controller/concerns/filter_sort_pagination.rb
298
+ homepage: https://gitlab.isoit.ru/ruby/sgrc/care
299
+ licenses: []
300
+ metadata:
301
+ homepage_uri: https://gitlab.isoit.ru/ruby/sgrc/care
302
+ post_install_message:
303
+ rdoc_options: []
304
+ require_paths:
305
+ - lib
306
+ required_ruby_version: !ruby/object:Gem::Requirement
307
+ requirements:
308
+ - - ">="
309
+ - !ruby/object:Gem::Version
310
+ version: 2.7.0
311
+ required_rubygems_version: !ruby/object:Gem::Requirement
312
+ requirements:
313
+ - - ">="
314
+ - !ruby/object:Gem::Version
315
+ version: '0'
316
+ requirements: []
317
+ rubygems_version: 3.1.2
318
+ signing_key:
319
+ specification_version: 4
320
+ summary: Care
321
+ test_files: []