agile-proxy-jruby 0.1.25-jruby
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.bowerrc +3 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +36 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/Guardfile +20 -0
- data/LICENSE +22 -0
- data/README.md +131 -0
- data/Rakefile +15 -0
- data/agile-proxy.gemspec +60 -0
- data/assets/index.html +39 -0
- data/assets/ui/app/AgileProxyApi.js +31 -0
- data/assets/ui/app/app.js +1 -0
- data/assets/ui/app/controller/Stubs.js +64 -0
- data/assets/ui/app/controller/main.js +12 -0
- data/assets/ui/app/directive/AppEnhancedFormElement.js +21 -0
- data/assets/ui/app/directive/AppFor.js +16 -0
- data/assets/ui/app/directive/AppResponseEditor.js +54 -0
- data/assets/ui/app/model/RequestSpec.js +6 -0
- data/assets/ui/app/routes.js +11 -0
- data/assets/ui/app/service/Dialog.js +49 -0
- data/assets/ui/app/service/DomId.js +10 -0
- data/assets/ui/app/service/Error.js +7 -0
- data/assets/ui/app/service/Stub.js +36 -0
- data/assets/ui/app/view/404.html +2 -0
- data/assets/ui/app/view/dialog/error.html +10 -0
- data/assets/ui/app/view/dialog/yesNo.html +8 -0
- data/assets/ui/app/view/responses/editForm.html +78 -0
- data/assets/ui/app/view/status.html +1 -0
- data/assets/ui/app/view/stubs.html +19 -0
- data/assets/ui/app/view/stubs/edit.html +58 -0
- data/assets/ui/css/main.css +3 -0
- data/bin/agile_proxy +4 -0
- data/bower.json +27 -0
- data/config.yml +6 -0
- data/db.yml +10 -0
- data/db/migrations/20140818110800_create_users.rb +9 -0
- data/db/migrations/20140818134700_create_applications.rb +10 -0
- data/db/migrations/20140818135200_create_request_specs.rb +13 -0
- data/db/migrations/20140821115300_create_responses.rb +14 -0
- data/db/migrations/20140823082900_add_method_to_request_specs.rb +7 -0
- data/db/migrations/20140823083900_rename_request_spec_columns.rb +8 -0
- data/db/migrations/20141031072100_add_url_type_to_request_specs.rb +8 -0
- data/db/migrations/20141105125600_add_conditions_to_request_specs.rb +7 -0
- data/db/migrations/20141106083100_add_username_and_password_to_applications.rb +8 -0
- data/db/migrations/20141119143800_add_record_to_applications.rb +7 -0
- data/db/migrations/20141119174300_create_recordings.rb +18 -0
- data/db/migrations/20150221152500_add_record_requests_to_request_specs.rb +7 -0
- data/db/schema.rb +78 -0
- data/db/seed.rb +26 -0
- data/echo_server.rb +19 -0
- data/examples/README.md +1 -0
- data/examples/facebook_api.html +59 -0
- data/examples/tumblr_api.html +22 -0
- data/lib/agile_proxy.rb +8 -0
- data/lib/agile_proxy/api/applications.rb +77 -0
- data/lib/agile_proxy/api/recordings.rb +52 -0
- data/lib/agile_proxy/api/request_spec_recordings.rb +52 -0
- data/lib/agile_proxy/api/request_specs.rb +86 -0
- data/lib/agile_proxy/api/root.rb +45 -0
- data/lib/agile_proxy/cli.rb +116 -0
- data/lib/agile_proxy/config.rb +66 -0
- data/lib/agile_proxy/handlers/handler.rb +43 -0
- data/lib/agile_proxy/handlers/proxy_handler.rb +111 -0
- data/lib/agile_proxy/handlers/request_handler.rb +75 -0
- data/lib/agile_proxy/handlers/stub_handler.rb +146 -0
- data/lib/agile_proxy/mitm.crt +22 -0
- data/lib/agile_proxy/mitm.key +27 -0
- data/lib/agile_proxy/model/application.rb +20 -0
- data/lib/agile_proxy/model/recording.rb +17 -0
- data/lib/agile_proxy/model/request_spec.rb +48 -0
- data/lib/agile_proxy/model/response.rb +51 -0
- data/lib/agile_proxy/model/user.rb +17 -0
- data/lib/agile_proxy/proxy_connection.rb +112 -0
- data/lib/agile_proxy/rack/get_only_cache.rb +30 -0
- data/lib/agile_proxy/route.rb +106 -0
- data/lib/agile_proxy/router.rb +99 -0
- data/lib/agile_proxy/server.rb +119 -0
- data/lib/agile_proxy/servers/api.rb +40 -0
- data/lib/agile_proxy/servers/request_spec.rb +40 -0
- data/lib/agile_proxy/servers/request_spec_direct.rb +35 -0
- data/lib/agile_proxy/version.rb +6 -0
- data/load_proxy.js +39 -0
- data/log/.gitkeep +0 -0
- data/spec/common_helper.rb +32 -0
- data/spec/fixtures/example_static_file.html +1 -0
- data/spec/fixtures/test-server.crt +15 -0
- data/spec/fixtures/test-server.key +15 -0
- data/spec/integration/helpers/request_spec_helper.rb +84 -0
- data/spec/integration/specs/lib/server_spec.rb +474 -0
- data/spec/integration_spec_helper.rb +16 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/support/test_server.rb +105 -0
- data/spec/unit/agile_proxy/api/applications_spec.rb +102 -0
- data/spec/unit/agile_proxy/api/common_helper.rb +31 -0
- data/spec/unit/agile_proxy/api/recordings_spec.rb +115 -0
- data/spec/unit/agile_proxy/api/request_spec_recordings_spec.rb +119 -0
- data/spec/unit/agile_proxy/api/request_specs_spec.rb +159 -0
- data/spec/unit/agile_proxy/handlers/handler_spec.rb +8 -0
- data/spec/unit/agile_proxy/handlers/proxy_handler_spec.rb +138 -0
- data/spec/unit/agile_proxy/handlers/request_handler_spec.rb +76 -0
- data/spec/unit/agile_proxy/handlers/stub_handler_spec.rb +177 -0
- data/spec/unit/agile_proxy/model/recording_spec.rb +0 -0
- data/spec/unit/agile_proxy/model/request_spec_spec.rb +45 -0
- data/spec/unit/agile_proxy/model/response_spec.rb +38 -0
- data/spec/unit/agile_proxy/server_spec.rb +91 -0
- data/spec/unit/agile_proxy/servers/api_spec.rb +35 -0
- data/spec/unit/agile_proxy/servers/request_spec_direct_spec.rb +51 -0
- data/spec/unit/agile_proxy/servers/request_spec_spec.rb +35 -0
- metadata +736 -0
data/config.yml
ADDED
data/db.yml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateRequestSpecs < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :request_specs do |t|
|
4
|
+
t.integer :user_id #The owner of this spec
|
5
|
+
t.integer :application_id #The application that this spec belongs to
|
6
|
+
t.string :spec #The url matching spec
|
7
|
+
t.text :note #A manual note for this spec
|
8
|
+
t.integer :response_id #The response template to respond with
|
9
|
+
end
|
10
|
+
add_index :request_specs, :application_id, :unique => false
|
11
|
+
add_index :request_specs, :user_id, :unique => false
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateResponses < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :responses do |t|
|
4
|
+
t.string :name #A user friendly name for the response
|
5
|
+
t.text :content
|
6
|
+
t.string :content_type
|
7
|
+
t.integer :status_code, :default => 200
|
8
|
+
t.text :headers, :default => "{}"
|
9
|
+
t.boolean :is_template
|
10
|
+
t.float :delay, :default => 0
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateRecordings < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :recordings do |t|
|
4
|
+
t.integer :application_id
|
5
|
+
t.text :request_headers
|
6
|
+
t.text :request_body
|
7
|
+
t.string :request_url
|
8
|
+
t.string :request_method
|
9
|
+
t.text :response_headers
|
10
|
+
t.text :response_body
|
11
|
+
t.text :response_status
|
12
|
+
t.integer :request_spec_id
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
add_index :recordings, :application_id, :unique => false
|
16
|
+
add_index :recordings, :request_spec_id, :unique => false
|
17
|
+
end
|
18
|
+
end
|
data/db/schema.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended that you check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(version: 20141119174300) do
|
15
|
+
|
16
|
+
create_table "applications", force: true do |t|
|
17
|
+
t.integer "user_id"
|
18
|
+
t.string "name"
|
19
|
+
t.datetime "created_at"
|
20
|
+
t.datetime "updated_at"
|
21
|
+
t.string "username", default: "anonymous"
|
22
|
+
t.string "password", default: "password"
|
23
|
+
t.boolean "record_requests", default: false
|
24
|
+
end
|
25
|
+
|
26
|
+
add_index "applications", ["user_id"], name: "index_applications_on_user_id"
|
27
|
+
|
28
|
+
create_table "recordings", force: true do |t|
|
29
|
+
t.integer "application_id"
|
30
|
+
t.text "request_headers"
|
31
|
+
t.text "request_body"
|
32
|
+
t.string "request_url"
|
33
|
+
t.string "request_method"
|
34
|
+
t.text "response_headers"
|
35
|
+
t.text "response_body"
|
36
|
+
t.text "response_status"
|
37
|
+
t.integer "request_spec_id"
|
38
|
+
t.datetime "created_at"
|
39
|
+
t.datetime "updated_at"
|
40
|
+
end
|
41
|
+
|
42
|
+
add_index "recordings", ["application_id"], name: "index_recordings_on_application_id"
|
43
|
+
add_index "recordings", ["request_spec_id"], name: "index_recordings_on_request_spec_id"
|
44
|
+
|
45
|
+
create_table "request_specs", force: true do |t|
|
46
|
+
t.integer "user_id"
|
47
|
+
t.integer "application_id"
|
48
|
+
t.string "url"
|
49
|
+
t.text "note"
|
50
|
+
t.integer "response_id"
|
51
|
+
t.string "http_method", default: "GET"
|
52
|
+
t.string "url_type", default: "url"
|
53
|
+
t.text "conditions", default: "{}"
|
54
|
+
end
|
55
|
+
|
56
|
+
add_index "request_specs", ["application_id"], name: "index_request_specs_on_application_id"
|
57
|
+
add_index "request_specs", ["user_id"], name: "index_request_specs_on_user_id"
|
58
|
+
|
59
|
+
create_table "responses", force: true do |t|
|
60
|
+
t.string "name"
|
61
|
+
t.text "content"
|
62
|
+
t.string "content_type"
|
63
|
+
t.integer "status_code", default: 200
|
64
|
+
t.text "headers", default: "{}"
|
65
|
+
t.boolean "is_template"
|
66
|
+
t.float "delay", default: 0.0
|
67
|
+
t.datetime "created_at"
|
68
|
+
t.datetime "updated_at"
|
69
|
+
end
|
70
|
+
|
71
|
+
create_table "users", force: true do |t|
|
72
|
+
t.string "name"
|
73
|
+
t.string "email"
|
74
|
+
t.datetime "created_at"
|
75
|
+
t.datetime "updated_at"
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/db/seed.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'agile_proxy/model/user'
|
2
|
+
require 'agile_proxy/model/application'
|
3
|
+
module AgileProxy
|
4
|
+
class Seed
|
5
|
+
class << self
|
6
|
+
def load_seed
|
7
|
+
create_default_user
|
8
|
+
create_default_application
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def create_default_user
|
14
|
+
User.create name: 'public', email: 'public@agileproxy.com', id: 1 if (User.where(name: 'public').count == 0)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_default_application
|
18
|
+
Application.create user_id: public_user.id, name: 'Default Application', username: nil, password: nil, id: 1 if (Application.where(name: 'Default Application').count == 0)
|
19
|
+
end
|
20
|
+
|
21
|
+
def public_user
|
22
|
+
User.where(name: 'public').first
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/echo_server.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'goliath'
|
4
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
5
|
+
class Echo < Goliath::API
|
6
|
+
cattr_accessor :counter
|
7
|
+
def response_code
|
8
|
+
ENV['STATUS_CODE'] || 200
|
9
|
+
end
|
10
|
+
def response(env)
|
11
|
+
self.counter = counter || 0
|
12
|
+
req_body = env['rack.input'].read
|
13
|
+
request_info = "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
|
14
|
+
res_body = request_info
|
15
|
+
res_body += "\n#{req_body}" unless req_body.empty?
|
16
|
+
self.counter += 1
|
17
|
+
[response_code, { 'HTTP-X-EchoServer' => request_info, 'HTTP-X-EchoCount' => "#{counter}" }, res_body]
|
18
|
+
end
|
19
|
+
end
|
data/examples/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
See example specs in `spec/requests/examples`.
|
@@ -0,0 +1,59 @@
|
|
1
|
+
<div id="fb-root"></div>
|
2
|
+
<script>
|
3
|
+
// Load the SDK Asynchronously
|
4
|
+
(function(d){
|
5
|
+
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
|
6
|
+
if (d.getElementById(id)) {return;}
|
7
|
+
js = d.createElement('script'); js.id = id; js.async = true;
|
8
|
+
js.src = "//connect.facebook.net/en_US/all.js";
|
9
|
+
ref.parentNode.insertBefore(js, ref);
|
10
|
+
}(document));
|
11
|
+
|
12
|
+
// Init the SDK upon load
|
13
|
+
window.fbAsyncInit = function() {
|
14
|
+
FB.init({
|
15
|
+
appId : '408416075843608', // App ID
|
16
|
+
//channelUrl : '//'+window.location.hostname+'/channel', // Path to your Channel File
|
17
|
+
status : true, // check login status
|
18
|
+
cookie : true, // enable cookies to allow the server to access the session
|
19
|
+
xfbml : true // parse XFBML
|
20
|
+
});
|
21
|
+
|
22
|
+
// listen for and handle auth.statusChange events
|
23
|
+
FB.Event.subscribe('auth.statusChange', function(response) {
|
24
|
+
if (response.authResponse) {
|
25
|
+
// user has auth'd your app and is logged into Facebook
|
26
|
+
FB.api('/me', function(me){
|
27
|
+
if (me.name) {
|
28
|
+
document.getElementById('auth-displayname').innerHTML = me.name;
|
29
|
+
}
|
30
|
+
});
|
31
|
+
document.getElementById('auth-loggedout').style.display = 'none';
|
32
|
+
document.getElementById('auth-loggedin').style.display = 'block';
|
33
|
+
} else {
|
34
|
+
// user has not auth'd your app, or is not logged into Facebook
|
35
|
+
document.getElementById('auth-loggedout').style.display = 'block';
|
36
|
+
document.getElementById('auth-loggedin').style.display = 'none';
|
37
|
+
}
|
38
|
+
});
|
39
|
+
|
40
|
+
// respond to clicks on the login and logout links
|
41
|
+
document.getElementById('auth-loginlink').addEventListener('click', function(){
|
42
|
+
FB.login();
|
43
|
+
});
|
44
|
+
document.getElementById('auth-logoutlink').addEventListener('click', function(){
|
45
|
+
FB.logout();
|
46
|
+
});
|
47
|
+
}
|
48
|
+
</script>
|
49
|
+
|
50
|
+
<h1>Facebook Client-side Authentication Example</h1>
|
51
|
+
<div id="auth-status">
|
52
|
+
<div id="auth-loggedout">
|
53
|
+
<a href="#" id="auth-loginlink">Login</a>
|
54
|
+
</div>
|
55
|
+
<div id="auth-loggedin" style="display:none">
|
56
|
+
Hi, <span id="auth-displayname"></span>
|
57
|
+
(<a href="#" id="auth-logoutlink">logout</a>)
|
58
|
+
</div>
|
59
|
+
</div>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<body>
|
3
|
+
<h1>Latest news</h1>
|
4
|
+
<div id="news"></div>
|
5
|
+
|
6
|
+
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.min.js'></script>
|
7
|
+
<script type='text/javascript'>
|
8
|
+
$(function () {
|
9
|
+
var url = 'http://blog.howmanyleft.co.uk/api/read/json?callback=?&type=text&num=3&filter=text';
|
10
|
+
$.getJSON(url, function (data) {
|
11
|
+
$.each(data.posts, function (idx, post) {
|
12
|
+
var title = post['regular-title'];
|
13
|
+
var href = post['url-with-slug'];
|
14
|
+
var body = post['regular-body'];
|
15
|
+
$('#news').append(
|
16
|
+
'<h3><a href="' + href + '">' + title + '</a></h3>' +
|
17
|
+
'<p>' + body + '</p>');
|
18
|
+
});
|
19
|
+
});
|
20
|
+
})
|
21
|
+
</script>
|
22
|
+
</body>
|
data/lib/agile_proxy.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'agile_proxy/version'
|
2
|
+
require 'agile_proxy/config'
|
3
|
+
require 'agile_proxy/handlers/handler'
|
4
|
+
require 'agile_proxy/handlers/request_handler'
|
5
|
+
require 'agile_proxy/handlers/stub_handler'
|
6
|
+
require 'agile_proxy/handlers/proxy_handler'
|
7
|
+
require 'agile_proxy/server'
|
8
|
+
require 'agile_proxy/proxy_connection'
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module AgileProxy
|
2
|
+
module Api
|
3
|
+
#
|
4
|
+
# = A grape api for applications
|
5
|
+
#
|
6
|
+
# An application is a central resource for the proxy, it is the 'application under test or development'
|
7
|
+
#
|
8
|
+
# The proxy server can handle multiple applications by assigning each one a different username and password
|
9
|
+
# that is used when connecting to the proxy.
|
10
|
+
# Each application can have its own set of stubs, can be set to record or not and much much more.
|
11
|
+
class Applications < Grape::API
|
12
|
+
include Grape::Kaminari
|
13
|
+
helpers do
|
14
|
+
# We only allow selected parameters through - spec and note
|
15
|
+
def permitted_params
|
16
|
+
@permitted_params ||= declared(
|
17
|
+
params,
|
18
|
+
{ include_missing: false },
|
19
|
+
[:username, :password, :name, :record_requests]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Convenient access to the record specified in the id parameter
|
24
|
+
def record
|
25
|
+
current_user.applications.where(id: params[:id]).first
|
26
|
+
end
|
27
|
+
|
28
|
+
# Convenient access to the record parameters from a POST or a PUT, only permitted will be returned
|
29
|
+
def record_params
|
30
|
+
permitted_params.with_indifferent_access
|
31
|
+
end
|
32
|
+
|
33
|
+
def default_json_spec
|
34
|
+
{}
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
resource :applications do
|
40
|
+
desc 'List all applications for the user'
|
41
|
+
paginate per_page: 20, max_per_page: 200
|
42
|
+
get do
|
43
|
+
authenticate!
|
44
|
+
scope = current_user.applications
|
45
|
+
{ applications: paginate(scope).as_json(default_json_spec), total: scope.count }
|
46
|
+
end
|
47
|
+
desc 'Delete all applications for the user'
|
48
|
+
delete do
|
49
|
+
authenticate!
|
50
|
+
scope = current_user.applications
|
51
|
+
scope.destroy_all
|
52
|
+
{ applications: [], total: 0 }
|
53
|
+
end
|
54
|
+
desc 'Create a new application for the user'
|
55
|
+
post do
|
56
|
+
authenticate!
|
57
|
+
current_user.applications.create!(record_params.merge user_id: current_user.id).as_json(default_json_spec)
|
58
|
+
end
|
59
|
+
desc 'Get an application by id'
|
60
|
+
get ':id' do
|
61
|
+
authenticate!
|
62
|
+
record.as_json(default_json_spec)
|
63
|
+
end
|
64
|
+
delete ':id' do
|
65
|
+
authenticate!
|
66
|
+
record.tap(&:destroy).as_json(default_json_spec)
|
67
|
+
end
|
68
|
+
desc 'Update a request application'
|
69
|
+
put ':id' do
|
70
|
+
authenticate!
|
71
|
+
record.tap { |r| r.update_attributes(record_params) }.as_json(default_json_spec)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|