openshift-origin-console 1.3.2
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.
- data/COPYRIGHT +1 -0
- data/Gemfile +21 -0
- data/LICENSE +203 -0
- data/README.md +123 -0
- data/Rakefile +44 -0
- data/app/assets/images/cartridge-edge.gif +0 -0
- data/app/assets/images/console/arrow-down.png +0 -0
- data/app/assets/images/console/console-sprite.png +0 -0
- data/app/assets/images/favicon-32.png +0 -0
- data/app/assets/images/loader-dark.gif +0 -0
- data/app/assets/images/loader.gif +0 -0
- data/app/assets/images/sprite-vert.png +0 -0
- data/app/assets/javascripts/console.js +10 -0
- data/app/assets/javascripts/console/form.js.coffee +51 -0
- data/app/assets/stylesheets/_alerts.scss +84 -0
- data/app/assets/stylesheets/_breadcrumbs.scss +31 -0
- data/app/assets/stylesheets/_buttons.scss +229 -0
- data/app/assets/stylesheets/_code.scss +86 -0
- data/app/assets/stylesheets/_custom.scss +207 -0
- data/app/assets/stylesheets/_footer.scss +54 -0
- data/app/assets/stylesheets/_forms.scss +710 -0
- data/app/assets/stylesheets/_grid.scss +28 -0
- data/app/assets/stylesheets/_input-prepend-append.scss +138 -0
- data/app/assets/stylesheets/_labels.scss +40 -0
- data/app/assets/stylesheets/_mixins.scss +76 -0
- data/app/assets/stylesheets/_override-variables.scss +1 -0
- data/app/assets/stylesheets/_responsive.scss +438 -0
- data/app/assets/stylesheets/_ribbon.scss +57 -0
- data/app/assets/stylesheets/_type.scss +306 -0
- data/app/assets/stylesheets/_utilities.scss +10 -0
- data/app/assets/stylesheets/_variables.scss +131 -0
- data/app/assets/stylesheets/common.css.scss +82 -0
- data/app/assets/stylesheets/console/_application.scss +194 -0
- data/app/assets/stylesheets/console/_base.scss +26 -0
- data/app/assets/stylesheets/console/_breadcrumbs.scss +32 -0
- data/app/assets/stylesheets/console/_buttons.scss +214 -0
- data/app/assets/stylesheets/console/_core.scss +1002 -0
- data/app/assets/stylesheets/console/_dropdowns.scss +63 -0
- data/app/assets/stylesheets/console/_help.scss +54 -0
- data/app/assets/stylesheets/console/_mixins.scss +11 -0
- data/app/assets/stylesheets/console/_navbar.scss +415 -0
- data/app/assets/stylesheets/console/_ribbon.scss +82 -0
- data/app/assets/stylesheets/console/_tile.scss +122 -0
- data/app/assets/stylesheets/origin.css.scss +37 -0
- data/app/controllers/account/dashboard.rb +13 -0
- data/app/controllers/account_controller.rb +3 -0
- data/app/controllers/application_types_controller.rb +80 -0
- data/app/controllers/applications_controller.rb +183 -0
- data/app/controllers/building_controller.rb +81 -0
- data/app/controllers/capability_aware.rb +18 -0
- data/app/controllers/cartridge_types_controller.rb +53 -0
- data/app/controllers/cartridges_controller.rb +43 -0
- data/app/controllers/console/auth/basic.rb +65 -0
- data/app/controllers/console/auth/none.rb +5 -0
- data/app/controllers/console/auth/remote_user.rb +69 -0
- data/app/controllers/console/rescue.rb +48 -0
- data/app/controllers/console_controller.rb +19 -0
- data/app/controllers/console_index_controller.rb +14 -0
- data/app/controllers/domain_aware.rb +26 -0
- data/app/controllers/domain_session_sweeper.rb +29 -0
- data/app/controllers/domains_controller.rb +30 -0
- data/app/controllers/keys_controller.rb +43 -0
- data/app/controllers/scaling_controller.rb +46 -0
- data/app/controllers/sshkey_aware.rb +23 -0
- data/app/controllers/sshkey_session_sweeper.rb +29 -0
- data/app/controllers/user_session_sweeper.rb +29 -0
- data/app/helpers/console/community_helper.rb +78 -0
- data/app/helpers/console/console_helper.rb +26 -0
- data/app/helpers/console/help_helper.rb +270 -0
- data/app/helpers/console/html5_boilerplate_helper.rb +63 -0
- data/app/helpers/console/layout_helper.rb +277 -0
- data/app/helpers/console/model_helper.rb +106 -0
- data/app/helpers/console/secured_helper.rb +5 -0
- data/app/models/alias.rb +10 -0
- data/app/models/application.rb +148 -0
- data/app/models/application_associations.rb +36 -0
- data/app/models/application_template.rb +90 -0
- data/app/models/application_type.rb +258 -0
- data/app/models/async_aware.rb +60 -0
- data/app/models/capabilities.rb +62 -0
- data/app/models/cartridge.rb +122 -0
- data/app/models/cartridge_type.rb +140 -0
- data/app/models/domain.rb +44 -0
- data/app/models/domain_associations.rb +33 -0
- data/app/models/embedded.rb +11 -0
- data/app/models/gear.rb +13 -0
- data/app/models/gear_group.rb +104 -0
- data/app/models/key.rb +87 -0
- data/app/models/quickstart.rb +135 -0
- data/app/models/rest_api.rb +130 -0
- data/app/models/rest_api/base.rb +781 -0
- data/app/models/rest_api/cacheable.rb +91 -0
- data/app/models/rest_api/environment.rb +13 -0
- data/app/models/rest_api/info.rb +34 -0
- data/app/models/rest_api/log_subscriber.rb +29 -0
- data/app/models/rest_api/railties/controller_runtime.rb +37 -0
- data/app/models/user.rb +27 -0
- data/app/models/user_associations.rb +6 -0
- data/app/views/account/_domain.html.haml +14 -0
- data/app/views/account/_keys.html.haml +20 -0
- data/app/views/account/_user.html.haml +5 -0
- data/app/views/account/show.html.haml +15 -0
- data/app/views/application_templates/_application_template.html.haml +5 -0
- data/app/views/application_types/_application_type.html.haml +19 -0
- data/app/views/application_types/_custom.html.haml +19 -0
- data/app/views/application_types/_persisted.html.haml +26 -0
- data/app/views/application_types/_tile.html.haml +9 -0
- data/app/views/application_types/index.html.haml +87 -0
- data/app/views/application_types/search.html.haml +67 -0
- data/app/views/application_types/show.html.haml +219 -0
- data/app/views/applications/_application.html.haml +34 -0
- data/app/views/applications/_applications_filter.html.haml +8 -0
- data/app/views/applications/_footer.html.haml +0 -0
- data/app/views/applications/_name.html.haml +28 -0
- data/app/views/applications/delete.html.haml +19 -0
- data/app/views/applications/get_started.html.haml +145 -0
- data/app/views/applications/index.html.haml +55 -0
- data/app/views/applications/show.html.haml +193 -0
- data/app/views/building/delete.html.haml +22 -0
- data/app/views/building/new.html.haml +57 -0
- data/app/views/building/show.html.haml +12 -0
- data/app/views/cartridge_types/_cartridge_type.html.haml +61 -0
- data/app/views/cartridge_types/index.html.haml +37 -0
- data/app/views/cartridge_types/show.html.haml +21 -0
- data/app/views/cartridges/next_steps.html.haml +58 -0
- data/app/views/cartridges/show.html.haml +1 -0
- data/app/views/console/error.html.haml +58 -0
- data/app/views/console/help.html.haml +90 -0
- data/app/views/console/not_found.html.haml +69 -0
- data/app/views/console/unauthorized.html.haml +7 -0
- data/app/views/domains/_domain.html.haml +14 -0
- data/app/views/domains/_form.html.haml +13 -0
- data/app/views/domains/edit.html.haml +5 -0
- data/app/views/domains/new.html.haml +6 -0
- data/app/views/keys/_form.html.haml +14 -0
- data/app/views/keys/_simple_form.html.haml +14 -0
- data/app/views/keys/new.html.haml +2 -0
- data/app/views/layouts/_footer.html.haml +38 -0
- data/app/views/layouts/_head.html.haml +35 -0
- data/app/views/layouts/console.html.haml +60 -0
- data/app/views/layouts/console/_header.html.haml +44 -0
- data/app/views/layouts/console/_identity.html.haml +7 -0
- data/app/views/layouts/console/_javascripts.html.haml +5 -0
- data/app/views/layouts/console/_stylesheets.html.haml +6 -0
- data/app/views/scaling/delete.html.haml +17 -0
- data/app/views/scaling/new.html.haml +24 -0
- data/app/views/scaling/show.html.haml +81 -0
- data/app/views/shared/_tracking.html.haml +0 -0
- data/conf/console.conf.example +108 -0
- data/conf/openshift_console.conf +10 -0
- data/config/cartridge_types.yml +54 -0
- data/config/initializers/barista_config.rb +86 -0
- data/config/initializers/cartridge_types.rb +5 -0
- data/config/initializers/console_security.rb +1 -0
- data/config/initializers/date_helper.rb +5 -0
- data/config/initializers/extended_logger.rb +51 -0
- data/config/initializers/formtastic.rb +100 -0
- data/config/initializers/inflections.rb +38 -0
- data/config/initializers/rdiscount.rb +8 -0
- data/config/initializers/rest_api.rb +22 -0
- data/config/initializers/sass.rb +30 -0
- data/config/initializers/session_trace.rb +32 -0
- data/config/initializers/x_frame_options.rb +53 -0
- data/config/locales/en.yml +12 -0
- data/lib/active_resource/associations.rb +107 -0
- data/lib/active_resource/associations/builder/association.rb +35 -0
- data/lib/active_resource/associations/builder/belongs_to.rb +5 -0
- data/lib/active_resource/associations/builder/has_many.rb +5 -0
- data/lib/active_resource/associations/builder/has_one.rb +5 -0
- data/lib/active_resource/persistent_connection.rb +341 -0
- data/lib/active_resource/persistent_http_mock.rb +68 -0
- data/lib/active_resource/reflection.rb +78 -0
- data/lib/console.rb +8 -0
- data/lib/console/config_file.rb +13 -0
- data/lib/console/configuration.rb +163 -0
- data/lib/console/engine.rb +28 -0
- data/lib/console/formtastic/bootstrap_form_builder.rb +369 -0
- data/lib/console/rails/app_redirector.rb +40 -0
- data/lib/console/rails/filter_hash.rb +15 -0
- data/lib/console/rails/routes.rb +51 -0
- data/lib/console/version.rb +5 -0
- data/lib/tasks/assets.rake +79 -0
- data/lib/tasks/stats.rake +18 -0
- data/lib/tasks/test_suites.rake +73 -0
- data/test/coverage_helper.rb +27 -0
- data/test/fixtures/cartridges.json +1 -0
- data/test/fixtures/quickstarts.csv +3 -0
- data/test/functional/account_controller_test.rb +14 -0
- data/test/functional/application_types_controller_test.rb +251 -0
- data/test/functional/applications_controller_sanity_test.rb +26 -0
- data/test/functional/applications_controller_test.rb +365 -0
- data/test/functional/building_controller_test.rb +203 -0
- data/test/functional/cartridge_types_controller_isolation_test.rb +68 -0
- data/test/functional/cartridge_types_controller_test.rb +48 -0
- data/test/functional/cartridges_controller_test.rb +83 -0
- data/test/functional/console_auth_basic_controller_test.rb +82 -0
- data/test/functional/console_auth_remote_user_controller_test.rb +90 -0
- data/test/functional/console_index_controller_test.rb +22 -0
- data/test/functional/domains_controller_test.rb +194 -0
- data/test/functional/keys_controller_test.rb +163 -0
- data/test/functional/quickstarts.json +18 -0
- data/test/functional/scaling_controller_test.rb +153 -0
- data/test/integration/assets_test.rb +34 -0
- data/test/integration/help_link_test.rb +43 -0
- data/test/integration/quickstarts_test.rb +24 -0
- data/test/integration/rescue_from_test.rb +25 -0
- data/test/integration/rest_api/application_test.rb +115 -0
- data/test/integration/rest_api/cartridge_test.rb +44 -0
- data/test/integration/rest_api/cartridge_type_test.rb +143 -0
- data/test/integration/rest_api/domain_test.rb +91 -0
- data/test/integration/rest_api/info_test.rb +9 -0
- data/test/integration/rest_api/key_test.rb +85 -0
- data/test/integration/static_pages_test.rb +44 -0
- data/test/rails_app/Rakefile +7 -0
- data/test/rails_app/app/controllers/application_controller.rb +5 -0
- data/test/rails_app/config.ru +4 -0
- data/test/rails_app/config/application.rb +48 -0
- data/test/rails_app/config/boot.rb +10 -0
- data/test/rails_app/config/database.yml +25 -0
- data/test/rails_app/config/environment.rb +5 -0
- data/test/rails_app/config/environments/development.rb +38 -0
- data/test/rails_app/config/environments/production.rb +70 -0
- data/test/rails_app/config/environments/test.rb +43 -0
- data/test/rails_app/config/initializers/auth.rb +0 -0
- data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_app/config/initializers/inflections.rb +10 -0
- data/test/rails_app/config/initializers/mime_types.rb +5 -0
- data/test/rails_app/config/initializers/secret_token.rb +7 -0
- data/test/rails_app/config/initializers/session_store.rb +8 -0
- data/test/rails_app/config/locales/en.yml +5 -0
- data/test/rails_app/config/routes.rb +4 -0
- data/test/rails_app/script/rails +6 -0
- data/test/support/auth.rb +111 -0
- data/test/support/base.rb +142 -0
- data/test/support/errors.rb +28 -0
- data/test/support/rest_api.rb +189 -0
- data/test/test_helper.rb +14 -0
- data/test/unit/active_model_compliance_test.rb +23 -0
- data/test/unit/async_aware_test.rb +55 -0
- data/test/unit/configuration_test.rb +158 -0
- data/test/unit/filter_hash_test.rb +64 -0
- data/test/unit/helpers/model_helper_test.rb +61 -0
- data/test/unit/overrides_test.rb +9 -0
- data/test/unit/rest_api_test.rb +1590 -0
- data/vendor/assets/javascripts/MIT-LICENSE.txt +20 -0
- data/vendor/assets/javascripts/bootstrap-collapse.js +157 -0
- data/vendor/assets/javascripts/bootstrap-dropdown.js +100 -0
- data/vendor/assets/javascripts/bootstrap-tab.js +135 -0
- data/vendor/assets/javascripts/bootstrap-transition.js +61 -0
- data/vendor/assets/javascripts/jquery.spin.js +47 -0
- data/vendor/assets/javascripts/jquery.ui.widget.js +16 -0
- data/vendor/assets/javascripts/jquery_cookie.js +41 -0
- data/vendor/assets/javascripts/jquery_validate_min.js +51 -0
- data/vendor/assets/javascripts/modernizr.min.js +2 -0
- data/vendor/assets/javascripts/plugins.js +16 -0
- data/vendor/assets/stylesheets/bootstrap/_accordion.scss +28 -0
- data/vendor/assets/stylesheets/bootstrap/_alerts.scss +70 -0
- data/vendor/assets/stylesheets/bootstrap/_breadcrumbs.scss +22 -0
- data/vendor/assets/stylesheets/bootstrap/_button-groups.scss +147 -0
- data/vendor/assets/stylesheets/bootstrap/_buttons.scss +183 -0
- data/vendor/assets/stylesheets/bootstrap/_carousel.scss +121 -0
- data/vendor/assets/stylesheets/bootstrap/_close.scss +18 -0
- data/vendor/assets/stylesheets/bootstrap/_code.scss +57 -0
- data/vendor/assets/stylesheets/bootstrap/_component-animations.scss +18 -0
- data/vendor/assets/stylesheets/bootstrap/_dropdowns.scss +130 -0
- data/vendor/assets/stylesheets/bootstrap/_forms.scss +522 -0
- data/vendor/assets/stylesheets/bootstrap/_grid.scss +8 -0
- data/vendor/assets/stylesheets/bootstrap/_hero-unit.scss +20 -0
- data/vendor/assets/stylesheets/bootstrap/_labels.scss +32 -0
- data/vendor/assets/stylesheets/bootstrap/_layouts.scss +17 -0
- data/vendor/assets/stylesheets/bootstrap/_mixins.scss +602 -0
- data/vendor/assets/stylesheets/bootstrap/_modals.scss +84 -0
- data/vendor/assets/stylesheets/bootstrap/_navbar.scss +299 -0
- data/vendor/assets/stylesheets/bootstrap/_navs.scss +353 -0
- data/vendor/assets/stylesheets/bootstrap/_pager.scss +30 -0
- data/vendor/assets/stylesheets/bootstrap/_pagination.scss +55 -0
- data/vendor/assets/stylesheets/bootstrap/_popovers.scss +49 -0
- data/vendor/assets/stylesheets/bootstrap/_progress-bars.scss +95 -0
- data/vendor/assets/stylesheets/bootstrap/_reset.scss +126 -0
- data/vendor/assets/stylesheets/bootstrap/_scaffolding.scss +33 -0
- data/vendor/assets/stylesheets/bootstrap/_sprites.scss +158 -0
- data/vendor/assets/stylesheets/bootstrap/_tables.scss +150 -0
- data/vendor/assets/stylesheets/bootstrap/_thumbnails.scss +35 -0
- data/vendor/assets/stylesheets/bootstrap/_tooltip.scss +35 -0
- data/vendor/assets/stylesheets/bootstrap/_type.scss +218 -0
- data/vendor/assets/stylesheets/bootstrap/_utilities.scss +23 -0
- data/vendor/assets/stylesheets/bootstrap/_variables.scss +107 -0
- data/vendor/assets/stylesheets/bootstrap/_wells.scss +17 -0
- data/vendor/assets/stylesheets/bootstrap/bootstrap.scss +66 -0
- data/vendor/assets/stylesheets/bootstrap/responsive.scss +334 -0
- metadata +506 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Reproduced from https://github.com/rails/rails/pull/230/files for Association support
|
|
3
|
+
#
|
|
4
|
+
module ActiveResource::Associations::Builder
|
|
5
|
+
class Association #:nodoc:
|
|
6
|
+
|
|
7
|
+
# providing a Class-Variable, which will have a differend store of subclasses
|
|
8
|
+
class_attribute :valid_options
|
|
9
|
+
self.valid_options = [:class_name]
|
|
10
|
+
|
|
11
|
+
# would identify subclasses of association
|
|
12
|
+
class_attribute :macro
|
|
13
|
+
|
|
14
|
+
attr_reader :model, :name, :options, :klass
|
|
15
|
+
|
|
16
|
+
def self.build(model, name, options)
|
|
17
|
+
new(model, name, options).build
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(model, name, options)
|
|
21
|
+
@model, @name, @options = model, name, options
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def build
|
|
25
|
+
validate_options
|
|
26
|
+
reflection = model.create_reflection(self.class.macro, name, options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def validate_options
|
|
32
|
+
options.assert_valid_keys(self.class.valid_options)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
require 'active_support/core_ext/benchmark'
|
|
2
|
+
require 'net/https'
|
|
3
|
+
require 'date'
|
|
4
|
+
require 'time'
|
|
5
|
+
require 'uri'
|
|
6
|
+
require 'net/http/persistent'
|
|
7
|
+
|
|
8
|
+
# Derived from ActiveResource::Connection
|
|
9
|
+
module ActiveResource
|
|
10
|
+
# Class to handle connections to remote web services.
|
|
11
|
+
# This class is used by ActiveResource::Base to interface with REST
|
|
12
|
+
# services.
|
|
13
|
+
class PersistentConnection
|
|
14
|
+
|
|
15
|
+
HTTP_FORMAT_HEADER_NAMES = { :get => 'Accept',
|
|
16
|
+
:put => 'Content-Type',
|
|
17
|
+
:post => 'Content-Type',
|
|
18
|
+
:patch => 'Content-Type',
|
|
19
|
+
:delete => 'Accept',
|
|
20
|
+
:head => 'Accept'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
class ServerRefusedConnection < Errno::ECONNREFUSED
|
|
24
|
+
def initialize(site,path=nil)
|
|
25
|
+
@site, @path = site, path
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def message
|
|
29
|
+
"Connection refused to #{@site}#{@path}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
attr_reader :site, :user, :password, :auth_type, :timeout, :proxy, :ssl_options, :connection_name
|
|
34
|
+
attr_accessor :format
|
|
35
|
+
|
|
36
|
+
class << self
|
|
37
|
+
def requests
|
|
38
|
+
@@requests ||= []
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Override to change the Persistent slot
|
|
43
|
+
def connection_name
|
|
44
|
+
@connection_name || 'active_resource'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# The +site+ parameter is required and will set the +site+
|
|
48
|
+
# attribute to the URI for the remote resource service.
|
|
49
|
+
def initialize(site, format = ActiveResource::Formats::XmlFormat)
|
|
50
|
+
raise ArgumentError, 'Missing site URI' unless site
|
|
51
|
+
@user = @password = nil
|
|
52
|
+
@uri_parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI
|
|
53
|
+
self.site = site
|
|
54
|
+
self.format = format
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Set URI for remote service.
|
|
58
|
+
def site=(site)
|
|
59
|
+
@site = site.is_a?(URI) ? site : @uri_parser.parse(site)
|
|
60
|
+
@user = @uri_parser.unescape(@site.user) if @site.user
|
|
61
|
+
@password = @uri_parser.unescape(@site.password) if @site.password
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Set the proxy for remote service.
|
|
65
|
+
def proxy=(proxy)
|
|
66
|
+
@proxy = proxy.is_a?(URI) ? proxy : @uri_parser.parse(proxy)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Sets the user for remote service.
|
|
70
|
+
def user=(user)
|
|
71
|
+
@user = user
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Sets the password for remote service.
|
|
75
|
+
def password=(password)
|
|
76
|
+
@password = password
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Sets the auth type for remote service.
|
|
80
|
+
def auth_type=(auth_type)
|
|
81
|
+
@auth_type = legitimize_auth_type(auth_type)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Sets the debug output stream for HTTP requests
|
|
85
|
+
def debug_output=(debug_output)
|
|
86
|
+
@debug_output = debug_output
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
[:idle_timeout, :read_timeout, :open_timeout, :timeout].each do |sym|
|
|
90
|
+
define_method :"#{sym}=" do |value|
|
|
91
|
+
instance_variable_set(:"@#{sym}", value)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Hash of options applied to Net::HTTP instance when +site+ protocol is 'https'.
|
|
96
|
+
def ssl_options=(opts={})
|
|
97
|
+
@ssl_options = opts
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Name for this group of requests, passed to Net::HTTP::Persistent
|
|
101
|
+
def connection_name=(name)
|
|
102
|
+
@connection_name = name
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Executes a GET request.
|
|
106
|
+
# Used to get (find) resources.
|
|
107
|
+
# Note; removed format.decode wrapper and .get method call
|
|
108
|
+
def get(path, headers = {})
|
|
109
|
+
with_auth { request(:get, path, build_request_headers(headers, :get, self.site.merge(path))) }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Executes a DELETE request (see HTTP protocol documentation if unfamiliar).
|
|
113
|
+
# Used to delete resources.
|
|
114
|
+
def delete(path, headers = {})
|
|
115
|
+
with_auth { request(:delete, path, build_request_headers(headers, :delete, self.site.merge(path))) }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Executes a PUT request (see HTTP protocol documentation if unfamiliar).
|
|
119
|
+
# Used to update resources.
|
|
120
|
+
def put(path, body = '', headers = {})
|
|
121
|
+
with_auth { request(:put, path, body.to_s, build_request_headers(headers, :put, self.site.merge(path))) }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Executes a POST request.
|
|
125
|
+
# Used to create new resources.
|
|
126
|
+
def post(path, body = '', headers = {})
|
|
127
|
+
with_auth { request(:post, path, body.to_s, build_request_headers(headers, :post, self.site.merge(path))) }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Executes a PATCH request.
|
|
131
|
+
# Used to create new resources.
|
|
132
|
+
def patch(path, body = '', headers = {})
|
|
133
|
+
with_auth { request(:patch, path, body.to_s, build_request_headers(headers, :patch, self.site.merge(path))) }
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Executes a HEAD request.
|
|
137
|
+
# Used to obtain meta-information about resources, such as whether they exist and their size (via response headers).
|
|
138
|
+
def head(path, headers = {})
|
|
139
|
+
with_auth { request(:head, path, build_request_headers(headers, :head, self.site.merge(path))) }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
private
|
|
143
|
+
# Makes a request to the remote service.
|
|
144
|
+
def request(method, path, *arguments)
|
|
145
|
+
req = case method
|
|
146
|
+
when :get
|
|
147
|
+
req = Net::HTTP::Get.new path, arguments[0]
|
|
148
|
+
when :head
|
|
149
|
+
req = Net::HTTP::Head.new path, arguments[0]
|
|
150
|
+
when :delete
|
|
151
|
+
req = Net::HTTP::Delete.new path, arguments[0]
|
|
152
|
+
when :put
|
|
153
|
+
req = Net::HTTP::Put.new path, arguments[1]
|
|
154
|
+
req.body = arguments[0]
|
|
155
|
+
req
|
|
156
|
+
when :patch
|
|
157
|
+
req = Net::HTTP::Patch.new path, arguments[1]
|
|
158
|
+
req.body = arguments[0]
|
|
159
|
+
req
|
|
160
|
+
when :post
|
|
161
|
+
req = Net::HTTP::Post.new path, arguments[1]
|
|
162
|
+
req.body = arguments[0]
|
|
163
|
+
req
|
|
164
|
+
else
|
|
165
|
+
raise StandardError, "Method not recognized #{method}"
|
|
166
|
+
end
|
|
167
|
+
result = ActiveSupport::Notifications.instrument("request.active_resource") do |payload|
|
|
168
|
+
payload[:method] = method
|
|
169
|
+
payload[:request_uri] = "#{site.scheme}://#{site.host}:#{site.port}#{path}"
|
|
170
|
+
payload[:result] = http.request site, req
|
|
171
|
+
end
|
|
172
|
+
handle_response(result)
|
|
173
|
+
rescue Timeout::Error => e
|
|
174
|
+
raise TimeoutError.new(e.message)
|
|
175
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
176
|
+
raise SSLError.new(e.message)
|
|
177
|
+
rescue Net::HTTP::Persistent::Error => e
|
|
178
|
+
raise ConnectionError.new(e.message)
|
|
179
|
+
rescue Errno::ECONNREFUSED => e
|
|
180
|
+
raise ServerRefusedConnection.new(site, req.path)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Handles response and error codes from the remote service.
|
|
184
|
+
def handle_response(response)
|
|
185
|
+
case response.code.to_i
|
|
186
|
+
when 301,302
|
|
187
|
+
raise(Redirection.new(response))
|
|
188
|
+
when 200...400
|
|
189
|
+
response
|
|
190
|
+
when 400
|
|
191
|
+
raise(BadRequest.new(response))
|
|
192
|
+
when 401
|
|
193
|
+
raise(UnauthorizedAccess.new(response))
|
|
194
|
+
when 403
|
|
195
|
+
raise(ForbiddenAccess.new(response))
|
|
196
|
+
when 404
|
|
197
|
+
raise(ResourceNotFound.new(response))
|
|
198
|
+
when 405
|
|
199
|
+
raise(MethodNotAllowed.new(response))
|
|
200
|
+
when 409
|
|
201
|
+
raise(ResourceConflict.new(response))
|
|
202
|
+
when 410
|
|
203
|
+
raise(ResourceGone.new(response))
|
|
204
|
+
when 422
|
|
205
|
+
raise(ResourceInvalid.new(response))
|
|
206
|
+
when 401...500
|
|
207
|
+
raise(ClientError.new(response))
|
|
208
|
+
when 500...600
|
|
209
|
+
raise(ServerError.new(response))
|
|
210
|
+
else
|
|
211
|
+
raise(ConnectionError.new(response, "Unknown response code: #{response.code}"))
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Get or create Net::HTTP::Persistent instance for communication with the
|
|
216
|
+
# remote service and resources.
|
|
217
|
+
def http
|
|
218
|
+
@http ||= configure_http(new_http)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def new_http
|
|
222
|
+
http = Net::HTTP::Persistent.new connection_name
|
|
223
|
+
http.proxy = @proxy if @proxy
|
|
224
|
+
http
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def configure_http(http)
|
|
228
|
+
http = apply_ssl_options(http)
|
|
229
|
+
|
|
230
|
+
# Net::HTTP timeouts default to 60 seconds.
|
|
231
|
+
if @timeout
|
|
232
|
+
http.open_timeout = @timeout
|
|
233
|
+
http.read_timeout = @timeout
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
[:read_timeout, :open_timeout, :idle_timeout].each do |sym|
|
|
237
|
+
http.send(:"#{sym}=", instance_variable_get(:"@#{sym}")) if instance_variable_get(:"@#{sym}")
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
http
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def apply_ssl_options(http)
|
|
244
|
+
return http unless @site.is_a?(URI::HTTPS)
|
|
245
|
+
|
|
246
|
+
#http.ssl(true) #changed
|
|
247
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
248
|
+
return http unless defined?(@ssl_options)
|
|
249
|
+
|
|
250
|
+
[:ca_path, :ca_file,
|
|
251
|
+
:cert, :key, :cert_store, :ssl_timeout, :ssl_version,
|
|
252
|
+
:verify_mode, :verify_callback, :verify_depth
|
|
253
|
+
].each do |sym|
|
|
254
|
+
http.send(:"#{sym}=", @ssl_options[sym]) if @ssl_options[sym]
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
http
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def default_header
|
|
261
|
+
@default_header ||= {}
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# Builds headers for request to remote service.
|
|
265
|
+
def build_request_headers(headers, http_method, uri)
|
|
266
|
+
authorization_header(http_method, uri).update(default_header).update(http_format_header(http_method)).update(headers)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def response_auth_header
|
|
270
|
+
@response_auth_header ||= ""
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def with_auth
|
|
274
|
+
retried ||= false
|
|
275
|
+
yield
|
|
276
|
+
rescue UnauthorizedAccess => e
|
|
277
|
+
raise if retried || auth_type != :digest
|
|
278
|
+
@response_auth_header = e.response['WWW-Authenticate']
|
|
279
|
+
retried = true
|
|
280
|
+
retry
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def authorization_header(http_method, uri)
|
|
284
|
+
if @user || @password
|
|
285
|
+
if auth_type == :digest
|
|
286
|
+
{ 'Authorization' => digest_auth_header(http_method, uri) }
|
|
287
|
+
else
|
|
288
|
+
{ 'Authorization' => 'Basic ' + ["#{@user}:#{@password}"].pack('m').delete("\r\n") }
|
|
289
|
+
end
|
|
290
|
+
else
|
|
291
|
+
{}
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def digest_auth_header(http_method, uri)
|
|
296
|
+
params = extract_params_from_response
|
|
297
|
+
|
|
298
|
+
ha1 = Digest::MD5.hexdigest("#{@user}:#{params['realm']}:#{@password}")
|
|
299
|
+
ha2 = Digest::MD5.hexdigest("#{http_method.to_s.upcase}:#{uri.path}")
|
|
300
|
+
|
|
301
|
+
params.merge!('cnonce' => client_nonce)
|
|
302
|
+
request_digest = Digest::MD5.hexdigest([ha1, params['nonce'], "0", params['cnonce'], params['qop'], ha2].join(":"))
|
|
303
|
+
"Digest #{auth_attributes_for(uri, request_digest, params)}"
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def client_nonce
|
|
307
|
+
Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535)))
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def extract_params_from_response
|
|
311
|
+
params = {}
|
|
312
|
+
if response_auth_header =~ /^(\w+) (.*)/
|
|
313
|
+
$2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
|
|
314
|
+
end
|
|
315
|
+
params
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def auth_attributes_for(uri, request_digest, params)
|
|
319
|
+
[
|
|
320
|
+
%Q(username="#{@user}"),
|
|
321
|
+
%Q(realm="#{params['realm']}"),
|
|
322
|
+
%Q(qop="#{params['qop']}"),
|
|
323
|
+
%Q(uri="#{uri.path}"),
|
|
324
|
+
%Q(nonce="#{params['nonce']}"),
|
|
325
|
+
%Q(nc="0"),
|
|
326
|
+
%Q(cnonce="#{params['cnonce']}"),
|
|
327
|
+
%Q(opaque="#{params['opaque']}"),
|
|
328
|
+
%Q(response="#{request_digest}")].join(", ")
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def http_format_header(http_method)
|
|
332
|
+
{HTTP_FORMAT_HEADER_NAMES[http_method] => format.mime_type}
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def legitimize_auth_type(auth_type)
|
|
336
|
+
return :basic if auth_type.nil?
|
|
337
|
+
auth_type = auth_type.to_sym
|
|
338
|
+
[:basic, :digest].include?(auth_type) ? auth_type : :basic
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#
|
|
2
|
+
# When this module is included it will prevent normal ActiveResource calls from being made. Be sure to
|
|
3
|
+
# use ActiveSupport::Testing::Isolation and require this module in the setup method if you want to use
|
|
4
|
+
# ActiveResource::HttpMock in the same test suite that hits the server.
|
|
5
|
+
#
|
|
6
|
+
require 'active_resource/http_mock'
|
|
7
|
+
|
|
8
|
+
# Duplicate of ActiveResource::HttpMock method
|
|
9
|
+
class ActiveResource::PersistentConnection
|
|
10
|
+
private
|
|
11
|
+
silence_warnings do
|
|
12
|
+
alias_method :http_without_mock, :http
|
|
13
|
+
# changes behavior, will not cache http object
|
|
14
|
+
def http
|
|
15
|
+
if ActiveResource::HttpMock.enabled?
|
|
16
|
+
ActiveResource::HttpMock.new(@site)
|
|
17
|
+
else
|
|
18
|
+
http_without_mock
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class ActiveResource::HttpMock
|
|
25
|
+
def self.enabled=(bool)
|
|
26
|
+
@enabled = bool
|
|
27
|
+
end
|
|
28
|
+
def self.enabled?
|
|
29
|
+
@enabled
|
|
30
|
+
end
|
|
31
|
+
def request(uri, req)
|
|
32
|
+
headers = {}
|
|
33
|
+
req.each_capitalized{ |k,v| headers[k] = v unless k == 'Accept' && v == '*/*' }
|
|
34
|
+
request = ActiveResource::Request.new(req.method.downcase.to_sym, req.path, req.request_body_permitted? ? req.body : nil, headers)
|
|
35
|
+
self.class.requests << request
|
|
36
|
+
if response = self.class.responses.assoc(request)
|
|
37
|
+
response[1]
|
|
38
|
+
else
|
|
39
|
+
raise ActiveResource::InvalidRequestError.new("Could not find a response recorded for\n #{request.inspect}\n - Responses recorded are:\n #{self.class.responses.map{|r| r.inspect}.join("\n ")}")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Add PATCH support
|
|
45
|
+
class ActiveResource::HttpMock::Responder
|
|
46
|
+
def patch(path, request_headers = {}, body = nil, status = 200, response_headers = {})
|
|
47
|
+
request = ActiveResource::Request.new(:patch, path, nil, request_headers)
|
|
48
|
+
response = ActiveResource::Response.new(body || "", status, response_headers)
|
|
49
|
+
|
|
50
|
+
delete_duplicate_responses(request)
|
|
51
|
+
|
|
52
|
+
@responses << [request, response]
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
class ActiveResource::HttpMock
|
|
56
|
+
class << self
|
|
57
|
+
def patch(path, body, headers)
|
|
58
|
+
request = ActiveResource::Request.new(:patch, path, body, headers)
|
|
59
|
+
self.class.requests << request
|
|
60
|
+
if response = self.class.responses.assoc(request)
|
|
61
|
+
response[1]
|
|
62
|
+
else
|
|
63
|
+
raise InvalidRequestError.new("Could not find a response recorded for \#{request.to_s} - Responses recorded are: \#{inspect_responses}")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|