apisonator 2.100.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +317 -0
- data/Gemfile +11 -0
- data/Gemfile.base +65 -0
- data/Gemfile.lock +319 -0
- data/Gemfile.on_prem +1 -0
- data/Gemfile.on_prem.lock +297 -0
- data/LICENSE +202 -0
- data/NOTICE +15 -0
- data/README.md +230 -0
- data/Rakefile +287 -0
- data/apisonator.gemspec +47 -0
- data/app/api/api.rb +13 -0
- data/app/api/internal/alert_limits.rb +32 -0
- data/app/api/internal/application_keys.rb +49 -0
- data/app/api/internal/application_referrer_filters.rb +43 -0
- data/app/api/internal/applications.rb +77 -0
- data/app/api/internal/errors.rb +54 -0
- data/app/api/internal/events.rb +42 -0
- data/app/api/internal/internal.rb +104 -0
- data/app/api/internal/metrics.rb +40 -0
- data/app/api/internal/service_tokens.rb +46 -0
- data/app/api/internal/services.rb +58 -0
- data/app/api/internal/stats.rb +42 -0
- data/app/api/internal/usagelimits.rb +62 -0
- data/app/api/internal/utilization.rb +23 -0
- data/bin/3scale_backend +223 -0
- data/bin/3scale_backend_worker +26 -0
- data/config.ru +4 -0
- data/config/puma.rb +192 -0
- data/config/schedule.rb +9 -0
- data/ext/mkrf_conf.rb +64 -0
- data/lib/3scale/backend.rb +67 -0
- data/lib/3scale/backend/alert_limit.rb +56 -0
- data/lib/3scale/backend/alerts.rb +137 -0
- data/lib/3scale/backend/analytics/kinesis.rb +3 -0
- data/lib/3scale/backend/analytics/kinesis/adapter.rb +180 -0
- data/lib/3scale/backend/analytics/kinesis/exporter.rb +86 -0
- data/lib/3scale/backend/analytics/kinesis/job.rb +135 -0
- data/lib/3scale/backend/analytics/redshift.rb +3 -0
- data/lib/3scale/backend/analytics/redshift/adapter.rb +367 -0
- data/lib/3scale/backend/analytics/redshift/importer.rb +83 -0
- data/lib/3scale/backend/analytics/redshift/job.rb +33 -0
- data/lib/3scale/backend/application.rb +330 -0
- data/lib/3scale/backend/application_events.rb +76 -0
- data/lib/3scale/backend/background_job.rb +65 -0
- data/lib/3scale/backend/configurable.rb +20 -0
- data/lib/3scale/backend/configuration.rb +151 -0
- data/lib/3scale/backend/configuration/loader.rb +42 -0
- data/lib/3scale/backend/constants.rb +19 -0
- data/lib/3scale/backend/cors.rb +84 -0
- data/lib/3scale/backend/distributed_lock.rb +67 -0
- data/lib/3scale/backend/environment.rb +21 -0
- data/lib/3scale/backend/error_storage.rb +52 -0
- data/lib/3scale/backend/errors.rb +343 -0
- data/lib/3scale/backend/event_storage.rb +120 -0
- data/lib/3scale/backend/experiment.rb +84 -0
- data/lib/3scale/backend/extensions.rb +5 -0
- data/lib/3scale/backend/extensions/array.rb +19 -0
- data/lib/3scale/backend/extensions/hash.rb +26 -0
- data/lib/3scale/backend/extensions/nil_class.rb +13 -0
- data/lib/3scale/backend/extensions/redis.rb +44 -0
- data/lib/3scale/backend/extensions/string.rb +13 -0
- data/lib/3scale/backend/extensions/time.rb +110 -0
- data/lib/3scale/backend/failed_jobs_scheduler.rb +141 -0
- data/lib/3scale/backend/job_fetcher.rb +122 -0
- data/lib/3scale/backend/listener.rb +728 -0
- data/lib/3scale/backend/listener_metrics.rb +99 -0
- data/lib/3scale/backend/logging.rb +48 -0
- data/lib/3scale/backend/logging/external.rb +44 -0
- data/lib/3scale/backend/logging/external/impl.rb +93 -0
- data/lib/3scale/backend/logging/external/impl/airbrake.rb +66 -0
- data/lib/3scale/backend/logging/external/impl/bugsnag.rb +69 -0
- data/lib/3scale/backend/logging/external/impl/default.rb +18 -0
- data/lib/3scale/backend/logging/external/resque.rb +57 -0
- data/lib/3scale/backend/logging/logger.rb +18 -0
- data/lib/3scale/backend/logging/middleware.rb +62 -0
- data/lib/3scale/backend/logging/middleware/json_writer.rb +21 -0
- data/lib/3scale/backend/logging/middleware/text_writer.rb +60 -0
- data/lib/3scale/backend/logging/middleware/writer.rb +143 -0
- data/lib/3scale/backend/logging/worker.rb +107 -0
- data/lib/3scale/backend/manifest.rb +80 -0
- data/lib/3scale/backend/memoizer.rb +277 -0
- data/lib/3scale/backend/metric.rb +275 -0
- data/lib/3scale/backend/metric/collection.rb +91 -0
- data/lib/3scale/backend/oauth.rb +4 -0
- data/lib/3scale/backend/oauth/token.rb +26 -0
- data/lib/3scale/backend/oauth/token_key.rb +30 -0
- data/lib/3scale/backend/oauth/token_storage.rb +313 -0
- data/lib/3scale/backend/oauth/token_value.rb +25 -0
- data/lib/3scale/backend/period.rb +3 -0
- data/lib/3scale/backend/period/boundary.rb +107 -0
- data/lib/3scale/backend/period/cache.rb +28 -0
- data/lib/3scale/backend/period/period.rb +402 -0
- data/lib/3scale/backend/queue_storage.rb +16 -0
- data/lib/3scale/backend/rack.rb +49 -0
- data/lib/3scale/backend/rack/exception_catcher.rb +136 -0
- data/lib/3scale/backend/rack/internal_error_catcher.rb +23 -0
- data/lib/3scale/backend/rack/prometheus.rb +19 -0
- data/lib/3scale/backend/saas.rb +6 -0
- data/lib/3scale/backend/saas_analytics.rb +4 -0
- data/lib/3scale/backend/server.rb +30 -0
- data/lib/3scale/backend/server/falcon.rb +52 -0
- data/lib/3scale/backend/server/puma.rb +71 -0
- data/lib/3scale/backend/service.rb +317 -0
- data/lib/3scale/backend/service_token.rb +97 -0
- data/lib/3scale/backend/stats.rb +8 -0
- data/lib/3scale/backend/stats/aggregator.rb +170 -0
- data/lib/3scale/backend/stats/aggregators/base.rb +72 -0
- data/lib/3scale/backend/stats/aggregators/response_code.rb +58 -0
- data/lib/3scale/backend/stats/aggregators/usage.rb +34 -0
- data/lib/3scale/backend/stats/bucket_reader.rb +135 -0
- data/lib/3scale/backend/stats/bucket_storage.rb +108 -0
- data/lib/3scale/backend/stats/cleaner.rb +195 -0
- data/lib/3scale/backend/stats/codes_commons.rb +14 -0
- data/lib/3scale/backend/stats/delete_job_def.rb +60 -0
- data/lib/3scale/backend/stats/key_generator.rb +73 -0
- data/lib/3scale/backend/stats/keys.rb +104 -0
- data/lib/3scale/backend/stats/partition_eraser_job.rb +58 -0
- data/lib/3scale/backend/stats/partition_generator_job.rb +46 -0
- data/lib/3scale/backend/stats/period_commons.rb +34 -0
- data/lib/3scale/backend/stats/stats_parser.rb +141 -0
- data/lib/3scale/backend/stats/storage.rb +113 -0
- data/lib/3scale/backend/statsd.rb +14 -0
- data/lib/3scale/backend/storable.rb +35 -0
- data/lib/3scale/backend/storage.rb +40 -0
- data/lib/3scale/backend/storage_async.rb +4 -0
- data/lib/3scale/backend/storage_async/async_redis.rb +21 -0
- data/lib/3scale/backend/storage_async/client.rb +205 -0
- data/lib/3scale/backend/storage_async/pipeline.rb +79 -0
- data/lib/3scale/backend/storage_async/resque_extensions.rb +30 -0
- data/lib/3scale/backend/storage_helpers.rb +278 -0
- data/lib/3scale/backend/storage_key_helpers.rb +9 -0
- data/lib/3scale/backend/storage_sync.rb +43 -0
- data/lib/3scale/backend/transaction.rb +62 -0
- data/lib/3scale/backend/transactor.rb +177 -0
- data/lib/3scale/backend/transactor/limit_headers.rb +54 -0
- data/lib/3scale/backend/transactor/notify_batcher.rb +139 -0
- data/lib/3scale/backend/transactor/notify_job.rb +47 -0
- data/lib/3scale/backend/transactor/process_job.rb +33 -0
- data/lib/3scale/backend/transactor/report_job.rb +84 -0
- data/lib/3scale/backend/transactor/status.rb +236 -0
- data/lib/3scale/backend/transactor/usage_report.rb +182 -0
- data/lib/3scale/backend/usage.rb +63 -0
- data/lib/3scale/backend/usage_limit.rb +115 -0
- data/lib/3scale/backend/use_cases/provider_key_change_use_case.rb +60 -0
- data/lib/3scale/backend/util.rb +17 -0
- data/lib/3scale/backend/validators.rb +26 -0
- data/lib/3scale/backend/validators/base.rb +36 -0
- data/lib/3scale/backend/validators/key.rb +17 -0
- data/lib/3scale/backend/validators/limits.rb +57 -0
- data/lib/3scale/backend/validators/oauth_key.rb +15 -0
- data/lib/3scale/backend/validators/oauth_setting.rb +15 -0
- data/lib/3scale/backend/validators/redirect_uri.rb +33 -0
- data/lib/3scale/backend/validators/referrer.rb +60 -0
- data/lib/3scale/backend/validators/service_state.rb +15 -0
- data/lib/3scale/backend/validators/state.rb +15 -0
- data/lib/3scale/backend/version.rb +5 -0
- data/lib/3scale/backend/views/oauth_access_tokens.builder +14 -0
- data/lib/3scale/backend/views/oauth_app_id_by_token.builder +4 -0
- data/lib/3scale/backend/worker.rb +87 -0
- data/lib/3scale/backend/worker_async.rb +88 -0
- data/lib/3scale/backend/worker_metrics.rb +44 -0
- data/lib/3scale/backend/worker_sync.rb +32 -0
- data/lib/3scale/bundler_shim.rb +17 -0
- data/lib/3scale/prometheus_server.rb +10 -0
- data/lib/3scale/tasks/connectivity.rake +41 -0
- data/lib/3scale/tasks/helpers.rb +3 -0
- data/lib/3scale/tasks/helpers/environment.rb +23 -0
- data/lib/3scale/tasks/stats.rake +131 -0
- data/lib/3scale/tasks/swagger.rake +46 -0
- data/licenses.xml +1215 -0
- metadata +227 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
class Usage
|
4
|
+
class << self
|
5
|
+
def application_usage(application, timestamp)
|
6
|
+
usage(application, timestamp) do |metric_id, instance_period|
|
7
|
+
Stats::Keys.application_usage_value_key(
|
8
|
+
application.service_id, application.id, metric_id, instance_period)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def is_set?(usage_str)
|
13
|
+
usage_str && usage_str[0] == '#'.freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_from(usage_str, current_value = 0)
|
17
|
+
if is_set? usage_str
|
18
|
+
usage_str[1..-1].to_i
|
19
|
+
else
|
20
|
+
# Note: this relies on the fact that NilClass#to_i returns 0
|
21
|
+
# and String#to_i returns 0 on non-numeric contents.
|
22
|
+
current_value + usage_str.to_i
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def usage(obj, timestamp)
|
29
|
+
# The timestamp does not change, so we can generate all the
|
30
|
+
# instantiated periods just once.
|
31
|
+
# This is important. Without this, the code can generate many instance
|
32
|
+
# periods and it ends up consuming a significant part of the total CPU
|
33
|
+
# time.
|
34
|
+
instance_periods = Period::instance_periods_for_ts(timestamp)
|
35
|
+
|
36
|
+
pairs = metric_period_pairs obj.usage_limits
|
37
|
+
return {} if pairs.empty?
|
38
|
+
|
39
|
+
keys = pairs.map do |(metric_id, period)|
|
40
|
+
yield metric_id, instance_periods[period]
|
41
|
+
end
|
42
|
+
|
43
|
+
values = {}
|
44
|
+
pairs.zip(storage.mget(keys)) do |(metric_id, period), value|
|
45
|
+
values[period] ||= {}
|
46
|
+
values[period][metric_id] = value.to_i
|
47
|
+
end
|
48
|
+
values
|
49
|
+
end
|
50
|
+
|
51
|
+
def metric_period_pairs(usage_limits)
|
52
|
+
usage_limits.map do |usage_limit|
|
53
|
+
[usage_limit.metric_id, usage_limit.period]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def storage
|
58
|
+
Storage.instance
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
class UsageLimit
|
4
|
+
include Storable
|
5
|
+
|
6
|
+
PERIODS = (Period::ALL_DESC - [Period::Second]).freeze
|
7
|
+
|
8
|
+
attr_accessor :service_id, :plan_id, :metric_id, :period, :value
|
9
|
+
|
10
|
+
def metric_name
|
11
|
+
Metric.load_name(service_id, metric_id)
|
12
|
+
end
|
13
|
+
|
14
|
+
# NOTE: validate can ONLY be called with the guarantee that usage_data
|
15
|
+
# will have a matching period key.
|
16
|
+
def validate(usage_data)
|
17
|
+
usage_data[period][metric_id].to_i <= value
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
include Memoizer::Decorator
|
22
|
+
|
23
|
+
def load_all(service_id, plan_id)
|
24
|
+
metric_ids = Metric.load_all_ids(service_id)
|
25
|
+
return metric_ids if metric_ids.empty?
|
26
|
+
|
27
|
+
results = []
|
28
|
+
with_pairs_and_values service_id, plan_id, metric_ids do |pair, value|
|
29
|
+
value and results << new(service_id: service_id,
|
30
|
+
plan_id: plan_id,
|
31
|
+
metric_id: pair[0],
|
32
|
+
period: pair[1],
|
33
|
+
value: value.to_i)
|
34
|
+
end
|
35
|
+
results
|
36
|
+
end
|
37
|
+
memoize :load_all
|
38
|
+
|
39
|
+
def load_value(service_id, plan_id, metric_id, period)
|
40
|
+
raw_value = storage.get(key(service_id, plan_id, metric_id, period))
|
41
|
+
raw_value and raw_value.to_i
|
42
|
+
end
|
43
|
+
|
44
|
+
def save(attributes)
|
45
|
+
service_id = attributes[:service_id]
|
46
|
+
plan_id = attributes[:plan_id]
|
47
|
+
prefix = key_prefix(service_id, plan_id, attributes[:metric_id])
|
48
|
+
storage.pipelined do
|
49
|
+
PERIODS.each do |period|
|
50
|
+
p_val = attributes[period.to_sym]
|
51
|
+
p_val and storage.set(key_for_period(prefix, period), p_val)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
clear_cache(service_id, plan_id)
|
55
|
+
end
|
56
|
+
|
57
|
+
def delete(service_id, plan_id, metric_id, period)
|
58
|
+
storage.del(key(service_id, plan_id, metric_id, period))
|
59
|
+
clear_cache(service_id, plan_id)
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def key(service_id, plan_id, metric_id, period)
|
65
|
+
key_for_period(key_prefix(service_id, plan_id, metric_id), period)
|
66
|
+
end
|
67
|
+
|
68
|
+
# NOTE: metric_id == nil is an accepted value
|
69
|
+
def key_prefix(service_id, plan_id, metric_id = :none)
|
70
|
+
"usage_limit/service_id:#{service_id}/plan_id:#{plan_id}/metric_id:" \
|
71
|
+
"#{"#{metric_id}/" if metric_id != :none}"
|
72
|
+
end
|
73
|
+
|
74
|
+
# receives a key prefix and a pair [metric_id, period]
|
75
|
+
def key_for_pair(key_pre, pair)
|
76
|
+
encode_key("#{key_pre}#{pair[0]}/#{pair[1]}")
|
77
|
+
end
|
78
|
+
|
79
|
+
def key_for_period(key_pre, period)
|
80
|
+
encode_key(key_pre + period.to_s)
|
81
|
+
end
|
82
|
+
|
83
|
+
# yields [pair(metric_id, period), value]
|
84
|
+
def with_pairs_and_values(service_id, plan_id, metric_ids, &blk)
|
85
|
+
pairs, values = get_pairs_and_values_for service_id, plan_id, metric_ids
|
86
|
+
pairs.zip values, &blk
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_pairs_and_values_for(service_id, plan_id, metric_ids)
|
90
|
+
pairs, keys = generate_pairs_and_keys_for service_id, plan_id, metric_ids
|
91
|
+
|
92
|
+
[pairs, storage.mget(keys)]
|
93
|
+
end
|
94
|
+
|
95
|
+
def generate_pairs_and_keys_for(service_id, plan_id, metric_ids)
|
96
|
+
pairs = []
|
97
|
+
keys = []
|
98
|
+
|
99
|
+
prefix = key_prefix service_id, plan_id
|
100
|
+
metric_ids.product PERIODS do |pair|
|
101
|
+
pairs << pair
|
102
|
+
keys << key_for_pair(prefix, pair)
|
103
|
+
end
|
104
|
+
|
105
|
+
[pairs, keys]
|
106
|
+
end
|
107
|
+
|
108
|
+
def clear_cache(service_id, plan_id)
|
109
|
+
Memoizer.clear(Memoizer.build_key(self, :load_all, service_id, plan_id))
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
class ProviderKeyChangeUseCase
|
4
|
+
|
5
|
+
def initialize(old_key, new_key)
|
6
|
+
@old_key = old_key
|
7
|
+
@new_key = new_key
|
8
|
+
|
9
|
+
validate_input
|
10
|
+
end
|
11
|
+
|
12
|
+
def process
|
13
|
+
default_service_id = Service.default_id(@old_key)
|
14
|
+
|
15
|
+
# Change the provider key on all the services and
|
16
|
+
# add all the services to the new provider
|
17
|
+
service_ids.each do |service_id|
|
18
|
+
storage.set Service.storage_key(service_id, :provider_key), @new_key
|
19
|
+
storage.sadd Service.storage_key_by_provider(@new_key, :ids), service_id
|
20
|
+
end
|
21
|
+
|
22
|
+
# Set the default service id to the new provider
|
23
|
+
storage.set Service.storage_key_by_provider(@new_key, :id), default_service_id
|
24
|
+
|
25
|
+
# Remove the old provider key and services associated to it
|
26
|
+
storage.del Service.storage_key_by_provider(@old_key, :id)
|
27
|
+
storage.del Service.storage_key_by_provider(@old_key, :ids)
|
28
|
+
|
29
|
+
clear_cache service_ids
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def service_ids
|
35
|
+
@service_ids ||= Service.list(@old_key)
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate_input
|
39
|
+
raise InvalidProviderKeys if [@old_key, @new_key].
|
40
|
+
any?{ |key| key.nil? || key.empty? } || @old_key == @new_key
|
41
|
+
|
42
|
+
raise ProviderKeyExists, @new_key if Service.list(@new_key).size != 0
|
43
|
+
|
44
|
+
raise ProviderKeyNotFound, @old_key if service_ids.size == 0
|
45
|
+
end
|
46
|
+
|
47
|
+
def storage
|
48
|
+
Service.storage
|
49
|
+
end
|
50
|
+
|
51
|
+
def clear_cache(service_ids)
|
52
|
+
service_ids.each do |service_id|
|
53
|
+
Service.clear_cache(@old_key, service_id)
|
54
|
+
Service.clear_cache(@new_key, service_id)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'etc'
|
3
|
+
|
4
|
+
module ThreeScale
|
5
|
+
module Backend
|
6
|
+
module Util
|
7
|
+
def self.number_of_cpus
|
8
|
+
Etc.nprocessors
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.root_dir
|
12
|
+
File.expand_path(File.join(Array.new(4, '..'.freeze)),
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require '3scale/backend/validators/base'
|
2
|
+
require '3scale/backend/validators/oauth_setting'
|
3
|
+
require '3scale/backend/validators/key'
|
4
|
+
require '3scale/backend/validators/oauth_key'
|
5
|
+
require '3scale/backend/validators/limits'
|
6
|
+
require '3scale/backend/validators/redirect_uri'
|
7
|
+
require '3scale/backend/validators/referrer'
|
8
|
+
require '3scale/backend/validators/state'
|
9
|
+
require '3scale/backend/validators/service_state'
|
10
|
+
|
11
|
+
module ThreeScale
|
12
|
+
module Backend
|
13
|
+
module Validators
|
14
|
+
COMMON_VALIDATORS = [Validators::Referrer,
|
15
|
+
Validators::State, # application state
|
16
|
+
Validators::ServiceState, # service state
|
17
|
+
Validators::Limits].freeze
|
18
|
+
|
19
|
+
VALIDATORS = ([Validators::Key] + COMMON_VALIDATORS).freeze
|
20
|
+
|
21
|
+
OAUTH_VALIDATORS = ([Validators::OauthSetting,
|
22
|
+
Validators::OauthKey,
|
23
|
+
Validators::RedirectURI] + COMMON_VALIDATORS).freeze
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module Validators
|
4
|
+
class Base
|
5
|
+
def self.apply(status, params)
|
6
|
+
new(status, params).apply
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(status, params)
|
10
|
+
@status = status
|
11
|
+
@params = params
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :status
|
15
|
+
attr_reader :params
|
16
|
+
|
17
|
+
def service
|
18
|
+
@service ||= Service.load_by_id!(status.service_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def application
|
22
|
+
status.application
|
23
|
+
end
|
24
|
+
|
25
|
+
def succeed!
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def fail!(error)
|
30
|
+
status.reject!(error)
|
31
|
+
false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module Validators
|
4
|
+
class Key < Base
|
5
|
+
def apply
|
6
|
+
if service.backend_version.to_i == 1 ||
|
7
|
+
application.has_no_keys? ||
|
8
|
+
application.has_key?(params[:app_key])
|
9
|
+
succeed!
|
10
|
+
else
|
11
|
+
fail!(ApplicationKeyInvalid.new(params[:app_key]))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module Validators
|
4
|
+
class Limits < Base
|
5
|
+
|
6
|
+
def apply
|
7
|
+
valid_limits? ? succeed! : fail!(LimitsExceeded.new)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def process(values, raw_usage)
|
13
|
+
if raw_usage
|
14
|
+
metrics = Metric.load_all(status.service_id)
|
15
|
+
usage = metrics.process_usage(raw_usage, status.flat_usage)
|
16
|
+
values = filter_metrics(values, usage.keys)
|
17
|
+
values = increment_or_set(values, usage)
|
18
|
+
end
|
19
|
+
|
20
|
+
values
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_limits?
|
24
|
+
processed_values = process(status.values, params[:usage])
|
25
|
+
status.application.usage_limits.all? do |limit|
|
26
|
+
limit.validate(processed_values)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def filter_metrics(values, metric_ids)
|
31
|
+
values.inject({}) do |memo, (period, usage)|
|
32
|
+
memo[period] = slice_hash(usage, metric_ids)
|
33
|
+
memo
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def increment_or_set(values, usage)
|
38
|
+
usage.inject(values) do |memo, (metric_id, value)|
|
39
|
+
memo.keys.each do |period|
|
40
|
+
memo[period][metric_id] = Usage.get_from value, memo[period][metric_id].to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
memo
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO: Move this to extensions/hash.rb
|
48
|
+
def slice_hash(hash, keys)
|
49
|
+
keys.inject({}) do |memo, key|
|
50
|
+
memo[key] = hash[key] if hash.has_key?(key)
|
51
|
+
memo
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module Validators
|
4
|
+
class OauthKey < Base
|
5
|
+
def apply
|
6
|
+
if params[:app_key].nil? || (!params[:app_key].empty? && application.has_key?(params[:app_key]))
|
7
|
+
succeed!
|
8
|
+
else
|
9
|
+
fail!(ApplicationKeyInvalid.new(params[:app_key]))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ThreeScale
|
2
|
+
module Backend
|
3
|
+
module Validators
|
4
|
+
class RedirectURI < Base
|
5
|
+
# This should've been named redirect_uri as per OAuth specs, but was
|
6
|
+
# initially named redirect_url. We check both fields, prioritizing the
|
7
|
+
# contents in the legacy redirect_url parameter over the "new"
|
8
|
+
# redirect_uri one.
|
9
|
+
REDIRECT_URL = 'redirect_url'.freeze
|
10
|
+
REDIRECT_URI = 'redirect_uri'.freeze
|
11
|
+
|
12
|
+
def apply
|
13
|
+
invalid_exception = RedirectURIInvalid
|
14
|
+
redirect_uri = if params.has_key? REDIRECT_URL
|
15
|
+
invalid_exception = RedirectURLInvalid
|
16
|
+
params[REDIRECT_URL]
|
17
|
+
elsif params.has_key? REDIRECT_URI
|
18
|
+
status.redirect_uri_field = REDIRECT_URI
|
19
|
+
params[REDIRECT_URI]
|
20
|
+
else
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
if redirect_uri.nil? || redirect_uri.empty? || application.redirect_url == redirect_uri
|
25
|
+
succeed!
|
26
|
+
else
|
27
|
+
fail!(invalid_exception.new redirect_uri)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|