linked_rails 0.0.4.pre.g2c53724b3 → 0.0.4.pre.g72bb595fe
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 +4 -4
- data/app/controllers/linked_rails/bulk_controller.rb +34 -1
- data/app/models/linked_rails/form.rb +1 -0
- data/app/models/linked_rails/manifest.rb +24 -8
- data/app/models/linked_rails/menus/list.rb +1 -1
- data/app/models/linked_rails/ontology.rb +1 -0
- data/app/policies/linked_rails/form_policy.rb +13 -0
- data/app/policies/linked_rails/ontology_policy.rb +13 -0
- data/app/workers/linked_rails/invalidation_stream_worker.rb +16 -0
- data/lib/generators/linked_rails/install/templates/locales.yml +2 -0
- data/lib/linked_rails/controller/error_handling.rb +5 -0
- data/lib/linked_rails/errors/forbidden.rb +37 -0
- data/lib/linked_rails/errors.rb +3 -0
- data/lib/linked_rails/helpers/resource_helper.rb +7 -0
- data/lib/linked_rails/model/cacheable.rb +45 -0
- data/lib/linked_rails/model.rb +1 -0
- data/lib/linked_rails/policy.rb +4 -0
- data/lib/linked_rails/storage.rb +32 -0
- data/lib/linked_rails.rb +6 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7810fdc42df9533cc1828c33aec04953486145ee0c744607b01b5f514d67dcb0
|
4
|
+
data.tar.gz: 9056187a625becc1c3e4c234ae7b06b77e77f0d4d3bdcb5d6c24b1249e1e21a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d294b57b181d6995d88ee5967c61d9bd5c69a2a1e3dc6843848032c4f9ee36c7c762d2f163022e97cdd35219bc6d395392b0af9863ab7f0a4dcb924f5c4358ef
|
7
|
+
data.tar.gz: 880a18f47ab624f736ab12421c3ea8c6a4810f9602149d35efca16e5edb21e9563280bfbe9721acf0860a5c7a2602632a0f7056ca5cd7b207e9e4c7582da9f5c
|
@@ -21,8 +21,11 @@ module LinkedRails
|
|
21
21
|
return response_for_wrong_host(opts) if wrong_host?(opts[:iri])
|
22
22
|
|
23
23
|
include = opts[:include].to_s == 'true'
|
24
|
+
resource = LinkedRails.iri_mapper.resource_from_iri(request_path_to_url(opts[:iri]), user_context)
|
24
25
|
|
25
|
-
response_from_request(include, RDF::URI(opts[:iri]))
|
26
|
+
return response_from_request(include, RDF::URI(opts[:iri])) if resource.blank?
|
27
|
+
|
28
|
+
response_from_resource(include, opts[:iri], resource)
|
26
29
|
rescue StandardError => e
|
27
30
|
handle_resource_error(opts, e)
|
28
31
|
end
|
@@ -84,6 +87,13 @@ module LinkedRails
|
|
84
87
|
false
|
85
88
|
end
|
86
89
|
|
90
|
+
def resource_cache_control(cacheable, status, resource_policy)
|
91
|
+
return :private unless status == 200 && cacheable
|
92
|
+
return 'no-cache' unless resource_policy.try(:public_resource?)
|
93
|
+
|
94
|
+
:public
|
95
|
+
end
|
96
|
+
|
87
97
|
def resource_params(param)
|
88
98
|
params = param.permit(:include, :iri)
|
89
99
|
params[:iri] = URI(params[:iri])
|
@@ -131,6 +141,12 @@ module LinkedRails
|
|
131
141
|
}.merge(opts)
|
132
142
|
end
|
133
143
|
|
144
|
+
def resource_status(resource_policy)
|
145
|
+
raise(LinkedRails::Errors::Forbidden.new(query: :show?)) unless resource_policy.show?
|
146
|
+
|
147
|
+
200
|
148
|
+
end
|
149
|
+
|
134
150
|
def response_for_wrong_host(opts)
|
135
151
|
iri = opts[:iri]
|
136
152
|
term = term_from_vocab(iri)
|
@@ -139,6 +155,23 @@ module LinkedRails
|
|
139
155
|
ontology_term_response(iri, term, opts[:include])
|
140
156
|
end
|
141
157
|
|
158
|
+
def response_from_resource(include, iri, resource)
|
159
|
+
resource_policy = policy(resource)
|
160
|
+
status = resource_status(resource_policy)
|
161
|
+
|
162
|
+
resource_response(
|
163
|
+
iri,
|
164
|
+
body: response_from_resource_body(include, iri, resource, status),
|
165
|
+
cache: resource_cache_control(resource.try(:cacheable?), status, resource_policy),
|
166
|
+
language: I18n.locale,
|
167
|
+
status: status
|
168
|
+
)
|
169
|
+
end
|
170
|
+
|
171
|
+
def response_from_resource_body(include, _iri, resource, status)
|
172
|
+
include && status == 200 ? resource_body(resource) : nil
|
173
|
+
end
|
174
|
+
|
142
175
|
def term_from_vocab(iri)
|
143
176
|
vocab = Vocab.for(iri)
|
144
177
|
tag = iri.to_s.split(vocab.to_s).last
|
@@ -5,15 +5,11 @@ module LinkedRails
|
|
5
5
|
include ActiveModel::Model
|
6
6
|
include LinkedRails::Model
|
7
7
|
|
8
|
-
MANIFEST_KEY = 'cache:Manifest'
|
9
|
-
CACHE_DB = ENV.fetch('PERSISTENT_REDIS_DATABASE', '6')
|
10
|
-
|
11
8
|
def save
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
}
|
9
|
+
Storage.hset(
|
10
|
+
:persistent,
|
11
|
+
:manifest,
|
12
|
+
LinkedRails.iri.to_s => web_manifest.to_json
|
17
13
|
)
|
18
14
|
end
|
19
15
|
|
@@ -162,5 +158,25 @@ module LinkedRails
|
|
162
158
|
def tracking
|
163
159
|
[]
|
164
160
|
end
|
161
|
+
|
162
|
+
class << self
|
163
|
+
def destroy(iri)
|
164
|
+
Storage.hdel(:persistent, :manifest, iri)
|
165
|
+
end
|
166
|
+
|
167
|
+
def move(from, to)
|
168
|
+
Storage.hset(
|
169
|
+
:persistent,
|
170
|
+
:redirect_prefix,
|
171
|
+
from => to
|
172
|
+
)
|
173
|
+
|
174
|
+
data = Storage.hget(:persistent, :manifest, from)
|
175
|
+
|
176
|
+
Storage.hset(:persistent, :manifest, to, data) if data
|
177
|
+
|
178
|
+
destroy(from)
|
179
|
+
end
|
180
|
+
end
|
165
181
|
end
|
166
182
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LinkedRails
|
4
|
+
class InvalidationStreamWorker < ActiveJob::Base
|
5
|
+
def perform(type, iri, resource_type)
|
6
|
+
entry = {
|
7
|
+
type: type,
|
8
|
+
resource: iri,
|
9
|
+
resourceType: resource_type
|
10
|
+
}
|
11
|
+
id = Storage.xadd(:stream, LinkedRails.cache_stream, entry)
|
12
|
+
|
13
|
+
raise('No message id returned, implies failure') if id.blank?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -6,6 +6,10 @@ module LinkedRails
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
include ActiveSupport::Rescuable
|
8
8
|
|
9
|
+
included do
|
10
|
+
rescue_from LinkedRails::Errors::Forbidden, with: :handle_error
|
11
|
+
end
|
12
|
+
|
9
13
|
private
|
10
14
|
|
11
15
|
def add_error_snackbar(error)
|
@@ -69,6 +73,7 @@ module LinkedRails
|
|
69
73
|
'Doorkeeper::Errors::InvalidGrantReuse' => 422,
|
70
74
|
'LinkedRails::Auth::Errors::Expired' => 410,
|
71
75
|
'LinkedRails::Auth::Errors::Unauthorized' => 401,
|
76
|
+
'LinkedRails::Errors::Forbidden' => 403,
|
72
77
|
'Pundit::NotAuthorizedError' => 403
|
73
78
|
}
|
74
79
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LinkedRails
|
4
|
+
module Errors
|
5
|
+
class Forbidden < StandardError
|
6
|
+
attr_reader :query, :record, :policy, :action
|
7
|
+
|
8
|
+
# @param [Hash] options
|
9
|
+
# @option options [String] query The action of the request
|
10
|
+
# @option options [ActiveRecord::Base] record The record that was requested
|
11
|
+
# @option options [Policy] policy The policy that raised the exception
|
12
|
+
# @option options [String] message Override the default error message
|
13
|
+
# @return [String] the message
|
14
|
+
def initialize(**options)
|
15
|
+
@query = options.fetch(:query).to_s
|
16
|
+
@record = options[:record]
|
17
|
+
@policy = options[:policy]
|
18
|
+
@action = @query[-1] == '?' ? @query[0..-2] : @query
|
19
|
+
@message = options[:message]
|
20
|
+
|
21
|
+
raise StandardError if @query.blank? && @message.blank?
|
22
|
+
|
23
|
+
super(@message || default_message)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def default_message
|
29
|
+
I18n.t(
|
30
|
+
"pundit.#{@policy.class.to_s.underscore}.#{@query}",
|
31
|
+
action: @action,
|
32
|
+
default: I18n.t('errors.access_denied')
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -46,6 +46,13 @@ module LinkedRails
|
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
|
+
def request_path_to_url(path)
|
50
|
+
return path unless path.present? && URI(path).relative?
|
51
|
+
|
52
|
+
port = [80, 443].include?(request.port) ? nil : request.port
|
53
|
+
URI::Generic.new(request.scheme, nil, request.host, port, nil, path, nil, nil, nil).to_s
|
54
|
+
end
|
55
|
+
|
49
56
|
def build_new_resource
|
50
57
|
controller_class.build_new(user_context: user_context)
|
51
58
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LinkedRails
|
4
|
+
module Model
|
5
|
+
module Cacheable
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
if respond_to?(:after_commit)
|
10
|
+
after_commit :publish_create, on: :create, if: :should_publish_changes
|
11
|
+
after_commit :publish_update, on: :update, if: :should_publish_changes
|
12
|
+
after_commit :publish_delete, on: :destroy, if: :should_publish_changes
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def cacheable?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def publish_create
|
21
|
+
publish_message('io.ontola.transactions.Created')
|
22
|
+
end
|
23
|
+
|
24
|
+
def publish_update
|
25
|
+
publish_message('io.ontola.transactions.Updated')
|
26
|
+
end
|
27
|
+
|
28
|
+
def publish_delete
|
29
|
+
publish_message('io.ontola.transactions.Deleted')
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def publish_message(type)
|
35
|
+
LinkedRails::InvalidationStreamWorker.perform_now(type, iri.to_s, self.class.iri.to_s)
|
36
|
+
rescue StandardError
|
37
|
+
LinkedRails::InvalidationStreamWorker.perform_later(type, iri.to_s, self.class.iri.to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
def should_publish_changes
|
41
|
+
cacheable? && !Rails.env.test?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/linked_rails/model.rb
CHANGED
data/lib/linked_rails/policy.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'redis'
|
4
|
+
|
5
|
+
module LinkedRails
|
6
|
+
class Storage
|
7
|
+
REDIS_DB = {
|
8
|
+
cache: LinkedRails.cache_redis_database,
|
9
|
+
persistent: LinkedRails.persistent_redis_database,
|
10
|
+
stream: LinkedRails.stream_redis_database
|
11
|
+
}.freeze
|
12
|
+
KEYS = {
|
13
|
+
manifest: 'cache:Manifest',
|
14
|
+
redirect_exact: 'cache:Redirect:Exact',
|
15
|
+
redirect_prefix: 'cache:Redirect:Prefix'
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
class << self
|
19
|
+
%i[xadd].each do |method|
|
20
|
+
define_method(method) do |db, *args|
|
21
|
+
Redis.new(db: REDIS_DB.fetch(db)).send(method, *args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
%i[hset hdel hget].each do |method|
|
26
|
+
define_method(method) do |db, key, *args|
|
27
|
+
Redis.new(db: REDIS_DB.fetch(db)).send(method, KEYS.fetch(key), *args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/linked_rails.rb
CHANGED
@@ -22,6 +22,10 @@ module LinkedRails
|
|
22
22
|
|
23
23
|
mattr_accessor :whitelisted_spi_ips
|
24
24
|
mattr_writer :host, :scheme
|
25
|
+
mattr_accessor :persistent_redis_database, default: ENV['PERSISTENT_REDIS_DATABASE'].presence || 6
|
26
|
+
mattr_accessor :stream_redis_database, default: ENV['STREAM_REDIS_DATABASE'].presence || 7
|
27
|
+
mattr_accessor :cache_redis_database, default: ENV['CACHE_REDIS_DATABASE'].presence || 8
|
28
|
+
mattr_accessor :cache_stream, default: ENV['CACHE_STREAM'].presence || 'transactions'
|
25
29
|
|
26
30
|
def self.configurable_class(parent, klass, default: nil, reader: nil) # rubocop:disable Metrics/AbcSize
|
27
31
|
method = :"#{[parent, klass.to_s.downcase].compact.join('_')}_class"
|
@@ -84,6 +88,7 @@ ActiveSupport::Inflector.inflections do |inflect|
|
|
84
88
|
inflect.acronym 'SHACL'
|
85
89
|
end
|
86
90
|
|
91
|
+
require 'linked_rails/errors'
|
87
92
|
require 'linked_rails/uri_template'
|
88
93
|
require 'linked_rails/vocab'
|
89
94
|
require 'linked_rails/cache'
|
@@ -101,3 +106,4 @@ require 'linked_rails/routes'
|
|
101
106
|
require 'linked_rails/serializer'
|
102
107
|
require 'linked_rails/translate'
|
103
108
|
require 'linked_rails/railtie'
|
109
|
+
require 'linked_rails/storage'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: linked_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.4.pre.
|
4
|
+
version: 0.0.4.pre.g72bb595fe
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arthur Dingemans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_response
|
@@ -299,8 +299,10 @@ files:
|
|
299
299
|
- app/policies/linked_rails/collection/view_policy.rb
|
300
300
|
- app/policies/linked_rails/collection_policy.rb
|
301
301
|
- app/policies/linked_rails/enum_value_policy.rb
|
302
|
+
- app/policies/linked_rails/form_policy.rb
|
302
303
|
- app/policies/linked_rails/menus/item_policy.rb
|
303
304
|
- app/policies/linked_rails/menus/list_policy.rb
|
305
|
+
- app/policies/linked_rails/ontology_policy.rb
|
304
306
|
- app/policies/linked_rails/sequence_policy.rb
|
305
307
|
- app/serializers/linked_rails/actions/item_serializer.rb
|
306
308
|
- app/serializers/linked_rails/actions/object_serializer.rb
|
@@ -338,6 +340,7 @@ files:
|
|
338
340
|
- app/serializers/linked_rails/web_page_serializer.rb
|
339
341
|
- app/serializers/linked_rails/web_site_serializer.rb
|
340
342
|
- app/serializers/linked_rails/widget_serializer.rb
|
343
|
+
- app/workers/linked_rails/invalidation_stream_worker.rb
|
341
344
|
- config/initializers/inflections.rb
|
342
345
|
- lib/generators/linked_rails/install/install_generator.rb
|
343
346
|
- lib/generators/linked_rails/install/templates/README
|
@@ -387,6 +390,8 @@ files:
|
|
387
390
|
- lib/linked_rails/enhancements/destroyable/controller.rb
|
388
391
|
- lib/linked_rails/enhancements/updatable/controller.rb
|
389
392
|
- lib/linked_rails/enhancements/updatable/serializer.rb
|
393
|
+
- lib/linked_rails/errors.rb
|
394
|
+
- lib/linked_rails/errors/forbidden.rb
|
390
395
|
- lib/linked_rails/helpers/delta_helper.rb
|
391
396
|
- lib/linked_rails/helpers/ontola_actions_helper.rb
|
392
397
|
- lib/linked_rails/helpers/resource_helper.rb
|
@@ -395,6 +400,7 @@ files:
|
|
395
400
|
- lib/linked_rails/middleware/linked_data_params.rb
|
396
401
|
- lib/linked_rails/model.rb
|
397
402
|
- lib/linked_rails/model/actionable.rb
|
403
|
+
- lib/linked_rails/model/cacheable.rb
|
398
404
|
- lib/linked_rails/model/collections.rb
|
399
405
|
- lib/linked_rails/model/dirty.rb
|
400
406
|
- lib/linked_rails/model/enhancements.rb
|
@@ -418,6 +424,7 @@ files:
|
|
418
424
|
- lib/linked_rails/serializer/actionable.rb
|
419
425
|
- lib/linked_rails/serializer/menuable.rb
|
420
426
|
- lib/linked_rails/serializer/singularable.rb
|
427
|
+
- lib/linked_rails/storage.rb
|
421
428
|
- lib/linked_rails/test_methods.rb
|
422
429
|
- lib/linked_rails/translate.rb
|
423
430
|
- lib/linked_rails/types/iri_type.rb
|